@@ -9,146 +9,146 @@ |
||
| 9 | 9 | * Updates the customer billing and shipping address and returns an updated cart--things such as taxes may be recalculated. |
| 10 | 10 | */ |
| 11 | 11 | class CartUpdateCustomer extends AbstractCartRoute { |
| 12 | - use DraftOrderTrait; |
|
| 12 | + use DraftOrderTrait; |
|
| 13 | 13 | |
| 14 | - /** |
|
| 15 | - * The route identifier. |
|
| 16 | - * |
|
| 17 | - * @var string |
|
| 18 | - */ |
|
| 19 | - const IDENTIFIER = 'cart-update-customer'; |
|
| 14 | + /** |
|
| 15 | + * The route identifier. |
|
| 16 | + * |
|
| 17 | + * @var string |
|
| 18 | + */ |
|
| 19 | + const IDENTIFIER = 'cart-update-customer'; |
|
| 20 | 20 | |
| 21 | - /** |
|
| 22 | - * Get the path of this REST route. |
|
| 23 | - * |
|
| 24 | - * @return string |
|
| 25 | - */ |
|
| 26 | - public function get_path() { |
|
| 27 | - return '/cart/update-customer'; |
|
| 28 | - } |
|
| 21 | + /** |
|
| 22 | + * Get the path of this REST route. |
|
| 23 | + * |
|
| 24 | + * @return string |
|
| 25 | + */ |
|
| 26 | + public function get_path() { |
|
| 27 | + return '/cart/update-customer'; |
|
| 28 | + } |
|
| 29 | 29 | |
| 30 | - /** |
|
| 31 | - * Get method arguments for this REST route. |
|
| 32 | - * |
|
| 33 | - * @return array An array of endpoints. |
|
| 34 | - */ |
|
| 35 | - public function get_args() { |
|
| 36 | - return [ |
|
| 37 | - [ |
|
| 38 | - 'methods' => \WP_REST_Server::CREATABLE, |
|
| 39 | - 'callback' => [ $this, 'get_response' ], |
|
| 40 | - 'permission_callback' => '__return_true', |
|
| 41 | - 'args' => [ |
|
| 42 | - 'billing_address' => [ |
|
| 43 | - 'description' => __( 'Billing address.', 'woocommerce' ), |
|
| 44 | - 'type' => 'object', |
|
| 45 | - 'context' => [ 'view', 'edit' ], |
|
| 46 | - 'properties' => $this->schema->billing_address_schema->get_properties(), |
|
| 47 | - 'sanitize_callback' => [ $this->schema->billing_address_schema, 'sanitize_callback' ], |
|
| 48 | - 'validate_callback' => [ $this->schema->billing_address_schema, 'validate_callback' ], |
|
| 49 | - ], |
|
| 50 | - 'shipping_address' => [ |
|
| 51 | - 'description' => __( 'Shipping address.', 'woocommerce' ), |
|
| 52 | - 'type' => 'object', |
|
| 53 | - 'context' => [ 'view', 'edit' ], |
|
| 54 | - 'properties' => $this->schema->shipping_address_schema->get_properties(), |
|
| 55 | - 'sanitize_callback' => [ $this->schema->shipping_address_schema, 'sanitize_callback' ], |
|
| 56 | - 'validate_callback' => [ $this->schema->shipping_address_schema, 'validate_callback' ], |
|
| 57 | - ], |
|
| 58 | - ], |
|
| 59 | - ], |
|
| 60 | - 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 61 | - 'allow_batch' => [ 'v1' => true ], |
|
| 62 | - ]; |
|
| 63 | - } |
|
| 30 | + /** |
|
| 31 | + * Get method arguments for this REST route. |
|
| 32 | + * |
|
| 33 | + * @return array An array of endpoints. |
|
| 34 | + */ |
|
| 35 | + public function get_args() { |
|
| 36 | + return [ |
|
| 37 | + [ |
|
| 38 | + 'methods' => \WP_REST_Server::CREATABLE, |
|
| 39 | + 'callback' => [ $this, 'get_response' ], |
|
| 40 | + 'permission_callback' => '__return_true', |
|
| 41 | + 'args' => [ |
|
| 42 | + 'billing_address' => [ |
|
| 43 | + 'description' => __( 'Billing address.', 'woocommerce' ), |
|
| 44 | + 'type' => 'object', |
|
| 45 | + 'context' => [ 'view', 'edit' ], |
|
| 46 | + 'properties' => $this->schema->billing_address_schema->get_properties(), |
|
| 47 | + 'sanitize_callback' => [ $this->schema->billing_address_schema, 'sanitize_callback' ], |
|
| 48 | + 'validate_callback' => [ $this->schema->billing_address_schema, 'validate_callback' ], |
|
| 49 | + ], |
|
| 50 | + 'shipping_address' => [ |
|
| 51 | + 'description' => __( 'Shipping address.', 'woocommerce' ), |
|
| 52 | + 'type' => 'object', |
|
| 53 | + 'context' => [ 'view', 'edit' ], |
|
| 54 | + 'properties' => $this->schema->shipping_address_schema->get_properties(), |
|
| 55 | + 'sanitize_callback' => [ $this->schema->shipping_address_schema, 'sanitize_callback' ], |
|
| 56 | + 'validate_callback' => [ $this->schema->shipping_address_schema, 'validate_callback' ], |
|
| 57 | + ], |
|
| 58 | + ], |
|
| 59 | + ], |
|
| 60 | + 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 61 | + 'allow_batch' => [ 'v1' => true ], |
|
| 62 | + ]; |
|
| 63 | + } |
|
| 64 | 64 | |
| 65 | - /** |
|
| 66 | - * Handle the request and return a valid response for this endpoint. |
|
| 67 | - * |
|
| 68 | - * @param \WP_REST_Request $request Request object. |
|
| 69 | - * @return \WP_REST_Response |
|
| 70 | - */ |
|
| 71 | - protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 72 | - $cart = $this->cart_controller->get_cart_instance(); |
|
| 73 | - $billing = $request['billing_address'] ?? []; |
|
| 74 | - $shipping = $request['shipping_address'] ?? []; |
|
| 75 | - $customer = wc()->customer; |
|
| 65 | + /** |
|
| 66 | + * Handle the request and return a valid response for this endpoint. |
|
| 67 | + * |
|
| 68 | + * @param \WP_REST_Request $request Request object. |
|
| 69 | + * @return \WP_REST_Response |
|
| 70 | + */ |
|
| 71 | + protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 72 | + $cart = $this->cart_controller->get_cart_instance(); |
|
| 73 | + $billing = $request['billing_address'] ?? []; |
|
| 74 | + $shipping = $request['shipping_address'] ?? []; |
|
| 75 | + $customer = wc()->customer; |
|
| 76 | 76 | |
| 77 | - if ( ! $cart->needs_shipping() && ! isset( $request['shipping_address'] ) ) { |
|
| 78 | - // If the cart does not need shipping, shipping address is forced to match billing address unless defined. |
|
| 79 | - $shipping = $request['billing_address'] ?? $this->get_customer_billing_address( $customer ); |
|
| 80 | - } |
|
| 77 | + if ( ! $cart->needs_shipping() && ! isset( $request['shipping_address'] ) ) { |
|
| 78 | + // If the cart does not need shipping, shipping address is forced to match billing address unless defined. |
|
| 79 | + $shipping = $request['billing_address'] ?? $this->get_customer_billing_address( $customer ); |
|
| 80 | + } |
|
| 81 | 81 | |
| 82 | - $customer->set_props( |
|
| 83 | - array( |
|
| 84 | - 'billing_first_name' => $billing['first_name'] ?? null, |
|
| 85 | - 'billing_last_name' => $billing['last_name'] ?? null, |
|
| 86 | - 'billing_company' => $billing['company'] ?? null, |
|
| 87 | - 'billing_address_1' => $billing['address_1'] ?? null, |
|
| 88 | - 'billing_address_2' => $billing['address_2'] ?? null, |
|
| 89 | - 'billing_city' => $billing['city'] ?? null, |
|
| 90 | - 'billing_state' => $billing['state'] ?? null, |
|
| 91 | - 'billing_postcode' => $billing['postcode'] ?? null, |
|
| 92 | - 'billing_country' => $billing['country'] ?? null, |
|
| 93 | - 'billing_phone' => $billing['phone'] ?? null, |
|
| 94 | - 'billing_email' => $billing['email'] ?? null, |
|
| 95 | - 'shipping_first_name' => $shipping['first_name'] ?? null, |
|
| 96 | - 'shipping_last_name' => $shipping['last_name'] ?? null, |
|
| 97 | - 'shipping_company' => $shipping['company'] ?? null, |
|
| 98 | - 'shipping_address_1' => $shipping['address_1'] ?? null, |
|
| 99 | - 'shipping_address_2' => $shipping['address_2'] ?? null, |
|
| 100 | - 'shipping_city' => $shipping['city'] ?? null, |
|
| 101 | - 'shipping_state' => $shipping['state'] ?? null, |
|
| 102 | - 'shipping_postcode' => $shipping['postcode'] ?? null, |
|
| 103 | - 'shipping_country' => $shipping['country'] ?? null, |
|
| 104 | - 'shipping_phone' => $shipping['phone'] ?? null, |
|
| 105 | - ) |
|
| 106 | - ); |
|
| 82 | + $customer->set_props( |
|
| 83 | + array( |
|
| 84 | + 'billing_first_name' => $billing['first_name'] ?? null, |
|
| 85 | + 'billing_last_name' => $billing['last_name'] ?? null, |
|
| 86 | + 'billing_company' => $billing['company'] ?? null, |
|
| 87 | + 'billing_address_1' => $billing['address_1'] ?? null, |
|
| 88 | + 'billing_address_2' => $billing['address_2'] ?? null, |
|
| 89 | + 'billing_city' => $billing['city'] ?? null, |
|
| 90 | + 'billing_state' => $billing['state'] ?? null, |
|
| 91 | + 'billing_postcode' => $billing['postcode'] ?? null, |
|
| 92 | + 'billing_country' => $billing['country'] ?? null, |
|
| 93 | + 'billing_phone' => $billing['phone'] ?? null, |
|
| 94 | + 'billing_email' => $billing['email'] ?? null, |
|
| 95 | + 'shipping_first_name' => $shipping['first_name'] ?? null, |
|
| 96 | + 'shipping_last_name' => $shipping['last_name'] ?? null, |
|
| 97 | + 'shipping_company' => $shipping['company'] ?? null, |
|
| 98 | + 'shipping_address_1' => $shipping['address_1'] ?? null, |
|
| 99 | + 'shipping_address_2' => $shipping['address_2'] ?? null, |
|
| 100 | + 'shipping_city' => $shipping['city'] ?? null, |
|
| 101 | + 'shipping_state' => $shipping['state'] ?? null, |
|
| 102 | + 'shipping_postcode' => $shipping['postcode'] ?? null, |
|
| 103 | + 'shipping_country' => $shipping['country'] ?? null, |
|
| 104 | + 'shipping_phone' => $shipping['phone'] ?? null, |
|
| 105 | + ) |
|
| 106 | + ); |
|
| 107 | 107 | |
| 108 | - wc_do_deprecated_action( |
|
| 109 | - 'woocommerce_blocks_cart_update_customer_from_request', |
|
| 110 | - array( |
|
| 111 | - $customer, |
|
| 112 | - $request, |
|
| 113 | - ), |
|
| 114 | - '7.2.0', |
|
| 115 | - 'woocommerce_store_api_cart_update_customer_from_request', |
|
| 116 | - 'This action was deprecated in WooCommerce Blocks version 7.2.0. Please use woocommerce_store_api_cart_update_customer_from_request instead.' |
|
| 117 | - ); |
|
| 108 | + wc_do_deprecated_action( |
|
| 109 | + 'woocommerce_blocks_cart_update_customer_from_request', |
|
| 110 | + array( |
|
| 111 | + $customer, |
|
| 112 | + $request, |
|
| 113 | + ), |
|
| 114 | + '7.2.0', |
|
| 115 | + 'woocommerce_store_api_cart_update_customer_from_request', |
|
| 116 | + 'This action was deprecated in WooCommerce Blocks version 7.2.0. Please use woocommerce_store_api_cart_update_customer_from_request instead.' |
|
| 117 | + ); |
|
| 118 | 118 | |
| 119 | - /** |
|
| 120 | - * Fires when the Checkout Block/Store API updates a customer from the API request data. |
|
| 121 | - * |
|
| 122 | - * @param \WC_Customer $customer Customer object. |
|
| 123 | - * @param \WP_REST_Request $request Full details about the request. |
|
| 124 | - */ |
|
| 125 | - do_action( 'woocommerce_store_api_cart_update_customer_from_request', $customer, $request ); |
|
| 119 | + /** |
|
| 120 | + * Fires when the Checkout Block/Store API updates a customer from the API request data. |
|
| 121 | + * |
|
| 122 | + * @param \WC_Customer $customer Customer object. |
|
| 123 | + * @param \WP_REST_Request $request Full details about the request. |
|
| 124 | + */ |
|
| 125 | + do_action( 'woocommerce_store_api_cart_update_customer_from_request', $customer, $request ); |
|
| 126 | 126 | |
| 127 | - $customer->save(); |
|
| 127 | + $customer->save(); |
|
| 128 | 128 | |
| 129 | - $this->calculate_totals(); |
|
| 129 | + $this->calculate_totals(); |
|
| 130 | 130 | |
| 131 | - return rest_ensure_response( $this->schema->get_item_response( $cart ) ); |
|
| 132 | - } |
|
| 131 | + return rest_ensure_response( $this->schema->get_item_response( $cart ) ); |
|
| 132 | + } |
|
| 133 | 133 | |
| 134 | - /** |
|
| 135 | - * Get full customer billing address. |
|
| 136 | - * |
|
| 137 | - * @param \WC_Customer $customer Customer object. |
|
| 138 | - * @return array |
|
| 139 | - */ |
|
| 140 | - protected function get_customer_billing_address( \WC_Customer $customer ) { |
|
| 141 | - return [ |
|
| 142 | - 'first_name' => $customer->get_billing_first_name(), |
|
| 143 | - 'last_name' => $customer->get_billing_last_name(), |
|
| 144 | - 'company' => $customer->get_billing_company(), |
|
| 145 | - 'address_1' => $customer->get_billing_address_1(), |
|
| 146 | - 'address_2' => $customer->get_billing_address_2(), |
|
| 147 | - 'city' => $customer->get_billing_city(), |
|
| 148 | - 'state' => $customer->get_billing_state(), |
|
| 149 | - 'postcode' => $customer->get_billing_postcode(), |
|
| 150 | - 'country' => $customer->get_billing_country(), |
|
| 151 | - 'phone' => $customer->get_billing_phone(), |
|
| 152 | - ]; |
|
| 153 | - } |
|
| 134 | + /** |
|
| 135 | + * Get full customer billing address. |
|
| 136 | + * |
|
| 137 | + * @param \WC_Customer $customer Customer object. |
|
| 138 | + * @return array |
|
| 139 | + */ |
|
| 140 | + protected function get_customer_billing_address( \WC_Customer $customer ) { |
|
| 141 | + return [ |
|
| 142 | + 'first_name' => $customer->get_billing_first_name(), |
|
| 143 | + 'last_name' => $customer->get_billing_last_name(), |
|
| 144 | + 'company' => $customer->get_billing_company(), |
|
| 145 | + 'address_1' => $customer->get_billing_address_1(), |
|
| 146 | + 'address_2' => $customer->get_billing_address_2(), |
|
| 147 | + 'city' => $customer->get_billing_city(), |
|
| 148 | + 'state' => $customer->get_billing_state(), |
|
| 149 | + 'postcode' => $customer->get_billing_postcode(), |
|
| 150 | + 'country' => $customer->get_billing_country(), |
|
| 151 | + 'phone' => $customer->get_billing_phone(), |
|
| 152 | + ]; |
|
| 153 | + } |
|
| 154 | 154 | } |
@@ -36,29 +36,29 @@ discard block |
||
| 36 | 36 | return [ |
| 37 | 37 | [ |
| 38 | 38 | 'methods' => \WP_REST_Server::CREATABLE, |
| 39 | - 'callback' => [ $this, 'get_response' ], |
|
| 39 | + 'callback' => [$this, 'get_response'], |
|
| 40 | 40 | 'permission_callback' => '__return_true', |
| 41 | 41 | 'args' => [ |
| 42 | 42 | 'billing_address' => [ |
| 43 | - 'description' => __( 'Billing address.', 'woocommerce' ), |
|
| 43 | + 'description' => __('Billing address.', 'woocommerce'), |
|
| 44 | 44 | 'type' => 'object', |
| 45 | - 'context' => [ 'view', 'edit' ], |
|
| 45 | + 'context' => ['view', 'edit'], |
|
| 46 | 46 | 'properties' => $this->schema->billing_address_schema->get_properties(), |
| 47 | - 'sanitize_callback' => [ $this->schema->billing_address_schema, 'sanitize_callback' ], |
|
| 48 | - 'validate_callback' => [ $this->schema->billing_address_schema, 'validate_callback' ], |
|
| 47 | + 'sanitize_callback' => [$this->schema->billing_address_schema, 'sanitize_callback'], |
|
| 48 | + 'validate_callback' => [$this->schema->billing_address_schema, 'validate_callback'], |
|
| 49 | 49 | ], |
| 50 | 50 | 'shipping_address' => [ |
| 51 | - 'description' => __( 'Shipping address.', 'woocommerce' ), |
|
| 51 | + 'description' => __('Shipping address.', 'woocommerce'), |
|
| 52 | 52 | 'type' => 'object', |
| 53 | - 'context' => [ 'view', 'edit' ], |
|
| 53 | + 'context' => ['view', 'edit'], |
|
| 54 | 54 | 'properties' => $this->schema->shipping_address_schema->get_properties(), |
| 55 | - 'sanitize_callback' => [ $this->schema->shipping_address_schema, 'sanitize_callback' ], |
|
| 56 | - 'validate_callback' => [ $this->schema->shipping_address_schema, 'validate_callback' ], |
|
| 55 | + 'sanitize_callback' => [$this->schema->shipping_address_schema, 'sanitize_callback'], |
|
| 56 | + 'validate_callback' => [$this->schema->shipping_address_schema, 'validate_callback'], |
|
| 57 | 57 | ], |
| 58 | 58 | ], |
| 59 | 59 | ], |
| 60 | - 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 61 | - 'allow_batch' => [ 'v1' => true ], |
|
| 60 | + 'schema' => [$this->schema, 'get_public_item_schema'], |
|
| 61 | + 'allow_batch' => ['v1' => true], |
|
| 62 | 62 | ]; |
| 63 | 63 | } |
| 64 | 64 | |
@@ -68,15 +68,15 @@ discard block |
||
| 68 | 68 | * @param \WP_REST_Request $request Request object. |
| 69 | 69 | * @return \WP_REST_Response |
| 70 | 70 | */ |
| 71 | - protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 71 | + protected function get_route_post_response(\WP_REST_Request $request) { |
|
| 72 | 72 | $cart = $this->cart_controller->get_cart_instance(); |
| 73 | 73 | $billing = $request['billing_address'] ?? []; |
| 74 | 74 | $shipping = $request['shipping_address'] ?? []; |
| 75 | 75 | $customer = wc()->customer; |
| 76 | 76 | |
| 77 | - if ( ! $cart->needs_shipping() && ! isset( $request['shipping_address'] ) ) { |
|
| 77 | + if (!$cart->needs_shipping() && !isset($request['shipping_address'])) { |
|
| 78 | 78 | // If the cart does not need shipping, shipping address is forced to match billing address unless defined. |
| 79 | - $shipping = $request['billing_address'] ?? $this->get_customer_billing_address( $customer ); |
|
| 79 | + $shipping = $request['billing_address'] ?? $this->get_customer_billing_address($customer); |
|
| 80 | 80 | } |
| 81 | 81 | |
| 82 | 82 | $customer->set_props( |
@@ -122,13 +122,13 @@ discard block |
||
| 122 | 122 | * @param \WC_Customer $customer Customer object. |
| 123 | 123 | * @param \WP_REST_Request $request Full details about the request. |
| 124 | 124 | */ |
| 125 | - do_action( 'woocommerce_store_api_cart_update_customer_from_request', $customer, $request ); |
|
| 125 | + do_action('woocommerce_store_api_cart_update_customer_from_request', $customer, $request); |
|
| 126 | 126 | |
| 127 | 127 | $customer->save(); |
| 128 | 128 | |
| 129 | 129 | $this->calculate_totals(); |
| 130 | 130 | |
| 131 | - return rest_ensure_response( $this->schema->get_item_response( $cart ) ); |
|
| 131 | + return rest_ensure_response($this->schema->get_item_response($cart)); |
|
| 132 | 132 | } |
| 133 | 133 | |
| 134 | 134 | /** |
@@ -137,7 +137,7 @@ discard block |
||
| 137 | 137 | * @param \WC_Customer $customer Customer object. |
| 138 | 138 | * @return array |
| 139 | 139 | */ |
| 140 | - protected function get_customer_billing_address( \WC_Customer $customer ) { |
|
| 140 | + protected function get_customer_billing_address(\WC_Customer $customer) { |
|
| 141 | 141 | return [ |
| 142 | 142 | 'first_name' => $customer->get_billing_first_name(), |
| 143 | 143 | 'last_name' => $customer->get_billing_last_name(), |
@@ -5,46 +5,46 @@ |
||
| 5 | 5 | * ProductTags class. |
| 6 | 6 | */ |
| 7 | 7 | class ProductTags extends AbstractTermsRoute { |
| 8 | - /** |
|
| 9 | - * The route identifier. |
|
| 10 | - * |
|
| 11 | - * @var string |
|
| 12 | - */ |
|
| 13 | - const IDENTIFIER = 'product-tags'; |
|
| 8 | + /** |
|
| 9 | + * The route identifier. |
|
| 10 | + * |
|
| 11 | + * @var string |
|
| 12 | + */ |
|
| 13 | + const IDENTIFIER = 'product-tags'; |
|
| 14 | 14 | |
| 15 | - /** |
|
| 16 | - * Get the path of this REST route. |
|
| 17 | - * |
|
| 18 | - * @return string |
|
| 19 | - */ |
|
| 20 | - public function get_path() { |
|
| 21 | - return '/products/tags'; |
|
| 22 | - } |
|
| 15 | + /** |
|
| 16 | + * Get the path of this REST route. |
|
| 17 | + * |
|
| 18 | + * @return string |
|
| 19 | + */ |
|
| 20 | + public function get_path() { |
|
| 21 | + return '/products/tags'; |
|
| 22 | + } |
|
| 23 | 23 | |
| 24 | - /** |
|
| 25 | - * Get method arguments for this REST route. |
|
| 26 | - * |
|
| 27 | - * @return array An array of endpoints. |
|
| 28 | - */ |
|
| 29 | - public function get_args() { |
|
| 30 | - return [ |
|
| 31 | - [ |
|
| 32 | - 'methods' => \WP_REST_Server::READABLE, |
|
| 33 | - 'callback' => [ $this, 'get_response' ], |
|
| 34 | - 'permission_callback' => '__return_true', |
|
| 35 | - 'args' => $this->get_collection_params(), |
|
| 36 | - ], |
|
| 37 | - 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 38 | - ]; |
|
| 39 | - } |
|
| 24 | + /** |
|
| 25 | + * Get method arguments for this REST route. |
|
| 26 | + * |
|
| 27 | + * @return array An array of endpoints. |
|
| 28 | + */ |
|
| 29 | + public function get_args() { |
|
| 30 | + return [ |
|
| 31 | + [ |
|
| 32 | + 'methods' => \WP_REST_Server::READABLE, |
|
| 33 | + 'callback' => [ $this, 'get_response' ], |
|
| 34 | + 'permission_callback' => '__return_true', |
|
| 35 | + 'args' => $this->get_collection_params(), |
|
| 36 | + ], |
|
| 37 | + 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 38 | + ]; |
|
| 39 | + } |
|
| 40 | 40 | |
| 41 | - /** |
|
| 42 | - * Get a collection of terms. |
|
| 43 | - * |
|
| 44 | - * @param \WP_REST_Request $request Request object. |
|
| 45 | - * @return \WP_REST_Response |
|
| 46 | - */ |
|
| 47 | - protected function get_route_response( \WP_REST_Request $request ) { |
|
| 48 | - return $this->get_terms_response( 'product_tag', $request ); |
|
| 49 | - } |
|
| 41 | + /** |
|
| 42 | + * Get a collection of terms. |
|
| 43 | + * |
|
| 44 | + * @param \WP_REST_Request $request Request object. |
|
| 45 | + * @return \WP_REST_Response |
|
| 46 | + */ |
|
| 47 | + protected function get_route_response( \WP_REST_Request $request ) { |
|
| 48 | + return $this->get_terms_response( 'product_tag', $request ); |
|
| 49 | + } |
|
| 50 | 50 | } |
@@ -30,11 +30,11 @@ discard block |
||
| 30 | 30 | return [ |
| 31 | 31 | [ |
| 32 | 32 | 'methods' => \WP_REST_Server::READABLE, |
| 33 | - 'callback' => [ $this, 'get_response' ], |
|
| 33 | + 'callback' => [$this, 'get_response'], |
|
| 34 | 34 | 'permission_callback' => '__return_true', |
| 35 | 35 | 'args' => $this->get_collection_params(), |
| 36 | 36 | ], |
| 37 | - 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 37 | + 'schema' => [$this->schema, 'get_public_item_schema'], |
|
| 38 | 38 | ]; |
| 39 | 39 | } |
| 40 | 40 | |
@@ -44,7 +44,7 @@ discard block |
||
| 44 | 44 | * @param \WP_REST_Request $request Request object. |
| 45 | 45 | * @return \WP_REST_Response |
| 46 | 46 | */ |
| 47 | - protected function get_route_response( \WP_REST_Request $request ) { |
|
| 48 | - return $this->get_terms_response( 'product_tag', $request ); |
|
| 47 | + protected function get_route_response(\WP_REST_Request $request) { |
|
| 48 | + return $this->get_terms_response('product_tag', $request); |
|
| 49 | 49 | } |
| 50 | 50 | } |
@@ -8,80 +8,80 @@ |
||
| 8 | 8 | * CartRemoveItem class. |
| 9 | 9 | */ |
| 10 | 10 | class CartRemoveItem extends AbstractCartRoute { |
| 11 | - use DraftOrderTrait; |
|
| 11 | + use DraftOrderTrait; |
|
| 12 | 12 | |
| 13 | - /** |
|
| 14 | - * The route identifier. |
|
| 15 | - * |
|
| 16 | - * @var string |
|
| 17 | - */ |
|
| 18 | - const IDENTIFIER = 'cart-remove-item'; |
|
| 13 | + /** |
|
| 14 | + * The route identifier. |
|
| 15 | + * |
|
| 16 | + * @var string |
|
| 17 | + */ |
|
| 18 | + const IDENTIFIER = 'cart-remove-item'; |
|
| 19 | 19 | |
| 20 | - /** |
|
| 21 | - * Get the path of this REST route. |
|
| 22 | - * |
|
| 23 | - * @return string |
|
| 24 | - */ |
|
| 25 | - public function get_path() { |
|
| 26 | - return '/cart/remove-item'; |
|
| 27 | - } |
|
| 20 | + /** |
|
| 21 | + * Get the path of this REST route. |
|
| 22 | + * |
|
| 23 | + * @return string |
|
| 24 | + */ |
|
| 25 | + public function get_path() { |
|
| 26 | + return '/cart/remove-item'; |
|
| 27 | + } |
|
| 28 | 28 | |
| 29 | - /** |
|
| 30 | - * Get method arguments for this REST route. |
|
| 31 | - * |
|
| 32 | - * @return array An array of endpoints. |
|
| 33 | - */ |
|
| 34 | - public function get_args() { |
|
| 35 | - return [ |
|
| 36 | - [ |
|
| 37 | - 'methods' => \WP_REST_Server::CREATABLE, |
|
| 38 | - 'callback' => [ $this, 'get_response' ], |
|
| 39 | - 'permission_callback' => '__return_true', |
|
| 40 | - 'args' => [ |
|
| 41 | - 'key' => [ |
|
| 42 | - 'description' => __( 'Unique identifier (key) for the cart item.', 'woocommerce' ), |
|
| 43 | - 'type' => 'string', |
|
| 44 | - ], |
|
| 45 | - ], |
|
| 46 | - ], |
|
| 47 | - 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 48 | - 'allow_batch' => [ 'v1' => true ], |
|
| 49 | - ]; |
|
| 50 | - } |
|
| 29 | + /** |
|
| 30 | + * Get method arguments for this REST route. |
|
| 31 | + * |
|
| 32 | + * @return array An array of endpoints. |
|
| 33 | + */ |
|
| 34 | + public function get_args() { |
|
| 35 | + return [ |
|
| 36 | + [ |
|
| 37 | + 'methods' => \WP_REST_Server::CREATABLE, |
|
| 38 | + 'callback' => [ $this, 'get_response' ], |
|
| 39 | + 'permission_callback' => '__return_true', |
|
| 40 | + 'args' => [ |
|
| 41 | + 'key' => [ |
|
| 42 | + 'description' => __( 'Unique identifier (key) for the cart item.', 'woocommerce' ), |
|
| 43 | + 'type' => 'string', |
|
| 44 | + ], |
|
| 45 | + ], |
|
| 46 | + ], |
|
| 47 | + 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 48 | + 'allow_batch' => [ 'v1' => true ], |
|
| 49 | + ]; |
|
| 50 | + } |
|
| 51 | 51 | |
| 52 | - /** |
|
| 53 | - * Handle the request and return a valid response for this endpoint. |
|
| 54 | - * |
|
| 55 | - * @throws RouteException On error. |
|
| 56 | - * @param \WP_REST_Request $request Request object. |
|
| 57 | - * @return \WP_REST_Response |
|
| 58 | - */ |
|
| 59 | - protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 60 | - $cart = $this->cart_controller->get_cart_instance(); |
|
| 61 | - $cart_item = $this->cart_controller->get_cart_item( $request['key'] ); |
|
| 52 | + /** |
|
| 53 | + * Handle the request and return a valid response for this endpoint. |
|
| 54 | + * |
|
| 55 | + * @throws RouteException On error. |
|
| 56 | + * @param \WP_REST_Request $request Request object. |
|
| 57 | + * @return \WP_REST_Response |
|
| 58 | + */ |
|
| 59 | + protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 60 | + $cart = $this->cart_controller->get_cart_instance(); |
|
| 61 | + $cart_item = $this->cart_controller->get_cart_item( $request['key'] ); |
|
| 62 | 62 | |
| 63 | - if ( empty( $cart_item ) ) { |
|
| 64 | - throw new RouteException( 'woocommerce_rest_cart_invalid_key', __( 'Cart item no longer exists or is invalid.', 'woocommerce' ), 409 ); |
|
| 65 | - } |
|
| 63 | + if ( empty( $cart_item ) ) { |
|
| 64 | + throw new RouteException( 'woocommerce_rest_cart_invalid_key', __( 'Cart item no longer exists or is invalid.', 'woocommerce' ), 409 ); |
|
| 65 | + } |
|
| 66 | 66 | |
| 67 | - $cart->remove_cart_item( $request['key'] ); |
|
| 68 | - $this->maybe_release_stock(); |
|
| 67 | + $cart->remove_cart_item( $request['key'] ); |
|
| 68 | + $this->maybe_release_stock(); |
|
| 69 | 69 | |
| 70 | - return rest_ensure_response( $this->schema->get_item_response( $cart ) ); |
|
| 71 | - } |
|
| 70 | + return rest_ensure_response( $this->schema->get_item_response( $cart ) ); |
|
| 71 | + } |
|
| 72 | 72 | |
| 73 | - /** |
|
| 74 | - * If there is a draft order, releases stock. |
|
| 75 | - * |
|
| 76 | - * @return void |
|
| 77 | - */ |
|
| 78 | - protected function maybe_release_stock() { |
|
| 79 | - $draft_order_id = $this->get_draft_order_id(); |
|
| 73 | + /** |
|
| 74 | + * If there is a draft order, releases stock. |
|
| 75 | + * |
|
| 76 | + * @return void |
|
| 77 | + */ |
|
| 78 | + protected function maybe_release_stock() { |
|
| 79 | + $draft_order_id = $this->get_draft_order_id(); |
|
| 80 | 80 | |
| 81 | - if ( ! $draft_order_id ) { |
|
| 82 | - return; |
|
| 83 | - } |
|
| 81 | + if ( ! $draft_order_id ) { |
|
| 82 | + return; |
|
| 83 | + } |
|
| 84 | 84 | |
| 85 | - wc_release_stock_for_order( $draft_order_id ); |
|
| 86 | - } |
|
| 85 | + wc_release_stock_for_order( $draft_order_id ); |
|
| 86 | + } |
|
| 87 | 87 | } |
@@ -35,17 +35,17 @@ discard block |
||
| 35 | 35 | return [ |
| 36 | 36 | [ |
| 37 | 37 | 'methods' => \WP_REST_Server::CREATABLE, |
| 38 | - 'callback' => [ $this, 'get_response' ], |
|
| 38 | + 'callback' => [$this, 'get_response'], |
|
| 39 | 39 | 'permission_callback' => '__return_true', |
| 40 | 40 | 'args' => [ |
| 41 | 41 | 'key' => [ |
| 42 | - 'description' => __( 'Unique identifier (key) for the cart item.', 'woocommerce' ), |
|
| 42 | + 'description' => __('Unique identifier (key) for the cart item.', 'woocommerce'), |
|
| 43 | 43 | 'type' => 'string', |
| 44 | 44 | ], |
| 45 | 45 | ], |
| 46 | 46 | ], |
| 47 | - 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 48 | - 'allow_batch' => [ 'v1' => true ], |
|
| 47 | + 'schema' => [$this->schema, 'get_public_item_schema'], |
|
| 48 | + 'allow_batch' => ['v1' => true], |
|
| 49 | 49 | ]; |
| 50 | 50 | } |
| 51 | 51 | |
@@ -56,18 +56,18 @@ discard block |
||
| 56 | 56 | * @param \WP_REST_Request $request Request object. |
| 57 | 57 | * @return \WP_REST_Response |
| 58 | 58 | */ |
| 59 | - protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 59 | + protected function get_route_post_response(\WP_REST_Request $request) { |
|
| 60 | 60 | $cart = $this->cart_controller->get_cart_instance(); |
| 61 | - $cart_item = $this->cart_controller->get_cart_item( $request['key'] ); |
|
| 61 | + $cart_item = $this->cart_controller->get_cart_item($request['key']); |
|
| 62 | 62 | |
| 63 | - if ( empty( $cart_item ) ) { |
|
| 64 | - throw new RouteException( 'woocommerce_rest_cart_invalid_key', __( 'Cart item no longer exists or is invalid.', 'woocommerce' ), 409 ); |
|
| 63 | + if (empty($cart_item)) { |
|
| 64 | + throw new RouteException('woocommerce_rest_cart_invalid_key', __('Cart item no longer exists or is invalid.', 'woocommerce'), 409); |
|
| 65 | 65 | } |
| 66 | 66 | |
| 67 | - $cart->remove_cart_item( $request['key'] ); |
|
| 67 | + $cart->remove_cart_item($request['key']); |
|
| 68 | 68 | $this->maybe_release_stock(); |
| 69 | 69 | |
| 70 | - return rest_ensure_response( $this->schema->get_item_response( $cart ) ); |
|
| 70 | + return rest_ensure_response($this->schema->get_item_response($cart)); |
|
| 71 | 71 | } |
| 72 | 72 | |
| 73 | 73 | /** |
@@ -78,10 +78,10 @@ discard block |
||
| 78 | 78 | protected function maybe_release_stock() { |
| 79 | 79 | $draft_order_id = $this->get_draft_order_id(); |
| 80 | 80 | |
| 81 | - if ( ! $draft_order_id ) { |
|
| 81 | + if (!$draft_order_id) { |
|
| 82 | 82 | return; |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | - wc_release_stock_for_order( $draft_order_id ); |
|
| 85 | + wc_release_stock_for_order($draft_order_id); |
|
| 86 | 86 | } |
| 87 | 87 | } |
@@ -7,92 +7,92 @@ |
||
| 7 | 7 | * CartCouponsByCode class. |
| 8 | 8 | */ |
| 9 | 9 | class CartCouponsByCode extends AbstractCartRoute { |
| 10 | - /** |
|
| 11 | - * The route identifier. |
|
| 12 | - * |
|
| 13 | - * @var string |
|
| 14 | - */ |
|
| 15 | - const IDENTIFIER = 'cart-coupons-by-code'; |
|
| 10 | + /** |
|
| 11 | + * The route identifier. |
|
| 12 | + * |
|
| 13 | + * @var string |
|
| 14 | + */ |
|
| 15 | + const IDENTIFIER = 'cart-coupons-by-code'; |
|
| 16 | 16 | |
| 17 | - /** |
|
| 18 | - * The routes schema. |
|
| 19 | - * |
|
| 20 | - * @var string |
|
| 21 | - */ |
|
| 22 | - const SCHEMA_TYPE = 'cart-coupon'; |
|
| 17 | + /** |
|
| 18 | + * The routes schema. |
|
| 19 | + * |
|
| 20 | + * @var string |
|
| 21 | + */ |
|
| 22 | + const SCHEMA_TYPE = 'cart-coupon'; |
|
| 23 | 23 | |
| 24 | - /** |
|
| 25 | - * Get the path of this REST route. |
|
| 26 | - * |
|
| 27 | - * @return string |
|
| 28 | - */ |
|
| 29 | - public function get_path() { |
|
| 30 | - return '/cart/coupons/(?P<code>[\w-]+)'; |
|
| 31 | - } |
|
| 24 | + /** |
|
| 25 | + * Get the path of this REST route. |
|
| 26 | + * |
|
| 27 | + * @return string |
|
| 28 | + */ |
|
| 29 | + public function get_path() { |
|
| 30 | + return '/cart/coupons/(?P<code>[\w-]+)'; |
|
| 31 | + } |
|
| 32 | 32 | |
| 33 | - /** |
|
| 34 | - * Get method arguments for this REST route. |
|
| 35 | - * |
|
| 36 | - * @return array An array of endpoints. |
|
| 37 | - */ |
|
| 38 | - public function get_args() { |
|
| 39 | - return [ |
|
| 40 | - 'args' => [ |
|
| 41 | - 'code' => [ |
|
| 42 | - 'description' => __( 'Unique identifier for the coupon within the cart.', 'woocommerce' ), |
|
| 43 | - 'type' => 'string', |
|
| 44 | - ], |
|
| 45 | - ], |
|
| 46 | - [ |
|
| 47 | - 'methods' => \WP_REST_Server::READABLE, |
|
| 48 | - 'callback' => [ $this, 'get_response' ], |
|
| 49 | - 'permission_callback' => '__return_true', |
|
| 50 | - 'args' => [ |
|
| 51 | - 'context' => $this->get_context_param( [ 'default' => 'view' ] ), |
|
| 52 | - ], |
|
| 53 | - ], |
|
| 54 | - [ |
|
| 55 | - 'methods' => \WP_REST_Server::DELETABLE, |
|
| 56 | - 'callback' => [ $this, 'get_response' ], |
|
| 57 | - 'permission_callback' => '__return_true', |
|
| 58 | - ], |
|
| 59 | - 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 60 | - 'allow_batch' => [ 'v1' => true ], |
|
| 61 | - ]; |
|
| 62 | - } |
|
| 33 | + /** |
|
| 34 | + * Get method arguments for this REST route. |
|
| 35 | + * |
|
| 36 | + * @return array An array of endpoints. |
|
| 37 | + */ |
|
| 38 | + public function get_args() { |
|
| 39 | + return [ |
|
| 40 | + 'args' => [ |
|
| 41 | + 'code' => [ |
|
| 42 | + 'description' => __( 'Unique identifier for the coupon within the cart.', 'woocommerce' ), |
|
| 43 | + 'type' => 'string', |
|
| 44 | + ], |
|
| 45 | + ], |
|
| 46 | + [ |
|
| 47 | + 'methods' => \WP_REST_Server::READABLE, |
|
| 48 | + 'callback' => [ $this, 'get_response' ], |
|
| 49 | + 'permission_callback' => '__return_true', |
|
| 50 | + 'args' => [ |
|
| 51 | + 'context' => $this->get_context_param( [ 'default' => 'view' ] ), |
|
| 52 | + ], |
|
| 53 | + ], |
|
| 54 | + [ |
|
| 55 | + 'methods' => \WP_REST_Server::DELETABLE, |
|
| 56 | + 'callback' => [ $this, 'get_response' ], |
|
| 57 | + 'permission_callback' => '__return_true', |
|
| 58 | + ], |
|
| 59 | + 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 60 | + 'allow_batch' => [ 'v1' => true ], |
|
| 61 | + ]; |
|
| 62 | + } |
|
| 63 | 63 | |
| 64 | - /** |
|
| 65 | - * Get a single cart coupon. |
|
| 66 | - * |
|
| 67 | - * @throws RouteException On error. |
|
| 68 | - * @param \WP_REST_Request $request Request object. |
|
| 69 | - * @return \WP_REST_Response |
|
| 70 | - */ |
|
| 71 | - protected function get_route_response( \WP_REST_Request $request ) { |
|
| 72 | - if ( ! $this->cart_controller->has_coupon( $request['code'] ) ) { |
|
| 73 | - throw new RouteException( 'woocommerce_rest_cart_coupon_invalid_code', __( 'Coupon does not exist in the cart.', 'woocommerce' ), 404 ); |
|
| 74 | - } |
|
| 64 | + /** |
|
| 65 | + * Get a single cart coupon. |
|
| 66 | + * |
|
| 67 | + * @throws RouteException On error. |
|
| 68 | + * @param \WP_REST_Request $request Request object. |
|
| 69 | + * @return \WP_REST_Response |
|
| 70 | + */ |
|
| 71 | + protected function get_route_response( \WP_REST_Request $request ) { |
|
| 72 | + if ( ! $this->cart_controller->has_coupon( $request['code'] ) ) { |
|
| 73 | + throw new RouteException( 'woocommerce_rest_cart_coupon_invalid_code', __( 'Coupon does not exist in the cart.', 'woocommerce' ), 404 ); |
|
| 74 | + } |
|
| 75 | 75 | |
| 76 | - return $this->prepare_item_for_response( $request['code'], $request ); |
|
| 77 | - } |
|
| 76 | + return $this->prepare_item_for_response( $request['code'], $request ); |
|
| 77 | + } |
|
| 78 | 78 | |
| 79 | - /** |
|
| 80 | - * Delete a single cart coupon. |
|
| 81 | - * |
|
| 82 | - * @throws RouteException On error. |
|
| 83 | - * @param \WP_REST_Request $request Request object. |
|
| 84 | - * @return \WP_REST_Response |
|
| 85 | - */ |
|
| 86 | - protected function get_route_delete_response( \WP_REST_Request $request ) { |
|
| 87 | - if ( ! $this->cart_controller->has_coupon( $request['code'] ) ) { |
|
| 88 | - throw new RouteException( 'woocommerce_rest_cart_coupon_invalid_code', __( 'Coupon does not exist in the cart.', 'woocommerce' ), 404 ); |
|
| 89 | - } |
|
| 79 | + /** |
|
| 80 | + * Delete a single cart coupon. |
|
| 81 | + * |
|
| 82 | + * @throws RouteException On error. |
|
| 83 | + * @param \WP_REST_Request $request Request object. |
|
| 84 | + * @return \WP_REST_Response |
|
| 85 | + */ |
|
| 86 | + protected function get_route_delete_response( \WP_REST_Request $request ) { |
|
| 87 | + if ( ! $this->cart_controller->has_coupon( $request['code'] ) ) { |
|
| 88 | + throw new RouteException( 'woocommerce_rest_cart_coupon_invalid_code', __( 'Coupon does not exist in the cart.', 'woocommerce' ), 404 ); |
|
| 89 | + } |
|
| 90 | 90 | |
| 91 | - $cart = $this->cart_controller->get_cart_instance(); |
|
| 91 | + $cart = $this->cart_controller->get_cart_instance(); |
|
| 92 | 92 | |
| 93 | - $cart->remove_coupon( $request['code'] ); |
|
| 94 | - $cart->calculate_totals(); |
|
| 93 | + $cart->remove_coupon( $request['code'] ); |
|
| 94 | + $cart->calculate_totals(); |
|
| 95 | 95 | |
| 96 | - return new \WP_REST_Response( null, 204 ); |
|
| 97 | - } |
|
| 96 | + return new \WP_REST_Response( null, 204 ); |
|
| 97 | + } |
|
| 98 | 98 | } |
@@ -39,25 +39,25 @@ discard block |
||
| 39 | 39 | return [ |
| 40 | 40 | 'args' => [ |
| 41 | 41 | 'code' => [ |
| 42 | - 'description' => __( 'Unique identifier for the coupon within the cart.', 'woocommerce' ), |
|
| 42 | + 'description' => __('Unique identifier for the coupon within the cart.', 'woocommerce'), |
|
| 43 | 43 | 'type' => 'string', |
| 44 | 44 | ], |
| 45 | 45 | ], |
| 46 | 46 | [ |
| 47 | 47 | 'methods' => \WP_REST_Server::READABLE, |
| 48 | - 'callback' => [ $this, 'get_response' ], |
|
| 48 | + 'callback' => [$this, 'get_response'], |
|
| 49 | 49 | 'permission_callback' => '__return_true', |
| 50 | 50 | 'args' => [ |
| 51 | - 'context' => $this->get_context_param( [ 'default' => 'view' ] ), |
|
| 51 | + 'context' => $this->get_context_param(['default' => 'view']), |
|
| 52 | 52 | ], |
| 53 | 53 | ], |
| 54 | 54 | [ |
| 55 | 55 | 'methods' => \WP_REST_Server::DELETABLE, |
| 56 | - 'callback' => [ $this, 'get_response' ], |
|
| 56 | + 'callback' => [$this, 'get_response'], |
|
| 57 | 57 | 'permission_callback' => '__return_true', |
| 58 | 58 | ], |
| 59 | - 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 60 | - 'allow_batch' => [ 'v1' => true ], |
|
| 59 | + 'schema' => [$this->schema, 'get_public_item_schema'], |
|
| 60 | + 'allow_batch' => ['v1' => true], |
|
| 61 | 61 | ]; |
| 62 | 62 | } |
| 63 | 63 | |
@@ -68,12 +68,12 @@ discard block |
||
| 68 | 68 | * @param \WP_REST_Request $request Request object. |
| 69 | 69 | * @return \WP_REST_Response |
| 70 | 70 | */ |
| 71 | - protected function get_route_response( \WP_REST_Request $request ) { |
|
| 72 | - if ( ! $this->cart_controller->has_coupon( $request['code'] ) ) { |
|
| 73 | - throw new RouteException( 'woocommerce_rest_cart_coupon_invalid_code', __( 'Coupon does not exist in the cart.', 'woocommerce' ), 404 ); |
|
| 71 | + protected function get_route_response(\WP_REST_Request $request) { |
|
| 72 | + if (!$this->cart_controller->has_coupon($request['code'])) { |
|
| 73 | + throw new RouteException('woocommerce_rest_cart_coupon_invalid_code', __('Coupon does not exist in the cart.', 'woocommerce'), 404); |
|
| 74 | 74 | } |
| 75 | 75 | |
| 76 | - return $this->prepare_item_for_response( $request['code'], $request ); |
|
| 76 | + return $this->prepare_item_for_response($request['code'], $request); |
|
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | /** |
@@ -83,16 +83,16 @@ discard block |
||
| 83 | 83 | * @param \WP_REST_Request $request Request object. |
| 84 | 84 | * @return \WP_REST_Response |
| 85 | 85 | */ |
| 86 | - protected function get_route_delete_response( \WP_REST_Request $request ) { |
|
| 87 | - if ( ! $this->cart_controller->has_coupon( $request['code'] ) ) { |
|
| 88 | - throw new RouteException( 'woocommerce_rest_cart_coupon_invalid_code', __( 'Coupon does not exist in the cart.', 'woocommerce' ), 404 ); |
|
| 86 | + protected function get_route_delete_response(\WP_REST_Request $request) { |
|
| 87 | + if (!$this->cart_controller->has_coupon($request['code'])) { |
|
| 88 | + throw new RouteException('woocommerce_rest_cart_coupon_invalid_code', __('Coupon does not exist in the cart.', 'woocommerce'), 404); |
|
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | $cart = $this->cart_controller->get_cart_instance(); |
| 92 | 92 | |
| 93 | - $cart->remove_coupon( $request['code'] ); |
|
| 93 | + $cart->remove_coupon($request['code']); |
|
| 94 | 94 | $cart->calculate_totals(); |
| 95 | 95 | |
| 96 | - return new \WP_REST_Response( null, 204 ); |
|
| 96 | + return new \WP_REST_Response(null, 204); |
|
| 97 | 97 | } |
| 98 | 98 | } |
@@ -7,68 +7,68 @@ |
||
| 7 | 7 | * CartExtensions class. |
| 8 | 8 | */ |
| 9 | 9 | class CartExtensions extends AbstractCartRoute { |
| 10 | - /** |
|
| 11 | - * The route identifier. |
|
| 12 | - * |
|
| 13 | - * @var string |
|
| 14 | - */ |
|
| 15 | - const IDENTIFIER = 'cart-extensions'; |
|
| 10 | + /** |
|
| 11 | + * The route identifier. |
|
| 12 | + * |
|
| 13 | + * @var string |
|
| 14 | + */ |
|
| 15 | + const IDENTIFIER = 'cart-extensions'; |
|
| 16 | 16 | |
| 17 | - /** |
|
| 18 | - * The routes schema. |
|
| 19 | - * |
|
| 20 | - * @var string |
|
| 21 | - */ |
|
| 22 | - const SCHEMA_TYPE = 'cart-extensions'; |
|
| 17 | + /** |
|
| 18 | + * The routes schema. |
|
| 19 | + * |
|
| 20 | + * @var string |
|
| 21 | + */ |
|
| 22 | + const SCHEMA_TYPE = 'cart-extensions'; |
|
| 23 | 23 | |
| 24 | - /** |
|
| 25 | - * Get the path of this REST route. |
|
| 26 | - * |
|
| 27 | - * @return string |
|
| 28 | - */ |
|
| 29 | - public function get_path() { |
|
| 30 | - return '/cart/extensions'; |
|
| 31 | - } |
|
| 24 | + /** |
|
| 25 | + * Get the path of this REST route. |
|
| 26 | + * |
|
| 27 | + * @return string |
|
| 28 | + */ |
|
| 29 | + public function get_path() { |
|
| 30 | + return '/cart/extensions'; |
|
| 31 | + } |
|
| 32 | 32 | |
| 33 | - /** |
|
| 34 | - * Get method arguments for this REST route. |
|
| 35 | - * |
|
| 36 | - * @return array An array of endpoints. |
|
| 37 | - */ |
|
| 38 | - public function get_args() { |
|
| 39 | - return [ |
|
| 40 | - [ |
|
| 41 | - 'methods' => \WP_REST_Server::CREATABLE, |
|
| 42 | - 'callback' => [ $this, 'get_response' ], |
|
| 43 | - 'permission_callback' => '__return_true', |
|
| 44 | - 'args' => [ |
|
| 45 | - 'namespace' => [ |
|
| 46 | - 'description' => __( 'Extension\'s name - this will be used to ensure the data in the request is routed appropriately.', 'woocommerce' ), |
|
| 47 | - 'type' => 'string', |
|
| 48 | - ], |
|
| 49 | - 'data' => [ |
|
| 50 | - 'description' => __( 'Additional data to pass to the extension', 'woocommerce' ), |
|
| 51 | - 'type' => 'object', |
|
| 52 | - ], |
|
| 53 | - ], |
|
| 54 | - ], |
|
| 55 | - 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 56 | - 'allow_batch' => [ 'v1' => true ], |
|
| 57 | - ]; |
|
| 58 | - } |
|
| 33 | + /** |
|
| 34 | + * Get method arguments for this REST route. |
|
| 35 | + * |
|
| 36 | + * @return array An array of endpoints. |
|
| 37 | + */ |
|
| 38 | + public function get_args() { |
|
| 39 | + return [ |
|
| 40 | + [ |
|
| 41 | + 'methods' => \WP_REST_Server::CREATABLE, |
|
| 42 | + 'callback' => [ $this, 'get_response' ], |
|
| 43 | + 'permission_callback' => '__return_true', |
|
| 44 | + 'args' => [ |
|
| 45 | + 'namespace' => [ |
|
| 46 | + 'description' => __( 'Extension\'s name - this will be used to ensure the data in the request is routed appropriately.', 'woocommerce' ), |
|
| 47 | + 'type' => 'string', |
|
| 48 | + ], |
|
| 49 | + 'data' => [ |
|
| 50 | + 'description' => __( 'Additional data to pass to the extension', 'woocommerce' ), |
|
| 51 | + 'type' => 'object', |
|
| 52 | + ], |
|
| 53 | + ], |
|
| 54 | + ], |
|
| 55 | + 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 56 | + 'allow_batch' => [ 'v1' => true ], |
|
| 57 | + ]; |
|
| 58 | + } |
|
| 59 | 59 | |
| 60 | - /** |
|
| 61 | - * Handle the request and return a valid response for this endpoint. |
|
| 62 | - * |
|
| 63 | - * @throws RouteException On error. |
|
| 64 | - * @param \WP_REST_Request $request Request object. |
|
| 65 | - * @return \WP_REST_Response |
|
| 66 | - */ |
|
| 67 | - protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 68 | - try { |
|
| 69 | - return $this->schema->get_item_response( $request ); |
|
| 70 | - } catch ( \WC_REST_Exception $e ) { |
|
| 71 | - throw new RouteException( $e->getErrorCode(), $e->getMessage(), $e->getCode() ); |
|
| 72 | - } |
|
| 73 | - } |
|
| 60 | + /** |
|
| 61 | + * Handle the request and return a valid response for this endpoint. |
|
| 62 | + * |
|
| 63 | + * @throws RouteException On error. |
|
| 64 | + * @param \WP_REST_Request $request Request object. |
|
| 65 | + * @return \WP_REST_Response |
|
| 66 | + */ |
|
| 67 | + protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 68 | + try { |
|
| 69 | + return $this->schema->get_item_response( $request ); |
|
| 70 | + } catch ( \WC_REST_Exception $e ) { |
|
| 71 | + throw new RouteException( $e->getErrorCode(), $e->getMessage(), $e->getCode() ); |
|
| 72 | + } |
|
| 73 | + } |
|
| 74 | 74 | } |
@@ -39,21 +39,21 @@ discard block |
||
| 39 | 39 | return [ |
| 40 | 40 | [ |
| 41 | 41 | 'methods' => \WP_REST_Server::CREATABLE, |
| 42 | - 'callback' => [ $this, 'get_response' ], |
|
| 42 | + 'callback' => [$this, 'get_response'], |
|
| 43 | 43 | 'permission_callback' => '__return_true', |
| 44 | 44 | 'args' => [ |
| 45 | 45 | 'namespace' => [ |
| 46 | - 'description' => __( 'Extension\'s name - this will be used to ensure the data in the request is routed appropriately.', 'woocommerce' ), |
|
| 46 | + 'description' => __('Extension\'s name - this will be used to ensure the data in the request is routed appropriately.', 'woocommerce'), |
|
| 47 | 47 | 'type' => 'string', |
| 48 | 48 | ], |
| 49 | 49 | 'data' => [ |
| 50 | - 'description' => __( 'Additional data to pass to the extension', 'woocommerce' ), |
|
| 50 | + 'description' => __('Additional data to pass to the extension', 'woocommerce'), |
|
| 51 | 51 | 'type' => 'object', |
| 52 | 52 | ], |
| 53 | 53 | ], |
| 54 | 54 | ], |
| 55 | - 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 56 | - 'allow_batch' => [ 'v1' => true ], |
|
| 55 | + 'schema' => [$this->schema, 'get_public_item_schema'], |
|
| 56 | + 'allow_batch' => ['v1' => true], |
|
| 57 | 57 | ]; |
| 58 | 58 | } |
| 59 | 59 | |
@@ -64,11 +64,11 @@ discard block |
||
| 64 | 64 | * @param \WP_REST_Request $request Request object. |
| 65 | 65 | * @return \WP_REST_Response |
| 66 | 66 | */ |
| 67 | - protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 67 | + protected function get_route_post_response(\WP_REST_Request $request) { |
|
| 68 | 68 | try { |
| 69 | - return $this->schema->get_item_response( $request ); |
|
| 70 | - } catch ( \WC_REST_Exception $e ) { |
|
| 71 | - throw new RouteException( $e->getErrorCode(), $e->getMessage(), $e->getCode() ); |
|
| 69 | + return $this->schema->get_item_response($request); |
|
| 70 | + } catch (\WC_REST_Exception $e) { |
|
| 71 | + throw new RouteException($e->getErrorCode(), $e->getMessage(), $e->getCode()); |
|
| 72 | 72 | } |
| 73 | 73 | } |
| 74 | 74 | } |
@@ -10,119 +10,119 @@ |
||
| 10 | 10 | * Batch Route class. |
| 11 | 11 | */ |
| 12 | 12 | class Batch extends AbstractRoute implements RouteInterface { |
| 13 | - /** |
|
| 14 | - * The route identifier. |
|
| 15 | - * |
|
| 16 | - * @var string |
|
| 17 | - */ |
|
| 18 | - const IDENTIFIER = 'batch'; |
|
| 13 | + /** |
|
| 14 | + * The route identifier. |
|
| 15 | + * |
|
| 16 | + * @var string |
|
| 17 | + */ |
|
| 18 | + const IDENTIFIER = 'batch'; |
|
| 19 | 19 | |
| 20 | - /** |
|
| 21 | - * The schema item identifier. |
|
| 22 | - * |
|
| 23 | - * @var string |
|
| 24 | - */ |
|
| 25 | - const SCHEMA_TYPE = 'batch'; |
|
| 20 | + /** |
|
| 21 | + * The schema item identifier. |
|
| 22 | + * |
|
| 23 | + * @var string |
|
| 24 | + */ |
|
| 25 | + const SCHEMA_TYPE = 'batch'; |
|
| 26 | 26 | |
| 27 | - /** |
|
| 28 | - * Get the path of this REST route. |
|
| 29 | - * |
|
| 30 | - * @return string |
|
| 31 | - */ |
|
| 32 | - public function get_path() { |
|
| 33 | - return '/batch'; |
|
| 34 | - } |
|
| 27 | + /** |
|
| 28 | + * Get the path of this REST route. |
|
| 29 | + * |
|
| 30 | + * @return string |
|
| 31 | + */ |
|
| 32 | + public function get_path() { |
|
| 33 | + return '/batch'; |
|
| 34 | + } |
|
| 35 | 35 | |
| 36 | - /** |
|
| 37 | - * Get arguments for this REST route. |
|
| 38 | - * |
|
| 39 | - * @return array An array of endpoints. |
|
| 40 | - */ |
|
| 41 | - public function get_args() { |
|
| 42 | - return array( |
|
| 43 | - 'callback' => [ $this, 'get_response' ], |
|
| 44 | - 'methods' => 'POST', |
|
| 45 | - 'permission_callback' => '__return_true', |
|
| 46 | - 'args' => array( |
|
| 47 | - 'validation' => array( |
|
| 48 | - 'type' => 'string', |
|
| 49 | - 'enum' => array( 'require-all-validate', 'normal' ), |
|
| 50 | - 'default' => 'normal', |
|
| 51 | - ), |
|
| 52 | - 'requests' => array( |
|
| 53 | - 'required' => true, |
|
| 54 | - 'type' => 'array', |
|
| 55 | - 'maxItems' => 25, |
|
| 56 | - 'items' => array( |
|
| 57 | - 'type' => 'object', |
|
| 58 | - 'properties' => array( |
|
| 59 | - 'method' => array( |
|
| 60 | - 'type' => 'string', |
|
| 61 | - 'enum' => array( 'POST', 'PUT', 'PATCH', 'DELETE' ), |
|
| 62 | - 'default' => 'POST', |
|
| 63 | - ), |
|
| 64 | - 'path' => array( |
|
| 65 | - 'type' => 'string', |
|
| 66 | - 'required' => true, |
|
| 67 | - ), |
|
| 68 | - 'body' => array( |
|
| 69 | - 'type' => 'object', |
|
| 70 | - 'properties' => array(), |
|
| 71 | - 'additionalProperties' => true, |
|
| 72 | - ), |
|
| 73 | - 'headers' => array( |
|
| 74 | - 'type' => 'object', |
|
| 75 | - 'properties' => array(), |
|
| 76 | - 'additionalProperties' => array( |
|
| 77 | - 'type' => array( 'string', 'array' ), |
|
| 78 | - 'items' => array( |
|
| 79 | - 'type' => 'string', |
|
| 80 | - ), |
|
| 81 | - ), |
|
| 82 | - ), |
|
| 83 | - ), |
|
| 84 | - ), |
|
| 85 | - ), |
|
| 86 | - ), |
|
| 87 | - ); |
|
| 88 | - } |
|
| 36 | + /** |
|
| 37 | + * Get arguments for this REST route. |
|
| 38 | + * |
|
| 39 | + * @return array An array of endpoints. |
|
| 40 | + */ |
|
| 41 | + public function get_args() { |
|
| 42 | + return array( |
|
| 43 | + 'callback' => [ $this, 'get_response' ], |
|
| 44 | + 'methods' => 'POST', |
|
| 45 | + 'permission_callback' => '__return_true', |
|
| 46 | + 'args' => array( |
|
| 47 | + 'validation' => array( |
|
| 48 | + 'type' => 'string', |
|
| 49 | + 'enum' => array( 'require-all-validate', 'normal' ), |
|
| 50 | + 'default' => 'normal', |
|
| 51 | + ), |
|
| 52 | + 'requests' => array( |
|
| 53 | + 'required' => true, |
|
| 54 | + 'type' => 'array', |
|
| 55 | + 'maxItems' => 25, |
|
| 56 | + 'items' => array( |
|
| 57 | + 'type' => 'object', |
|
| 58 | + 'properties' => array( |
|
| 59 | + 'method' => array( |
|
| 60 | + 'type' => 'string', |
|
| 61 | + 'enum' => array( 'POST', 'PUT', 'PATCH', 'DELETE' ), |
|
| 62 | + 'default' => 'POST', |
|
| 63 | + ), |
|
| 64 | + 'path' => array( |
|
| 65 | + 'type' => 'string', |
|
| 66 | + 'required' => true, |
|
| 67 | + ), |
|
| 68 | + 'body' => array( |
|
| 69 | + 'type' => 'object', |
|
| 70 | + 'properties' => array(), |
|
| 71 | + 'additionalProperties' => true, |
|
| 72 | + ), |
|
| 73 | + 'headers' => array( |
|
| 74 | + 'type' => 'object', |
|
| 75 | + 'properties' => array(), |
|
| 76 | + 'additionalProperties' => array( |
|
| 77 | + 'type' => array( 'string', 'array' ), |
|
| 78 | + 'items' => array( |
|
| 79 | + 'type' => 'string', |
|
| 80 | + ), |
|
| 81 | + ), |
|
| 82 | + ), |
|
| 83 | + ), |
|
| 84 | + ), |
|
| 85 | + ), |
|
| 86 | + ), |
|
| 87 | + ); |
|
| 88 | + } |
|
| 89 | 89 | |
| 90 | - /** |
|
| 91 | - * Get the route response. |
|
| 92 | - * |
|
| 93 | - * @see WP_REST_Server::serve_batch_request_v1 |
|
| 94 | - * https://developer.wordpress.org/reference/classes/wp_rest_server/serve_batch_request_v1/ |
|
| 95 | - * |
|
| 96 | - * @throws RouteException On error. |
|
| 97 | - * |
|
| 98 | - * @param WP_REST_Request $request Request object. |
|
| 99 | - * @return WP_REST_Response |
|
| 100 | - */ |
|
| 101 | - public function get_response( WP_REST_Request $request ) { |
|
| 102 | - try { |
|
| 103 | - foreach ( $request['requests'] as $args ) { |
|
| 104 | - if ( ! stristr( $args['path'], 'wc/store' ) ) { |
|
| 105 | - throw new RouteException( 'woocommerce_rest_invalid_path', __( 'Invalid path provided.', 'woocommerce' ), 400 ); |
|
| 106 | - } |
|
| 107 | - } |
|
| 108 | - $response = rest_get_server()->serve_batch_request_v1( $request ); |
|
| 109 | - } catch ( RouteException $error ) { |
|
| 110 | - $response = $this->get_route_error_response( $error->getErrorCode(), $error->getMessage(), $error->getCode(), $error->getAdditionalData() ); |
|
| 111 | - } catch ( \Exception $error ) { |
|
| 112 | - $response = $this->get_route_error_response( 'woocommerce_rest_unknown_server_error', $error->getMessage(), 500 ); |
|
| 113 | - } |
|
| 90 | + /** |
|
| 91 | + * Get the route response. |
|
| 92 | + * |
|
| 93 | + * @see WP_REST_Server::serve_batch_request_v1 |
|
| 94 | + * https://developer.wordpress.org/reference/classes/wp_rest_server/serve_batch_request_v1/ |
|
| 95 | + * |
|
| 96 | + * @throws RouteException On error. |
|
| 97 | + * |
|
| 98 | + * @param WP_REST_Request $request Request object. |
|
| 99 | + * @return WP_REST_Response |
|
| 100 | + */ |
|
| 101 | + public function get_response( WP_REST_Request $request ) { |
|
| 102 | + try { |
|
| 103 | + foreach ( $request['requests'] as $args ) { |
|
| 104 | + if ( ! stristr( $args['path'], 'wc/store' ) ) { |
|
| 105 | + throw new RouteException( 'woocommerce_rest_invalid_path', __( 'Invalid path provided.', 'woocommerce' ), 400 ); |
|
| 106 | + } |
|
| 107 | + } |
|
| 108 | + $response = rest_get_server()->serve_batch_request_v1( $request ); |
|
| 109 | + } catch ( RouteException $error ) { |
|
| 110 | + $response = $this->get_route_error_response( $error->getErrorCode(), $error->getMessage(), $error->getCode(), $error->getAdditionalData() ); |
|
| 111 | + } catch ( \Exception $error ) { |
|
| 112 | + $response = $this->get_route_error_response( 'woocommerce_rest_unknown_server_error', $error->getMessage(), 500 ); |
|
| 113 | + } |
|
| 114 | 114 | |
| 115 | - if ( is_wp_error( $response ) ) { |
|
| 116 | - $response = $this->error_to_response( $response ); |
|
| 117 | - } |
|
| 115 | + if ( is_wp_error( $response ) ) { |
|
| 116 | + $response = $this->error_to_response( $response ); |
|
| 117 | + } |
|
| 118 | 118 | |
| 119 | - $nonce = wp_create_nonce( 'wc_store_api' ); |
|
| 119 | + $nonce = wp_create_nonce( 'wc_store_api' ); |
|
| 120 | 120 | |
| 121 | - $response->header( 'Nonce', $nonce ); |
|
| 122 | - $response->header( 'X-WC-Store-API-Nonce', $nonce ); |
|
| 123 | - $response->header( 'Nonce-Timestamp', time() ); |
|
| 124 | - $response->header( 'User-ID', get_current_user_id() ); |
|
| 121 | + $response->header( 'Nonce', $nonce ); |
|
| 122 | + $response->header( 'X-WC-Store-API-Nonce', $nonce ); |
|
| 123 | + $response->header( 'Nonce-Timestamp', time() ); |
|
| 124 | + $response->header( 'User-ID', get_current_user_id() ); |
|
| 125 | 125 | |
| 126 | - return $response; |
|
| 127 | - } |
|
| 126 | + return $response; |
|
| 127 | + } |
|
| 128 | 128 | } |
@@ -40,13 +40,13 @@ discard block |
||
| 40 | 40 | */ |
| 41 | 41 | public function get_args() { |
| 42 | 42 | return array( |
| 43 | - 'callback' => [ $this, 'get_response' ], |
|
| 43 | + 'callback' => [$this, 'get_response'], |
|
| 44 | 44 | 'methods' => 'POST', |
| 45 | 45 | 'permission_callback' => '__return_true', |
| 46 | 46 | 'args' => array( |
| 47 | 47 | 'validation' => array( |
| 48 | 48 | 'type' => 'string', |
| 49 | - 'enum' => array( 'require-all-validate', 'normal' ), |
|
| 49 | + 'enum' => array('require-all-validate', 'normal'), |
|
| 50 | 50 | 'default' => 'normal', |
| 51 | 51 | ), |
| 52 | 52 | 'requests' => array( |
@@ -58,7 +58,7 @@ discard block |
||
| 58 | 58 | 'properties' => array( |
| 59 | 59 | 'method' => array( |
| 60 | 60 | 'type' => 'string', |
| 61 | - 'enum' => array( 'POST', 'PUT', 'PATCH', 'DELETE' ), |
|
| 61 | + 'enum' => array('POST', 'PUT', 'PATCH', 'DELETE'), |
|
| 62 | 62 | 'default' => 'POST', |
| 63 | 63 | ), |
| 64 | 64 | 'path' => array( |
@@ -74,7 +74,7 @@ discard block |
||
| 74 | 74 | 'type' => 'object', |
| 75 | 75 | 'properties' => array(), |
| 76 | 76 | 'additionalProperties' => array( |
| 77 | - 'type' => array( 'string', 'array' ), |
|
| 77 | + 'type' => array('string', 'array'), |
|
| 78 | 78 | 'items' => array( |
| 79 | 79 | 'type' => 'string', |
| 80 | 80 | ), |
@@ -98,30 +98,30 @@ discard block |
||
| 98 | 98 | * @param WP_REST_Request $request Request object. |
| 99 | 99 | * @return WP_REST_Response |
| 100 | 100 | */ |
| 101 | - public function get_response( WP_REST_Request $request ) { |
|
| 101 | + public function get_response(WP_REST_Request $request) { |
|
| 102 | 102 | try { |
| 103 | - foreach ( $request['requests'] as $args ) { |
|
| 104 | - if ( ! stristr( $args['path'], 'wc/store' ) ) { |
|
| 105 | - throw new RouteException( 'woocommerce_rest_invalid_path', __( 'Invalid path provided.', 'woocommerce' ), 400 ); |
|
| 103 | + foreach ($request['requests'] as $args) { |
|
| 104 | + if (!stristr($args['path'], 'wc/store')) { |
|
| 105 | + throw new RouteException('woocommerce_rest_invalid_path', __('Invalid path provided.', 'woocommerce'), 400); |
|
| 106 | 106 | } |
| 107 | 107 | } |
| 108 | - $response = rest_get_server()->serve_batch_request_v1( $request ); |
|
| 109 | - } catch ( RouteException $error ) { |
|
| 110 | - $response = $this->get_route_error_response( $error->getErrorCode(), $error->getMessage(), $error->getCode(), $error->getAdditionalData() ); |
|
| 111 | - } catch ( \Exception $error ) { |
|
| 112 | - $response = $this->get_route_error_response( 'woocommerce_rest_unknown_server_error', $error->getMessage(), 500 ); |
|
| 108 | + $response = rest_get_server()->serve_batch_request_v1($request); |
|
| 109 | + } catch (RouteException $error) { |
|
| 110 | + $response = $this->get_route_error_response($error->getErrorCode(), $error->getMessage(), $error->getCode(), $error->getAdditionalData()); |
|
| 111 | + } catch (\Exception $error) { |
|
| 112 | + $response = $this->get_route_error_response('woocommerce_rest_unknown_server_error', $error->getMessage(), 500); |
|
| 113 | 113 | } |
| 114 | 114 | |
| 115 | - if ( is_wp_error( $response ) ) { |
|
| 116 | - $response = $this->error_to_response( $response ); |
|
| 115 | + if (is_wp_error($response)) { |
|
| 116 | + $response = $this->error_to_response($response); |
|
| 117 | 117 | } |
| 118 | 118 | |
| 119 | - $nonce = wp_create_nonce( 'wc_store_api' ); |
|
| 119 | + $nonce = wp_create_nonce('wc_store_api'); |
|
| 120 | 120 | |
| 121 | - $response->header( 'Nonce', $nonce ); |
|
| 122 | - $response->header( 'X-WC-Store-API-Nonce', $nonce ); |
|
| 123 | - $response->header( 'Nonce-Timestamp', time() ); |
|
| 124 | - $response->header( 'User-ID', get_current_user_id() ); |
|
| 121 | + $response->header('Nonce', $nonce); |
|
| 122 | + $response->header('X-WC-Store-API-Nonce', $nonce); |
|
| 123 | + $response->header('Nonce-Timestamp', time()); |
|
| 124 | + $response->header('User-ID', get_current_user_id()); |
|
| 125 | 125 | |
| 126 | 126 | return $response; |
| 127 | 127 | } |
@@ -12,313 +12,313 @@ |
||
| 12 | 12 | * AbstractRoute class. |
| 13 | 13 | */ |
| 14 | 14 | abstract class AbstractRoute implements RouteInterface { |
| 15 | - /** |
|
| 16 | - * Schema class instance. |
|
| 17 | - * |
|
| 18 | - * @var AbstractSchema |
|
| 19 | - */ |
|
| 20 | - protected $schema; |
|
| 21 | - |
|
| 22 | - /** |
|
| 23 | - * Route namespace. |
|
| 24 | - * |
|
| 25 | - * @var string |
|
| 26 | - */ |
|
| 27 | - protected $namespace = 'wc/store/v1'; |
|
| 28 | - |
|
| 29 | - /** |
|
| 30 | - * Schema Controller instance. |
|
| 31 | - * |
|
| 32 | - * @var SchemaController |
|
| 33 | - */ |
|
| 34 | - protected $schema_controller; |
|
| 35 | - |
|
| 36 | - /** |
|
| 37 | - * The routes schema. |
|
| 38 | - * |
|
| 39 | - * @var string |
|
| 40 | - */ |
|
| 41 | - const SCHEMA_TYPE = ''; |
|
| 42 | - |
|
| 43 | - /** |
|
| 44 | - * The routes schema version. |
|
| 45 | - * |
|
| 46 | - * @var integer |
|
| 47 | - */ |
|
| 48 | - const SCHEMA_VERSION = 1; |
|
| 49 | - |
|
| 50 | - /** |
|
| 51 | - * Constructor. |
|
| 52 | - * |
|
| 53 | - * @param SchemaController $schema_controller Schema Controller instance. |
|
| 54 | - * @param AbstractSchema $schema Schema class for this route. |
|
| 55 | - */ |
|
| 56 | - public function __construct( SchemaController $schema_controller, AbstractSchema $schema ) { |
|
| 57 | - $this->schema_controller = $schema_controller; |
|
| 58 | - $this->schema = $schema; |
|
| 59 | - } |
|
| 60 | - |
|
| 61 | - /** |
|
| 62 | - * Get the namespace for this route. |
|
| 63 | - * |
|
| 64 | - * @return string |
|
| 65 | - */ |
|
| 66 | - public function get_namespace() { |
|
| 67 | - return $this->namespace; |
|
| 68 | - } |
|
| 69 | - |
|
| 70 | - /** |
|
| 71 | - * Set the namespace for this route. |
|
| 72 | - * |
|
| 73 | - * @param string $namespace Given namespace. |
|
| 74 | - */ |
|
| 75 | - public function set_namespace( $namespace ) { |
|
| 76 | - $this->namespace = $namespace; |
|
| 77 | - } |
|
| 78 | - |
|
| 79 | - /** |
|
| 80 | - * Get item schema properties. |
|
| 81 | - * |
|
| 82 | - * @return array |
|
| 83 | - */ |
|
| 84 | - public function get_item_schema() { |
|
| 85 | - return $this->schema->get_item_schema(); |
|
| 86 | - } |
|
| 87 | - |
|
| 88 | - /** |
|
| 89 | - * Get the route response based on the type of request. |
|
| 90 | - * |
|
| 91 | - * @param \WP_REST_Request $request Request object. |
|
| 92 | - * @return \WP_REST_Response |
|
| 93 | - */ |
|
| 94 | - public function get_response( \WP_REST_Request $request ) { |
|
| 95 | - $response = null; |
|
| 96 | - try { |
|
| 97 | - switch ( $request->get_method() ) { |
|
| 98 | - case 'POST': |
|
| 99 | - $response = $this->get_route_post_response( $request ); |
|
| 100 | - break; |
|
| 101 | - case 'PUT': |
|
| 102 | - case 'PATCH': |
|
| 103 | - $response = $this->get_route_update_response( $request ); |
|
| 104 | - break; |
|
| 105 | - case 'DELETE': |
|
| 106 | - $response = $this->get_route_delete_response( $request ); |
|
| 107 | - break; |
|
| 108 | - default: |
|
| 109 | - $response = $this->get_route_response( $request ); |
|
| 110 | - break; |
|
| 111 | - } |
|
| 112 | - } catch ( RouteException $error ) { |
|
| 113 | - $response = $this->get_route_error_response( $error->getErrorCode(), $error->getMessage(), $error->getCode(), $error->getAdditionalData() ); |
|
| 114 | - } catch ( InvalidCartException $error ) { |
|
| 115 | - $response = $this->get_route_error_response_from_object( $error->getError(), $error->getCode(), $error->getAdditionalData() ); |
|
| 116 | - } catch ( \Exception $error ) { |
|
| 117 | - $response = $this->get_route_error_response( 'woocommerce_rest_unknown_server_error', $error->getMessage(), 500 ); |
|
| 118 | - } |
|
| 119 | - |
|
| 120 | - if ( is_wp_error( $response ) ) { |
|
| 121 | - $response = $this->error_to_response( $response ); |
|
| 122 | - } |
|
| 123 | - |
|
| 124 | - return $response; |
|
| 125 | - } |
|
| 126 | - |
|
| 127 | - /** |
|
| 128 | - * Converts an error to a response object. Based on \WP_REST_Server. |
|
| 129 | - * |
|
| 130 | - * @param \WP_Error $error WP_Error instance. |
|
| 131 | - * @return \WP_REST_Response List of associative arrays with code and message keys. |
|
| 132 | - */ |
|
| 133 | - protected function error_to_response( $error ) { |
|
| 134 | - $error_data = $error->get_error_data(); |
|
| 135 | - $status = isset( $error_data, $error_data['status'] ) ? $error_data['status'] : 500; |
|
| 136 | - $errors = []; |
|
| 137 | - |
|
| 138 | - foreach ( (array) $error->errors as $code => $messages ) { |
|
| 139 | - foreach ( (array) $messages as $message ) { |
|
| 140 | - $errors[] = array( |
|
| 141 | - 'code' => $code, |
|
| 142 | - 'message' => $message, |
|
| 143 | - 'data' => $error->get_error_data( $code ), |
|
| 144 | - ); |
|
| 145 | - } |
|
| 146 | - } |
|
| 147 | - |
|
| 148 | - $data = array_shift( $errors ); |
|
| 149 | - |
|
| 150 | - if ( count( $errors ) ) { |
|
| 151 | - $data['additional_errors'] = $errors; |
|
| 152 | - } |
|
| 153 | - |
|
| 154 | - return new \WP_REST_Response( $data, $status ); |
|
| 155 | - } |
|
| 156 | - |
|
| 157 | - /** |
|
| 158 | - * Get route response for GET requests. |
|
| 159 | - * |
|
| 160 | - * When implemented, should return a \WP_REST_Response. |
|
| 161 | - * |
|
| 162 | - * @throws RouteException On error. |
|
| 163 | - * @param \WP_REST_Request $request Request object. |
|
| 164 | - */ |
|
| 165 | - protected function get_route_response( \WP_REST_Request $request ) { |
|
| 166 | - throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); |
|
| 167 | - } |
|
| 168 | - |
|
| 169 | - /** |
|
| 170 | - * Get route response for POST requests. |
|
| 171 | - * |
|
| 172 | - * When implemented, should return a \WP_REST_Response. |
|
| 173 | - * |
|
| 174 | - * @throws RouteException On error. |
|
| 175 | - * @param \WP_REST_Request $request Request object. |
|
| 176 | - */ |
|
| 177 | - protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 178 | - throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); |
|
| 179 | - } |
|
| 180 | - |
|
| 181 | - /** |
|
| 182 | - * Get route response for PUT requests. |
|
| 183 | - * |
|
| 184 | - * When implemented, should return a \WP_REST_Response. |
|
| 185 | - * |
|
| 186 | - * @throws RouteException On error. |
|
| 187 | - * @param \WP_REST_Request $request Request object. |
|
| 188 | - */ |
|
| 189 | - protected function get_route_update_response( \WP_REST_Request $request ) { |
|
| 190 | - throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); |
|
| 191 | - } |
|
| 192 | - |
|
| 193 | - /** |
|
| 194 | - * Get route response for DELETE requests. |
|
| 195 | - * |
|
| 196 | - * When implemented, should return a \WP_REST_Response. |
|
| 197 | - * |
|
| 198 | - * @throws RouteException On error. |
|
| 199 | - * @param \WP_REST_Request $request Request object. |
|
| 200 | - */ |
|
| 201 | - protected function get_route_delete_response( \WP_REST_Request $request ) { |
|
| 202 | - throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); |
|
| 203 | - } |
|
| 204 | - |
|
| 205 | - /** |
|
| 206 | - * Get route response when something went wrong. |
|
| 207 | - * |
|
| 208 | - * @param string $error_code String based error code. |
|
| 209 | - * @param string $error_message User facing error message. |
|
| 210 | - * @param int $http_status_code HTTP status. Defaults to 500. |
|
| 211 | - * @param array $additional_data Extra data (key value pairs) to expose in the error response. |
|
| 212 | - * @return \WP_Error WP Error object. |
|
| 213 | - */ |
|
| 214 | - protected function get_route_error_response( $error_code, $error_message, $http_status_code = 500, $additional_data = [] ) { |
|
| 215 | - return new \WP_Error( $error_code, $error_message, array_merge( $additional_data, [ 'status' => $http_status_code ] ) ); |
|
| 216 | - } |
|
| 217 | - |
|
| 218 | - /** |
|
| 219 | - * Get route response when something went wrong and the supplied error is a WP_Error. This currently only happens |
|
| 220 | - * when an item in the cart is out of stock, partially out of stock, can only be bought individually, or when the |
|
| 221 | - * item is not purchasable. |
|
| 222 | - * |
|
| 223 | - * @param WP_Error $error_object The WP_Error object containing the error. |
|
| 224 | - * @param int $http_status_code HTTP status. Defaults to 500. |
|
| 225 | - * @param array $additional_data Extra data (key value pairs) to expose in the error response. |
|
| 226 | - * @return WP_Error WP Error object. |
|
| 227 | - */ |
|
| 228 | - protected function get_route_error_response_from_object( $error_object, $http_status_code = 500, $additional_data = [] ) { |
|
| 229 | - $error_object->add_data( array_merge( $additional_data, [ 'status' => $http_status_code ] ) ); |
|
| 230 | - return $error_object; |
|
| 231 | - } |
|
| 232 | - |
|
| 233 | - /** |
|
| 234 | - * Prepare a single item for response. |
|
| 235 | - * |
|
| 236 | - * @param mixed $item Item to format to schema. |
|
| 237 | - * @param \WP_REST_Request $request Request object. |
|
| 238 | - * @return \WP_REST_Response $response Response data. |
|
| 239 | - */ |
|
| 240 | - public function prepare_item_for_response( $item, \WP_REST_Request $request ) { |
|
| 241 | - $response = rest_ensure_response( $this->schema->get_item_response( $item ) ); |
|
| 242 | - $response->add_links( $this->prepare_links( $item, $request ) ); |
|
| 243 | - |
|
| 244 | - return $response; |
|
| 245 | - } |
|
| 246 | - |
|
| 247 | - /** |
|
| 248 | - * Retrieves the context param. |
|
| 249 | - * |
|
| 250 | - * Ensures consistent descriptions between endpoints, and populates enum from schema. |
|
| 251 | - * |
|
| 252 | - * @param array $args Optional. Additional arguments for context parameter. Default empty array. |
|
| 253 | - * @return array Context parameter details. |
|
| 254 | - */ |
|
| 255 | - protected function get_context_param( $args = array() ) { |
|
| 256 | - $param_details = array( |
|
| 257 | - 'description' => __( 'Scope under which the request is made; determines fields present in response.', 'woocommerce' ), |
|
| 258 | - 'type' => 'string', |
|
| 259 | - 'sanitize_callback' => 'sanitize_key', |
|
| 260 | - 'validate_callback' => 'rest_validate_request_arg', |
|
| 261 | - ); |
|
| 262 | - |
|
| 263 | - $schema = $this->get_item_schema(); |
|
| 264 | - |
|
| 265 | - if ( empty( $schema['properties'] ) ) { |
|
| 266 | - return array_merge( $param_details, $args ); |
|
| 267 | - } |
|
| 268 | - |
|
| 269 | - $contexts = array(); |
|
| 270 | - |
|
| 271 | - foreach ( $schema['properties'] as $attributes ) { |
|
| 272 | - if ( ! empty( $attributes['context'] ) ) { |
|
| 273 | - $contexts = array_merge( $contexts, $attributes['context'] ); |
|
| 274 | - } |
|
| 275 | - } |
|
| 276 | - |
|
| 277 | - if ( ! empty( $contexts ) ) { |
|
| 278 | - $param_details['enum'] = array_unique( $contexts ); |
|
| 279 | - rsort( $param_details['enum'] ); |
|
| 280 | - } |
|
| 281 | - |
|
| 282 | - return array_merge( $param_details, $args ); |
|
| 283 | - } |
|
| 284 | - |
|
| 285 | - /** |
|
| 286 | - * Prepares a response for insertion into a collection. |
|
| 287 | - * |
|
| 288 | - * @param \WP_REST_Response $response Response object. |
|
| 289 | - * @return array|mixed Response data, ready for insertion into collection data. |
|
| 290 | - */ |
|
| 291 | - protected function prepare_response_for_collection( \WP_REST_Response $response ) { |
|
| 292 | - $data = (array) $response->get_data(); |
|
| 293 | - $server = rest_get_server(); |
|
| 294 | - $links = $server::get_compact_response_links( $response ); |
|
| 295 | - |
|
| 296 | - if ( ! empty( $links ) ) { |
|
| 297 | - $data['_links'] = $links; |
|
| 298 | - } |
|
| 299 | - |
|
| 300 | - return $data; |
|
| 301 | - } |
|
| 302 | - |
|
| 303 | - /** |
|
| 304 | - * Prepare links for the request. |
|
| 305 | - * |
|
| 306 | - * @param mixed $item Item to prepare. |
|
| 307 | - * @param \WP_REST_Request $request Request object. |
|
| 308 | - * @return array |
|
| 309 | - */ |
|
| 310 | - protected function prepare_links( $item, $request ) { |
|
| 311 | - return []; |
|
| 312 | - } |
|
| 313 | - |
|
| 314 | - /** |
|
| 315 | - * Retrieves the query params for the collections. |
|
| 316 | - * |
|
| 317 | - * @return array Query parameters for the collection. |
|
| 318 | - */ |
|
| 319 | - public function get_collection_params() { |
|
| 320 | - return array( |
|
| 321 | - 'context' => $this->get_context_param(), |
|
| 322 | - ); |
|
| 323 | - } |
|
| 15 | + /** |
|
| 16 | + * Schema class instance. |
|
| 17 | + * |
|
| 18 | + * @var AbstractSchema |
|
| 19 | + */ |
|
| 20 | + protected $schema; |
|
| 21 | + |
|
| 22 | + /** |
|
| 23 | + * Route namespace. |
|
| 24 | + * |
|
| 25 | + * @var string |
|
| 26 | + */ |
|
| 27 | + protected $namespace = 'wc/store/v1'; |
|
| 28 | + |
|
| 29 | + /** |
|
| 30 | + * Schema Controller instance. |
|
| 31 | + * |
|
| 32 | + * @var SchemaController |
|
| 33 | + */ |
|
| 34 | + protected $schema_controller; |
|
| 35 | + |
|
| 36 | + /** |
|
| 37 | + * The routes schema. |
|
| 38 | + * |
|
| 39 | + * @var string |
|
| 40 | + */ |
|
| 41 | + const SCHEMA_TYPE = ''; |
|
| 42 | + |
|
| 43 | + /** |
|
| 44 | + * The routes schema version. |
|
| 45 | + * |
|
| 46 | + * @var integer |
|
| 47 | + */ |
|
| 48 | + const SCHEMA_VERSION = 1; |
|
| 49 | + |
|
| 50 | + /** |
|
| 51 | + * Constructor. |
|
| 52 | + * |
|
| 53 | + * @param SchemaController $schema_controller Schema Controller instance. |
|
| 54 | + * @param AbstractSchema $schema Schema class for this route. |
|
| 55 | + */ |
|
| 56 | + public function __construct( SchemaController $schema_controller, AbstractSchema $schema ) { |
|
| 57 | + $this->schema_controller = $schema_controller; |
|
| 58 | + $this->schema = $schema; |
|
| 59 | + } |
|
| 60 | + |
|
| 61 | + /** |
|
| 62 | + * Get the namespace for this route. |
|
| 63 | + * |
|
| 64 | + * @return string |
|
| 65 | + */ |
|
| 66 | + public function get_namespace() { |
|
| 67 | + return $this->namespace; |
|
| 68 | + } |
|
| 69 | + |
|
| 70 | + /** |
|
| 71 | + * Set the namespace for this route. |
|
| 72 | + * |
|
| 73 | + * @param string $namespace Given namespace. |
|
| 74 | + */ |
|
| 75 | + public function set_namespace( $namespace ) { |
|
| 76 | + $this->namespace = $namespace; |
|
| 77 | + } |
|
| 78 | + |
|
| 79 | + /** |
|
| 80 | + * Get item schema properties. |
|
| 81 | + * |
|
| 82 | + * @return array |
|
| 83 | + */ |
|
| 84 | + public function get_item_schema() { |
|
| 85 | + return $this->schema->get_item_schema(); |
|
| 86 | + } |
|
| 87 | + |
|
| 88 | + /** |
|
| 89 | + * Get the route response based on the type of request. |
|
| 90 | + * |
|
| 91 | + * @param \WP_REST_Request $request Request object. |
|
| 92 | + * @return \WP_REST_Response |
|
| 93 | + */ |
|
| 94 | + public function get_response( \WP_REST_Request $request ) { |
|
| 95 | + $response = null; |
|
| 96 | + try { |
|
| 97 | + switch ( $request->get_method() ) { |
|
| 98 | + case 'POST': |
|
| 99 | + $response = $this->get_route_post_response( $request ); |
|
| 100 | + break; |
|
| 101 | + case 'PUT': |
|
| 102 | + case 'PATCH': |
|
| 103 | + $response = $this->get_route_update_response( $request ); |
|
| 104 | + break; |
|
| 105 | + case 'DELETE': |
|
| 106 | + $response = $this->get_route_delete_response( $request ); |
|
| 107 | + break; |
|
| 108 | + default: |
|
| 109 | + $response = $this->get_route_response( $request ); |
|
| 110 | + break; |
|
| 111 | + } |
|
| 112 | + } catch ( RouteException $error ) { |
|
| 113 | + $response = $this->get_route_error_response( $error->getErrorCode(), $error->getMessage(), $error->getCode(), $error->getAdditionalData() ); |
|
| 114 | + } catch ( InvalidCartException $error ) { |
|
| 115 | + $response = $this->get_route_error_response_from_object( $error->getError(), $error->getCode(), $error->getAdditionalData() ); |
|
| 116 | + } catch ( \Exception $error ) { |
|
| 117 | + $response = $this->get_route_error_response( 'woocommerce_rest_unknown_server_error', $error->getMessage(), 500 ); |
|
| 118 | + } |
|
| 119 | + |
|
| 120 | + if ( is_wp_error( $response ) ) { |
|
| 121 | + $response = $this->error_to_response( $response ); |
|
| 122 | + } |
|
| 123 | + |
|
| 124 | + return $response; |
|
| 125 | + } |
|
| 126 | + |
|
| 127 | + /** |
|
| 128 | + * Converts an error to a response object. Based on \WP_REST_Server. |
|
| 129 | + * |
|
| 130 | + * @param \WP_Error $error WP_Error instance. |
|
| 131 | + * @return \WP_REST_Response List of associative arrays with code and message keys. |
|
| 132 | + */ |
|
| 133 | + protected function error_to_response( $error ) { |
|
| 134 | + $error_data = $error->get_error_data(); |
|
| 135 | + $status = isset( $error_data, $error_data['status'] ) ? $error_data['status'] : 500; |
|
| 136 | + $errors = []; |
|
| 137 | + |
|
| 138 | + foreach ( (array) $error->errors as $code => $messages ) { |
|
| 139 | + foreach ( (array) $messages as $message ) { |
|
| 140 | + $errors[] = array( |
|
| 141 | + 'code' => $code, |
|
| 142 | + 'message' => $message, |
|
| 143 | + 'data' => $error->get_error_data( $code ), |
|
| 144 | + ); |
|
| 145 | + } |
|
| 146 | + } |
|
| 147 | + |
|
| 148 | + $data = array_shift( $errors ); |
|
| 149 | + |
|
| 150 | + if ( count( $errors ) ) { |
|
| 151 | + $data['additional_errors'] = $errors; |
|
| 152 | + } |
|
| 153 | + |
|
| 154 | + return new \WP_REST_Response( $data, $status ); |
|
| 155 | + } |
|
| 156 | + |
|
| 157 | + /** |
|
| 158 | + * Get route response for GET requests. |
|
| 159 | + * |
|
| 160 | + * When implemented, should return a \WP_REST_Response. |
|
| 161 | + * |
|
| 162 | + * @throws RouteException On error. |
|
| 163 | + * @param \WP_REST_Request $request Request object. |
|
| 164 | + */ |
|
| 165 | + protected function get_route_response( \WP_REST_Request $request ) { |
|
| 166 | + throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); |
|
| 167 | + } |
|
| 168 | + |
|
| 169 | + /** |
|
| 170 | + * Get route response for POST requests. |
|
| 171 | + * |
|
| 172 | + * When implemented, should return a \WP_REST_Response. |
|
| 173 | + * |
|
| 174 | + * @throws RouteException On error. |
|
| 175 | + * @param \WP_REST_Request $request Request object. |
|
| 176 | + */ |
|
| 177 | + protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 178 | + throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); |
|
| 179 | + } |
|
| 180 | + |
|
| 181 | + /** |
|
| 182 | + * Get route response for PUT requests. |
|
| 183 | + * |
|
| 184 | + * When implemented, should return a \WP_REST_Response. |
|
| 185 | + * |
|
| 186 | + * @throws RouteException On error. |
|
| 187 | + * @param \WP_REST_Request $request Request object. |
|
| 188 | + */ |
|
| 189 | + protected function get_route_update_response( \WP_REST_Request $request ) { |
|
| 190 | + throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); |
|
| 191 | + } |
|
| 192 | + |
|
| 193 | + /** |
|
| 194 | + * Get route response for DELETE requests. |
|
| 195 | + * |
|
| 196 | + * When implemented, should return a \WP_REST_Response. |
|
| 197 | + * |
|
| 198 | + * @throws RouteException On error. |
|
| 199 | + * @param \WP_REST_Request $request Request object. |
|
| 200 | + */ |
|
| 201 | + protected function get_route_delete_response( \WP_REST_Request $request ) { |
|
| 202 | + throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); |
|
| 203 | + } |
|
| 204 | + |
|
| 205 | + /** |
|
| 206 | + * Get route response when something went wrong. |
|
| 207 | + * |
|
| 208 | + * @param string $error_code String based error code. |
|
| 209 | + * @param string $error_message User facing error message. |
|
| 210 | + * @param int $http_status_code HTTP status. Defaults to 500. |
|
| 211 | + * @param array $additional_data Extra data (key value pairs) to expose in the error response. |
|
| 212 | + * @return \WP_Error WP Error object. |
|
| 213 | + */ |
|
| 214 | + protected function get_route_error_response( $error_code, $error_message, $http_status_code = 500, $additional_data = [] ) { |
|
| 215 | + return new \WP_Error( $error_code, $error_message, array_merge( $additional_data, [ 'status' => $http_status_code ] ) ); |
|
| 216 | + } |
|
| 217 | + |
|
| 218 | + /** |
|
| 219 | + * Get route response when something went wrong and the supplied error is a WP_Error. This currently only happens |
|
| 220 | + * when an item in the cart is out of stock, partially out of stock, can only be bought individually, or when the |
|
| 221 | + * item is not purchasable. |
|
| 222 | + * |
|
| 223 | + * @param WP_Error $error_object The WP_Error object containing the error. |
|
| 224 | + * @param int $http_status_code HTTP status. Defaults to 500. |
|
| 225 | + * @param array $additional_data Extra data (key value pairs) to expose in the error response. |
|
| 226 | + * @return WP_Error WP Error object. |
|
| 227 | + */ |
|
| 228 | + protected function get_route_error_response_from_object( $error_object, $http_status_code = 500, $additional_data = [] ) { |
|
| 229 | + $error_object->add_data( array_merge( $additional_data, [ 'status' => $http_status_code ] ) ); |
|
| 230 | + return $error_object; |
|
| 231 | + } |
|
| 232 | + |
|
| 233 | + /** |
|
| 234 | + * Prepare a single item for response. |
|
| 235 | + * |
|
| 236 | + * @param mixed $item Item to format to schema. |
|
| 237 | + * @param \WP_REST_Request $request Request object. |
|
| 238 | + * @return \WP_REST_Response $response Response data. |
|
| 239 | + */ |
|
| 240 | + public function prepare_item_for_response( $item, \WP_REST_Request $request ) { |
|
| 241 | + $response = rest_ensure_response( $this->schema->get_item_response( $item ) ); |
|
| 242 | + $response->add_links( $this->prepare_links( $item, $request ) ); |
|
| 243 | + |
|
| 244 | + return $response; |
|
| 245 | + } |
|
| 246 | + |
|
| 247 | + /** |
|
| 248 | + * Retrieves the context param. |
|
| 249 | + * |
|
| 250 | + * Ensures consistent descriptions between endpoints, and populates enum from schema. |
|
| 251 | + * |
|
| 252 | + * @param array $args Optional. Additional arguments for context parameter. Default empty array. |
|
| 253 | + * @return array Context parameter details. |
|
| 254 | + */ |
|
| 255 | + protected function get_context_param( $args = array() ) { |
|
| 256 | + $param_details = array( |
|
| 257 | + 'description' => __( 'Scope under which the request is made; determines fields present in response.', 'woocommerce' ), |
|
| 258 | + 'type' => 'string', |
|
| 259 | + 'sanitize_callback' => 'sanitize_key', |
|
| 260 | + 'validate_callback' => 'rest_validate_request_arg', |
|
| 261 | + ); |
|
| 262 | + |
|
| 263 | + $schema = $this->get_item_schema(); |
|
| 264 | + |
|
| 265 | + if ( empty( $schema['properties'] ) ) { |
|
| 266 | + return array_merge( $param_details, $args ); |
|
| 267 | + } |
|
| 268 | + |
|
| 269 | + $contexts = array(); |
|
| 270 | + |
|
| 271 | + foreach ( $schema['properties'] as $attributes ) { |
|
| 272 | + if ( ! empty( $attributes['context'] ) ) { |
|
| 273 | + $contexts = array_merge( $contexts, $attributes['context'] ); |
|
| 274 | + } |
|
| 275 | + } |
|
| 276 | + |
|
| 277 | + if ( ! empty( $contexts ) ) { |
|
| 278 | + $param_details['enum'] = array_unique( $contexts ); |
|
| 279 | + rsort( $param_details['enum'] ); |
|
| 280 | + } |
|
| 281 | + |
|
| 282 | + return array_merge( $param_details, $args ); |
|
| 283 | + } |
|
| 284 | + |
|
| 285 | + /** |
|
| 286 | + * Prepares a response for insertion into a collection. |
|
| 287 | + * |
|
| 288 | + * @param \WP_REST_Response $response Response object. |
|
| 289 | + * @return array|mixed Response data, ready for insertion into collection data. |
|
| 290 | + */ |
|
| 291 | + protected function prepare_response_for_collection( \WP_REST_Response $response ) { |
|
| 292 | + $data = (array) $response->get_data(); |
|
| 293 | + $server = rest_get_server(); |
|
| 294 | + $links = $server::get_compact_response_links( $response ); |
|
| 295 | + |
|
| 296 | + if ( ! empty( $links ) ) { |
|
| 297 | + $data['_links'] = $links; |
|
| 298 | + } |
|
| 299 | + |
|
| 300 | + return $data; |
|
| 301 | + } |
|
| 302 | + |
|
| 303 | + /** |
|
| 304 | + * Prepare links for the request. |
|
| 305 | + * |
|
| 306 | + * @param mixed $item Item to prepare. |
|
| 307 | + * @param \WP_REST_Request $request Request object. |
|
| 308 | + * @return array |
|
| 309 | + */ |
|
| 310 | + protected function prepare_links( $item, $request ) { |
|
| 311 | + return []; |
|
| 312 | + } |
|
| 313 | + |
|
| 314 | + /** |
|
| 315 | + * Retrieves the query params for the collections. |
|
| 316 | + * |
|
| 317 | + * @return array Query parameters for the collection. |
|
| 318 | + */ |
|
| 319 | + public function get_collection_params() { |
|
| 320 | + return array( |
|
| 321 | + 'context' => $this->get_context_param(), |
|
| 322 | + ); |
|
| 323 | + } |
|
| 324 | 324 | } |
@@ -53,7 +53,7 @@ discard block |
||
| 53 | 53 | * @param SchemaController $schema_controller Schema Controller instance. |
| 54 | 54 | * @param AbstractSchema $schema Schema class for this route. |
| 55 | 55 | */ |
| 56 | - public function __construct( SchemaController $schema_controller, AbstractSchema $schema ) { |
|
| 56 | + public function __construct(SchemaController $schema_controller, AbstractSchema $schema) { |
|
| 57 | 57 | $this->schema_controller = $schema_controller; |
| 58 | 58 | $this->schema = $schema; |
| 59 | 59 | } |
@@ -72,7 +72,7 @@ discard block |
||
| 72 | 72 | * |
| 73 | 73 | * @param string $namespace Given namespace. |
| 74 | 74 | */ |
| 75 | - public function set_namespace( $namespace ) { |
|
| 75 | + public function set_namespace($namespace) { |
|
| 76 | 76 | $this->namespace = $namespace; |
| 77 | 77 | } |
| 78 | 78 | |
@@ -91,34 +91,34 @@ discard block |
||
| 91 | 91 | * @param \WP_REST_Request $request Request object. |
| 92 | 92 | * @return \WP_REST_Response |
| 93 | 93 | */ |
| 94 | - public function get_response( \WP_REST_Request $request ) { |
|
| 94 | + public function get_response(\WP_REST_Request $request) { |
|
| 95 | 95 | $response = null; |
| 96 | 96 | try { |
| 97 | - switch ( $request->get_method() ) { |
|
| 97 | + switch ($request->get_method()) { |
|
| 98 | 98 | case 'POST': |
| 99 | - $response = $this->get_route_post_response( $request ); |
|
| 99 | + $response = $this->get_route_post_response($request); |
|
| 100 | 100 | break; |
| 101 | 101 | case 'PUT': |
| 102 | 102 | case 'PATCH': |
| 103 | - $response = $this->get_route_update_response( $request ); |
|
| 103 | + $response = $this->get_route_update_response($request); |
|
| 104 | 104 | break; |
| 105 | 105 | case 'DELETE': |
| 106 | - $response = $this->get_route_delete_response( $request ); |
|
| 106 | + $response = $this->get_route_delete_response($request); |
|
| 107 | 107 | break; |
| 108 | 108 | default: |
| 109 | - $response = $this->get_route_response( $request ); |
|
| 109 | + $response = $this->get_route_response($request); |
|
| 110 | 110 | break; |
| 111 | 111 | } |
| 112 | - } catch ( RouteException $error ) { |
|
| 113 | - $response = $this->get_route_error_response( $error->getErrorCode(), $error->getMessage(), $error->getCode(), $error->getAdditionalData() ); |
|
| 114 | - } catch ( InvalidCartException $error ) { |
|
| 115 | - $response = $this->get_route_error_response_from_object( $error->getError(), $error->getCode(), $error->getAdditionalData() ); |
|
| 116 | - } catch ( \Exception $error ) { |
|
| 117 | - $response = $this->get_route_error_response( 'woocommerce_rest_unknown_server_error', $error->getMessage(), 500 ); |
|
| 112 | + } catch (RouteException $error) { |
|
| 113 | + $response = $this->get_route_error_response($error->getErrorCode(), $error->getMessage(), $error->getCode(), $error->getAdditionalData()); |
|
| 114 | + } catch (InvalidCartException $error) { |
|
| 115 | + $response = $this->get_route_error_response_from_object($error->getError(), $error->getCode(), $error->getAdditionalData()); |
|
| 116 | + } catch (\Exception $error) { |
|
| 117 | + $response = $this->get_route_error_response('woocommerce_rest_unknown_server_error', $error->getMessage(), 500); |
|
| 118 | 118 | } |
| 119 | 119 | |
| 120 | - if ( is_wp_error( $response ) ) { |
|
| 121 | - $response = $this->error_to_response( $response ); |
|
| 120 | + if (is_wp_error($response)) { |
|
| 121 | + $response = $this->error_to_response($response); |
|
| 122 | 122 | } |
| 123 | 123 | |
| 124 | 124 | return $response; |
@@ -130,28 +130,28 @@ discard block |
||
| 130 | 130 | * @param \WP_Error $error WP_Error instance. |
| 131 | 131 | * @return \WP_REST_Response List of associative arrays with code and message keys. |
| 132 | 132 | */ |
| 133 | - protected function error_to_response( $error ) { |
|
| 133 | + protected function error_to_response($error) { |
|
| 134 | 134 | $error_data = $error->get_error_data(); |
| 135 | - $status = isset( $error_data, $error_data['status'] ) ? $error_data['status'] : 500; |
|
| 135 | + $status = isset($error_data, $error_data['status']) ? $error_data['status'] : 500; |
|
| 136 | 136 | $errors = []; |
| 137 | 137 | |
| 138 | - foreach ( (array) $error->errors as $code => $messages ) { |
|
| 139 | - foreach ( (array) $messages as $message ) { |
|
| 138 | + foreach ((array) $error->errors as $code => $messages) { |
|
| 139 | + foreach ((array) $messages as $message) { |
|
| 140 | 140 | $errors[] = array( |
| 141 | 141 | 'code' => $code, |
| 142 | 142 | 'message' => $message, |
| 143 | - 'data' => $error->get_error_data( $code ), |
|
| 143 | + 'data' => $error->get_error_data($code), |
|
| 144 | 144 | ); |
| 145 | 145 | } |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | - $data = array_shift( $errors ); |
|
| 148 | + $data = array_shift($errors); |
|
| 149 | 149 | |
| 150 | - if ( count( $errors ) ) { |
|
| 150 | + if (count($errors)) { |
|
| 151 | 151 | $data['additional_errors'] = $errors; |
| 152 | 152 | } |
| 153 | 153 | |
| 154 | - return new \WP_REST_Response( $data, $status ); |
|
| 154 | + return new \WP_REST_Response($data, $status); |
|
| 155 | 155 | } |
| 156 | 156 | |
| 157 | 157 | /** |
@@ -162,8 +162,8 @@ discard block |
||
| 162 | 162 | * @throws RouteException On error. |
| 163 | 163 | * @param \WP_REST_Request $request Request object. |
| 164 | 164 | */ |
| 165 | - protected function get_route_response( \WP_REST_Request $request ) { |
|
| 166 | - throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); |
|
| 165 | + protected function get_route_response(\WP_REST_Request $request) { |
|
| 166 | + throw new RouteException('woocommerce_rest_invalid_endpoint', __('Method not implemented', 'woocommerce'), 404); |
|
| 167 | 167 | } |
| 168 | 168 | |
| 169 | 169 | /** |
@@ -174,8 +174,8 @@ discard block |
||
| 174 | 174 | * @throws RouteException On error. |
| 175 | 175 | * @param \WP_REST_Request $request Request object. |
| 176 | 176 | */ |
| 177 | - protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 178 | - throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); |
|
| 177 | + protected function get_route_post_response(\WP_REST_Request $request) { |
|
| 178 | + throw new RouteException('woocommerce_rest_invalid_endpoint', __('Method not implemented', 'woocommerce'), 404); |
|
| 179 | 179 | } |
| 180 | 180 | |
| 181 | 181 | /** |
@@ -186,8 +186,8 @@ discard block |
||
| 186 | 186 | * @throws RouteException On error. |
| 187 | 187 | * @param \WP_REST_Request $request Request object. |
| 188 | 188 | */ |
| 189 | - protected function get_route_update_response( \WP_REST_Request $request ) { |
|
| 190 | - throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); |
|
| 189 | + protected function get_route_update_response(\WP_REST_Request $request) { |
|
| 190 | + throw new RouteException('woocommerce_rest_invalid_endpoint', __('Method not implemented', 'woocommerce'), 404); |
|
| 191 | 191 | } |
| 192 | 192 | |
| 193 | 193 | /** |
@@ -198,8 +198,8 @@ discard block |
||
| 198 | 198 | * @throws RouteException On error. |
| 199 | 199 | * @param \WP_REST_Request $request Request object. |
| 200 | 200 | */ |
| 201 | - protected function get_route_delete_response( \WP_REST_Request $request ) { |
|
| 202 | - throw new RouteException( 'woocommerce_rest_invalid_endpoint', __( 'Method not implemented', 'woocommerce' ), 404 ); |
|
| 201 | + protected function get_route_delete_response(\WP_REST_Request $request) { |
|
| 202 | + throw new RouteException('woocommerce_rest_invalid_endpoint', __('Method not implemented', 'woocommerce'), 404); |
|
| 203 | 203 | } |
| 204 | 204 | |
| 205 | 205 | /** |
@@ -211,8 +211,8 @@ discard block |
||
| 211 | 211 | * @param array $additional_data Extra data (key value pairs) to expose in the error response. |
| 212 | 212 | * @return \WP_Error WP Error object. |
| 213 | 213 | */ |
| 214 | - protected function get_route_error_response( $error_code, $error_message, $http_status_code = 500, $additional_data = [] ) { |
|
| 215 | - return new \WP_Error( $error_code, $error_message, array_merge( $additional_data, [ 'status' => $http_status_code ] ) ); |
|
| 214 | + protected function get_route_error_response($error_code, $error_message, $http_status_code = 500, $additional_data = []) { |
|
| 215 | + return new \WP_Error($error_code, $error_message, array_merge($additional_data, ['status' => $http_status_code])); |
|
| 216 | 216 | } |
| 217 | 217 | |
| 218 | 218 | /** |
@@ -225,8 +225,8 @@ discard block |
||
| 225 | 225 | * @param array $additional_data Extra data (key value pairs) to expose in the error response. |
| 226 | 226 | * @return WP_Error WP Error object. |
| 227 | 227 | */ |
| 228 | - protected function get_route_error_response_from_object( $error_object, $http_status_code = 500, $additional_data = [] ) { |
|
| 229 | - $error_object->add_data( array_merge( $additional_data, [ 'status' => $http_status_code ] ) ); |
|
| 228 | + protected function get_route_error_response_from_object($error_object, $http_status_code = 500, $additional_data = []) { |
|
| 229 | + $error_object->add_data(array_merge($additional_data, ['status' => $http_status_code])); |
|
| 230 | 230 | return $error_object; |
| 231 | 231 | } |
| 232 | 232 | |
@@ -237,9 +237,9 @@ discard block |
||
| 237 | 237 | * @param \WP_REST_Request $request Request object. |
| 238 | 238 | * @return \WP_REST_Response $response Response data. |
| 239 | 239 | */ |
| 240 | - public function prepare_item_for_response( $item, \WP_REST_Request $request ) { |
|
| 241 | - $response = rest_ensure_response( $this->schema->get_item_response( $item ) ); |
|
| 242 | - $response->add_links( $this->prepare_links( $item, $request ) ); |
|
| 240 | + public function prepare_item_for_response($item, \WP_REST_Request $request) { |
|
| 241 | + $response = rest_ensure_response($this->schema->get_item_response($item)); |
|
| 242 | + $response->add_links($this->prepare_links($item, $request)); |
|
| 243 | 243 | |
| 244 | 244 | return $response; |
| 245 | 245 | } |
@@ -252,9 +252,9 @@ discard block |
||
| 252 | 252 | * @param array $args Optional. Additional arguments for context parameter. Default empty array. |
| 253 | 253 | * @return array Context parameter details. |
| 254 | 254 | */ |
| 255 | - protected function get_context_param( $args = array() ) { |
|
| 255 | + protected function get_context_param($args = array()) { |
|
| 256 | 256 | $param_details = array( |
| 257 | - 'description' => __( 'Scope under which the request is made; determines fields present in response.', 'woocommerce' ), |
|
| 257 | + 'description' => __('Scope under which the request is made; determines fields present in response.', 'woocommerce'), |
|
| 258 | 258 | 'type' => 'string', |
| 259 | 259 | 'sanitize_callback' => 'sanitize_key', |
| 260 | 260 | 'validate_callback' => 'rest_validate_request_arg', |
@@ -262,24 +262,24 @@ discard block |
||
| 262 | 262 | |
| 263 | 263 | $schema = $this->get_item_schema(); |
| 264 | 264 | |
| 265 | - if ( empty( $schema['properties'] ) ) { |
|
| 266 | - return array_merge( $param_details, $args ); |
|
| 265 | + if (empty($schema['properties'])) { |
|
| 266 | + return array_merge($param_details, $args); |
|
| 267 | 267 | } |
| 268 | 268 | |
| 269 | 269 | $contexts = array(); |
| 270 | 270 | |
| 271 | - foreach ( $schema['properties'] as $attributes ) { |
|
| 272 | - if ( ! empty( $attributes['context'] ) ) { |
|
| 273 | - $contexts = array_merge( $contexts, $attributes['context'] ); |
|
| 271 | + foreach ($schema['properties'] as $attributes) { |
|
| 272 | + if (!empty($attributes['context'])) { |
|
| 273 | + $contexts = array_merge($contexts, $attributes['context']); |
|
| 274 | 274 | } |
| 275 | 275 | } |
| 276 | 276 | |
| 277 | - if ( ! empty( $contexts ) ) { |
|
| 278 | - $param_details['enum'] = array_unique( $contexts ); |
|
| 279 | - rsort( $param_details['enum'] ); |
|
| 277 | + if (!empty($contexts)) { |
|
| 278 | + $param_details['enum'] = array_unique($contexts); |
|
| 279 | + rsort($param_details['enum']); |
|
| 280 | 280 | } |
| 281 | 281 | |
| 282 | - return array_merge( $param_details, $args ); |
|
| 282 | + return array_merge($param_details, $args); |
|
| 283 | 283 | } |
| 284 | 284 | |
| 285 | 285 | /** |
@@ -288,12 +288,12 @@ discard block |
||
| 288 | 288 | * @param \WP_REST_Response $response Response object. |
| 289 | 289 | * @return array|mixed Response data, ready for insertion into collection data. |
| 290 | 290 | */ |
| 291 | - protected function prepare_response_for_collection( \WP_REST_Response $response ) { |
|
| 291 | + protected function prepare_response_for_collection(\WP_REST_Response $response) { |
|
| 292 | 292 | $data = (array) $response->get_data(); |
| 293 | 293 | $server = rest_get_server(); |
| 294 | - $links = $server::get_compact_response_links( $response ); |
|
| 294 | + $links = $server::get_compact_response_links($response); |
|
| 295 | 295 | |
| 296 | - if ( ! empty( $links ) ) { |
|
| 296 | + if (!empty($links)) { |
|
| 297 | 297 | $data['_links'] = $links; |
| 298 | 298 | } |
| 299 | 299 | |
@@ -307,7 +307,7 @@ discard block |
||
| 307 | 307 | * @param \WP_REST_Request $request Request object. |
| 308 | 308 | * @return array |
| 309 | 309 | */ |
| 310 | - protected function prepare_links( $item, $request ) { |
|
| 310 | + protected function prepare_links($item, $request) { |
|
| 311 | 311 | return []; |
| 312 | 312 | } |
| 313 | 313 | |
@@ -7,141 +7,141 @@ |
||
| 7 | 7 | * CartCoupons class. |
| 8 | 8 | */ |
| 9 | 9 | class CartCoupons extends AbstractCartRoute { |
| 10 | - /** |
|
| 11 | - * The route identifier. |
|
| 12 | - * |
|
| 13 | - * @var string |
|
| 14 | - */ |
|
| 15 | - const IDENTIFIER = 'cart-coupons'; |
|
| 16 | - |
|
| 17 | - /** |
|
| 18 | - * The routes schema. |
|
| 19 | - * |
|
| 20 | - * @var string |
|
| 21 | - */ |
|
| 22 | - const SCHEMA_TYPE = 'cart-coupon'; |
|
| 23 | - |
|
| 24 | - /** |
|
| 25 | - * Get the path of this REST route. |
|
| 26 | - * |
|
| 27 | - * @return string |
|
| 28 | - */ |
|
| 29 | - public function get_path() { |
|
| 30 | - return '/cart/coupons'; |
|
| 31 | - } |
|
| 32 | - |
|
| 33 | - /** |
|
| 34 | - * Get method arguments for this REST route. |
|
| 35 | - * |
|
| 36 | - * @return array An array of endpoints. |
|
| 37 | - */ |
|
| 38 | - public function get_args() { |
|
| 39 | - return [ |
|
| 40 | - [ |
|
| 41 | - 'methods' => \WP_REST_Server::READABLE, |
|
| 42 | - 'callback' => [ $this, 'get_response' ], |
|
| 43 | - 'permission_callback' => '__return_true', |
|
| 44 | - 'args' => [ |
|
| 45 | - 'context' => $this->get_context_param( [ 'default' => 'view' ] ), |
|
| 46 | - ], |
|
| 47 | - ], |
|
| 48 | - [ |
|
| 49 | - 'methods' => \WP_REST_Server::CREATABLE, |
|
| 50 | - 'callback' => [ $this, 'get_response' ], |
|
| 51 | - 'permission_callback' => '__return_true', |
|
| 52 | - 'args' => $this->schema->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), |
|
| 53 | - ], |
|
| 54 | - [ |
|
| 55 | - 'methods' => \WP_REST_Server::DELETABLE, |
|
| 56 | - 'permission_callback' => '__return_true', |
|
| 57 | - 'callback' => [ $this, 'get_response' ], |
|
| 58 | - ], |
|
| 59 | - 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 60 | - 'allow_batch' => [ 'v1' => true ], |
|
| 61 | - ]; |
|
| 62 | - } |
|
| 63 | - |
|
| 64 | - /** |
|
| 65 | - * Get a collection of cart coupons. |
|
| 66 | - * |
|
| 67 | - * @throws RouteException On error. |
|
| 68 | - * @param \WP_REST_Request $request Request object. |
|
| 69 | - * @return \WP_REST_Response |
|
| 70 | - */ |
|
| 71 | - protected function get_route_response( \WP_REST_Request $request ) { |
|
| 72 | - $cart_coupons = $this->cart_controller->get_cart_coupons(); |
|
| 73 | - $items = []; |
|
| 74 | - |
|
| 75 | - foreach ( $cart_coupons as $coupon_code ) { |
|
| 76 | - $response = rest_ensure_response( $this->schema->get_item_response( $coupon_code ) ); |
|
| 77 | - $response->add_links( $this->prepare_links( $coupon_code, $request ) ); |
|
| 78 | - |
|
| 79 | - $response = $this->prepare_response_for_collection( $response ); |
|
| 80 | - $items[] = $response; |
|
| 81 | - } |
|
| 82 | - |
|
| 83 | - $response = rest_ensure_response( $items ); |
|
| 84 | - |
|
| 85 | - return $response; |
|
| 86 | - } |
|
| 87 | - |
|
| 88 | - /** |
|
| 89 | - * Add a coupon to the cart and return the result. |
|
| 90 | - * |
|
| 91 | - * @throws RouteException On error. |
|
| 92 | - * @param \WP_REST_Request $request Request object. |
|
| 93 | - * @return \WP_REST_Response |
|
| 94 | - */ |
|
| 95 | - protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 96 | - if ( ! wc_coupons_enabled() ) { |
|
| 97 | - throw new RouteException( 'woocommerce_rest_cart_coupon_disabled', __( 'Coupons are disabled.', 'woocommerce' ), 404 ); |
|
| 98 | - } |
|
| 99 | - |
|
| 100 | - try { |
|
| 101 | - $this->cart_controller->apply_coupon( $request['code'] ); |
|
| 102 | - } catch ( \WC_REST_Exception $e ) { |
|
| 103 | - throw new RouteException( $e->getErrorCode(), $e->getMessage(), $e->getCode() ); |
|
| 104 | - } |
|
| 105 | - |
|
| 106 | - $response = $this->prepare_item_for_response( $request['code'], $request ); |
|
| 107 | - $response->set_status( 201 ); |
|
| 108 | - |
|
| 109 | - return $response; |
|
| 110 | - } |
|
| 111 | - |
|
| 112 | - /** |
|
| 113 | - * Deletes all coupons in the cart. |
|
| 114 | - * |
|
| 115 | - * @throws RouteException On error. |
|
| 116 | - * @param \WP_REST_Request $request Request object. |
|
| 117 | - * @return \WP_REST_Response |
|
| 118 | - */ |
|
| 119 | - protected function get_route_delete_response( \WP_REST_Request $request ) { |
|
| 120 | - $cart = $this->cart_controller->get_cart_instance(); |
|
| 121 | - |
|
| 122 | - $cart->remove_coupons(); |
|
| 123 | - $cart->calculate_totals(); |
|
| 124 | - |
|
| 125 | - return new \WP_REST_Response( [], 200 ); |
|
| 126 | - } |
|
| 127 | - |
|
| 128 | - /** |
|
| 129 | - * Prepare links for the request. |
|
| 130 | - * |
|
| 131 | - * @param string $coupon_code Coupon code. |
|
| 132 | - * @param \WP_REST_Request $request Request object. |
|
| 133 | - * @return array |
|
| 134 | - */ |
|
| 135 | - protected function prepare_links( $coupon_code, $request ) { |
|
| 136 | - $base = $this->get_namespace() . $this->get_path(); |
|
| 137 | - $links = array( |
|
| 138 | - 'self' => array( |
|
| 139 | - 'href' => rest_url( trailingslashit( $base ) . $coupon_code ), |
|
| 140 | - ), |
|
| 141 | - 'collection' => array( |
|
| 142 | - 'href' => rest_url( $base ), |
|
| 143 | - ), |
|
| 144 | - ); |
|
| 145 | - return $links; |
|
| 146 | - } |
|
| 10 | + /** |
|
| 11 | + * The route identifier. |
|
| 12 | + * |
|
| 13 | + * @var string |
|
| 14 | + */ |
|
| 15 | + const IDENTIFIER = 'cart-coupons'; |
|
| 16 | + |
|
| 17 | + /** |
|
| 18 | + * The routes schema. |
|
| 19 | + * |
|
| 20 | + * @var string |
|
| 21 | + */ |
|
| 22 | + const SCHEMA_TYPE = 'cart-coupon'; |
|
| 23 | + |
|
| 24 | + /** |
|
| 25 | + * Get the path of this REST route. |
|
| 26 | + * |
|
| 27 | + * @return string |
|
| 28 | + */ |
|
| 29 | + public function get_path() { |
|
| 30 | + return '/cart/coupons'; |
|
| 31 | + } |
|
| 32 | + |
|
| 33 | + /** |
|
| 34 | + * Get method arguments for this REST route. |
|
| 35 | + * |
|
| 36 | + * @return array An array of endpoints. |
|
| 37 | + */ |
|
| 38 | + public function get_args() { |
|
| 39 | + return [ |
|
| 40 | + [ |
|
| 41 | + 'methods' => \WP_REST_Server::READABLE, |
|
| 42 | + 'callback' => [ $this, 'get_response' ], |
|
| 43 | + 'permission_callback' => '__return_true', |
|
| 44 | + 'args' => [ |
|
| 45 | + 'context' => $this->get_context_param( [ 'default' => 'view' ] ), |
|
| 46 | + ], |
|
| 47 | + ], |
|
| 48 | + [ |
|
| 49 | + 'methods' => \WP_REST_Server::CREATABLE, |
|
| 50 | + 'callback' => [ $this, 'get_response' ], |
|
| 51 | + 'permission_callback' => '__return_true', |
|
| 52 | + 'args' => $this->schema->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), |
|
| 53 | + ], |
|
| 54 | + [ |
|
| 55 | + 'methods' => \WP_REST_Server::DELETABLE, |
|
| 56 | + 'permission_callback' => '__return_true', |
|
| 57 | + 'callback' => [ $this, 'get_response' ], |
|
| 58 | + ], |
|
| 59 | + 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 60 | + 'allow_batch' => [ 'v1' => true ], |
|
| 61 | + ]; |
|
| 62 | + } |
|
| 63 | + |
|
| 64 | + /** |
|
| 65 | + * Get a collection of cart coupons. |
|
| 66 | + * |
|
| 67 | + * @throws RouteException On error. |
|
| 68 | + * @param \WP_REST_Request $request Request object. |
|
| 69 | + * @return \WP_REST_Response |
|
| 70 | + */ |
|
| 71 | + protected function get_route_response( \WP_REST_Request $request ) { |
|
| 72 | + $cart_coupons = $this->cart_controller->get_cart_coupons(); |
|
| 73 | + $items = []; |
|
| 74 | + |
|
| 75 | + foreach ( $cart_coupons as $coupon_code ) { |
|
| 76 | + $response = rest_ensure_response( $this->schema->get_item_response( $coupon_code ) ); |
|
| 77 | + $response->add_links( $this->prepare_links( $coupon_code, $request ) ); |
|
| 78 | + |
|
| 79 | + $response = $this->prepare_response_for_collection( $response ); |
|
| 80 | + $items[] = $response; |
|
| 81 | + } |
|
| 82 | + |
|
| 83 | + $response = rest_ensure_response( $items ); |
|
| 84 | + |
|
| 85 | + return $response; |
|
| 86 | + } |
|
| 87 | + |
|
| 88 | + /** |
|
| 89 | + * Add a coupon to the cart and return the result. |
|
| 90 | + * |
|
| 91 | + * @throws RouteException On error. |
|
| 92 | + * @param \WP_REST_Request $request Request object. |
|
| 93 | + * @return \WP_REST_Response |
|
| 94 | + */ |
|
| 95 | + protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 96 | + if ( ! wc_coupons_enabled() ) { |
|
| 97 | + throw new RouteException( 'woocommerce_rest_cart_coupon_disabled', __( 'Coupons are disabled.', 'woocommerce' ), 404 ); |
|
| 98 | + } |
|
| 99 | + |
|
| 100 | + try { |
|
| 101 | + $this->cart_controller->apply_coupon( $request['code'] ); |
|
| 102 | + } catch ( \WC_REST_Exception $e ) { |
|
| 103 | + throw new RouteException( $e->getErrorCode(), $e->getMessage(), $e->getCode() ); |
|
| 104 | + } |
|
| 105 | + |
|
| 106 | + $response = $this->prepare_item_for_response( $request['code'], $request ); |
|
| 107 | + $response->set_status( 201 ); |
|
| 108 | + |
|
| 109 | + return $response; |
|
| 110 | + } |
|
| 111 | + |
|
| 112 | + /** |
|
| 113 | + * Deletes all coupons in the cart. |
|
| 114 | + * |
|
| 115 | + * @throws RouteException On error. |
|
| 116 | + * @param \WP_REST_Request $request Request object. |
|
| 117 | + * @return \WP_REST_Response |
|
| 118 | + */ |
|
| 119 | + protected function get_route_delete_response( \WP_REST_Request $request ) { |
|
| 120 | + $cart = $this->cart_controller->get_cart_instance(); |
|
| 121 | + |
|
| 122 | + $cart->remove_coupons(); |
|
| 123 | + $cart->calculate_totals(); |
|
| 124 | + |
|
| 125 | + return new \WP_REST_Response( [], 200 ); |
|
| 126 | + } |
|
| 127 | + |
|
| 128 | + /** |
|
| 129 | + * Prepare links for the request. |
|
| 130 | + * |
|
| 131 | + * @param string $coupon_code Coupon code. |
|
| 132 | + * @param \WP_REST_Request $request Request object. |
|
| 133 | + * @return array |
|
| 134 | + */ |
|
| 135 | + protected function prepare_links( $coupon_code, $request ) { |
|
| 136 | + $base = $this->get_namespace() . $this->get_path(); |
|
| 137 | + $links = array( |
|
| 138 | + 'self' => array( |
|
| 139 | + 'href' => rest_url( trailingslashit( $base ) . $coupon_code ), |
|
| 140 | + ), |
|
| 141 | + 'collection' => array( |
|
| 142 | + 'href' => rest_url( $base ), |
|
| 143 | + ), |
|
| 144 | + ); |
|
| 145 | + return $links; |
|
| 146 | + } |
|
| 147 | 147 | } |
@@ -39,25 +39,25 @@ discard block |
||
| 39 | 39 | return [ |
| 40 | 40 | [ |
| 41 | 41 | 'methods' => \WP_REST_Server::READABLE, |
| 42 | - 'callback' => [ $this, 'get_response' ], |
|
| 42 | + 'callback' => [$this, 'get_response'], |
|
| 43 | 43 | 'permission_callback' => '__return_true', |
| 44 | 44 | 'args' => [ |
| 45 | - 'context' => $this->get_context_param( [ 'default' => 'view' ] ), |
|
| 45 | + 'context' => $this->get_context_param(['default' => 'view']), |
|
| 46 | 46 | ], |
| 47 | 47 | ], |
| 48 | 48 | [ |
| 49 | 49 | 'methods' => \WP_REST_Server::CREATABLE, |
| 50 | - 'callback' => [ $this, 'get_response' ], |
|
| 50 | + 'callback' => [$this, 'get_response'], |
|
| 51 | 51 | 'permission_callback' => '__return_true', |
| 52 | - 'args' => $this->schema->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ), |
|
| 52 | + 'args' => $this->schema->get_endpoint_args_for_item_schema(\WP_REST_Server::CREATABLE), |
|
| 53 | 53 | ], |
| 54 | 54 | [ |
| 55 | 55 | 'methods' => \WP_REST_Server::DELETABLE, |
| 56 | 56 | 'permission_callback' => '__return_true', |
| 57 | - 'callback' => [ $this, 'get_response' ], |
|
| 57 | + 'callback' => [$this, 'get_response'], |
|
| 58 | 58 | ], |
| 59 | - 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 60 | - 'allow_batch' => [ 'v1' => true ], |
|
| 59 | + 'schema' => [$this->schema, 'get_public_item_schema'], |
|
| 60 | + 'allow_batch' => ['v1' => true], |
|
| 61 | 61 | ]; |
| 62 | 62 | } |
| 63 | 63 | |
@@ -68,19 +68,19 @@ discard block |
||
| 68 | 68 | * @param \WP_REST_Request $request Request object. |
| 69 | 69 | * @return \WP_REST_Response |
| 70 | 70 | */ |
| 71 | - protected function get_route_response( \WP_REST_Request $request ) { |
|
| 71 | + protected function get_route_response(\WP_REST_Request $request) { |
|
| 72 | 72 | $cart_coupons = $this->cart_controller->get_cart_coupons(); |
| 73 | 73 | $items = []; |
| 74 | 74 | |
| 75 | - foreach ( $cart_coupons as $coupon_code ) { |
|
| 76 | - $response = rest_ensure_response( $this->schema->get_item_response( $coupon_code ) ); |
|
| 77 | - $response->add_links( $this->prepare_links( $coupon_code, $request ) ); |
|
| 75 | + foreach ($cart_coupons as $coupon_code) { |
|
| 76 | + $response = rest_ensure_response($this->schema->get_item_response($coupon_code)); |
|
| 77 | + $response->add_links($this->prepare_links($coupon_code, $request)); |
|
| 78 | 78 | |
| 79 | - $response = $this->prepare_response_for_collection( $response ); |
|
| 79 | + $response = $this->prepare_response_for_collection($response); |
|
| 80 | 80 | $items[] = $response; |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | - $response = rest_ensure_response( $items ); |
|
| 83 | + $response = rest_ensure_response($items); |
|
| 84 | 84 | |
| 85 | 85 | return $response; |
| 86 | 86 | } |
@@ -92,19 +92,19 @@ discard block |
||
| 92 | 92 | * @param \WP_REST_Request $request Request object. |
| 93 | 93 | * @return \WP_REST_Response |
| 94 | 94 | */ |
| 95 | - protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 96 | - if ( ! wc_coupons_enabled() ) { |
|
| 97 | - throw new RouteException( 'woocommerce_rest_cart_coupon_disabled', __( 'Coupons are disabled.', 'woocommerce' ), 404 ); |
|
| 95 | + protected function get_route_post_response(\WP_REST_Request $request) { |
|
| 96 | + if (!wc_coupons_enabled()) { |
|
| 97 | + throw new RouteException('woocommerce_rest_cart_coupon_disabled', __('Coupons are disabled.', 'woocommerce'), 404); |
|
| 98 | 98 | } |
| 99 | 99 | |
| 100 | 100 | try { |
| 101 | - $this->cart_controller->apply_coupon( $request['code'] ); |
|
| 102 | - } catch ( \WC_REST_Exception $e ) { |
|
| 103 | - throw new RouteException( $e->getErrorCode(), $e->getMessage(), $e->getCode() ); |
|
| 101 | + $this->cart_controller->apply_coupon($request['code']); |
|
| 102 | + } catch (\WC_REST_Exception $e) { |
|
| 103 | + throw new RouteException($e->getErrorCode(), $e->getMessage(), $e->getCode()); |
|
| 104 | 104 | } |
| 105 | 105 | |
| 106 | - $response = $this->prepare_item_for_response( $request['code'], $request ); |
|
| 107 | - $response->set_status( 201 ); |
|
| 106 | + $response = $this->prepare_item_for_response($request['code'], $request); |
|
| 107 | + $response->set_status(201); |
|
| 108 | 108 | |
| 109 | 109 | return $response; |
| 110 | 110 | } |
@@ -116,13 +116,13 @@ discard block |
||
| 116 | 116 | * @param \WP_REST_Request $request Request object. |
| 117 | 117 | * @return \WP_REST_Response |
| 118 | 118 | */ |
| 119 | - protected function get_route_delete_response( \WP_REST_Request $request ) { |
|
| 119 | + protected function get_route_delete_response(\WP_REST_Request $request) { |
|
| 120 | 120 | $cart = $this->cart_controller->get_cart_instance(); |
| 121 | 121 | |
| 122 | 122 | $cart->remove_coupons(); |
| 123 | 123 | $cart->calculate_totals(); |
| 124 | 124 | |
| 125 | - return new \WP_REST_Response( [], 200 ); |
|
| 125 | + return new \WP_REST_Response([], 200); |
|
| 126 | 126 | } |
| 127 | 127 | |
| 128 | 128 | /** |
@@ -132,14 +132,14 @@ discard block |
||
| 132 | 132 | * @param \WP_REST_Request $request Request object. |
| 133 | 133 | * @return array |
| 134 | 134 | */ |
| 135 | - protected function prepare_links( $coupon_code, $request ) { |
|
| 135 | + protected function prepare_links($coupon_code, $request) { |
|
| 136 | 136 | $base = $this->get_namespace() . $this->get_path(); |
| 137 | 137 | $links = array( |
| 138 | 138 | 'self' => array( |
| 139 | - 'href' => rest_url( trailingslashit( $base ) . $coupon_code ), |
|
| 139 | + 'href' => rest_url(trailingslashit($base) . $coupon_code), |
|
| 140 | 140 | ), |
| 141 | 141 | 'collection' => array( |
| 142 | - 'href' => rest_url( $base ), |
|
| 142 | + 'href' => rest_url($base), |
|
| 143 | 143 | ), |
| 144 | 144 | ); |
| 145 | 145 | return $links; |
@@ -13,787 +13,786 @@ |
||
| 13 | 13 | * Checkout class. |
| 14 | 14 | */ |
| 15 | 15 | class Checkout extends AbstractCartRoute { |
| 16 | - use DraftOrderTrait; |
|
| 17 | - |
|
| 18 | - /** |
|
| 19 | - * The route identifier. |
|
| 20 | - * |
|
| 21 | - * @var string |
|
| 22 | - */ |
|
| 23 | - const IDENTIFIER = 'checkout'; |
|
| 24 | - |
|
| 25 | - /** |
|
| 26 | - * The routes schema. |
|
| 27 | - * |
|
| 28 | - * @var string |
|
| 29 | - */ |
|
| 30 | - const SCHEMA_TYPE = 'checkout'; |
|
| 31 | - |
|
| 32 | - /** |
|
| 33 | - * Holds the current order being processed. |
|
| 34 | - * |
|
| 35 | - * @var \WC_Order |
|
| 36 | - */ |
|
| 37 | - private $order = null; |
|
| 38 | - |
|
| 39 | - /** |
|
| 40 | - * Get the path of this REST route. |
|
| 41 | - * |
|
| 42 | - * @return string |
|
| 43 | - */ |
|
| 44 | - public function get_path() { |
|
| 45 | - return '/checkout'; |
|
| 46 | - } |
|
| 47 | - |
|
| 48 | - /** |
|
| 49 | - * Checks if a nonce is required for the route. |
|
| 50 | - * |
|
| 51 | - * @param \WP_REST_Request $request Request. |
|
| 52 | - * @return bool |
|
| 53 | - */ |
|
| 54 | - protected function requires_nonce( \WP_REST_Request $request ) { |
|
| 55 | - return true; |
|
| 56 | - } |
|
| 57 | - |
|
| 58 | - /** |
|
| 59 | - * Get method arguments for this REST route. |
|
| 60 | - * |
|
| 61 | - * @return array An array of endpoints. |
|
| 62 | - */ |
|
| 63 | - public function get_args() { |
|
| 64 | - return [ |
|
| 65 | - [ |
|
| 66 | - 'methods' => \WP_REST_Server::READABLE, |
|
| 67 | - 'callback' => [ $this, 'get_response' ], |
|
| 68 | - 'permission_callback' => '__return_true', |
|
| 69 | - 'args' => [ |
|
| 70 | - 'context' => $this->get_context_param( [ 'default' => 'view' ] ), |
|
| 71 | - ], |
|
| 72 | - ], |
|
| 73 | - [ |
|
| 74 | - 'methods' => \WP_REST_Server::CREATABLE, |
|
| 75 | - 'callback' => [ $this, 'get_response' ], |
|
| 76 | - 'permission_callback' => '__return_true', |
|
| 77 | - 'args' => array_merge( |
|
| 78 | - [ |
|
| 79 | - 'payment_data' => [ |
|
| 80 | - 'description' => __( 'Data to pass through to the payment method when processing payment.', 'woocommerce' ), |
|
| 81 | - 'type' => 'array', |
|
| 82 | - 'items' => [ |
|
| 83 | - 'type' => 'object', |
|
| 84 | - 'properties' => [ |
|
| 85 | - 'key' => [ |
|
| 86 | - 'type' => 'string', |
|
| 87 | - ], |
|
| 88 | - 'value' => [ |
|
| 89 | - 'type' => [ 'string', 'boolean' ], |
|
| 90 | - ], |
|
| 91 | - ], |
|
| 92 | - ], |
|
| 93 | - ], |
|
| 94 | - ], |
|
| 95 | - $this->schema->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ) |
|
| 96 | - ), |
|
| 97 | - ], |
|
| 98 | - 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 99 | - 'allow_batch' => [ 'v1' => true ], |
|
| 100 | - ]; |
|
| 101 | - } |
|
| 102 | - |
|
| 103 | - /** |
|
| 104 | - * Prepare a single item for response. Handles setting the status based on the payment result. |
|
| 105 | - * |
|
| 106 | - * @param mixed $item Item to format to schema. |
|
| 107 | - * @param \WP_REST_Request $request Request object. |
|
| 108 | - * @return \WP_REST_Response $response Response data. |
|
| 109 | - */ |
|
| 110 | - public function prepare_item_for_response( $item, \WP_REST_Request $request ) { |
|
| 111 | - $response = parent::prepare_item_for_response( $item, $request ); |
|
| 112 | - $status_codes = [ |
|
| 113 | - 'success' => 200, |
|
| 114 | - 'pending' => 202, |
|
| 115 | - 'failure' => 400, |
|
| 116 | - 'error' => 500, |
|
| 117 | - ]; |
|
| 118 | - |
|
| 119 | - if ( isset( $item->payment_result ) && $item->payment_result instanceof PaymentResult ) { |
|
| 120 | - $response->set_status( $status_codes[ $item->payment_result->status ] ?? 200 ); |
|
| 121 | - } |
|
| 122 | - |
|
| 123 | - return $response; |
|
| 124 | - } |
|
| 125 | - |
|
| 126 | - /** |
|
| 127 | - * Convert the cart into a new draft order, or update an existing draft order, and return an updated cart response. |
|
| 128 | - * |
|
| 129 | - * @throws RouteException On error. |
|
| 130 | - * @param \WP_REST_Request $request Request object. |
|
| 131 | - * @return \WP_REST_Response |
|
| 132 | - */ |
|
| 133 | - protected function get_route_response( \WP_REST_Request $request ) { |
|
| 134 | - $this->create_or_update_draft_order( $request ); |
|
| 135 | - |
|
| 136 | - return $this->prepare_item_for_response( |
|
| 137 | - (object) [ |
|
| 138 | - 'order' => $this->order, |
|
| 139 | - 'payment_result' => new PaymentResult(), |
|
| 140 | - ], |
|
| 141 | - $request |
|
| 142 | - ); |
|
| 143 | - } |
|
| 144 | - |
|
| 145 | - /** |
|
| 146 | - * Process an order. |
|
| 147 | - * |
|
| 148 | - * 1. Obtain Draft Order |
|
| 149 | - * 2. Process Request |
|
| 150 | - * 3. Process Customer |
|
| 151 | - * 4. Validate Order |
|
| 152 | - * 5. Process Payment |
|
| 153 | - * |
|
| 154 | - * @throws RouteException On error. |
|
| 155 | - * @throws InvalidStockLevelsInCartException On error. |
|
| 156 | - * |
|
| 157 | - * @param \WP_REST_Request $request Request object. |
|
| 158 | - * |
|
| 159 | - * @return \WP_REST_Response |
|
| 160 | - */ |
|
| 161 | - protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 162 | - /** |
|
| 163 | - * Validate items etc are allowed in the order before the order is processed. This will fix violations and tell |
|
| 164 | - * the customer. |
|
| 165 | - */ |
|
| 166 | - $this->cart_controller->validate_cart(); |
|
| 167 | - |
|
| 168 | - /** |
|
| 169 | - * Obtain Draft Order and process request data. |
|
| 170 | - * |
|
| 171 | - * Note: Customer data is persisted from the request first so that OrderController::update_addresses_from_cart |
|
| 172 | - * uses the up to date customer address. |
|
| 173 | - */ |
|
| 174 | - $this->update_customer_from_request( $request ); |
|
| 175 | - $this->create_or_update_draft_order( $request ); |
|
| 176 | - $this->update_order_from_request( $request ); |
|
| 177 | - |
|
| 178 | - /** |
|
| 179 | - * Process customer data. |
|
| 180 | - * |
|
| 181 | - * Update order with customer details, and sign up a user account as necessary. |
|
| 182 | - */ |
|
| 183 | - $this->process_customer( $request ); |
|
| 184 | - |
|
| 185 | - /** |
|
| 186 | - * Validate order. |
|
| 187 | - * |
|
| 188 | - * This logic ensures the order is valid before payment is attempted. |
|
| 189 | - */ |
|
| 190 | - $this->order_controller->validate_order_before_payment( $this->order ); |
|
| 191 | - |
|
| 192 | - wc_do_deprecated_action( |
|
| 193 | - '__experimental_woocommerce_blocks_checkout_order_processed', |
|
| 194 | - array( |
|
| 195 | - $this->order, |
|
| 196 | - ), |
|
| 197 | - '6.3.0', |
|
| 198 | - 'woocommerce_store_api_checkout_order_processed', |
|
| 199 | - 'This action was deprecated in WooCommerce Blocks version 6.3.0. Please use woocommerce_store_api_checkout_order_processed instead.' |
|
| 200 | - ); |
|
| 201 | - |
|
| 202 | - wc_do_deprecated_action( |
|
| 203 | - 'woocommerce_blocks_checkout_order_processed', |
|
| 204 | - array( |
|
| 205 | - $this->order, |
|
| 206 | - ), |
|
| 207 | - '7.2.0', |
|
| 208 | - 'woocommerce_store_api_checkout_order_processed', |
|
| 209 | - 'This action was deprecated in WooCommerce Blocks version 7.2.0. Please use woocommerce_store_api_checkout_order_processed instead.' |
|
| 210 | - ); |
|
| 211 | - |
|
| 212 | - /** |
|
| 213 | - * Fires before an order is processed by the Checkout Block/Store API. |
|
| 214 | - * |
|
| 215 | - * This hook informs extensions that $order has completed processing and is ready for payment. |
|
| 216 | - * |
|
| 217 | - * This is similar to existing core hook woocommerce_checkout_order_processed. We're using a new action: |
|
| 218 | - * - To keep the interface focused (only pass $order, not passing request data). |
|
| 219 | - * - This also explicitly indicates these orders are from checkout block/StoreAPI. |
|
| 220 | - * |
|
| 221 | - * @see https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3238 |
|
| 222 | - * @example See docs/examples/checkout-order-processed.md |
|
| 223 | - |
|
| 224 | - * @param \WC_Order $order Order object. |
|
| 225 | - */ |
|
| 226 | - do_action( 'woocommerce_store_api_checkout_order_processed', $this->order ); |
|
| 227 | - |
|
| 228 | - /** |
|
| 229 | - * Process the payment and return the results. |
|
| 230 | - */ |
|
| 231 | - $payment_result = new PaymentResult(); |
|
| 232 | - |
|
| 233 | - if ( $this->order->needs_payment() ) { |
|
| 234 | - $this->process_payment( $request, $payment_result ); |
|
| 235 | - } else { |
|
| 236 | - $this->process_without_payment( $request, $payment_result ); |
|
| 237 | - } |
|
| 238 | - |
|
| 239 | - return $this->prepare_item_for_response( |
|
| 240 | - (object) [ |
|
| 241 | - 'order' => wc_get_order( $this->order ), |
|
| 242 | - 'payment_result' => $payment_result, |
|
| 243 | - ], |
|
| 244 | - $request |
|
| 245 | - ); |
|
| 246 | - } |
|
| 247 | - |
|
| 248 | - /** |
|
| 249 | - * Get route response when something went wrong. |
|
| 250 | - * |
|
| 251 | - * @param string $error_code String based error code. |
|
| 252 | - * @param string $error_message User facing error message. |
|
| 253 | - * @param int $http_status_code HTTP status. Defaults to 500. |
|
| 254 | - * @param array $additional_data Extra data (key value pairs) to expose in the error response. |
|
| 255 | - * @return \WP_Error WP Error object. |
|
| 256 | - */ |
|
| 257 | - protected function get_route_error_response( $error_code, $error_message, $http_status_code = 500, $additional_data = [] ) { |
|
| 258 | - $error_from_message = new \WP_Error( |
|
| 259 | - $error_code, |
|
| 260 | - $error_message |
|
| 261 | - ); |
|
| 262 | - // 409 is when there was a conflict, so we return the cart so the client can resolve it. |
|
| 263 | - if ( 409 === $http_status_code ) { |
|
| 264 | - return $this->add_data_to_error_object( $error_from_message, $additional_data, $http_status_code, true ); |
|
| 265 | - } |
|
| 266 | - return $this->add_data_to_error_object( $error_from_message, $additional_data, $http_status_code ); |
|
| 267 | - } |
|
| 268 | - |
|
| 269 | - /** |
|
| 270 | - * Get route response when something went wrong. |
|
| 271 | - * |
|
| 272 | - * @param \WP_Error $error_object User facing error message. |
|
| 273 | - * @param int $http_status_code HTTP status. Defaults to 500. |
|
| 274 | - * @param array $additional_data Extra data (key value pairs) to expose in the error response. |
|
| 275 | - * @return \WP_Error WP Error object. |
|
| 276 | - */ |
|
| 277 | - protected function get_route_error_response_from_object( $error_object, $http_status_code = 500, $additional_data = [] ) { |
|
| 278 | - // 409 is when there was a conflict, so we return the cart so the client can resolve it. |
|
| 279 | - if ( 409 === $http_status_code ) { |
|
| 280 | - return $this->add_data_to_error_object( $error_object, $additional_data, $http_status_code, true ); |
|
| 281 | - } |
|
| 282 | - return $this->add_data_to_error_object( $error_object, $additional_data, $http_status_code ); |
|
| 283 | - } |
|
| 284 | - |
|
| 285 | - /** |
|
| 286 | - * Adds additional data to the \WP_Error object. |
|
| 287 | - * |
|
| 288 | - * @param \WP_Error $error The error object to add the cart to. |
|
| 289 | - * @param array $data The data to add to the error object. |
|
| 290 | - * @param int $http_status_code The HTTP status code this error should return. |
|
| 291 | - * @param bool $include_cart Whether the cart should be included in the error data. |
|
| 292 | - * @returns \WP_Error The \WP_Error with the cart added. |
|
| 293 | - */ |
|
| 294 | - private function add_data_to_error_object( $error, $data, $http_status_code, bool $include_cart = false ) { |
|
| 295 | - $data = array_merge( $data, [ 'status' => $http_status_code ] ); |
|
| 296 | - if ( $include_cart ) { |
|
| 297 | - $data = array_merge( $data, [ 'cart' => wc()->api->get_endpoint_data( '/wc/store/v1/cart' ) ] ); |
|
| 298 | - } |
|
| 299 | - $error->add_data( $data ); |
|
| 300 | - return $error; |
|
| 301 | - } |
|
| 302 | - |
|
| 303 | - /** |
|
| 304 | - * Create or update a draft order based on the cart. |
|
| 305 | - * |
|
| 306 | - * @param \WP_REST_Request $request Full details about the request. |
|
| 307 | - * @throws RouteException On error. |
|
| 308 | - */ |
|
| 309 | - private function create_or_update_draft_order( \WP_REST_Request $request ) { |
|
| 310 | - $this->order = $this->get_draft_order(); |
|
| 311 | - |
|
| 312 | - if ( ! $this->order ) { |
|
| 313 | - $this->order = $this->order_controller->create_order_from_cart(); |
|
| 314 | - } else { |
|
| 315 | - $this->order_controller->update_order_from_cart( $this->order ); |
|
| 316 | - } |
|
| 317 | - |
|
| 318 | - wc_do_deprecated_action( |
|
| 319 | - '__experimental_woocommerce_blocks_checkout_update_order_meta', |
|
| 320 | - array( |
|
| 321 | - $this->order, |
|
| 322 | - ), |
|
| 323 | - '6.3.0', |
|
| 324 | - 'woocommerce_store_api_checkout_update_order_meta', |
|
| 325 | - 'This action was deprecated in WooCommerce Blocks version 6.3.0. Please use woocommerce_store_api_checkout_update_order_meta instead.' |
|
| 326 | - ); |
|
| 327 | - |
|
| 328 | - wc_do_deprecated_action( |
|
| 329 | - 'woocommerce_blocks_checkout_update_order_meta', |
|
| 330 | - array( |
|
| 331 | - $this->order, |
|
| 332 | - ), |
|
| 333 | - '7.2.0', |
|
| 334 | - 'woocommerce_store_api_checkout_update_order_meta', |
|
| 335 | - 'This action was deprecated in WooCommerce Blocks version 7.2.0. Please use woocommerce_store_api_checkout_update_order_meta instead.' |
|
| 336 | - ); |
|
| 337 | - |
|
| 338 | - /** |
|
| 339 | - * Fires when the Checkout Block/Store API updates an order's meta data. |
|
| 340 | - * |
|
| 341 | - * This hook gives extensions the chance to add or update meta data on the $order. |
|
| 342 | - * Throwing an exception from a callback attached to this action will make the Checkout Block render in a warning state, effectively preventing checkout. |
|
| 343 | - * |
|
| 344 | - * This is similar to existing core hook woocommerce_checkout_update_order_meta. |
|
| 345 | - * We're using a new action: |
|
| 346 | - * - To keep the interface focused (only pass $order, not passing request data). |
|
| 347 | - * - This also explicitly indicates these orders are from checkout block/StoreAPI. |
|
| 348 | - * |
|
| 349 | - * @see https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3686 |
|
| 350 | - * |
|
| 351 | - * @param \WC_Order $order Order object. |
|
| 352 | - */ |
|
| 353 | - do_action( 'woocommerce_store_api_checkout_update_order_meta', $this->order ); |
|
| 354 | - |
|
| 355 | - // Confirm order is valid before proceeding further. |
|
| 356 | - if ( ! $this->order instanceof \WC_Order ) { |
|
| 357 | - throw new RouteException( |
|
| 358 | - 'woocommerce_rest_checkout_missing_order', |
|
| 359 | - __( 'Unable to create order', 'woocommerce' ), |
|
| 360 | - 500 |
|
| 361 | - ); |
|
| 362 | - } |
|
| 363 | - |
|
| 364 | - // Store order ID to session. |
|
| 365 | - $this->set_draft_order_id( $this->order->get_id() ); |
|
| 366 | - |
|
| 367 | - /** |
|
| 368 | - * Try to reserve stock for the order. |
|
| 369 | - * |
|
| 370 | - * If creating a draft order on checkout entry, set the timeout to 10 mins. |
|
| 371 | - * If POSTing to the checkout (attempting to pay), set the timeout to 60 mins (using the woocommerce_hold_stock_minutes option). |
|
| 372 | - */ |
|
| 373 | - try { |
|
| 374 | - $reserve_stock = new ReserveStock(); |
|
| 375 | - $duration = $request->get_method() === 'POST' ? (int) get_option( 'woocommerce_hold_stock_minutes', 60 ) : 10; |
|
| 376 | - $reserve_stock->reserve_stock_for_order( $this->order, $duration ); |
|
| 377 | - } catch ( ReserveStockException $e ) { |
|
| 378 | - throw new RouteException( |
|
| 379 | - $e->getErrorCode(), |
|
| 380 | - $e->getMessage(), |
|
| 381 | - $e->getCode() |
|
| 382 | - ); |
|
| 383 | - } |
|
| 384 | - } |
|
| 385 | - |
|
| 386 | - /** |
|
| 387 | - * Updates the current customer session using data from the request (e.g. address data). |
|
| 388 | - * |
|
| 389 | - * Address session data is synced to the order itself later on by OrderController::update_order_from_cart() |
|
| 390 | - * |
|
| 391 | - * @param \WP_REST_Request $request Full details about the request. |
|
| 392 | - */ |
|
| 393 | - private function update_customer_from_request( \WP_REST_Request $request ) { |
|
| 394 | - $customer = wc()->customer; |
|
| 395 | - |
|
| 396 | - // Billing address is a required field. |
|
| 397 | - foreach ( $request['billing_address'] as $key => $value ) { |
|
| 398 | - if ( is_callable( [ $customer, "set_billing_$key" ] ) ) { |
|
| 399 | - $customer->{"set_billing_$key"}( $value ); |
|
| 400 | - } |
|
| 401 | - } |
|
| 402 | - |
|
| 403 | - // If shipping address (optional field) was not provided, set it to the given billing address (required field). |
|
| 404 | - $shipping_address_values = $request['shipping_address'] ?? $request['billing_address']; |
|
| 405 | - |
|
| 406 | - foreach ( $shipping_address_values as $key => $value ) { |
|
| 407 | - if ( is_callable( [ $customer, "set_shipping_$key" ] ) ) { |
|
| 408 | - $customer->{"set_shipping_$key"}( $value ); |
|
| 409 | - } elseif ( 'phone' === $key ) { |
|
| 410 | - $customer->update_meta_data( 'shipping_phone', $value ); |
|
| 411 | - } |
|
| 412 | - } |
|
| 413 | - |
|
| 414 | - $customer->save(); |
|
| 415 | - } |
|
| 416 | - |
|
| 417 | - /** |
|
| 418 | - * Update the current order using the posted values from the request. |
|
| 419 | - * |
|
| 420 | - * @param \WP_REST_Request $request Full details about the request. |
|
| 421 | - */ |
|
| 422 | - private function update_order_from_request( \WP_REST_Request $request ) { |
|
| 423 | - $this->order->set_customer_note( $request['customer_note'] ?? '' ); |
|
| 424 | - $this->order->set_payment_method( $this->get_request_payment_method_id( $request ) ); |
|
| 425 | - |
|
| 426 | - wc_do_deprecated_action( |
|
| 427 | - '__experimental_woocommerce_blocks_checkout_update_order_from_request', |
|
| 428 | - array( |
|
| 429 | - $this->order, |
|
| 430 | - $request, |
|
| 431 | - ), |
|
| 432 | - '6.3.0', |
|
| 433 | - 'woocommerce_store_api_checkout_update_order_from_request', |
|
| 434 | - 'This action was deprecated in WooCommerce Blocks version 6.3.0. Please use woocommerce_store_api_checkout_update_order_from_request instead.' |
|
| 435 | - ); |
|
| 436 | - |
|
| 437 | - wc_do_deprecated_action( |
|
| 438 | - 'woocommerce_blocks_checkout_update_order_from_request', |
|
| 439 | - array( |
|
| 440 | - $this->order, |
|
| 441 | - $request, |
|
| 442 | - ), |
|
| 443 | - '7.2.0', |
|
| 444 | - 'woocommerce_store_api_checkout_update_order_from_request', |
|
| 445 | - 'This action was deprecated in WooCommerce Blocks version 7.2.0. Please use woocommerce_store_api_checkout_update_order_from_request instead.' |
|
| 446 | - ); |
|
| 447 | - |
|
| 448 | - /** |
|
| 449 | - * Fires when the Checkout Block/Store API updates an order's from the API request data. |
|
| 450 | - * |
|
| 451 | - * This hook gives extensions the chance to update orders based on the data in the request. This can be used in |
|
| 452 | - * conjunction with the ExtendSchema class to post custom data and then process it. |
|
| 453 | - * |
|
| 454 | - * @param \WC_Order $order Order object. |
|
| 455 | - * @param \WP_REST_Request $request Full details about the request. |
|
| 456 | - */ |
|
| 457 | - do_action( 'woocommerce_store_api_checkout_update_order_from_request', $this->order, $request ); |
|
| 458 | - |
|
| 459 | - $this->order->save(); |
|
| 460 | - } |
|
| 461 | - |
|
| 462 | - /** |
|
| 463 | - * For orders which do not require payment, just update status. |
|
| 464 | - * |
|
| 465 | - * @param \WP_REST_Request $request Request object. |
|
| 466 | - * @param PaymentResult $payment_result Payment result object. |
|
| 467 | - */ |
|
| 468 | - private function process_without_payment( \WP_REST_Request $request, PaymentResult $payment_result ) { |
|
| 469 | - // Transition the order to pending, and then completed. This ensures transactional emails fire for pending_to_complete events. |
|
| 470 | - $this->order->update_status( 'pending' ); |
|
| 471 | - $this->order->payment_complete(); |
|
| 472 | - |
|
| 473 | - // Mark the payment as successful. |
|
| 474 | - $payment_result->set_status( 'success' ); |
|
| 475 | - $payment_result->set_redirect_url( $this->order->get_checkout_order_received_url() ); |
|
| 476 | - } |
|
| 477 | - |
|
| 478 | - /** |
|
| 479 | - * Fires an action hook instructing active payment gateways to process the payment for an order and provide a result. |
|
| 480 | - * |
|
| 481 | - * @throws RouteException On error. |
|
| 482 | - * |
|
| 483 | - * @param \WP_REST_Request $request Request object. |
|
| 484 | - * @param PaymentResult $payment_result Payment result object. |
|
| 485 | - */ |
|
| 486 | - private function process_payment( \WP_REST_Request $request, PaymentResult $payment_result ) { |
|
| 487 | - try { |
|
| 488 | - // Transition the order to pending before making payment. |
|
| 489 | - $this->order->update_status( 'pending' ); |
|
| 490 | - |
|
| 491 | - // Prepare the payment context object to pass through payment hooks. |
|
| 492 | - $context = new PaymentContext(); |
|
| 493 | - $context->set_payment_method( $this->get_request_payment_method_id( $request ) ); |
|
| 494 | - $context->set_payment_data( $this->get_request_payment_data( $request ) ); |
|
| 495 | - $context->set_order( $this->order ); |
|
| 496 | - |
|
| 497 | - /** |
|
| 498 | - * Process payment with context. |
|
| 499 | - * |
|
| 500 | - * @hook woocommerce_rest_checkout_process_payment_with_context |
|
| 501 | - * |
|
| 502 | - * @throws \Exception If there is an error taking payment, an \Exception object can be thrown with an error message. |
|
| 503 | - * |
|
| 504 | - * @param PaymentContext $context Holds context for the payment, including order ID and payment method. |
|
| 505 | - * @param PaymentResult $payment_result Result object for the transaction. |
|
| 506 | - */ |
|
| 507 | - do_action_ref_array( 'woocommerce_rest_checkout_process_payment_with_context', [ $context, &$payment_result ] ); |
|
| 508 | - |
|
| 509 | - if ( ! $payment_result instanceof PaymentResult ) { |
|
| 510 | - throw new RouteException( 'woocommerce_rest_checkout_invalid_payment_result', __( 'Invalid payment result received from payment method.', 'woocommerce' ), 500 ); |
|
| 511 | - } |
|
| 512 | - } catch ( \Exception $e ) { |
|
| 513 | - throw new RouteException( 'woocommerce_rest_checkout_process_payment_error', $e->getMessage(), 400 ); |
|
| 514 | - } |
|
| 515 | - } |
|
| 516 | - |
|
| 517 | - /** |
|
| 518 | - * Gets the chosen payment method ID from the request. |
|
| 519 | - * |
|
| 520 | - * @throws RouteException On error. |
|
| 521 | - * @param \WP_REST_Request $request Request object. |
|
| 522 | - * @return string |
|
| 523 | - */ |
|
| 524 | - private function get_request_payment_method_id( \WP_REST_Request $request ) { |
|
| 525 | - $payment_method = $this->get_request_payment_method( $request ); |
|
| 526 | - return is_null( $payment_method ) ? '' : $payment_method->id; |
|
| 527 | - } |
|
| 528 | - |
|
| 529 | - /** |
|
| 530 | - * Gets the chosen payment method from the request. |
|
| 531 | - * |
|
| 532 | - * @throws RouteException On error. |
|
| 533 | - * @param \WP_REST_Request $request Request object. |
|
| 534 | - * @return \WC_Payment_Gateway|null |
|
| 535 | - */ |
|
| 536 | - private function get_request_payment_method( \WP_REST_Request $request ) { |
|
| 537 | - $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); |
|
| 538 | - $request_payment_method = wc_clean( wp_unslash( $request['payment_method'] ?? '' ) ); |
|
| 539 | - $requires_payment_method = $this->order->needs_payment(); |
|
| 540 | - |
|
| 541 | - if ( empty( $request_payment_method ) ) { |
|
| 542 | - if ( $requires_payment_method ) { |
|
| 543 | - throw new RouteException( |
|
| 544 | - 'woocommerce_rest_checkout_missing_payment_method', |
|
| 545 | - __( 'No payment method provided.', 'woocommerce' ), |
|
| 546 | - 400 |
|
| 547 | - ); |
|
| 548 | - } |
|
| 549 | - return null; |
|
| 550 | - } |
|
| 551 | - |
|
| 552 | - if ( ! isset( $available_gateways[ $request_payment_method ] ) ) { |
|
| 553 | - throw new RouteException( |
|
| 554 | - 'woocommerce_rest_checkout_payment_method_disabled', |
|
| 555 | - sprintf( |
|
| 556 | - // Translators: %s Payment method ID. |
|
| 557 | - __( 'The %s payment gateway is not available.', 'woocommerce' ), |
|
| 558 | - esc_html( $request_payment_method ) |
|
| 559 | - ), |
|
| 560 | - 400 |
|
| 561 | - ); |
|
| 562 | - } |
|
| 563 | - |
|
| 564 | - return $available_gateways[ $request_payment_method ]; |
|
| 565 | - } |
|
| 566 | - |
|
| 567 | - /** |
|
| 568 | - * Gets and formats payment request data. |
|
| 569 | - * |
|
| 570 | - * @param \WP_REST_Request $request Request object. |
|
| 571 | - * @return array |
|
| 572 | - */ |
|
| 573 | - private function get_request_payment_data( \WP_REST_Request $request ) { |
|
| 574 | - static $payment_data = []; |
|
| 575 | - if ( ! empty( $payment_data ) ) { |
|
| 576 | - return $payment_data; |
|
| 577 | - } |
|
| 578 | - if ( ! empty( $request['payment_data'] ) ) { |
|
| 579 | - foreach ( $request['payment_data'] as $data ) { |
|
| 580 | - $payment_data[ sanitize_key( $data['key'] ) ] = wc_clean( $data['value'] ); |
|
| 581 | - } |
|
| 582 | - } |
|
| 583 | - |
|
| 584 | - return $payment_data; |
|
| 585 | - } |
|
| 586 | - |
|
| 587 | - /** |
|
| 588 | - * Order processing relating to customer account. |
|
| 589 | - * |
|
| 590 | - * Creates a customer account as needed (based on request & store settings) and updates the order with the new customer ID. |
|
| 591 | - * Updates the order with user details (e.g. address). |
|
| 592 | - * |
|
| 593 | - * @throws RouteException API error object with error details. |
|
| 594 | - * @param \WP_REST_Request $request Request object. |
|
| 595 | - */ |
|
| 596 | - private function process_customer( \WP_REST_Request $request ) { |
|
| 597 | - try { |
|
| 598 | - if ( $this->should_create_customer_account( $request ) ) { |
|
| 599 | - $customer_id = $this->create_customer_account( |
|
| 600 | - $request['billing_address']['email'], |
|
| 601 | - $request['billing_address']['first_name'], |
|
| 602 | - $request['billing_address']['last_name'] |
|
| 603 | - ); |
|
| 604 | - // Log the customer in. |
|
| 605 | - wc_set_customer_auth_cookie( $customer_id ); |
|
| 606 | - |
|
| 607 | - // Associate customer with the order. |
|
| 608 | - $this->order->set_customer_id( $customer_id ); |
|
| 609 | - $this->order->save(); |
|
| 610 | - } |
|
| 611 | - } catch ( \Exception $error ) { |
|
| 612 | - switch ( $error->getMessage() ) { |
|
| 613 | - case 'registration-error-invalid-email': |
|
| 614 | - throw new RouteException( |
|
| 615 | - 'registration-error-invalid-email', |
|
| 616 | - __( 'Please provide a valid email address.', 'woocommerce' ), |
|
| 617 | - 400 |
|
| 618 | - ); |
|
| 619 | - case 'registration-error-email-exists': |
|
| 620 | - throw new RouteException( |
|
| 621 | - 'registration-error-email-exists', |
|
| 622 | - __( 'An account is already registered with your email address. Please log in before proceeding.', 'woocommerce' ), |
|
| 623 | - 400 |
|
| 624 | - ); |
|
| 625 | - } |
|
| 626 | - } |
|
| 627 | - |
|
| 628 | - // Persist customer address data to account. |
|
| 629 | - $this->order_controller->sync_customer_data_with_order( $this->order ); |
|
| 630 | - } |
|
| 631 | - |
|
| 632 | - /** |
|
| 633 | - * Check request options and store (shop) config to determine if a user account should be created as part of order |
|
| 634 | - * processing. |
|
| 635 | - * |
|
| 636 | - * @param \WP_REST_Request $request The current request object being handled. |
|
| 637 | - * @return boolean True if a new user account should be created. |
|
| 638 | - */ |
|
| 639 | - private function should_create_customer_account( \WP_REST_Request $request ) { |
|
| 640 | - if ( is_user_logged_in() ) { |
|
| 641 | - return false; |
|
| 642 | - } |
|
| 643 | - |
|
| 644 | - // Return false if registration is not enabled for the store. |
|
| 645 | - if ( false === filter_var( wc()->checkout()->is_registration_enabled(), FILTER_VALIDATE_BOOLEAN ) ) { |
|
| 646 | - return false; |
|
| 647 | - } |
|
| 648 | - |
|
| 649 | - // Return true if the store requires an account for all purchases. Note - checkbox is not displayed to shopper in this case. |
|
| 650 | - if ( true === filter_var( wc()->checkout()->is_registration_required(), FILTER_VALIDATE_BOOLEAN ) ) { |
|
| 651 | - return true; |
|
| 652 | - } |
|
| 653 | - |
|
| 654 | - // Create an account if requested via the endpoint. |
|
| 655 | - if ( true === filter_var( $request['create_account'], FILTER_VALIDATE_BOOLEAN ) ) { |
|
| 656 | - // User has requested an account as part of checkout processing. |
|
| 657 | - return true; |
|
| 658 | - } |
|
| 659 | - |
|
| 660 | - return false; |
|
| 661 | - } |
|
| 662 | - |
|
| 663 | - /** |
|
| 664 | - * Create a new account for a customer. |
|
| 665 | - * |
|
| 666 | - * The account is created with a generated username. The customer is sent |
|
| 667 | - * an email notifying them about the account and containing a link to set |
|
| 668 | - * their (initial) password. |
|
| 669 | - * |
|
| 670 | - * Intended as a replacement for wc_create_new_customer in WC core. |
|
| 671 | - * |
|
| 672 | - * @throws \Exception If an error is encountered when creating the user account. |
|
| 673 | - * |
|
| 674 | - * @param string $user_email The email address to use for the new account. |
|
| 675 | - * @param string $first_name The first name to use for the new account. |
|
| 676 | - * @param string $last_name The last name to use for the new account. |
|
| 677 | - * |
|
| 678 | - * @return int User id if successful |
|
| 679 | - */ |
|
| 680 | - private function create_customer_account( $user_email, $first_name, $last_name ) { |
|
| 681 | - if ( empty( $user_email ) || ! is_email( $user_email ) ) { |
|
| 682 | - throw new \Exception( 'registration-error-invalid-email' ); |
|
| 683 | - } |
|
| 684 | - |
|
| 685 | - if ( email_exists( $user_email ) ) { |
|
| 686 | - throw new \Exception( 'registration-error-email-exists' ); |
|
| 687 | - } |
|
| 688 | - |
|
| 689 | - $username = wc_create_new_customer_username( $user_email ); |
|
| 690 | - |
|
| 691 | - // Handle password creation. |
|
| 692 | - $password = wp_generate_password(); |
|
| 693 | - $password_generated = true; |
|
| 694 | - |
|
| 695 | - // Use WP_Error to handle registration errors. |
|
| 696 | - $errors = new \WP_Error(); |
|
| 697 | - |
|
| 698 | - /** |
|
| 699 | - * Fires before a customer account is registered. |
|
| 700 | - * |
|
| 701 | - * This hook fires before customer accounts are created and passes the form data (username, email) and an array |
|
| 702 | - * of errors. |
|
| 703 | - * |
|
| 704 | - * This could be used to add extra validation logic and append errors to the array. |
|
| 705 | - * |
|
| 706 | - * @internal Matches filter name in WooCommerce core. |
|
| 707 | - * |
|
| 708 | - * @param string $username Customer username. |
|
| 709 | - * @param string $user_email Customer email address. |
|
| 710 | - * @param \WP_Error $errors Error object. |
|
| 711 | - */ |
|
| 712 | - do_action( 'woocommerce_register_post', $username, $user_email, $errors ); |
|
| 713 | - |
|
| 714 | - /** |
|
| 715 | - * Filters registration errors before a customer account is registered. |
|
| 716 | - * |
|
| 717 | - * This hook filters registration errors. This can be used to manipulate the array of errors before |
|
| 718 | - * they are displayed. |
|
| 719 | - * |
|
| 720 | - * @internal Matches filter name in WooCommerce core. |
|
| 721 | - * |
|
| 722 | - * @param \WP_Error $errors Error object. |
|
| 723 | - * @param string $username Customer username. |
|
| 724 | - * @param string $user_email Customer email address. |
|
| 725 | - * @return \WP_Error |
|
| 726 | - */ |
|
| 727 | - $errors = apply_filters( 'woocommerce_registration_errors', $errors, $username, $user_email ); |
|
| 728 | - |
|
| 729 | - if ( is_wp_error( $errors ) && $errors->get_error_code() ) { |
|
| 730 | - throw new \Exception( $errors->get_error_code() ); |
|
| 731 | - } |
|
| 732 | - |
|
| 733 | - /** |
|
| 734 | - * Filters customer data before a customer account is registered. |
|
| 735 | - * |
|
| 736 | - * This hook filters customer data. It allows user data to be changed, for example, username, password, email, |
|
| 737 | - * first name, last name, and role. |
|
| 738 | - * |
|
| 739 | - * @param array $customer_data An array of customer (user) data. |
|
| 740 | - * @return array |
|
| 741 | - */ |
|
| 742 | - $new_customer_data = apply_filters( |
|
| 743 | - 'woocommerce_new_customer_data', |
|
| 744 | - array( |
|
| 745 | - 'user_login' => $username, |
|
| 746 | - 'user_pass' => $password, |
|
| 747 | - 'user_email' => $user_email, |
|
| 748 | - 'first_name' => $first_name, |
|
| 749 | - 'last_name' => $last_name, |
|
| 750 | - 'role' => 'customer', |
|
| 751 | - 'source' => 'store-api,', |
|
| 752 | - ) |
|
| 753 | - ); |
|
| 754 | - |
|
| 755 | - $customer_id = wp_insert_user( $new_customer_data ); |
|
| 756 | - |
|
| 757 | - if ( is_wp_error( $customer_id ) ) { |
|
| 758 | - throw $this->map_create_account_error( $customer_id ); |
|
| 759 | - } |
|
| 760 | - |
|
| 761 | - // Set account flag to remind customer to update generated password. |
|
| 762 | - update_user_option( $customer_id, 'default_password_nag', true, true ); |
|
| 763 | - |
|
| 764 | - /** |
|
| 765 | - * Fires after a customer account has been registered. |
|
| 766 | - * |
|
| 767 | - * This hook fires after customer accounts are created and passes the customer data. |
|
| 768 | - * |
|
| 769 | - * @internal Matches filter name in WooCommerce core. |
|
| 770 | - * |
|
| 771 | - * @param integer $customer_id New customer (user) ID. |
|
| 772 | - * @param array $new_customer_data Array of customer (user) data. |
|
| 773 | - * @param string $password_generated The generated password for the account. |
|
| 774 | - */ |
|
| 775 | - do_action( 'woocommerce_created_customer', $customer_id, $new_customer_data, $password_generated ); |
|
| 776 | - |
|
| 777 | - return $customer_id; |
|
| 778 | - } |
|
| 779 | - |
|
| 780 | - /** |
|
| 781 | - * Convert an account creation error to an exception. |
|
| 782 | - * |
|
| 783 | - * @param \WP_Error $error An error object. |
|
| 784 | - * @return \Exception. |
|
| 785 | - */ |
|
| 786 | - private function map_create_account_error( \WP_Error $error ) { |
|
| 787 | - switch ( $error->get_error_code() ) { |
|
| 788 | - // WordPress core error codes. |
|
| 789 | - case 'empty_username': |
|
| 790 | - case 'invalid_username': |
|
| 791 | - case 'empty_email': |
|
| 792 | - case 'invalid_email': |
|
| 793 | - case 'email_exists': |
|
| 794 | - case 'registerfail': |
|
| 795 | - return new \Exception( 'woocommerce_rest_checkout_create_account_failure' ); |
|
| 796 | - } |
|
| 797 | - return new \Exception( 'woocommerce_rest_checkout_create_account_failure' ); |
|
| 798 | - } |
|
| 16 | + use DraftOrderTrait; |
|
| 17 | + |
|
| 18 | + /** |
|
| 19 | + * The route identifier. |
|
| 20 | + * |
|
| 21 | + * @var string |
|
| 22 | + */ |
|
| 23 | + const IDENTIFIER = 'checkout'; |
|
| 24 | + |
|
| 25 | + /** |
|
| 26 | + * The routes schema. |
|
| 27 | + * |
|
| 28 | + * @var string |
|
| 29 | + */ |
|
| 30 | + const SCHEMA_TYPE = 'checkout'; |
|
| 31 | + |
|
| 32 | + /** |
|
| 33 | + * Holds the current order being processed. |
|
| 34 | + * |
|
| 35 | + * @var \WC_Order |
|
| 36 | + */ |
|
| 37 | + private $order = null; |
|
| 38 | + |
|
| 39 | + /** |
|
| 40 | + * Get the path of this REST route. |
|
| 41 | + * |
|
| 42 | + * @return string |
|
| 43 | + */ |
|
| 44 | + public function get_path() { |
|
| 45 | + return '/checkout'; |
|
| 46 | + } |
|
| 47 | + |
|
| 48 | + /** |
|
| 49 | + * Checks if a nonce is required for the route. |
|
| 50 | + * |
|
| 51 | + * @param \WP_REST_Request $request Request. |
|
| 52 | + * @return bool |
|
| 53 | + */ |
|
| 54 | + protected function requires_nonce( \WP_REST_Request $request ) { |
|
| 55 | + return true; |
|
| 56 | + } |
|
| 57 | + |
|
| 58 | + /** |
|
| 59 | + * Get method arguments for this REST route. |
|
| 60 | + * |
|
| 61 | + * @return array An array of endpoints. |
|
| 62 | + */ |
|
| 63 | + public function get_args() { |
|
| 64 | + return [ |
|
| 65 | + [ |
|
| 66 | + 'methods' => \WP_REST_Server::READABLE, |
|
| 67 | + 'callback' => [ $this, 'get_response' ], |
|
| 68 | + 'permission_callback' => '__return_true', |
|
| 69 | + 'args' => [ |
|
| 70 | + 'context' => $this->get_context_param( [ 'default' => 'view' ] ), |
|
| 71 | + ], |
|
| 72 | + ], |
|
| 73 | + [ |
|
| 74 | + 'methods' => \WP_REST_Server::CREATABLE, |
|
| 75 | + 'callback' => [ $this, 'get_response' ], |
|
| 76 | + 'permission_callback' => '__return_true', |
|
| 77 | + 'args' => array_merge( |
|
| 78 | + [ |
|
| 79 | + 'payment_data' => [ |
|
| 80 | + 'description' => __( 'Data to pass through to the payment method when processing payment.', 'woocommerce' ), |
|
| 81 | + 'type' => 'array', |
|
| 82 | + 'items' => [ |
|
| 83 | + 'type' => 'object', |
|
| 84 | + 'properties' => [ |
|
| 85 | + 'key' => [ |
|
| 86 | + 'type' => 'string', |
|
| 87 | + ], |
|
| 88 | + 'value' => [ |
|
| 89 | + 'type' => [ 'string', 'boolean' ], |
|
| 90 | + ], |
|
| 91 | + ], |
|
| 92 | + ], |
|
| 93 | + ], |
|
| 94 | + ], |
|
| 95 | + $this->schema->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ) |
|
| 96 | + ), |
|
| 97 | + ], |
|
| 98 | + 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 99 | + 'allow_batch' => [ 'v1' => true ], |
|
| 100 | + ]; |
|
| 101 | + } |
|
| 102 | + |
|
| 103 | + /** |
|
| 104 | + * Prepare a single item for response. Handles setting the status based on the payment result. |
|
| 105 | + * |
|
| 106 | + * @param mixed $item Item to format to schema. |
|
| 107 | + * @param \WP_REST_Request $request Request object. |
|
| 108 | + * @return \WP_REST_Response $response Response data. |
|
| 109 | + */ |
|
| 110 | + public function prepare_item_for_response( $item, \WP_REST_Request $request ) { |
|
| 111 | + $response = parent::prepare_item_for_response( $item, $request ); |
|
| 112 | + $status_codes = [ |
|
| 113 | + 'success' => 200, |
|
| 114 | + 'pending' => 202, |
|
| 115 | + 'failure' => 400, |
|
| 116 | + 'error' => 500, |
|
| 117 | + ]; |
|
| 118 | + |
|
| 119 | + if ( isset( $item->payment_result ) && $item->payment_result instanceof PaymentResult ) { |
|
| 120 | + $response->set_status( $status_codes[ $item->payment_result->status ] ?? 200 ); |
|
| 121 | + } |
|
| 122 | + |
|
| 123 | + return $response; |
|
| 124 | + } |
|
| 125 | + |
|
| 126 | + /** |
|
| 127 | + * Convert the cart into a new draft order, or update an existing draft order, and return an updated cart response. |
|
| 128 | + * |
|
| 129 | + * @throws RouteException On error. |
|
| 130 | + * @param \WP_REST_Request $request Request object. |
|
| 131 | + * @return \WP_REST_Response |
|
| 132 | + */ |
|
| 133 | + protected function get_route_response( \WP_REST_Request $request ) { |
|
| 134 | + $this->create_or_update_draft_order( $request ); |
|
| 135 | + |
|
| 136 | + return $this->prepare_item_for_response( |
|
| 137 | + (object) [ |
|
| 138 | + 'order' => $this->order, |
|
| 139 | + 'payment_result' => new PaymentResult(), |
|
| 140 | + ], |
|
| 141 | + $request |
|
| 142 | + ); |
|
| 143 | + } |
|
| 144 | + |
|
| 145 | + /** |
|
| 146 | + * Process an order. |
|
| 147 | + * |
|
| 148 | + * 1. Obtain Draft Order |
|
| 149 | + * 2. Process Request |
|
| 150 | + * 3. Process Customer |
|
| 151 | + * 4. Validate Order |
|
| 152 | + * 5. Process Payment |
|
| 153 | + * |
|
| 154 | + * @throws RouteException On error. |
|
| 155 | + * @throws InvalidStockLevelsInCartException On error. |
|
| 156 | + * |
|
| 157 | + * @param \WP_REST_Request $request Request object. |
|
| 158 | + * |
|
| 159 | + * @return \WP_REST_Response |
|
| 160 | + */ |
|
| 161 | + protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 162 | + /** |
|
| 163 | + * Validate items etc are allowed in the order before the order is processed. This will fix violations and tell |
|
| 164 | + * the customer. |
|
| 165 | + */ |
|
| 166 | + $this->cart_controller->validate_cart(); |
|
| 167 | + |
|
| 168 | + /** |
|
| 169 | + * Obtain Draft Order and process request data. |
|
| 170 | + * |
|
| 171 | + * Note: Customer data is persisted from the request first so that OrderController::update_addresses_from_cart |
|
| 172 | + * uses the up to date customer address. |
|
| 173 | + */ |
|
| 174 | + $this->update_customer_from_request( $request ); |
|
| 175 | + $this->create_or_update_draft_order( $request ); |
|
| 176 | + $this->update_order_from_request( $request ); |
|
| 177 | + |
|
| 178 | + /** |
|
| 179 | + * Process customer data. |
|
| 180 | + * |
|
| 181 | + * Update order with customer details, and sign up a user account as necessary. |
|
| 182 | + */ |
|
| 183 | + $this->process_customer( $request ); |
|
| 184 | + |
|
| 185 | + /** |
|
| 186 | + * Validate order. |
|
| 187 | + * |
|
| 188 | + * This logic ensures the order is valid before payment is attempted. |
|
| 189 | + */ |
|
| 190 | + $this->order_controller->validate_order_before_payment( $this->order ); |
|
| 191 | + |
|
| 192 | + wc_do_deprecated_action( |
|
| 193 | + '__experimental_woocommerce_blocks_checkout_order_processed', |
|
| 194 | + array( |
|
| 195 | + $this->order, |
|
| 196 | + ), |
|
| 197 | + '6.3.0', |
|
| 198 | + 'woocommerce_store_api_checkout_order_processed', |
|
| 199 | + 'This action was deprecated in WooCommerce Blocks version 6.3.0. Please use woocommerce_store_api_checkout_order_processed instead.' |
|
| 200 | + ); |
|
| 201 | + |
|
| 202 | + wc_do_deprecated_action( |
|
| 203 | + 'woocommerce_blocks_checkout_order_processed', |
|
| 204 | + array( |
|
| 205 | + $this->order, |
|
| 206 | + ), |
|
| 207 | + '7.2.0', |
|
| 208 | + 'woocommerce_store_api_checkout_order_processed', |
|
| 209 | + 'This action was deprecated in WooCommerce Blocks version 7.2.0. Please use woocommerce_store_api_checkout_order_processed instead.' |
|
| 210 | + ); |
|
| 211 | + |
|
| 212 | + /** |
|
| 213 | + * Fires before an order is processed by the Checkout Block/Store API. |
|
| 214 | + * |
|
| 215 | + * This hook informs extensions that $order has completed processing and is ready for payment. |
|
| 216 | + * |
|
| 217 | + * This is similar to existing core hook woocommerce_checkout_order_processed. We're using a new action: |
|
| 218 | + * - To keep the interface focused (only pass $order, not passing request data). |
|
| 219 | + * - This also explicitly indicates these orders are from checkout block/StoreAPI. |
|
| 220 | + * |
|
| 221 | + * @see https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3238 |
|
| 222 | + * @example See docs/examples/checkout-order-processed.md |
|
| 223 | + * @param \WC_Order $order Order object. |
|
| 224 | + */ |
|
| 225 | + do_action( 'woocommerce_store_api_checkout_order_processed', $this->order ); |
|
| 226 | + |
|
| 227 | + /** |
|
| 228 | + * Process the payment and return the results. |
|
| 229 | + */ |
|
| 230 | + $payment_result = new PaymentResult(); |
|
| 231 | + |
|
| 232 | + if ( $this->order->needs_payment() ) { |
|
| 233 | + $this->process_payment( $request, $payment_result ); |
|
| 234 | + } else { |
|
| 235 | + $this->process_without_payment( $request, $payment_result ); |
|
| 236 | + } |
|
| 237 | + |
|
| 238 | + return $this->prepare_item_for_response( |
|
| 239 | + (object) [ |
|
| 240 | + 'order' => wc_get_order( $this->order ), |
|
| 241 | + 'payment_result' => $payment_result, |
|
| 242 | + ], |
|
| 243 | + $request |
|
| 244 | + ); |
|
| 245 | + } |
|
| 246 | + |
|
| 247 | + /** |
|
| 248 | + * Get route response when something went wrong. |
|
| 249 | + * |
|
| 250 | + * @param string $error_code String based error code. |
|
| 251 | + * @param string $error_message User facing error message. |
|
| 252 | + * @param int $http_status_code HTTP status. Defaults to 500. |
|
| 253 | + * @param array $additional_data Extra data (key value pairs) to expose in the error response. |
|
| 254 | + * @return \WP_Error WP Error object. |
|
| 255 | + */ |
|
| 256 | + protected function get_route_error_response( $error_code, $error_message, $http_status_code = 500, $additional_data = [] ) { |
|
| 257 | + $error_from_message = new \WP_Error( |
|
| 258 | + $error_code, |
|
| 259 | + $error_message |
|
| 260 | + ); |
|
| 261 | + // 409 is when there was a conflict, so we return the cart so the client can resolve it. |
|
| 262 | + if ( 409 === $http_status_code ) { |
|
| 263 | + return $this->add_data_to_error_object( $error_from_message, $additional_data, $http_status_code, true ); |
|
| 264 | + } |
|
| 265 | + return $this->add_data_to_error_object( $error_from_message, $additional_data, $http_status_code ); |
|
| 266 | + } |
|
| 267 | + |
|
| 268 | + /** |
|
| 269 | + * Get route response when something went wrong. |
|
| 270 | + * |
|
| 271 | + * @param \WP_Error $error_object User facing error message. |
|
| 272 | + * @param int $http_status_code HTTP status. Defaults to 500. |
|
| 273 | + * @param array $additional_data Extra data (key value pairs) to expose in the error response. |
|
| 274 | + * @return \WP_Error WP Error object. |
|
| 275 | + */ |
|
| 276 | + protected function get_route_error_response_from_object( $error_object, $http_status_code = 500, $additional_data = [] ) { |
|
| 277 | + // 409 is when there was a conflict, so we return the cart so the client can resolve it. |
|
| 278 | + if ( 409 === $http_status_code ) { |
|
| 279 | + return $this->add_data_to_error_object( $error_object, $additional_data, $http_status_code, true ); |
|
| 280 | + } |
|
| 281 | + return $this->add_data_to_error_object( $error_object, $additional_data, $http_status_code ); |
|
| 282 | + } |
|
| 283 | + |
|
| 284 | + /** |
|
| 285 | + * Adds additional data to the \WP_Error object. |
|
| 286 | + * |
|
| 287 | + * @param \WP_Error $error The error object to add the cart to. |
|
| 288 | + * @param array $data The data to add to the error object. |
|
| 289 | + * @param int $http_status_code The HTTP status code this error should return. |
|
| 290 | + * @param bool $include_cart Whether the cart should be included in the error data. |
|
| 291 | + * @returns \WP_Error The \WP_Error with the cart added. |
|
| 292 | + */ |
|
| 293 | + private function add_data_to_error_object( $error, $data, $http_status_code, bool $include_cart = false ) { |
|
| 294 | + $data = array_merge( $data, [ 'status' => $http_status_code ] ); |
|
| 295 | + if ( $include_cart ) { |
|
| 296 | + $data = array_merge( $data, [ 'cart' => wc()->api->get_endpoint_data( '/wc/store/v1/cart' ) ] ); |
|
| 297 | + } |
|
| 298 | + $error->add_data( $data ); |
|
| 299 | + return $error; |
|
| 300 | + } |
|
| 301 | + |
|
| 302 | + /** |
|
| 303 | + * Create or update a draft order based on the cart. |
|
| 304 | + * |
|
| 305 | + * @param \WP_REST_Request $request Full details about the request. |
|
| 306 | + * @throws RouteException On error. |
|
| 307 | + */ |
|
| 308 | + private function create_or_update_draft_order( \WP_REST_Request $request ) { |
|
| 309 | + $this->order = $this->get_draft_order(); |
|
| 310 | + |
|
| 311 | + if ( ! $this->order ) { |
|
| 312 | + $this->order = $this->order_controller->create_order_from_cart(); |
|
| 313 | + } else { |
|
| 314 | + $this->order_controller->update_order_from_cart( $this->order ); |
|
| 315 | + } |
|
| 316 | + |
|
| 317 | + wc_do_deprecated_action( |
|
| 318 | + '__experimental_woocommerce_blocks_checkout_update_order_meta', |
|
| 319 | + array( |
|
| 320 | + $this->order, |
|
| 321 | + ), |
|
| 322 | + '6.3.0', |
|
| 323 | + 'woocommerce_store_api_checkout_update_order_meta', |
|
| 324 | + 'This action was deprecated in WooCommerce Blocks version 6.3.0. Please use woocommerce_store_api_checkout_update_order_meta instead.' |
|
| 325 | + ); |
|
| 326 | + |
|
| 327 | + wc_do_deprecated_action( |
|
| 328 | + 'woocommerce_blocks_checkout_update_order_meta', |
|
| 329 | + array( |
|
| 330 | + $this->order, |
|
| 331 | + ), |
|
| 332 | + '7.2.0', |
|
| 333 | + 'woocommerce_store_api_checkout_update_order_meta', |
|
| 334 | + 'This action was deprecated in WooCommerce Blocks version 7.2.0. Please use woocommerce_store_api_checkout_update_order_meta instead.' |
|
| 335 | + ); |
|
| 336 | + |
|
| 337 | + /** |
|
| 338 | + * Fires when the Checkout Block/Store API updates an order's meta data. |
|
| 339 | + * |
|
| 340 | + * This hook gives extensions the chance to add or update meta data on the $order. |
|
| 341 | + * Throwing an exception from a callback attached to this action will make the Checkout Block render in a warning state, effectively preventing checkout. |
|
| 342 | + * |
|
| 343 | + * This is similar to existing core hook woocommerce_checkout_update_order_meta. |
|
| 344 | + * We're using a new action: |
|
| 345 | + * - To keep the interface focused (only pass $order, not passing request data). |
|
| 346 | + * - This also explicitly indicates these orders are from checkout block/StoreAPI. |
|
| 347 | + * |
|
| 348 | + * @see https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3686 |
|
| 349 | + * |
|
| 350 | + * @param \WC_Order $order Order object. |
|
| 351 | + */ |
|
| 352 | + do_action( 'woocommerce_store_api_checkout_update_order_meta', $this->order ); |
|
| 353 | + |
|
| 354 | + // Confirm order is valid before proceeding further. |
|
| 355 | + if ( ! $this->order instanceof \WC_Order ) { |
|
| 356 | + throw new RouteException( |
|
| 357 | + 'woocommerce_rest_checkout_missing_order', |
|
| 358 | + __( 'Unable to create order', 'woocommerce' ), |
|
| 359 | + 500 |
|
| 360 | + ); |
|
| 361 | + } |
|
| 362 | + |
|
| 363 | + // Store order ID to session. |
|
| 364 | + $this->set_draft_order_id( $this->order->get_id() ); |
|
| 365 | + |
|
| 366 | + /** |
|
| 367 | + * Try to reserve stock for the order. |
|
| 368 | + * |
|
| 369 | + * If creating a draft order on checkout entry, set the timeout to 10 mins. |
|
| 370 | + * If POSTing to the checkout (attempting to pay), set the timeout to 60 mins (using the woocommerce_hold_stock_minutes option). |
|
| 371 | + */ |
|
| 372 | + try { |
|
| 373 | + $reserve_stock = new ReserveStock(); |
|
| 374 | + $duration = $request->get_method() === 'POST' ? (int) get_option( 'woocommerce_hold_stock_minutes', 60 ) : 10; |
|
| 375 | + $reserve_stock->reserve_stock_for_order( $this->order, $duration ); |
|
| 376 | + } catch ( ReserveStockException $e ) { |
|
| 377 | + throw new RouteException( |
|
| 378 | + $e->getErrorCode(), |
|
| 379 | + $e->getMessage(), |
|
| 380 | + $e->getCode() |
|
| 381 | + ); |
|
| 382 | + } |
|
| 383 | + } |
|
| 384 | + |
|
| 385 | + /** |
|
| 386 | + * Updates the current customer session using data from the request (e.g. address data). |
|
| 387 | + * |
|
| 388 | + * Address session data is synced to the order itself later on by OrderController::update_order_from_cart() |
|
| 389 | + * |
|
| 390 | + * @param \WP_REST_Request $request Full details about the request. |
|
| 391 | + */ |
|
| 392 | + private function update_customer_from_request( \WP_REST_Request $request ) { |
|
| 393 | + $customer = wc()->customer; |
|
| 394 | + |
|
| 395 | + // Billing address is a required field. |
|
| 396 | + foreach ( $request['billing_address'] as $key => $value ) { |
|
| 397 | + if ( is_callable( [ $customer, "set_billing_$key" ] ) ) { |
|
| 398 | + $customer->{"set_billing_$key"}( $value ); |
|
| 399 | + } |
|
| 400 | + } |
|
| 401 | + |
|
| 402 | + // If shipping address (optional field) was not provided, set it to the given billing address (required field). |
|
| 403 | + $shipping_address_values = $request['shipping_address'] ?? $request['billing_address']; |
|
| 404 | + |
|
| 405 | + foreach ( $shipping_address_values as $key => $value ) { |
|
| 406 | + if ( is_callable( [ $customer, "set_shipping_$key" ] ) ) { |
|
| 407 | + $customer->{"set_shipping_$key"}( $value ); |
|
| 408 | + } elseif ( 'phone' === $key ) { |
|
| 409 | + $customer->update_meta_data( 'shipping_phone', $value ); |
|
| 410 | + } |
|
| 411 | + } |
|
| 412 | + |
|
| 413 | + $customer->save(); |
|
| 414 | + } |
|
| 415 | + |
|
| 416 | + /** |
|
| 417 | + * Update the current order using the posted values from the request. |
|
| 418 | + * |
|
| 419 | + * @param \WP_REST_Request $request Full details about the request. |
|
| 420 | + */ |
|
| 421 | + private function update_order_from_request( \WP_REST_Request $request ) { |
|
| 422 | + $this->order->set_customer_note( $request['customer_note'] ?? '' ); |
|
| 423 | + $this->order->set_payment_method( $this->get_request_payment_method_id( $request ) ); |
|
| 424 | + |
|
| 425 | + wc_do_deprecated_action( |
|
| 426 | + '__experimental_woocommerce_blocks_checkout_update_order_from_request', |
|
| 427 | + array( |
|
| 428 | + $this->order, |
|
| 429 | + $request, |
|
| 430 | + ), |
|
| 431 | + '6.3.0', |
|
| 432 | + 'woocommerce_store_api_checkout_update_order_from_request', |
|
| 433 | + 'This action was deprecated in WooCommerce Blocks version 6.3.0. Please use woocommerce_store_api_checkout_update_order_from_request instead.' |
|
| 434 | + ); |
|
| 435 | + |
|
| 436 | + wc_do_deprecated_action( |
|
| 437 | + 'woocommerce_blocks_checkout_update_order_from_request', |
|
| 438 | + array( |
|
| 439 | + $this->order, |
|
| 440 | + $request, |
|
| 441 | + ), |
|
| 442 | + '7.2.0', |
|
| 443 | + 'woocommerce_store_api_checkout_update_order_from_request', |
|
| 444 | + 'This action was deprecated in WooCommerce Blocks version 7.2.0. Please use woocommerce_store_api_checkout_update_order_from_request instead.' |
|
| 445 | + ); |
|
| 446 | + |
|
| 447 | + /** |
|
| 448 | + * Fires when the Checkout Block/Store API updates an order's from the API request data. |
|
| 449 | + * |
|
| 450 | + * This hook gives extensions the chance to update orders based on the data in the request. This can be used in |
|
| 451 | + * conjunction with the ExtendSchema class to post custom data and then process it. |
|
| 452 | + * |
|
| 453 | + * @param \WC_Order $order Order object. |
|
| 454 | + * @param \WP_REST_Request $request Full details about the request. |
|
| 455 | + */ |
|
| 456 | + do_action( 'woocommerce_store_api_checkout_update_order_from_request', $this->order, $request ); |
|
| 457 | + |
|
| 458 | + $this->order->save(); |
|
| 459 | + } |
|
| 460 | + |
|
| 461 | + /** |
|
| 462 | + * For orders which do not require payment, just update status. |
|
| 463 | + * |
|
| 464 | + * @param \WP_REST_Request $request Request object. |
|
| 465 | + * @param PaymentResult $payment_result Payment result object. |
|
| 466 | + */ |
|
| 467 | + private function process_without_payment( \WP_REST_Request $request, PaymentResult $payment_result ) { |
|
| 468 | + // Transition the order to pending, and then completed. This ensures transactional emails fire for pending_to_complete events. |
|
| 469 | + $this->order->update_status( 'pending' ); |
|
| 470 | + $this->order->payment_complete(); |
|
| 471 | + |
|
| 472 | + // Mark the payment as successful. |
|
| 473 | + $payment_result->set_status( 'success' ); |
|
| 474 | + $payment_result->set_redirect_url( $this->order->get_checkout_order_received_url() ); |
|
| 475 | + } |
|
| 476 | + |
|
| 477 | + /** |
|
| 478 | + * Fires an action hook instructing active payment gateways to process the payment for an order and provide a result. |
|
| 479 | + * |
|
| 480 | + * @throws RouteException On error. |
|
| 481 | + * |
|
| 482 | + * @param \WP_REST_Request $request Request object. |
|
| 483 | + * @param PaymentResult $payment_result Payment result object. |
|
| 484 | + */ |
|
| 485 | + private function process_payment( \WP_REST_Request $request, PaymentResult $payment_result ) { |
|
| 486 | + try { |
|
| 487 | + // Transition the order to pending before making payment. |
|
| 488 | + $this->order->update_status( 'pending' ); |
|
| 489 | + |
|
| 490 | + // Prepare the payment context object to pass through payment hooks. |
|
| 491 | + $context = new PaymentContext(); |
|
| 492 | + $context->set_payment_method( $this->get_request_payment_method_id( $request ) ); |
|
| 493 | + $context->set_payment_data( $this->get_request_payment_data( $request ) ); |
|
| 494 | + $context->set_order( $this->order ); |
|
| 495 | + |
|
| 496 | + /** |
|
| 497 | + * Process payment with context. |
|
| 498 | + * |
|
| 499 | + * @hook woocommerce_rest_checkout_process_payment_with_context |
|
| 500 | + * |
|
| 501 | + * @throws \Exception If there is an error taking payment, an \Exception object can be thrown with an error message. |
|
| 502 | + * |
|
| 503 | + * @param PaymentContext $context Holds context for the payment, including order ID and payment method. |
|
| 504 | + * @param PaymentResult $payment_result Result object for the transaction. |
|
| 505 | + */ |
|
| 506 | + do_action_ref_array( 'woocommerce_rest_checkout_process_payment_with_context', [ $context, &$payment_result ] ); |
|
| 507 | + |
|
| 508 | + if ( ! $payment_result instanceof PaymentResult ) { |
|
| 509 | + throw new RouteException( 'woocommerce_rest_checkout_invalid_payment_result', __( 'Invalid payment result received from payment method.', 'woocommerce' ), 500 ); |
|
| 510 | + } |
|
| 511 | + } catch ( \Exception $e ) { |
|
| 512 | + throw new RouteException( 'woocommerce_rest_checkout_process_payment_error', $e->getMessage(), 400 ); |
|
| 513 | + } |
|
| 514 | + } |
|
| 515 | + |
|
| 516 | + /** |
|
| 517 | + * Gets the chosen payment method ID from the request. |
|
| 518 | + * |
|
| 519 | + * @throws RouteException On error. |
|
| 520 | + * @param \WP_REST_Request $request Request object. |
|
| 521 | + * @return string |
|
| 522 | + */ |
|
| 523 | + private function get_request_payment_method_id( \WP_REST_Request $request ) { |
|
| 524 | + $payment_method = $this->get_request_payment_method( $request ); |
|
| 525 | + return is_null( $payment_method ) ? '' : $payment_method->id; |
|
| 526 | + } |
|
| 527 | + |
|
| 528 | + /** |
|
| 529 | + * Gets the chosen payment method from the request. |
|
| 530 | + * |
|
| 531 | + * @throws RouteException On error. |
|
| 532 | + * @param \WP_REST_Request $request Request object. |
|
| 533 | + * @return \WC_Payment_Gateway|null |
|
| 534 | + */ |
|
| 535 | + private function get_request_payment_method( \WP_REST_Request $request ) { |
|
| 536 | + $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); |
|
| 537 | + $request_payment_method = wc_clean( wp_unslash( $request['payment_method'] ?? '' ) ); |
|
| 538 | + $requires_payment_method = $this->order->needs_payment(); |
|
| 539 | + |
|
| 540 | + if ( empty( $request_payment_method ) ) { |
|
| 541 | + if ( $requires_payment_method ) { |
|
| 542 | + throw new RouteException( |
|
| 543 | + 'woocommerce_rest_checkout_missing_payment_method', |
|
| 544 | + __( 'No payment method provided.', 'woocommerce' ), |
|
| 545 | + 400 |
|
| 546 | + ); |
|
| 547 | + } |
|
| 548 | + return null; |
|
| 549 | + } |
|
| 550 | + |
|
| 551 | + if ( ! isset( $available_gateways[ $request_payment_method ] ) ) { |
|
| 552 | + throw new RouteException( |
|
| 553 | + 'woocommerce_rest_checkout_payment_method_disabled', |
|
| 554 | + sprintf( |
|
| 555 | + // Translators: %s Payment method ID. |
|
| 556 | + __( 'The %s payment gateway is not available.', 'woocommerce' ), |
|
| 557 | + esc_html( $request_payment_method ) |
|
| 558 | + ), |
|
| 559 | + 400 |
|
| 560 | + ); |
|
| 561 | + } |
|
| 562 | + |
|
| 563 | + return $available_gateways[ $request_payment_method ]; |
|
| 564 | + } |
|
| 565 | + |
|
| 566 | + /** |
|
| 567 | + * Gets and formats payment request data. |
|
| 568 | + * |
|
| 569 | + * @param \WP_REST_Request $request Request object. |
|
| 570 | + * @return array |
|
| 571 | + */ |
|
| 572 | + private function get_request_payment_data( \WP_REST_Request $request ) { |
|
| 573 | + static $payment_data = []; |
|
| 574 | + if ( ! empty( $payment_data ) ) { |
|
| 575 | + return $payment_data; |
|
| 576 | + } |
|
| 577 | + if ( ! empty( $request['payment_data'] ) ) { |
|
| 578 | + foreach ( $request['payment_data'] as $data ) { |
|
| 579 | + $payment_data[ sanitize_key( $data['key'] ) ] = wc_clean( $data['value'] ); |
|
| 580 | + } |
|
| 581 | + } |
|
| 582 | + |
|
| 583 | + return $payment_data; |
|
| 584 | + } |
|
| 585 | + |
|
| 586 | + /** |
|
| 587 | + * Order processing relating to customer account. |
|
| 588 | + * |
|
| 589 | + * Creates a customer account as needed (based on request & store settings) and updates the order with the new customer ID. |
|
| 590 | + * Updates the order with user details (e.g. address). |
|
| 591 | + * |
|
| 592 | + * @throws RouteException API error object with error details. |
|
| 593 | + * @param \WP_REST_Request $request Request object. |
|
| 594 | + */ |
|
| 595 | + private function process_customer( \WP_REST_Request $request ) { |
|
| 596 | + try { |
|
| 597 | + if ( $this->should_create_customer_account( $request ) ) { |
|
| 598 | + $customer_id = $this->create_customer_account( |
|
| 599 | + $request['billing_address']['email'], |
|
| 600 | + $request['billing_address']['first_name'], |
|
| 601 | + $request['billing_address']['last_name'] |
|
| 602 | + ); |
|
| 603 | + // Log the customer in. |
|
| 604 | + wc_set_customer_auth_cookie( $customer_id ); |
|
| 605 | + |
|
| 606 | + // Associate customer with the order. |
|
| 607 | + $this->order->set_customer_id( $customer_id ); |
|
| 608 | + $this->order->save(); |
|
| 609 | + } |
|
| 610 | + } catch ( \Exception $error ) { |
|
| 611 | + switch ( $error->getMessage() ) { |
|
| 612 | + case 'registration-error-invalid-email': |
|
| 613 | + throw new RouteException( |
|
| 614 | + 'registration-error-invalid-email', |
|
| 615 | + __( 'Please provide a valid email address.', 'woocommerce' ), |
|
| 616 | + 400 |
|
| 617 | + ); |
|
| 618 | + case 'registration-error-email-exists': |
|
| 619 | + throw new RouteException( |
|
| 620 | + 'registration-error-email-exists', |
|
| 621 | + __( 'An account is already registered with your email address. Please log in before proceeding.', 'woocommerce' ), |
|
| 622 | + 400 |
|
| 623 | + ); |
|
| 624 | + } |
|
| 625 | + } |
|
| 626 | + |
|
| 627 | + // Persist customer address data to account. |
|
| 628 | + $this->order_controller->sync_customer_data_with_order( $this->order ); |
|
| 629 | + } |
|
| 630 | + |
|
| 631 | + /** |
|
| 632 | + * Check request options and store (shop) config to determine if a user account should be created as part of order |
|
| 633 | + * processing. |
|
| 634 | + * |
|
| 635 | + * @param \WP_REST_Request $request The current request object being handled. |
|
| 636 | + * @return boolean True if a new user account should be created. |
|
| 637 | + */ |
|
| 638 | + private function should_create_customer_account( \WP_REST_Request $request ) { |
|
| 639 | + if ( is_user_logged_in() ) { |
|
| 640 | + return false; |
|
| 641 | + } |
|
| 642 | + |
|
| 643 | + // Return false if registration is not enabled for the store. |
|
| 644 | + if ( false === filter_var( wc()->checkout()->is_registration_enabled(), FILTER_VALIDATE_BOOLEAN ) ) { |
|
| 645 | + return false; |
|
| 646 | + } |
|
| 647 | + |
|
| 648 | + // Return true if the store requires an account for all purchases. Note - checkbox is not displayed to shopper in this case. |
|
| 649 | + if ( true === filter_var( wc()->checkout()->is_registration_required(), FILTER_VALIDATE_BOOLEAN ) ) { |
|
| 650 | + return true; |
|
| 651 | + } |
|
| 652 | + |
|
| 653 | + // Create an account if requested via the endpoint. |
|
| 654 | + if ( true === filter_var( $request['create_account'], FILTER_VALIDATE_BOOLEAN ) ) { |
|
| 655 | + // User has requested an account as part of checkout processing. |
|
| 656 | + return true; |
|
| 657 | + } |
|
| 658 | + |
|
| 659 | + return false; |
|
| 660 | + } |
|
| 661 | + |
|
| 662 | + /** |
|
| 663 | + * Create a new account for a customer. |
|
| 664 | + * |
|
| 665 | + * The account is created with a generated username. The customer is sent |
|
| 666 | + * an email notifying them about the account and containing a link to set |
|
| 667 | + * their (initial) password. |
|
| 668 | + * |
|
| 669 | + * Intended as a replacement for wc_create_new_customer in WC core. |
|
| 670 | + * |
|
| 671 | + * @throws \Exception If an error is encountered when creating the user account. |
|
| 672 | + * |
|
| 673 | + * @param string $user_email The email address to use for the new account. |
|
| 674 | + * @param string $first_name The first name to use for the new account. |
|
| 675 | + * @param string $last_name The last name to use for the new account. |
|
| 676 | + * |
|
| 677 | + * @return int User id if successful |
|
| 678 | + */ |
|
| 679 | + private function create_customer_account( $user_email, $first_name, $last_name ) { |
|
| 680 | + if ( empty( $user_email ) || ! is_email( $user_email ) ) { |
|
| 681 | + throw new \Exception( 'registration-error-invalid-email' ); |
|
| 682 | + } |
|
| 683 | + |
|
| 684 | + if ( email_exists( $user_email ) ) { |
|
| 685 | + throw new \Exception( 'registration-error-email-exists' ); |
|
| 686 | + } |
|
| 687 | + |
|
| 688 | + $username = wc_create_new_customer_username( $user_email ); |
|
| 689 | + |
|
| 690 | + // Handle password creation. |
|
| 691 | + $password = wp_generate_password(); |
|
| 692 | + $password_generated = true; |
|
| 693 | + |
|
| 694 | + // Use WP_Error to handle registration errors. |
|
| 695 | + $errors = new \WP_Error(); |
|
| 696 | + |
|
| 697 | + /** |
|
| 698 | + * Fires before a customer account is registered. |
|
| 699 | + * |
|
| 700 | + * This hook fires before customer accounts are created and passes the form data (username, email) and an array |
|
| 701 | + * of errors. |
|
| 702 | + * |
|
| 703 | + * This could be used to add extra validation logic and append errors to the array. |
|
| 704 | + * |
|
| 705 | + * @internal Matches filter name in WooCommerce core. |
|
| 706 | + * |
|
| 707 | + * @param string $username Customer username. |
|
| 708 | + * @param string $user_email Customer email address. |
|
| 709 | + * @param \WP_Error $errors Error object. |
|
| 710 | + */ |
|
| 711 | + do_action( 'woocommerce_register_post', $username, $user_email, $errors ); |
|
| 712 | + |
|
| 713 | + /** |
|
| 714 | + * Filters registration errors before a customer account is registered. |
|
| 715 | + * |
|
| 716 | + * This hook filters registration errors. This can be used to manipulate the array of errors before |
|
| 717 | + * they are displayed. |
|
| 718 | + * |
|
| 719 | + * @internal Matches filter name in WooCommerce core. |
|
| 720 | + * |
|
| 721 | + * @param \WP_Error $errors Error object. |
|
| 722 | + * @param string $username Customer username. |
|
| 723 | + * @param string $user_email Customer email address. |
|
| 724 | + * @return \WP_Error |
|
| 725 | + */ |
|
| 726 | + $errors = apply_filters( 'woocommerce_registration_errors', $errors, $username, $user_email ); |
|
| 727 | + |
|
| 728 | + if ( is_wp_error( $errors ) && $errors->get_error_code() ) { |
|
| 729 | + throw new \Exception( $errors->get_error_code() ); |
|
| 730 | + } |
|
| 731 | + |
|
| 732 | + /** |
|
| 733 | + * Filters customer data before a customer account is registered. |
|
| 734 | + * |
|
| 735 | + * This hook filters customer data. It allows user data to be changed, for example, username, password, email, |
|
| 736 | + * first name, last name, and role. |
|
| 737 | + * |
|
| 738 | + * @param array $customer_data An array of customer (user) data. |
|
| 739 | + * @return array |
|
| 740 | + */ |
|
| 741 | + $new_customer_data = apply_filters( |
|
| 742 | + 'woocommerce_new_customer_data', |
|
| 743 | + array( |
|
| 744 | + 'user_login' => $username, |
|
| 745 | + 'user_pass' => $password, |
|
| 746 | + 'user_email' => $user_email, |
|
| 747 | + 'first_name' => $first_name, |
|
| 748 | + 'last_name' => $last_name, |
|
| 749 | + 'role' => 'customer', |
|
| 750 | + 'source' => 'store-api,', |
|
| 751 | + ) |
|
| 752 | + ); |
|
| 753 | + |
|
| 754 | + $customer_id = wp_insert_user( $new_customer_data ); |
|
| 755 | + |
|
| 756 | + if ( is_wp_error( $customer_id ) ) { |
|
| 757 | + throw $this->map_create_account_error( $customer_id ); |
|
| 758 | + } |
|
| 759 | + |
|
| 760 | + // Set account flag to remind customer to update generated password. |
|
| 761 | + update_user_option( $customer_id, 'default_password_nag', true, true ); |
|
| 762 | + |
|
| 763 | + /** |
|
| 764 | + * Fires after a customer account has been registered. |
|
| 765 | + * |
|
| 766 | + * This hook fires after customer accounts are created and passes the customer data. |
|
| 767 | + * |
|
| 768 | + * @internal Matches filter name in WooCommerce core. |
|
| 769 | + * |
|
| 770 | + * @param integer $customer_id New customer (user) ID. |
|
| 771 | + * @param array $new_customer_data Array of customer (user) data. |
|
| 772 | + * @param string $password_generated The generated password for the account. |
|
| 773 | + */ |
|
| 774 | + do_action( 'woocommerce_created_customer', $customer_id, $new_customer_data, $password_generated ); |
|
| 775 | + |
|
| 776 | + return $customer_id; |
|
| 777 | + } |
|
| 778 | + |
|
| 779 | + /** |
|
| 780 | + * Convert an account creation error to an exception. |
|
| 781 | + * |
|
| 782 | + * @param \WP_Error $error An error object. |
|
| 783 | + * @return \Exception. |
|
| 784 | + */ |
|
| 785 | + private function map_create_account_error( \WP_Error $error ) { |
|
| 786 | + switch ( $error->get_error_code() ) { |
|
| 787 | + // WordPress core error codes. |
|
| 788 | + case 'empty_username': |
|
| 789 | + case 'invalid_username': |
|
| 790 | + case 'empty_email': |
|
| 791 | + case 'invalid_email': |
|
| 792 | + case 'email_exists': |
|
| 793 | + case 'registerfail': |
|
| 794 | + return new \Exception( 'woocommerce_rest_checkout_create_account_failure' ); |
|
| 795 | + } |
|
| 796 | + return new \Exception( 'woocommerce_rest_checkout_create_account_failure' ); |
|
| 797 | + } |
|
| 799 | 798 | } |
@@ -51,7 +51,7 @@ discard block |
||
| 51 | 51 | * @param \WP_REST_Request $request Request. |
| 52 | 52 | * @return bool |
| 53 | 53 | */ |
| 54 | - protected function requires_nonce( \WP_REST_Request $request ) { |
|
| 54 | + protected function requires_nonce(\WP_REST_Request $request) { |
|
| 55 | 55 | return true; |
| 56 | 56 | } |
| 57 | 57 | |
@@ -64,20 +64,20 @@ discard block |
||
| 64 | 64 | return [ |
| 65 | 65 | [ |
| 66 | 66 | 'methods' => \WP_REST_Server::READABLE, |
| 67 | - 'callback' => [ $this, 'get_response' ], |
|
| 67 | + 'callback' => [$this, 'get_response'], |
|
| 68 | 68 | 'permission_callback' => '__return_true', |
| 69 | 69 | 'args' => [ |
| 70 | - 'context' => $this->get_context_param( [ 'default' => 'view' ] ), |
|
| 70 | + 'context' => $this->get_context_param(['default' => 'view']), |
|
| 71 | 71 | ], |
| 72 | 72 | ], |
| 73 | 73 | [ |
| 74 | 74 | 'methods' => \WP_REST_Server::CREATABLE, |
| 75 | - 'callback' => [ $this, 'get_response' ], |
|
| 75 | + 'callback' => [$this, 'get_response'], |
|
| 76 | 76 | 'permission_callback' => '__return_true', |
| 77 | 77 | 'args' => array_merge( |
| 78 | 78 | [ |
| 79 | 79 | 'payment_data' => [ |
| 80 | - 'description' => __( 'Data to pass through to the payment method when processing payment.', 'woocommerce' ), |
|
| 80 | + 'description' => __('Data to pass through to the payment method when processing payment.', 'woocommerce'), |
|
| 81 | 81 | 'type' => 'array', |
| 82 | 82 | 'items' => [ |
| 83 | 83 | 'type' => 'object', |
@@ -86,17 +86,17 @@ discard block |
||
| 86 | 86 | 'type' => 'string', |
| 87 | 87 | ], |
| 88 | 88 | 'value' => [ |
| 89 | - 'type' => [ 'string', 'boolean' ], |
|
| 89 | + 'type' => ['string', 'boolean'], |
|
| 90 | 90 | ], |
| 91 | 91 | ], |
| 92 | 92 | ], |
| 93 | 93 | ], |
| 94 | 94 | ], |
| 95 | - $this->schema->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ) |
|
| 95 | + $this->schema->get_endpoint_args_for_item_schema(\WP_REST_Server::CREATABLE) |
|
| 96 | 96 | ), |
| 97 | 97 | ], |
| 98 | - 'schema' => [ $this->schema, 'get_public_item_schema' ], |
|
| 99 | - 'allow_batch' => [ 'v1' => true ], |
|
| 98 | + 'schema' => [$this->schema, 'get_public_item_schema'], |
|
| 99 | + 'allow_batch' => ['v1' => true], |
|
| 100 | 100 | ]; |
| 101 | 101 | } |
| 102 | 102 | |
@@ -107,8 +107,8 @@ discard block |
||
| 107 | 107 | * @param \WP_REST_Request $request Request object. |
| 108 | 108 | * @return \WP_REST_Response $response Response data. |
| 109 | 109 | */ |
| 110 | - public function prepare_item_for_response( $item, \WP_REST_Request $request ) { |
|
| 111 | - $response = parent::prepare_item_for_response( $item, $request ); |
|
| 110 | + public function prepare_item_for_response($item, \WP_REST_Request $request) { |
|
| 111 | + $response = parent::prepare_item_for_response($item, $request); |
|
| 112 | 112 | $status_codes = [ |
| 113 | 113 | 'success' => 200, |
| 114 | 114 | 'pending' => 202, |
@@ -116,8 +116,8 @@ discard block |
||
| 116 | 116 | 'error' => 500, |
| 117 | 117 | ]; |
| 118 | 118 | |
| 119 | - if ( isset( $item->payment_result ) && $item->payment_result instanceof PaymentResult ) { |
|
| 120 | - $response->set_status( $status_codes[ $item->payment_result->status ] ?? 200 ); |
|
| 119 | + if (isset($item->payment_result) && $item->payment_result instanceof PaymentResult) { |
|
| 120 | + $response->set_status($status_codes[$item->payment_result->status] ?? 200); |
|
| 121 | 121 | } |
| 122 | 122 | |
| 123 | 123 | return $response; |
@@ -130,8 +130,8 @@ discard block |
||
| 130 | 130 | * @param \WP_REST_Request $request Request object. |
| 131 | 131 | * @return \WP_REST_Response |
| 132 | 132 | */ |
| 133 | - protected function get_route_response( \WP_REST_Request $request ) { |
|
| 134 | - $this->create_or_update_draft_order( $request ); |
|
| 133 | + protected function get_route_response(\WP_REST_Request $request) { |
|
| 134 | + $this->create_or_update_draft_order($request); |
|
| 135 | 135 | |
| 136 | 136 | return $this->prepare_item_for_response( |
| 137 | 137 | (object) [ |
@@ -158,7 +158,7 @@ discard block |
||
| 158 | 158 | * |
| 159 | 159 | * @return \WP_REST_Response |
| 160 | 160 | */ |
| 161 | - protected function get_route_post_response( \WP_REST_Request $request ) { |
|
| 161 | + protected function get_route_post_response(\WP_REST_Request $request) { |
|
| 162 | 162 | /** |
| 163 | 163 | * Validate items etc are allowed in the order before the order is processed. This will fix violations and tell |
| 164 | 164 | * the customer. |
@@ -171,23 +171,23 @@ discard block |
||
| 171 | 171 | * Note: Customer data is persisted from the request first so that OrderController::update_addresses_from_cart |
| 172 | 172 | * uses the up to date customer address. |
| 173 | 173 | */ |
| 174 | - $this->update_customer_from_request( $request ); |
|
| 175 | - $this->create_or_update_draft_order( $request ); |
|
| 176 | - $this->update_order_from_request( $request ); |
|
| 174 | + $this->update_customer_from_request($request); |
|
| 175 | + $this->create_or_update_draft_order($request); |
|
| 176 | + $this->update_order_from_request($request); |
|
| 177 | 177 | |
| 178 | 178 | /** |
| 179 | 179 | * Process customer data. |
| 180 | 180 | * |
| 181 | 181 | * Update order with customer details, and sign up a user account as necessary. |
| 182 | 182 | */ |
| 183 | - $this->process_customer( $request ); |
|
| 183 | + $this->process_customer($request); |
|
| 184 | 184 | |
| 185 | 185 | /** |
| 186 | 186 | * Validate order. |
| 187 | 187 | * |
| 188 | 188 | * This logic ensures the order is valid before payment is attempted. |
| 189 | 189 | */ |
| 190 | - $this->order_controller->validate_order_before_payment( $this->order ); |
|
| 190 | + $this->order_controller->validate_order_before_payment($this->order); |
|
| 191 | 191 | |
| 192 | 192 | wc_do_deprecated_action( |
| 193 | 193 | '__experimental_woocommerce_blocks_checkout_order_processed', |
@@ -223,22 +223,22 @@ discard block |
||
| 223 | 223 | |
| 224 | 224 | * @param \WC_Order $order Order object. |
| 225 | 225 | */ |
| 226 | - do_action( 'woocommerce_store_api_checkout_order_processed', $this->order ); |
|
| 226 | + do_action('woocommerce_store_api_checkout_order_processed', $this->order); |
|
| 227 | 227 | |
| 228 | 228 | /** |
| 229 | 229 | * Process the payment and return the results. |
| 230 | 230 | */ |
| 231 | 231 | $payment_result = new PaymentResult(); |
| 232 | 232 | |
| 233 | - if ( $this->order->needs_payment() ) { |
|
| 234 | - $this->process_payment( $request, $payment_result ); |
|
| 233 | + if ($this->order->needs_payment()) { |
|
| 234 | + $this->process_payment($request, $payment_result); |
|
| 235 | 235 | } else { |
| 236 | - $this->process_without_payment( $request, $payment_result ); |
|
| 236 | + $this->process_without_payment($request, $payment_result); |
|
| 237 | 237 | } |
| 238 | 238 | |
| 239 | 239 | return $this->prepare_item_for_response( |
| 240 | 240 | (object) [ |
| 241 | - 'order' => wc_get_order( $this->order ), |
|
| 241 | + 'order' => wc_get_order($this->order), |
|
| 242 | 242 | 'payment_result' => $payment_result, |
| 243 | 243 | ], |
| 244 | 244 | $request |
@@ -254,16 +254,16 @@ discard block |
||
| 254 | 254 | * @param array $additional_data Extra data (key value pairs) to expose in the error response. |
| 255 | 255 | * @return \WP_Error WP Error object. |
| 256 | 256 | */ |
| 257 | - protected function get_route_error_response( $error_code, $error_message, $http_status_code = 500, $additional_data = [] ) { |
|
| 257 | + protected function get_route_error_response($error_code, $error_message, $http_status_code = 500, $additional_data = []) { |
|
| 258 | 258 | $error_from_message = new \WP_Error( |
| 259 | 259 | $error_code, |
| 260 | 260 | $error_message |
| 261 | 261 | ); |
| 262 | 262 | // 409 is when there was a conflict, so we return the cart so the client can resolve it. |
| 263 | - if ( 409 === $http_status_code ) { |
|
| 264 | - return $this->add_data_to_error_object( $error_from_message, $additional_data, $http_status_code, true ); |
|
| 263 | + if (409 === $http_status_code) { |
|
| 264 | + return $this->add_data_to_error_object($error_from_message, $additional_data, $http_status_code, true); |
|
| 265 | 265 | } |
| 266 | - return $this->add_data_to_error_object( $error_from_message, $additional_data, $http_status_code ); |
|
| 266 | + return $this->add_data_to_error_object($error_from_message, $additional_data, $http_status_code); |
|
| 267 | 267 | } |
| 268 | 268 | |
| 269 | 269 | /** |
@@ -274,12 +274,12 @@ discard block |
||
| 274 | 274 | * @param array $additional_data Extra data (key value pairs) to expose in the error response. |
| 275 | 275 | * @return \WP_Error WP Error object. |
| 276 | 276 | */ |
| 277 | - protected function get_route_error_response_from_object( $error_object, $http_status_code = 500, $additional_data = [] ) { |
|
| 277 | + protected function get_route_error_response_from_object($error_object, $http_status_code = 500, $additional_data = []) { |
|
| 278 | 278 | // 409 is when there was a conflict, so we return the cart so the client can resolve it. |
| 279 | - if ( 409 === $http_status_code ) { |
|
| 280 | - return $this->add_data_to_error_object( $error_object, $additional_data, $http_status_code, true ); |
|
| 279 | + if (409 === $http_status_code) { |
|
| 280 | + return $this->add_data_to_error_object($error_object, $additional_data, $http_status_code, true); |
|
| 281 | 281 | } |
| 282 | - return $this->add_data_to_error_object( $error_object, $additional_data, $http_status_code ); |
|
| 282 | + return $this->add_data_to_error_object($error_object, $additional_data, $http_status_code); |
|
| 283 | 283 | } |
| 284 | 284 | |
| 285 | 285 | /** |
@@ -291,12 +291,12 @@ discard block |
||
| 291 | 291 | * @param bool $include_cart Whether the cart should be included in the error data. |
| 292 | 292 | * @returns \WP_Error The \WP_Error with the cart added. |
| 293 | 293 | */ |
| 294 | - private function add_data_to_error_object( $error, $data, $http_status_code, bool $include_cart = false ) { |
|
| 295 | - $data = array_merge( $data, [ 'status' => $http_status_code ] ); |
|
| 296 | - if ( $include_cart ) { |
|
| 297 | - $data = array_merge( $data, [ 'cart' => wc()->api->get_endpoint_data( '/wc/store/v1/cart' ) ] ); |
|
| 294 | + private function add_data_to_error_object($error, $data, $http_status_code, bool $include_cart = false) { |
|
| 295 | + $data = array_merge($data, ['status' => $http_status_code]); |
|
| 296 | + if ($include_cart) { |
|
| 297 | + $data = array_merge($data, ['cart' => wc()->api->get_endpoint_data('/wc/store/v1/cart')]); |
|
| 298 | 298 | } |
| 299 | - $error->add_data( $data ); |
|
| 299 | + $error->add_data($data); |
|
| 300 | 300 | return $error; |
| 301 | 301 | } |
| 302 | 302 | |
@@ -306,13 +306,13 @@ discard block |
||
| 306 | 306 | * @param \WP_REST_Request $request Full details about the request. |
| 307 | 307 | * @throws RouteException On error. |
| 308 | 308 | */ |
| 309 | - private function create_or_update_draft_order( \WP_REST_Request $request ) { |
|
| 309 | + private function create_or_update_draft_order(\WP_REST_Request $request) { |
|
| 310 | 310 | $this->order = $this->get_draft_order(); |
| 311 | 311 | |
| 312 | - if ( ! $this->order ) { |
|
| 312 | + if (!$this->order) { |
|
| 313 | 313 | $this->order = $this->order_controller->create_order_from_cart(); |
| 314 | 314 | } else { |
| 315 | - $this->order_controller->update_order_from_cart( $this->order ); |
|
| 315 | + $this->order_controller->update_order_from_cart($this->order); |
|
| 316 | 316 | } |
| 317 | 317 | |
| 318 | 318 | wc_do_deprecated_action( |
@@ -350,19 +350,19 @@ discard block |
||
| 350 | 350 | * |
| 351 | 351 | * @param \WC_Order $order Order object. |
| 352 | 352 | */ |
| 353 | - do_action( 'woocommerce_store_api_checkout_update_order_meta', $this->order ); |
|
| 353 | + do_action('woocommerce_store_api_checkout_update_order_meta', $this->order); |
|
| 354 | 354 | |
| 355 | 355 | // Confirm order is valid before proceeding further. |
| 356 | - if ( ! $this->order instanceof \WC_Order ) { |
|
| 356 | + if (!$this->order instanceof \WC_Order) { |
|
| 357 | 357 | throw new RouteException( |
| 358 | 358 | 'woocommerce_rest_checkout_missing_order', |
| 359 | - __( 'Unable to create order', 'woocommerce' ), |
|
| 359 | + __('Unable to create order', 'woocommerce'), |
|
| 360 | 360 | 500 |
| 361 | 361 | ); |
| 362 | 362 | } |
| 363 | 363 | |
| 364 | 364 | // Store order ID to session. |
| 365 | - $this->set_draft_order_id( $this->order->get_id() ); |
|
| 365 | + $this->set_draft_order_id($this->order->get_id()); |
|
| 366 | 366 | |
| 367 | 367 | /** |
| 368 | 368 | * Try to reserve stock for the order. |
@@ -372,9 +372,9 @@ discard block |
||
| 372 | 372 | */ |
| 373 | 373 | try { |
| 374 | 374 | $reserve_stock = new ReserveStock(); |
| 375 | - $duration = $request->get_method() === 'POST' ? (int) get_option( 'woocommerce_hold_stock_minutes', 60 ) : 10; |
|
| 376 | - $reserve_stock->reserve_stock_for_order( $this->order, $duration ); |
|
| 377 | - } catch ( ReserveStockException $e ) { |
|
| 375 | + $duration = $request->get_method() === 'POST' ? (int) get_option('woocommerce_hold_stock_minutes', 60) : 10; |
|
| 376 | + $reserve_stock->reserve_stock_for_order($this->order, $duration); |
|
| 377 | + } catch (ReserveStockException $e) { |
|
| 378 | 378 | throw new RouteException( |
| 379 | 379 | $e->getErrorCode(), |
| 380 | 380 | $e->getMessage(), |
@@ -390,24 +390,24 @@ discard block |
||
| 390 | 390 | * |
| 391 | 391 | * @param \WP_REST_Request $request Full details about the request. |
| 392 | 392 | */ |
| 393 | - private function update_customer_from_request( \WP_REST_Request $request ) { |
|
| 393 | + private function update_customer_from_request(\WP_REST_Request $request) { |
|
| 394 | 394 | $customer = wc()->customer; |
| 395 | 395 | |
| 396 | 396 | // Billing address is a required field. |
| 397 | - foreach ( $request['billing_address'] as $key => $value ) { |
|
| 398 | - if ( is_callable( [ $customer, "set_billing_$key" ] ) ) { |
|
| 399 | - $customer->{"set_billing_$key"}( $value ); |
|
| 397 | + foreach ($request['billing_address'] as $key => $value) { |
|
| 398 | + if (is_callable([$customer, "set_billing_$key"])) { |
|
| 399 | + $customer->{"set_billing_$key"}($value); |
|
| 400 | 400 | } |
| 401 | 401 | } |
| 402 | 402 | |
| 403 | 403 | // If shipping address (optional field) was not provided, set it to the given billing address (required field). |
| 404 | 404 | $shipping_address_values = $request['shipping_address'] ?? $request['billing_address']; |
| 405 | 405 | |
| 406 | - foreach ( $shipping_address_values as $key => $value ) { |
|
| 407 | - if ( is_callable( [ $customer, "set_shipping_$key" ] ) ) { |
|
| 408 | - $customer->{"set_shipping_$key"}( $value ); |
|
| 409 | - } elseif ( 'phone' === $key ) { |
|
| 410 | - $customer->update_meta_data( 'shipping_phone', $value ); |
|
| 406 | + foreach ($shipping_address_values as $key => $value) { |
|
| 407 | + if (is_callable([$customer, "set_shipping_$key"])) { |
|
| 408 | + $customer->{"set_shipping_$key"}($value); |
|
| 409 | + } elseif ('phone' === $key) { |
|
| 410 | + $customer->update_meta_data('shipping_phone', $value); |
|
| 411 | 411 | } |
| 412 | 412 | } |
| 413 | 413 | |
@@ -419,9 +419,9 @@ discard block |
||
| 419 | 419 | * |
| 420 | 420 | * @param \WP_REST_Request $request Full details about the request. |
| 421 | 421 | */ |
| 422 | - private function update_order_from_request( \WP_REST_Request $request ) { |
|
| 423 | - $this->order->set_customer_note( $request['customer_note'] ?? '' ); |
|
| 424 | - $this->order->set_payment_method( $this->get_request_payment_method_id( $request ) ); |
|
| 422 | + private function update_order_from_request(\WP_REST_Request $request) { |
|
| 423 | + $this->order->set_customer_note($request['customer_note'] ?? ''); |
|
| 424 | + $this->order->set_payment_method($this->get_request_payment_method_id($request)); |
|
| 425 | 425 | |
| 426 | 426 | wc_do_deprecated_action( |
| 427 | 427 | '__experimental_woocommerce_blocks_checkout_update_order_from_request', |
@@ -454,7 +454,7 @@ discard block |
||
| 454 | 454 | * @param \WC_Order $order Order object. |
| 455 | 455 | * @param \WP_REST_Request $request Full details about the request. |
| 456 | 456 | */ |
| 457 | - do_action( 'woocommerce_store_api_checkout_update_order_from_request', $this->order, $request ); |
|
| 457 | + do_action('woocommerce_store_api_checkout_update_order_from_request', $this->order, $request); |
|
| 458 | 458 | |
| 459 | 459 | $this->order->save(); |
| 460 | 460 | } |
@@ -465,14 +465,14 @@ discard block |
||
| 465 | 465 | * @param \WP_REST_Request $request Request object. |
| 466 | 466 | * @param PaymentResult $payment_result Payment result object. |
| 467 | 467 | */ |
| 468 | - private function process_without_payment( \WP_REST_Request $request, PaymentResult $payment_result ) { |
|
| 468 | + private function process_without_payment(\WP_REST_Request $request, PaymentResult $payment_result) { |
|
| 469 | 469 | // Transition the order to pending, and then completed. This ensures transactional emails fire for pending_to_complete events. |
| 470 | - $this->order->update_status( 'pending' ); |
|
| 470 | + $this->order->update_status('pending'); |
|
| 471 | 471 | $this->order->payment_complete(); |
| 472 | 472 | |
| 473 | 473 | // Mark the payment as successful. |
| 474 | - $payment_result->set_status( 'success' ); |
|
| 475 | - $payment_result->set_redirect_url( $this->order->get_checkout_order_received_url() ); |
|
| 474 | + $payment_result->set_status('success'); |
|
| 475 | + $payment_result->set_redirect_url($this->order->get_checkout_order_received_url()); |
|
| 476 | 476 | } |
| 477 | 477 | |
| 478 | 478 | /** |
@@ -483,16 +483,16 @@ discard block |
||
| 483 | 483 | * @param \WP_REST_Request $request Request object. |
| 484 | 484 | * @param PaymentResult $payment_result Payment result object. |
| 485 | 485 | */ |
| 486 | - private function process_payment( \WP_REST_Request $request, PaymentResult $payment_result ) { |
|
| 486 | + private function process_payment(\WP_REST_Request $request, PaymentResult $payment_result) { |
|
| 487 | 487 | try { |
| 488 | 488 | // Transition the order to pending before making payment. |
| 489 | - $this->order->update_status( 'pending' ); |
|
| 489 | + $this->order->update_status('pending'); |
|
| 490 | 490 | |
| 491 | 491 | // Prepare the payment context object to pass through payment hooks. |
| 492 | 492 | $context = new PaymentContext(); |
| 493 | - $context->set_payment_method( $this->get_request_payment_method_id( $request ) ); |
|
| 494 | - $context->set_payment_data( $this->get_request_payment_data( $request ) ); |
|
| 495 | - $context->set_order( $this->order ); |
|
| 493 | + $context->set_payment_method($this->get_request_payment_method_id($request)); |
|
| 494 | + $context->set_payment_data($this->get_request_payment_data($request)); |
|
| 495 | + $context->set_order($this->order); |
|
| 496 | 496 | |
| 497 | 497 | /** |
| 498 | 498 | * Process payment with context. |
@@ -504,13 +504,13 @@ discard block |
||
| 504 | 504 | * @param PaymentContext $context Holds context for the payment, including order ID and payment method. |
| 505 | 505 | * @param PaymentResult $payment_result Result object for the transaction. |
| 506 | 506 | */ |
| 507 | - do_action_ref_array( 'woocommerce_rest_checkout_process_payment_with_context', [ $context, &$payment_result ] ); |
|
| 507 | + do_action_ref_array('woocommerce_rest_checkout_process_payment_with_context', [$context, &$payment_result]); |
|
| 508 | 508 | |
| 509 | - if ( ! $payment_result instanceof PaymentResult ) { |
|
| 510 | - throw new RouteException( 'woocommerce_rest_checkout_invalid_payment_result', __( 'Invalid payment result received from payment method.', 'woocommerce' ), 500 ); |
|
| 509 | + if (!$payment_result instanceof PaymentResult) { |
|
| 510 | + throw new RouteException('woocommerce_rest_checkout_invalid_payment_result', __('Invalid payment result received from payment method.', 'woocommerce'), 500); |
|
| 511 | 511 | } |
| 512 | - } catch ( \Exception $e ) { |
|
| 513 | - throw new RouteException( 'woocommerce_rest_checkout_process_payment_error', $e->getMessage(), 400 ); |
|
| 512 | + } catch (\Exception $e) { |
|
| 513 | + throw new RouteException('woocommerce_rest_checkout_process_payment_error', $e->getMessage(), 400); |
|
| 514 | 514 | } |
| 515 | 515 | } |
| 516 | 516 | |
@@ -521,9 +521,9 @@ discard block |
||
| 521 | 521 | * @param \WP_REST_Request $request Request object. |
| 522 | 522 | * @return string |
| 523 | 523 | */ |
| 524 | - private function get_request_payment_method_id( \WP_REST_Request $request ) { |
|
| 525 | - $payment_method = $this->get_request_payment_method( $request ); |
|
| 526 | - return is_null( $payment_method ) ? '' : $payment_method->id; |
|
| 524 | + private function get_request_payment_method_id(\WP_REST_Request $request) { |
|
| 525 | + $payment_method = $this->get_request_payment_method($request); |
|
| 526 | + return is_null($payment_method) ? '' : $payment_method->id; |
|
| 527 | 527 | } |
| 528 | 528 | |
| 529 | 529 | /** |
@@ -533,35 +533,35 @@ discard block |
||
| 533 | 533 | * @param \WP_REST_Request $request Request object. |
| 534 | 534 | * @return \WC_Payment_Gateway|null |
| 535 | 535 | */ |
| 536 | - private function get_request_payment_method( \WP_REST_Request $request ) { |
|
| 536 | + private function get_request_payment_method(\WP_REST_Request $request) { |
|
| 537 | 537 | $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); |
| 538 | - $request_payment_method = wc_clean( wp_unslash( $request['payment_method'] ?? '' ) ); |
|
| 538 | + $request_payment_method = wc_clean(wp_unslash($request['payment_method'] ?? '')); |
|
| 539 | 539 | $requires_payment_method = $this->order->needs_payment(); |
| 540 | 540 | |
| 541 | - if ( empty( $request_payment_method ) ) { |
|
| 542 | - if ( $requires_payment_method ) { |
|
| 541 | + if (empty($request_payment_method)) { |
|
| 542 | + if ($requires_payment_method) { |
|
| 543 | 543 | throw new RouteException( |
| 544 | 544 | 'woocommerce_rest_checkout_missing_payment_method', |
| 545 | - __( 'No payment method provided.', 'woocommerce' ), |
|
| 545 | + __('No payment method provided.', 'woocommerce'), |
|
| 546 | 546 | 400 |
| 547 | 547 | ); |
| 548 | 548 | } |
| 549 | 549 | return null; |
| 550 | 550 | } |
| 551 | 551 | |
| 552 | - if ( ! isset( $available_gateways[ $request_payment_method ] ) ) { |
|
| 552 | + if (!isset($available_gateways[$request_payment_method])) { |
|
| 553 | 553 | throw new RouteException( |
| 554 | 554 | 'woocommerce_rest_checkout_payment_method_disabled', |
| 555 | 555 | sprintf( |
| 556 | 556 | // Translators: %s Payment method ID. |
| 557 | - __( 'The %s payment gateway is not available.', 'woocommerce' ), |
|
| 558 | - esc_html( $request_payment_method ) |
|
| 557 | + __('The %s payment gateway is not available.', 'woocommerce'), |
|
| 558 | + esc_html($request_payment_method) |
|
| 559 | 559 | ), |
| 560 | 560 | 400 |
| 561 | 561 | ); |
| 562 | 562 | } |
| 563 | 563 | |
| 564 | - return $available_gateways[ $request_payment_method ]; |
|
| 564 | + return $available_gateways[$request_payment_method]; |
|
| 565 | 565 | } |
| 566 | 566 | |
| 567 | 567 | /** |
@@ -570,14 +570,14 @@ discard block |
||
| 570 | 570 | * @param \WP_REST_Request $request Request object. |
| 571 | 571 | * @return array |
| 572 | 572 | */ |
| 573 | - private function get_request_payment_data( \WP_REST_Request $request ) { |
|
| 573 | + private function get_request_payment_data(\WP_REST_Request $request) { |
|
| 574 | 574 | static $payment_data = []; |
| 575 | - if ( ! empty( $payment_data ) ) { |
|
| 575 | + if (!empty($payment_data)) { |
|
| 576 | 576 | return $payment_data; |
| 577 | 577 | } |
| 578 | - if ( ! empty( $request['payment_data'] ) ) { |
|
| 579 | - foreach ( $request['payment_data'] as $data ) { |
|
| 580 | - $payment_data[ sanitize_key( $data['key'] ) ] = wc_clean( $data['value'] ); |
|
| 578 | + if (!empty($request['payment_data'])) { |
|
| 579 | + foreach ($request['payment_data'] as $data) { |
|
| 580 | + $payment_data[sanitize_key($data['key'])] = wc_clean($data['value']); |
|
| 581 | 581 | } |
| 582 | 582 | } |
| 583 | 583 | |
@@ -593,40 +593,40 @@ discard block |
||
| 593 | 593 | * @throws RouteException API error object with error details. |
| 594 | 594 | * @param \WP_REST_Request $request Request object. |
| 595 | 595 | */ |
| 596 | - private function process_customer( \WP_REST_Request $request ) { |
|
| 596 | + private function process_customer(\WP_REST_Request $request) { |
|
| 597 | 597 | try { |
| 598 | - if ( $this->should_create_customer_account( $request ) ) { |
|
| 598 | + if ($this->should_create_customer_account($request)) { |
|
| 599 | 599 | $customer_id = $this->create_customer_account( |
| 600 | 600 | $request['billing_address']['email'], |
| 601 | 601 | $request['billing_address']['first_name'], |
| 602 | 602 | $request['billing_address']['last_name'] |
| 603 | 603 | ); |
| 604 | 604 | // Log the customer in. |
| 605 | - wc_set_customer_auth_cookie( $customer_id ); |
|
| 605 | + wc_set_customer_auth_cookie($customer_id); |
|
| 606 | 606 | |
| 607 | 607 | // Associate customer with the order. |
| 608 | - $this->order->set_customer_id( $customer_id ); |
|
| 608 | + $this->order->set_customer_id($customer_id); |
|
| 609 | 609 | $this->order->save(); |
| 610 | 610 | } |
| 611 | - } catch ( \Exception $error ) { |
|
| 612 | - switch ( $error->getMessage() ) { |
|
| 611 | + } catch (\Exception $error) { |
|
| 612 | + switch ($error->getMessage()) { |
|
| 613 | 613 | case 'registration-error-invalid-email': |
| 614 | 614 | throw new RouteException( |
| 615 | 615 | 'registration-error-invalid-email', |
| 616 | - __( 'Please provide a valid email address.', 'woocommerce' ), |
|
| 616 | + __('Please provide a valid email address.', 'woocommerce'), |
|
| 617 | 617 | 400 |
| 618 | 618 | ); |
| 619 | 619 | case 'registration-error-email-exists': |
| 620 | 620 | throw new RouteException( |
| 621 | 621 | 'registration-error-email-exists', |
| 622 | - __( 'An account is already registered with your email address. Please log in before proceeding.', 'woocommerce' ), |
|
| 622 | + __('An account is already registered with your email address. Please log in before proceeding.', 'woocommerce'), |
|
| 623 | 623 | 400 |
| 624 | 624 | ); |
| 625 | 625 | } |
| 626 | 626 | } |
| 627 | 627 | |
| 628 | 628 | // Persist customer address data to account. |
| 629 | - $this->order_controller->sync_customer_data_with_order( $this->order ); |
|
| 629 | + $this->order_controller->sync_customer_data_with_order($this->order); |
|
| 630 | 630 | } |
| 631 | 631 | |
| 632 | 632 | /** |
@@ -636,23 +636,23 @@ discard block |
||
| 636 | 636 | * @param \WP_REST_Request $request The current request object being handled. |
| 637 | 637 | * @return boolean True if a new user account should be created. |
| 638 | 638 | */ |
| 639 | - private function should_create_customer_account( \WP_REST_Request $request ) { |
|
| 640 | - if ( is_user_logged_in() ) { |
|
| 639 | + private function should_create_customer_account(\WP_REST_Request $request) { |
|
| 640 | + if (is_user_logged_in()) { |
|
| 641 | 641 | return false; |
| 642 | 642 | } |
| 643 | 643 | |
| 644 | 644 | // Return false if registration is not enabled for the store. |
| 645 | - if ( false === filter_var( wc()->checkout()->is_registration_enabled(), FILTER_VALIDATE_BOOLEAN ) ) { |
|
| 645 | + if (false === filter_var(wc()->checkout()->is_registration_enabled(), FILTER_VALIDATE_BOOLEAN)) { |
|
| 646 | 646 | return false; |
| 647 | 647 | } |
| 648 | 648 | |
| 649 | 649 | // Return true if the store requires an account for all purchases. Note - checkbox is not displayed to shopper in this case. |
| 650 | - if ( true === filter_var( wc()->checkout()->is_registration_required(), FILTER_VALIDATE_BOOLEAN ) ) { |
|
| 650 | + if (true === filter_var(wc()->checkout()->is_registration_required(), FILTER_VALIDATE_BOOLEAN)) { |
|
| 651 | 651 | return true; |
| 652 | 652 | } |
| 653 | 653 | |
| 654 | 654 | // Create an account if requested via the endpoint. |
| 655 | - if ( true === filter_var( $request['create_account'], FILTER_VALIDATE_BOOLEAN ) ) { |
|
| 655 | + if (true === filter_var($request['create_account'], FILTER_VALIDATE_BOOLEAN)) { |
|
| 656 | 656 | // User has requested an account as part of checkout processing. |
| 657 | 657 | return true; |
| 658 | 658 | } |
@@ -677,16 +677,16 @@ discard block |
||
| 677 | 677 | * |
| 678 | 678 | * @return int User id if successful |
| 679 | 679 | */ |
| 680 | - private function create_customer_account( $user_email, $first_name, $last_name ) { |
|
| 681 | - if ( empty( $user_email ) || ! is_email( $user_email ) ) { |
|
| 682 | - throw new \Exception( 'registration-error-invalid-email' ); |
|
| 680 | + private function create_customer_account($user_email, $first_name, $last_name) { |
|
| 681 | + if (empty($user_email) || !is_email($user_email)) { |
|
| 682 | + throw new \Exception('registration-error-invalid-email'); |
|
| 683 | 683 | } |
| 684 | 684 | |
| 685 | - if ( email_exists( $user_email ) ) { |
|
| 686 | - throw new \Exception( 'registration-error-email-exists' ); |
|
| 685 | + if (email_exists($user_email)) { |
|
| 686 | + throw new \Exception('registration-error-email-exists'); |
|
| 687 | 687 | } |
| 688 | 688 | |
| 689 | - $username = wc_create_new_customer_username( $user_email ); |
|
| 689 | + $username = wc_create_new_customer_username($user_email); |
|
| 690 | 690 | |
| 691 | 691 | // Handle password creation. |
| 692 | 692 | $password = wp_generate_password(); |
@@ -709,7 +709,7 @@ discard block |
||
| 709 | 709 | * @param string $user_email Customer email address. |
| 710 | 710 | * @param \WP_Error $errors Error object. |
| 711 | 711 | */ |
| 712 | - do_action( 'woocommerce_register_post', $username, $user_email, $errors ); |
|
| 712 | + do_action('woocommerce_register_post', $username, $user_email, $errors); |
|
| 713 | 713 | |
| 714 | 714 | /** |
| 715 | 715 | * Filters registration errors before a customer account is registered. |
@@ -724,10 +724,10 @@ discard block |
||
| 724 | 724 | * @param string $user_email Customer email address. |
| 725 | 725 | * @return \WP_Error |
| 726 | 726 | */ |
| 727 | - $errors = apply_filters( 'woocommerce_registration_errors', $errors, $username, $user_email ); |
|
| 727 | + $errors = apply_filters('woocommerce_registration_errors', $errors, $username, $user_email); |
|
| 728 | 728 | |
| 729 | - if ( is_wp_error( $errors ) && $errors->get_error_code() ) { |
|
| 730 | - throw new \Exception( $errors->get_error_code() ); |
|
| 729 | + if (is_wp_error($errors) && $errors->get_error_code()) { |
|
| 730 | + throw new \Exception($errors->get_error_code()); |
|
| 731 | 731 | } |
| 732 | 732 | |
| 733 | 733 | /** |
@@ -752,14 +752,14 @@ discard block |
||
| 752 | 752 | ) |
| 753 | 753 | ); |
| 754 | 754 | |
| 755 | - $customer_id = wp_insert_user( $new_customer_data ); |
|
| 755 | + $customer_id = wp_insert_user($new_customer_data); |
|
| 756 | 756 | |
| 757 | - if ( is_wp_error( $customer_id ) ) { |
|
| 758 | - throw $this->map_create_account_error( $customer_id ); |
|
| 757 | + if (is_wp_error($customer_id)) { |
|
| 758 | + throw $this->map_create_account_error($customer_id); |
|
| 759 | 759 | } |
| 760 | 760 | |
| 761 | 761 | // Set account flag to remind customer to update generated password. |
| 762 | - update_user_option( $customer_id, 'default_password_nag', true, true ); |
|
| 762 | + update_user_option($customer_id, 'default_password_nag', true, true); |
|
| 763 | 763 | |
| 764 | 764 | /** |
| 765 | 765 | * Fires after a customer account has been registered. |
@@ -772,7 +772,7 @@ discard block |
||
| 772 | 772 | * @param array $new_customer_data Array of customer (user) data. |
| 773 | 773 | * @param string $password_generated The generated password for the account. |
| 774 | 774 | */ |
| 775 | - do_action( 'woocommerce_created_customer', $customer_id, $new_customer_data, $password_generated ); |
|
| 775 | + do_action('woocommerce_created_customer', $customer_id, $new_customer_data, $password_generated); |
|
| 776 | 776 | |
| 777 | 777 | return $customer_id; |
| 778 | 778 | } |
@@ -783,8 +783,8 @@ discard block |
||
| 783 | 783 | * @param \WP_Error $error An error object. |
| 784 | 784 | * @return \Exception. |
| 785 | 785 | */ |
| 786 | - private function map_create_account_error( \WP_Error $error ) { |
|
| 787 | - switch ( $error->get_error_code() ) { |
|
| 786 | + private function map_create_account_error(\WP_Error $error) { |
|
| 787 | + switch ($error->get_error_code()) { |
|
| 788 | 788 | // WordPress core error codes. |
| 789 | 789 | case 'empty_username': |
| 790 | 790 | case 'invalid_username': |
@@ -792,8 +792,8 @@ discard block |
||
| 792 | 792 | case 'invalid_email': |
| 793 | 793 | case 'email_exists': |
| 794 | 794 | case 'registerfail': |
| 795 | - return new \Exception( 'woocommerce_rest_checkout_create_account_failure' ); |
|
| 795 | + return new \Exception('woocommerce_rest_checkout_create_account_failure'); |
|
| 796 | 796 | } |
| 797 | - return new \Exception( 'woocommerce_rest_checkout_create_account_failure' ); |
|
| 797 | + return new \Exception('woocommerce_rest_checkout_create_account_failure'); |
|
| 798 | 798 | } |
| 799 | 799 | } |