Move REST API v2 to a new directory
This commit is contained in:
parent
a14ad889df
commit
7f1679d994
|
@ -0,0 +1,542 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Coupons controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /coupons endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Coupons controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_CRUD_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Coupons_V2_Controller extends WC_REST_Legacy_Coupons_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route base.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $rest_base = 'coupons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post type.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $post_type = 'shop_coupon';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the routes for coupons.
|
||||||
|
*/
|
||||||
|
public function register_routes() {
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base, array(
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_items' ),
|
||||||
|
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||||
|
'args' => $this->get_collection_params(),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::CREATABLE,
|
||||||
|
'callback' => array( $this, 'create_item' ),
|
||||||
|
'permission_callback' => array( $this, 'create_item_permissions_check' ),
|
||||||
|
'args' => array_merge(
|
||||||
|
$this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array(
|
||||||
|
'code' => array(
|
||||||
|
'description' => __( 'Coupon code.', 'woocommerce' ),
|
||||||
|
'required' => true,
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
|
||||||
|
'args' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_item' ),
|
||||||
|
'permission_callback' => array( $this, 'get_item_permissions_check' ),
|
||||||
|
'args' => array(
|
||||||
|
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::EDITABLE,
|
||||||
|
'callback' => array( $this, 'update_item' ),
|
||||||
|
'permission_callback' => array( $this, 'update_item_permissions_check' ),
|
||||||
|
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::DELETABLE,
|
||||||
|
'callback' => array( $this, 'delete_item' ),
|
||||||
|
'permission_callback' => array( $this, 'delete_item_permissions_check' ),
|
||||||
|
'args' => array(
|
||||||
|
'force' => array(
|
||||||
|
'default' => false,
|
||||||
|
'type' => 'boolean',
|
||||||
|
'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base . '/batch', array(
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::EDITABLE,
|
||||||
|
'callback' => array( $this, 'batch_items' ),
|
||||||
|
'permission_callback' => array( $this, 'batch_items_permissions_check' ),
|
||||||
|
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_batch_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get object.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param int $id Object ID.
|
||||||
|
* @return WC_Data
|
||||||
|
*/
|
||||||
|
protected function get_object( $id ) {
|
||||||
|
return new WC_Coupon( $id );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get formatted item data.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WC_Data $object WC_Data instance.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function get_formatted_item_data( $object ) {
|
||||||
|
$data = $object->get_data();
|
||||||
|
|
||||||
|
$format_decimal = array( 'amount', 'minimum_amount', 'maximum_amount' );
|
||||||
|
$format_date = array( 'date_created', 'date_modified', 'date_expires' );
|
||||||
|
$format_null = array( 'usage_limit', 'usage_limit_per_user', 'limit_usage_to_x_items' );
|
||||||
|
|
||||||
|
// Format decimal values.
|
||||||
|
foreach ( $format_decimal as $key ) {
|
||||||
|
$data[ $key ] = wc_format_decimal( $data[ $key ], 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format date values.
|
||||||
|
foreach ( $format_date as $key ) {
|
||||||
|
$datetime = $data[ $key ];
|
||||||
|
$data[ $key ] = wc_rest_prepare_date_response( $datetime, false );
|
||||||
|
$data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format null values.
|
||||||
|
foreach ( $format_null as $key ) {
|
||||||
|
$data[ $key ] = $data[ $key ] ? $data[ $key ] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'id' => $object->get_id(),
|
||||||
|
'code' => $data['code'],
|
||||||
|
'amount' => $data['amount'],
|
||||||
|
'date_created' => $data['date_created'],
|
||||||
|
'date_created_gmt' => $data['date_created_gmt'],
|
||||||
|
'date_modified' => $data['date_modified'],
|
||||||
|
'date_modified_gmt' => $data['date_modified_gmt'],
|
||||||
|
'discount_type' => $data['discount_type'],
|
||||||
|
'description' => $data['description'],
|
||||||
|
'date_expires' => $data['date_expires'],
|
||||||
|
'date_expires_gmt' => $data['date_expires_gmt'],
|
||||||
|
'usage_count' => $data['usage_count'],
|
||||||
|
'individual_use' => $data['individual_use'],
|
||||||
|
'product_ids' => $data['product_ids'],
|
||||||
|
'excluded_product_ids' => $data['excluded_product_ids'],
|
||||||
|
'usage_limit' => $data['usage_limit'],
|
||||||
|
'usage_limit_per_user' => $data['usage_limit_per_user'],
|
||||||
|
'limit_usage_to_x_items' => $data['limit_usage_to_x_items'],
|
||||||
|
'free_shipping' => $data['free_shipping'],
|
||||||
|
'product_categories' => $data['product_categories'],
|
||||||
|
'excluded_product_categories' => $data['excluded_product_categories'],
|
||||||
|
'exclude_sale_items' => $data['exclude_sale_items'],
|
||||||
|
'minimum_amount' => $data['minimum_amount'],
|
||||||
|
'maximum_amount' => $data['maximum_amount'],
|
||||||
|
'email_restrictions' => $data['email_restrictions'],
|
||||||
|
'used_by' => $data['used_by'],
|
||||||
|
'meta_data' => $data['meta_data'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a single coupon output for response.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WC_Data $object Object data.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function prepare_object_for_response( $object, $request ) {
|
||||||
|
$data = $this->get_formatted_item_data( $object );
|
||||||
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||||
|
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
$response->add_links( $this->prepare_links( $object, $request ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter the data for a response.
|
||||||
|
*
|
||||||
|
* The dynamic portion of the hook name, $this->post_type,
|
||||||
|
* refers to object type being prepared for the response.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Response $response The response object.
|
||||||
|
* @param WC_Data $object Object data.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
*/
|
||||||
|
return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare objects query.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function prepare_objects_query( $request ) {
|
||||||
|
$args = parent::prepare_objects_query( $request );
|
||||||
|
|
||||||
|
if ( ! empty( $request['code'] ) ) {
|
||||||
|
$id = wc_get_coupon_id_by_code( $request['code'] );
|
||||||
|
$args['post__in'] = array( $id );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get only ids.
|
||||||
|
$args['fields'] = 'ids';
|
||||||
|
|
||||||
|
return $args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only return writable props from schema.
|
||||||
|
*
|
||||||
|
* @param array $schema Schema.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function filter_writable_props( $schema ) {
|
||||||
|
return empty( $schema['readonly'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a single coupon for create or update.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @param bool $creating If is creating a new object.
|
||||||
|
* @return WP_Error|WC_Data
|
||||||
|
*/
|
||||||
|
protected function prepare_object_for_database( $request, $creating = false ) {
|
||||||
|
$id = isset( $request['id'] ) ? absint( $request['id'] ) : 0;
|
||||||
|
$coupon = new WC_Coupon( $id );
|
||||||
|
$schema = $this->get_item_schema();
|
||||||
|
$data_keys = array_keys( array_filter( $schema['properties'], array( $this, 'filter_writable_props' ) ) );
|
||||||
|
|
||||||
|
// Validate required POST fields.
|
||||||
|
if ( $creating && empty( $request['code'] ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_empty_coupon_code', sprintf( __( 'The coupon code cannot be empty.', 'woocommerce' ), 'code' ), array( 'status' => 400 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle all writable props.
|
||||||
|
foreach ( $data_keys as $key ) {
|
||||||
|
$value = $request[ $key ];
|
||||||
|
|
||||||
|
if ( ! is_null( $value ) ) {
|
||||||
|
switch ( $key ) {
|
||||||
|
case 'code':
|
||||||
|
$coupon_code = wc_format_coupon_code( $value );
|
||||||
|
$id = $coupon->get_id() ? $coupon->get_id() : 0;
|
||||||
|
$id_from_code = wc_get_coupon_id_by_code( $coupon_code, $id );
|
||||||
|
|
||||||
|
if ( $id_from_code ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), array( 'status' => 400 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$coupon->set_code( $coupon_code );
|
||||||
|
break;
|
||||||
|
case 'meta_data':
|
||||||
|
if ( is_array( $value ) ) {
|
||||||
|
foreach ( $value as $meta ) {
|
||||||
|
$coupon->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'description':
|
||||||
|
$coupon->set_description( wp_filter_post_kses( $value ) );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ( is_callable( array( $coupon, "set_{$key}" ) ) ) {
|
||||||
|
$coupon->{"set_{$key}"}( $value );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters an object before it is inserted via the REST API.
|
||||||
|
*
|
||||||
|
* The dynamic portion of the hook name, `$this->post_type`,
|
||||||
|
* refers to the object type slug.
|
||||||
|
*
|
||||||
|
* @param WC_Data $coupon Object object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @param bool $creating If is creating a new object.
|
||||||
|
*/
|
||||||
|
return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $coupon, $request, $creating );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Coupon's schema, conforming to JSON Schema.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => $this->post_type,
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the object.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'code' => array(
|
||||||
|
'description' => __( 'Coupon code.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'amount' => array(
|
||||||
|
'description' => __( 'The amount of discount. Should always be numeric, even if setting a percentage.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'date_created' => array(
|
||||||
|
'description' => __( "The date the coupon was created, in the site's timezone.", 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_created_gmt' => array(
|
||||||
|
'description' => __( 'The date the coupon was created, as GMT.', 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_modified' => array(
|
||||||
|
'description' => __( "The date the coupon was last modified, in the site's timezone.", 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_modified_gmt' => array(
|
||||||
|
'description' => __( 'The date the coupon was last modified, as GMT.', 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'discount_type' => array(
|
||||||
|
'description' => __( 'Determines the type of discount that will be applied.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'default' => 'fixed_cart',
|
||||||
|
'enum' => array_keys( wc_get_coupon_types() ),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'description' => array(
|
||||||
|
'description' => __( 'Coupon description.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'date_expires' => array(
|
||||||
|
'description' => __( "The date the coupon expires, in the site's timezone.", 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'date_expires_gmt' => array(
|
||||||
|
'description' => __( 'The date the coupon expires, as GMT.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'usage_count' => array(
|
||||||
|
'description' => __( 'Number of times the coupon has been used already.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'individual_use' => array(
|
||||||
|
'description' => __( 'If true, the coupon can only be used individually. Other applied coupons will be removed from the cart.', 'woocommerce' ),
|
||||||
|
'type' => 'boolean',
|
||||||
|
'default' => false,
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'product_ids' => array(
|
||||||
|
'description' => __( 'List of product IDs the coupon can be used on.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'excluded_product_ids' => array(
|
||||||
|
'description' => __( 'List of product IDs the coupon cannot be used on.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'usage_limit' => array(
|
||||||
|
'description' => __( 'How many times the coupon can be used in total.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'usage_limit_per_user' => array(
|
||||||
|
'description' => __( 'How many times the coupon can be used per customer.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'limit_usage_to_x_items' => array(
|
||||||
|
'description' => __( 'Max number of items in the cart the coupon can be applied to.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'free_shipping' => array(
|
||||||
|
'description' => __( 'If true and if the free shipping method requires a coupon, this coupon will enable free shipping.', 'woocommerce' ),
|
||||||
|
'type' => 'boolean',
|
||||||
|
'default' => false,
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'product_categories' => array(
|
||||||
|
'description' => __( 'List of category IDs the coupon applies to.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'excluded_product_categories' => array(
|
||||||
|
'description' => __( 'List of category IDs the coupon does not apply to.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'exclude_sale_items' => array(
|
||||||
|
'description' => __( 'If true, this coupon will not be applied to items that have sale prices.', 'woocommerce' ),
|
||||||
|
'type' => 'boolean',
|
||||||
|
'default' => false,
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'minimum_amount' => array(
|
||||||
|
'description' => __( 'Minimum order amount that needs to be in the cart before coupon applies.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'maximum_amount' => array(
|
||||||
|
'description' => __( 'Maximum order amount allowed when using the coupon.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'email_restrictions' => array(
|
||||||
|
'description' => __( 'List of email addresses that can use this coupon.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'used_by' => array(
|
||||||
|
'description' => __( 'List of user IDs (or guest email addresses) that have used the coupon.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'meta_data' => array(
|
||||||
|
'description' => __( 'Meta data.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Meta ID.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'key' => array(
|
||||||
|
'description' => __( 'Meta key.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'value' => array(
|
||||||
|
'description' => __( 'Meta value.', 'woocommerce' ),
|
||||||
|
'type' => 'mixed',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the query params for collections of attachments.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_collection_params() {
|
||||||
|
$params = parent::get_collection_params();
|
||||||
|
|
||||||
|
$params['code'] = array(
|
||||||
|
'description' => __( 'Limit result set to resources with a specific code.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
'validate_callback' => 'rest_validate_request_arg',
|
||||||
|
);
|
||||||
|
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,165 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Customer Downloads controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /customers/<customer_id>/downloads endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Customers controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Customer_Downloads_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Customer_Downloads_V2_Controller extends WC_REST_Customer_Downloads_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a single download output for response.
|
||||||
|
*
|
||||||
|
* @param stdClass $download Download object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response $response Response data.
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $download, $request ) {
|
||||||
|
$data = array(
|
||||||
|
'download_id' => $download->download_id,
|
||||||
|
'download_url' => $download->download_url,
|
||||||
|
'product_id' => $download->product_id,
|
||||||
|
'product_name' => $download->product_name,
|
||||||
|
'download_name' => $download->download_name,
|
||||||
|
'order_id' => $download->order_id,
|
||||||
|
'order_key' => $download->order_key,
|
||||||
|
'downloads_remaining' => '' === $download->downloads_remaining ? 'unlimited' : $download->downloads_remaining,
|
||||||
|
'access_expires' => $download->access_expires ? wc_rest_prepare_date_response( $download->access_expires ) : 'never',
|
||||||
|
'access_expires_gmt' => $download->access_expires ? wc_rest_prepare_date_response( get_gmt_from_date( $download->access_expires ) ) : 'never',
|
||||||
|
'file' => $download->file,
|
||||||
|
);
|
||||||
|
|
||||||
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||||
|
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
|
||||||
|
// Wrap the data in a response object.
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
$response->add_links( $this->prepare_links( $download, $request ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter customer download data returned from the REST API.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Response $response The response object.
|
||||||
|
* @param stdClass $download Download object used to create response.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
*/
|
||||||
|
return apply_filters( 'woocommerce_rest_prepare_customer_download', $response, $download, $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Customer Download's schema, conforming to JSON Schema.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => 'customer_download',
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'download_id' => array(
|
||||||
|
'description' => __( 'Download ID.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'download_url' => array(
|
||||||
|
'description' => __( 'Download file URL.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'product_id' => array(
|
||||||
|
'description' => __( 'Downloadable product ID.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'product_name' => array(
|
||||||
|
'description' => __( 'Product name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'download_name' => array(
|
||||||
|
'description' => __( 'Downloadable file name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'order_id' => array(
|
||||||
|
'description' => __( 'Order ID.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'order_key' => array(
|
||||||
|
'description' => __( 'Order key.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'downloads_remaining' => array(
|
||||||
|
'description' => __( 'Number of downloads remaining.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'access_expires' => array(
|
||||||
|
'description' => __( "The date when download access expires, in the site's timezone.", 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'access_expires_gmt' => array(
|
||||||
|
'description' => __( 'The date when download access expires, as GMT.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'file' => array(
|
||||||
|
'description' => __( 'File details.', 'woocommerce' ),
|
||||||
|
'type' => 'object',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
'properties' => array(
|
||||||
|
'name' => array(
|
||||||
|
'description' => __( 'File name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'file' => array(
|
||||||
|
'description' => __( 'File URL.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,364 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Customers controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /customers endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Customers controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Customers_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Customers_V2_Controller extends WC_REST_Customers_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get formatted item data.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WC_Data $object WC_Data instance.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function get_formatted_item_data( $object ) {
|
||||||
|
$data = $object->get_data();
|
||||||
|
$format_date = array( 'date_created', 'date_modified' );
|
||||||
|
|
||||||
|
// Format date values.
|
||||||
|
foreach ( $format_date as $key ) {
|
||||||
|
$datetime = $data[ $key ];
|
||||||
|
$data[ $key ] = wc_rest_prepare_date_response( $datetime, false );
|
||||||
|
$data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime );
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'id' => $object->get_id(),
|
||||||
|
'date_created' => $data['date_created'],
|
||||||
|
'date_created_gmt' => $data['date_created_gmt'],
|
||||||
|
'date_modified' => $data['date_modified'],
|
||||||
|
'date_modified_gmt' => $data['date_modified_gmt'],
|
||||||
|
'email' => $data['email'],
|
||||||
|
'first_name' => $data['first_name'],
|
||||||
|
'last_name' => $data['last_name'],
|
||||||
|
'role' => $data['role'],
|
||||||
|
'username' => $data['username'],
|
||||||
|
'billing' => $data['billing'],
|
||||||
|
'shipping' => $data['shipping'],
|
||||||
|
'is_paying_customer' => $data['is_paying_customer'],
|
||||||
|
'orders_count' => $object->get_order_count(),
|
||||||
|
'total_spent' => $object->get_total_spent(),
|
||||||
|
'avatar_url' => $object->get_avatar_url(),
|
||||||
|
'meta_data' => $data['meta_data'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a single customer output for response.
|
||||||
|
*
|
||||||
|
* @param WP_User $user_data User object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response $response Response data.
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $user_data, $request ) {
|
||||||
|
$customer = new WC_Customer( $user_data->ID );
|
||||||
|
$data = $this->get_formatted_item_data( $customer );
|
||||||
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||||
|
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
$response->add_links( $this->prepare_links( $user_data ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter customer data returned from the REST API.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Response $response The response object.
|
||||||
|
* @param WP_User $user_data User object used to create response.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
*/
|
||||||
|
return apply_filters( 'woocommerce_rest_prepare_customer', $response, $user_data, $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update customer meta fields.
|
||||||
|
*
|
||||||
|
* @param WC_Customer $customer Customer data.
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
*/
|
||||||
|
protected function update_customer_meta_fields( $customer, $request ) {
|
||||||
|
parent::update_customer_meta_fields( $customer, $request );
|
||||||
|
|
||||||
|
// Meta data.
|
||||||
|
if ( isset( $request['meta_data'] ) ) {
|
||||||
|
if ( is_array( $request['meta_data'] ) ) {
|
||||||
|
foreach ( $request['meta_data'] as $meta ) {
|
||||||
|
$customer->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Customer's schema, conforming to JSON Schema.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => 'customer',
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_created' => array(
|
||||||
|
'description' => __( "The date the customer was created, in the site's timezone.", 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_created_gmt' => array(
|
||||||
|
'description' => __( 'The date the order was created, as GMT.', 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_modified' => array(
|
||||||
|
'description' => __( "The date the customer was last modified, in the site's timezone.", 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_modified_gmt' => array(
|
||||||
|
'description' => __( 'The date the customer was last modified, as GMT.', 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'email' => array(
|
||||||
|
'description' => __( 'The email address for the customer.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'format' => 'email',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'first_name' => array(
|
||||||
|
'description' => __( 'Customer first name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'last_name' => array(
|
||||||
|
'description' => __( 'Customer last name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'role' => array(
|
||||||
|
'description' => __( 'Customer role.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'username' => array(
|
||||||
|
'description' => __( 'Customer login name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_user',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'password' => array(
|
||||||
|
'description' => __( 'Customer password.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'edit' ),
|
||||||
|
),
|
||||||
|
'billing' => array(
|
||||||
|
'description' => __( 'List of billing address data.', 'woocommerce' ),
|
||||||
|
'type' => 'object',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'properties' => array(
|
||||||
|
'first_name' => array(
|
||||||
|
'description' => __( 'First name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'last_name' => array(
|
||||||
|
'description' => __( 'Last name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'company' => array(
|
||||||
|
'description' => __( 'Company name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'address_1' => array(
|
||||||
|
'description' => __( 'Address line 1', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'address_2' => array(
|
||||||
|
'description' => __( 'Address line 2', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'city' => array(
|
||||||
|
'description' => __( 'City name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'state' => array(
|
||||||
|
'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'postcode' => array(
|
||||||
|
'description' => __( 'Postal code.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'country' => array(
|
||||||
|
'description' => __( 'ISO code of the country.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'email' => array(
|
||||||
|
'description' => __( 'Email address.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'format' => 'email',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'phone' => array(
|
||||||
|
'description' => __( 'Phone number.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'shipping' => array(
|
||||||
|
'description' => __( 'List of shipping address data.', 'woocommerce' ),
|
||||||
|
'type' => 'object',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'properties' => array(
|
||||||
|
'first_name' => array(
|
||||||
|
'description' => __( 'First name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'last_name' => array(
|
||||||
|
'description' => __( 'Last name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'company' => array(
|
||||||
|
'description' => __( 'Company name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'address_1' => array(
|
||||||
|
'description' => __( 'Address line 1', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'address_2' => array(
|
||||||
|
'description' => __( 'Address line 2', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'city' => array(
|
||||||
|
'description' => __( 'City name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'state' => array(
|
||||||
|
'description' => __( 'ISO code or name of the state, province or district.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'postcode' => array(
|
||||||
|
'description' => __( 'Postal code.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'country' => array(
|
||||||
|
'description' => __( 'ISO code of the country.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'is_paying_customer' => array(
|
||||||
|
'description' => __( 'Is the customer a paying customer?', 'woocommerce' ),
|
||||||
|
'type' => 'bool',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'orders_count' => array(
|
||||||
|
'description' => __( 'Quantity of orders made by the customer.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'total_spent' => array(
|
||||||
|
'description' => __( 'Total amount spent.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'avatar_url' => array(
|
||||||
|
'description' => __( 'Avatar URL.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'meta_data' => array(
|
||||||
|
'description' => __( 'Meta data.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Meta ID.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'key' => array(
|
||||||
|
'description' => __( 'Meta key.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'value' => array(
|
||||||
|
'description' => __( 'Meta value.', 'woocommerce' ),
|
||||||
|
'type' => 'mixed',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Network Orders controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /orders/network endpoint
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 3.4.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Network Orders controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Orders_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Network_Orders_V2_Controller extends WC_REST_Orders_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the routes for network orders.
|
||||||
|
*/
|
||||||
|
public function register_routes() {
|
||||||
|
if ( is_multisite() ) {
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base . '/network', array(
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'network_orders' ),
|
||||||
|
'permission_callback' => array( $this, 'network_orders_permissions_check' ),
|
||||||
|
'args' => $this->get_collection_params(),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the item's schema for display / public consumption purposes.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*
|
||||||
|
* @return array Public item schema data.
|
||||||
|
*/
|
||||||
|
public function get_public_item_schema() {
|
||||||
|
$schema = parent::get_public_item_schema();
|
||||||
|
|
||||||
|
$schema['properties']['blog'] = array(
|
||||||
|
'description' => __( 'Blog id of the record on the multisite.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
);
|
||||||
|
$schema['properties']['edit_url'] = array(
|
||||||
|
'description' => __( 'URL to edit the order', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
);
|
||||||
|
$schema['properties']['customer'][] = array(
|
||||||
|
'description' => __( 'Name of the customer for the order', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
);
|
||||||
|
$schema['properties']['status_name'][] = array(
|
||||||
|
'description' => __( 'Order Status', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
);
|
||||||
|
$schema['properties']['formatted_total'][] = array(
|
||||||
|
'description' => __( 'Order total formatted for locale', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
);
|
||||||
|
|
||||||
|
return $schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does a permissions check for the proper requested blog
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
*
|
||||||
|
* @return bool $permission
|
||||||
|
*/
|
||||||
|
public function network_orders_permissions_check( $request ) {
|
||||||
|
$blog_id = $request->get_param( 'blog_id' );
|
||||||
|
$blog_id = ! empty( $blog_id ) ? $blog_id : get_current_blog_id();
|
||||||
|
|
||||||
|
switch_to_blog( $blog_id );
|
||||||
|
|
||||||
|
$permission = $this->get_items_permissions_check( $request );
|
||||||
|
|
||||||
|
restore_current_blog();
|
||||||
|
|
||||||
|
return $permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a collection of orders from the requested blog id
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
*
|
||||||
|
* @return WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function network_orders( $request ) {
|
||||||
|
$blog_id = $request->get_param( 'blog_id' );
|
||||||
|
$blog_id = ! empty( $blog_id ) ? $blog_id : get_current_blog_id();
|
||||||
|
|
||||||
|
switch_to_blog( $blog_id );
|
||||||
|
|
||||||
|
add_filter( 'woocommerce_rest_orders_prepare_object_query', array( $this, 'network_orders_filter_args' ) );
|
||||||
|
$items = $this->get_items( $request );
|
||||||
|
remove_filter( 'woocommerce_rest_orders_prepare_object_query', array( $this, 'network_orders_filter_args' ) );
|
||||||
|
|
||||||
|
foreach ( $items->data as &$current_order ) {
|
||||||
|
$order = wc_get_order( $current_order['id'] );
|
||||||
|
|
||||||
|
$current_order['blog'] = get_blog_details( get_current_blog_id() );
|
||||||
|
$current_order['edit_url'] = get_admin_url( $blog_id, 'post.php?post=' . absint( $order->get_id() ) . '&action=edit' );
|
||||||
|
/* translators: 1: first name 2: last name */
|
||||||
|
$current_order['customer'] = trim( sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $order->get_billing_first_name(), $order->get_billing_last_name() ) );
|
||||||
|
$current_order['status_name'] = wc_get_order_status_name( $order->get_status() );
|
||||||
|
$current_order['formatted_total'] = $order->get_formatted_order_total();
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_current_blog();
|
||||||
|
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the post statuses to on hold and processing for the network order query.
|
||||||
|
*
|
||||||
|
* @param array $args Query args.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function network_orders_filter_args( $args ) {
|
||||||
|
$args['post_status'] = array(
|
||||||
|
'wc-on-hold',
|
||||||
|
'wc-processing',
|
||||||
|
);
|
||||||
|
|
||||||
|
return $args;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,182 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Order Notes controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /orders/<order_id>/notes endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Order Notes controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_ControllerWC_REST_Order_Notes_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Order_Notes_V2_Controller extends WC_REST_Order_Notes_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get order notes from an order.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
*
|
||||||
|
* @return array|WP_Error
|
||||||
|
*/
|
||||||
|
public function get_items( $request ) {
|
||||||
|
$order = wc_get_order( (int) $request['order_id'] );
|
||||||
|
|
||||||
|
if ( ! $order || $this->post_type !== $order->get_type() ) {
|
||||||
|
return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$args = array(
|
||||||
|
'post_id' => $order->get_id(),
|
||||||
|
'approve' => 'approve',
|
||||||
|
'type' => 'order_note',
|
||||||
|
);
|
||||||
|
|
||||||
|
// Allow filter by order note type.
|
||||||
|
if ( 'customer' === $request['type'] ) {
|
||||||
|
$args['meta_query'] = array( // WPCS: slow query ok.
|
||||||
|
array(
|
||||||
|
'key' => 'is_customer_note',
|
||||||
|
'value' => 1,
|
||||||
|
'compare' => '=',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} elseif ( 'internal' === $request['type'] ) {
|
||||||
|
$args['meta_query'] = array( // WPCS: slow query ok.
|
||||||
|
array(
|
||||||
|
'key' => 'is_customer_note',
|
||||||
|
'compare' => 'NOT EXISTS',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 );
|
||||||
|
|
||||||
|
$notes = get_comments( $args );
|
||||||
|
|
||||||
|
add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 );
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
foreach ( $notes as $note ) {
|
||||||
|
$order_note = $this->prepare_item_for_response( $note, $request );
|
||||||
|
$order_note = $this->prepare_response_for_collection( $order_note );
|
||||||
|
$data[] = $order_note;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rest_ensure_response( $data );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a single order note output for response.
|
||||||
|
*
|
||||||
|
* @param WP_Comment $note Order note object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response $response Response data.
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $note, $request ) {
|
||||||
|
$data = array(
|
||||||
|
'id' => (int) $note->comment_ID,
|
||||||
|
'date_created' => wc_rest_prepare_date_response( $note->comment_date ),
|
||||||
|
'date_created_gmt' => wc_rest_prepare_date_response( $note->comment_date_gmt ),
|
||||||
|
'note' => $note->comment_content,
|
||||||
|
'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ),
|
||||||
|
);
|
||||||
|
|
||||||
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||||
|
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
|
||||||
|
// Wrap the data in a response object.
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
$response->add_links( $this->prepare_links( $note ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter order note object returned from the REST API.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Response $response The response object.
|
||||||
|
* @param WP_Comment $note Order note object used to create response.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
*/
|
||||||
|
return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Order Notes schema, conforming to JSON Schema.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => 'order_note',
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_created' => array(
|
||||||
|
'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_created_gmt' => array(
|
||||||
|
'description' => __( 'The date the order note was created, as GMT.', 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'note' => array(
|
||||||
|
'description' => __( 'Order note content.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'customer_note' => array(
|
||||||
|
'description' => __( 'If true, the note will be shown to customers and they will be notified. If false, the note will be for admin reference only.', 'woocommerce' ),
|
||||||
|
'type' => 'boolean',
|
||||||
|
'default' => false,
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the query params for collections.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_collection_params() {
|
||||||
|
$params = array();
|
||||||
|
$params['context'] = $this->get_context_param( array( 'default' => 'view' ) );
|
||||||
|
$params['type'] = array(
|
||||||
|
'default' => 'any',
|
||||||
|
'description' => __( 'Limit result to customers or internal notes.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'enum' => array( 'any', 'customer', 'internal' ),
|
||||||
|
'sanitize_callback' => 'sanitize_key',
|
||||||
|
'validate_callback' => 'rest_validate_request_arg',
|
||||||
|
);
|
||||||
|
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,583 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Order Refunds controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /orders/<order_id>/refunds endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Order Refunds controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Orders_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Order_Refunds_V2_Controller extends WC_REST_Orders_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route base.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $rest_base = 'orders/(?P<order_id>[\d]+)/refunds';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post type.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $post_type = 'shop_order_refund';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the request.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $request = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Order refunds actions.
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
add_filter( "woocommerce_rest_{$this->post_type}_object_trashable", '__return_false' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the routes for order refunds.
|
||||||
|
*/
|
||||||
|
public function register_routes() {
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base, array(
|
||||||
|
'args' => array(
|
||||||
|
'order_id' => array(
|
||||||
|
'description' => __( 'The order ID.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_items' ),
|
||||||
|
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||||
|
'args' => $this->get_collection_params(),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::CREATABLE,
|
||||||
|
'callback' => array( $this, 'create_item' ),
|
||||||
|
'permission_callback' => array( $this, 'create_item_permissions_check' ),
|
||||||
|
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
|
||||||
|
'args' => array(
|
||||||
|
'order_id' => array(
|
||||||
|
'description' => __( 'The order ID.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_item' ),
|
||||||
|
'permission_callback' => array( $this, 'get_item_permissions_check' ),
|
||||||
|
'args' => array(
|
||||||
|
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::DELETABLE,
|
||||||
|
'callback' => array( $this, 'delete_item' ),
|
||||||
|
'permission_callback' => array( $this, 'delete_item_permissions_check' ),
|
||||||
|
'args' => array(
|
||||||
|
'force' => array(
|
||||||
|
'default' => true,
|
||||||
|
'type' => 'boolean',
|
||||||
|
'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get object.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param int $id Object ID.
|
||||||
|
* @return WC_Data
|
||||||
|
*/
|
||||||
|
protected function get_object( $id ) {
|
||||||
|
return wc_get_order( $id );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get formatted item data.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WC_Data $object WC_Data instance.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function get_formatted_item_data( $object ) {
|
||||||
|
$data = $object->get_data();
|
||||||
|
$format_decimal = array( 'amount' );
|
||||||
|
$format_date = array( 'date_created' );
|
||||||
|
$format_line_items = array( 'line_items' );
|
||||||
|
|
||||||
|
// Format decimal values.
|
||||||
|
foreach ( $format_decimal as $key ) {
|
||||||
|
$data[ $key ] = wc_format_decimal( $data[ $key ], $this->request['dp'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format date values.
|
||||||
|
foreach ( $format_date as $key ) {
|
||||||
|
$datetime = $data[ $key ];
|
||||||
|
$data[ $key ] = wc_rest_prepare_date_response( $datetime, false );
|
||||||
|
$data[ $key . '_gmt' ] = wc_rest_prepare_date_response( $datetime );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format line items.
|
||||||
|
foreach ( $format_line_items as $key ) {
|
||||||
|
$data[ $key ] = array_values( array_map( array( $this, 'get_order_item_data' ), $data[ $key ] ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'id' => $object->get_id(),
|
||||||
|
'date_created' => $data['date_created'],
|
||||||
|
'date_created_gmt' => $data['date_created_gmt'],
|
||||||
|
'amount' => $data['amount'],
|
||||||
|
'reason' => $data['reason'],
|
||||||
|
'refunded_by' => $data['refunded_by'],
|
||||||
|
'refunded_payment' => $data['refunded_payment'],
|
||||||
|
'meta_data' => $data['meta_data'],
|
||||||
|
'line_items' => $data['line_items'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a single order output for response.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
*
|
||||||
|
* @param WC_Data $object Object data.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
*
|
||||||
|
* @return WP_Error|WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function prepare_object_for_response( $object, $request ) {
|
||||||
|
$this->request = $request;
|
||||||
|
$this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] );
|
||||||
|
$order = wc_get_order( (int) $request['order_id'] );
|
||||||
|
|
||||||
|
if ( ! $order ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $object || $object->get_parent_id() !== $order->get_id() ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 );
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->get_formatted_item_data( $object );
|
||||||
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||||
|
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
|
||||||
|
// Wrap the data in a response object.
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
$response->add_links( $this->prepare_links( $object, $request ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter the data for a response.
|
||||||
|
*
|
||||||
|
* The dynamic portion of the hook name, $this->post_type,
|
||||||
|
* refers to object type being prepared for the response.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Response $response The response object.
|
||||||
|
* @param WC_Data $object Object data.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
*/
|
||||||
|
return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare links for the request.
|
||||||
|
*
|
||||||
|
* @param WC_Data $object Object data.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return array Links for the given post.
|
||||||
|
*/
|
||||||
|
protected function prepare_links( $object, $request ) {
|
||||||
|
$base = str_replace( '(?P<order_id>[\d]+)', $object->get_parent_id(), $this->rest_base );
|
||||||
|
$links = array(
|
||||||
|
'self' => array(
|
||||||
|
'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $object->get_id() ) ),
|
||||||
|
),
|
||||||
|
'collection' => array(
|
||||||
|
'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ),
|
||||||
|
),
|
||||||
|
'up' => array(
|
||||||
|
'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $object->get_parent_id() ) ),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $links;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare objects query.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function prepare_objects_query( $request ) {
|
||||||
|
$args = parent::prepare_objects_query( $request );
|
||||||
|
|
||||||
|
$args['post_status'] = array_keys( wc_get_order_statuses() );
|
||||||
|
$args['post_parent__in'] = array( absint( $request['order_id'] ) );
|
||||||
|
|
||||||
|
return $args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepares one object for create or update operation.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @param bool $creating If is creating a new object.
|
||||||
|
* @return WP_Error|WC_Data The prepared item, or WP_Error object on failure.
|
||||||
|
*/
|
||||||
|
protected function prepare_object_for_database( $request, $creating = false ) {
|
||||||
|
$order = wc_get_order( (int) $request['order_id'] );
|
||||||
|
|
||||||
|
if ( ! $order ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( 0 > $request['amount'] ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_invalid_order_refund', __( 'Refund amount must be greater than zero.', 'woocommerce' ), 400 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the refund.
|
||||||
|
$refund = wc_create_refund(
|
||||||
|
array(
|
||||||
|
'order_id' => $order->get_id(),
|
||||||
|
'amount' => $request['amount'],
|
||||||
|
'reason' => empty( $request['reason'] ) ? null : $request['reason'],
|
||||||
|
'refund_payment' => is_bool( $request['api_refund'] ) ? $request['api_refund'] : true,
|
||||||
|
'restock_items' => true,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( is_wp_error( $refund ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', $refund->get_error_message(), 500 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $refund ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_cannot_create_order_refund', __( 'Cannot create order refund, please try again.', 'woocommerce' ), 500 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! empty( $request['meta_data'] ) && is_array( $request['meta_data'] ) ) {
|
||||||
|
foreach ( $request['meta_data'] as $meta ) {
|
||||||
|
$refund->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' );
|
||||||
|
}
|
||||||
|
$refund->save_meta_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters an object before it is inserted via the REST API.
|
||||||
|
*
|
||||||
|
* The dynamic portion of the hook name, `$this->post_type`,
|
||||||
|
* refers to the object type slug.
|
||||||
|
*
|
||||||
|
* @param WC_Data $coupon Object object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @param bool $creating If is creating a new object.
|
||||||
|
*/
|
||||||
|
return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $refund, $request, $creating );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save an object data.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @param bool $creating If is creating a new object.
|
||||||
|
* @return WC_Data|WP_Error
|
||||||
|
*/
|
||||||
|
protected function save_object( $request, $creating = false ) {
|
||||||
|
try {
|
||||||
|
$object = $this->prepare_object_for_database( $request, $creating );
|
||||||
|
|
||||||
|
if ( is_wp_error( $object ) ) {
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->get_object( $object->get_id() );
|
||||||
|
} catch ( WC_Data_Exception $e ) {
|
||||||
|
return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() );
|
||||||
|
} catch ( WC_REST_Exception $e ) {
|
||||||
|
return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Order's schema, conforming to JSON Schema.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => $this->post_type,
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_created' => array(
|
||||||
|
'description' => __( "The date the order refund was created, in the site's timezone.", 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_created_gmt' => array(
|
||||||
|
'description' => __( 'The date the order refund was created, as GMT.', 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'amount' => array(
|
||||||
|
'description' => __( 'Refund amount.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'reason' => array(
|
||||||
|
'description' => __( 'Reason for refund.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'refunded_by' => array(
|
||||||
|
'description' => __( 'User ID of user who created the refund.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'refunded_payment' => array(
|
||||||
|
'description' => __( 'If the payment was refunded via the API.', 'woocommerce' ),
|
||||||
|
'type' => 'boolean',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
),
|
||||||
|
'meta_data' => array(
|
||||||
|
'description' => __( 'Meta data.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Meta ID.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'key' => array(
|
||||||
|
'description' => __( 'Meta key.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'value' => array(
|
||||||
|
'description' => __( 'Meta value.', 'woocommerce' ),
|
||||||
|
'type' => 'mixed',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'line_items' => array(
|
||||||
|
'description' => __( 'Line items data.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Item ID.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'name' => array(
|
||||||
|
'description' => __( 'Product name.', 'woocommerce' ),
|
||||||
|
'type' => 'mixed',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'product_id' => array(
|
||||||
|
'description' => __( 'Product ID.', 'woocommerce' ),
|
||||||
|
'type' => 'mixed',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'variation_id' => array(
|
||||||
|
'description' => __( 'Variation ID, if applicable.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'quantity' => array(
|
||||||
|
'description' => __( 'Quantity ordered.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'tax_class' => array(
|
||||||
|
'description' => __( 'Tax class of product.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'subtotal' => array(
|
||||||
|
'description' => __( 'Line subtotal (before discounts).', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'subtotal_tax' => array(
|
||||||
|
'description' => __( 'Line subtotal tax (before discounts).', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'total' => array(
|
||||||
|
'description' => __( 'Line total (after discounts).', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'total_tax' => array(
|
||||||
|
'description' => __( 'Line total tax (after discounts).', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'taxes' => array(
|
||||||
|
'description' => __( 'Line taxes.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Tax rate ID.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'total' => array(
|
||||||
|
'description' => __( 'Tax total.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'subtotal' => array(
|
||||||
|
'description' => __( 'Tax subtotal.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'meta_data' => array(
|
||||||
|
'description' => __( 'Meta data.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Meta ID.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'key' => array(
|
||||||
|
'description' => __( 'Meta key.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'value' => array(
|
||||||
|
'description' => __( 'Meta value.', 'woocommerce' ),
|
||||||
|
'type' => 'mixed',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'sku' => array(
|
||||||
|
'description' => __( 'Product SKU.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'price' => array(
|
||||||
|
'description' => __( 'Product price.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'api_refund' => array(
|
||||||
|
'description' => __( 'When true, the payment gateway API is used to generate the refund.', 'woocommerce' ),
|
||||||
|
'type' => 'boolean',
|
||||||
|
'context' => array( 'edit' ),
|
||||||
|
'default' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the query params for collections.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_collection_params() {
|
||||||
|
$params = parent::get_collection_params();
|
||||||
|
|
||||||
|
unset( $params['status'], $params['customer'], $params['product'] );
|
||||||
|
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,466 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API WC Payment gateways controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /payment_gateways endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paymenga gateways controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Payment_Gateways_V2_Controller extends WC_REST_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route base.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $rest_base = 'payment_gateways';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the route for /payment_gateways and /payment_gateways/<id>
|
||||||
|
*/
|
||||||
|
public function register_routes() {
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base, array(
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_items' ),
|
||||||
|
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||||
|
'args' => $this->get_collection_params(),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base . '/(?P<id>[\w-]+)', array(
|
||||||
|
'args' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_item' ),
|
||||||
|
'permission_callback' => array( $this, 'get_item_permissions_check' ),
|
||||||
|
'args' => array(
|
||||||
|
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::EDITABLE,
|
||||||
|
'callback' => array( $this, 'update_item' ),
|
||||||
|
'permission_callback' => array( $this, 'update_items_permissions_check' ),
|
||||||
|
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a given request has permission to view payment gateways.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_Error|boolean
|
||||||
|
*/
|
||||||
|
public function get_items_permissions_check( $request ) {
|
||||||
|
if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'read' ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given request has access to read a payment gateway.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_Error|boolean
|
||||||
|
*/
|
||||||
|
public function get_item_permissions_check( $request ) {
|
||||||
|
if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'read' ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a given request has permission to edit payment gateways.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_Error|boolean
|
||||||
|
*/
|
||||||
|
public function update_items_permissions_check( $request ) {
|
||||||
|
if ( ! wc_rest_check_manager_permissions( 'payment_gateways', 'edit' ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get payment gateways.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_Error|WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function get_items( $request ) {
|
||||||
|
$payment_gateways = WC()->payment_gateways->payment_gateways();
|
||||||
|
$response = array();
|
||||||
|
foreach ( $payment_gateways as $payment_gateway_id => $payment_gateway ) {
|
||||||
|
$payment_gateway->id = $payment_gateway_id;
|
||||||
|
$gateway = $this->prepare_item_for_response( $payment_gateway, $request );
|
||||||
|
$gateway = $this->prepare_response_for_collection( $gateway );
|
||||||
|
$response[] = $gateway;
|
||||||
|
}
|
||||||
|
return rest_ensure_response( $response );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a single payment gateway.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_REST_Response|WP_Error
|
||||||
|
*/
|
||||||
|
public function get_item( $request ) {
|
||||||
|
$gateway = $this->get_gateway( $request );
|
||||||
|
|
||||||
|
if ( is_null( $gateway ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$gateway = $this->prepare_item_for_response( $gateway, $request );
|
||||||
|
return rest_ensure_response( $gateway );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update A Single Payment Method.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_REST_Response|WP_Error
|
||||||
|
*/
|
||||||
|
public function update_item( $request ) {
|
||||||
|
$gateway = $this->get_gateway( $request );
|
||||||
|
|
||||||
|
if ( is_null( $gateway ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_payment_gateway_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get settings.
|
||||||
|
$gateway->init_form_fields();
|
||||||
|
$settings = $gateway->settings;
|
||||||
|
|
||||||
|
// Update settings.
|
||||||
|
if ( isset( $request['settings'] ) ) {
|
||||||
|
$errors_found = false;
|
||||||
|
foreach ( $gateway->form_fields as $key => $field ) {
|
||||||
|
if ( isset( $request['settings'][ $key ] ) ) {
|
||||||
|
if ( is_callable( array( $this, 'validate_setting_' . $field['type'] . '_field' ) ) ) {
|
||||||
|
$value = $this->{'validate_setting_' . $field['type'] . '_field'}( $request['settings'][ $key ], $field );
|
||||||
|
} else {
|
||||||
|
$value = $this->validate_setting_text_field( $request['settings'][ $key ], $field );
|
||||||
|
}
|
||||||
|
if ( is_wp_error( $value ) ) {
|
||||||
|
$errors_found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$settings[ $key ] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $errors_found ) {
|
||||||
|
return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update if this method is enabled or not.
|
||||||
|
if ( isset( $request['enabled'] ) ) {
|
||||||
|
$settings['enabled'] = wc_bool_to_string( $request['enabled'] );
|
||||||
|
$gateway->enabled = $settings['enabled'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update title.
|
||||||
|
if ( isset( $request['title'] ) ) {
|
||||||
|
$settings['title'] = $request['title'];
|
||||||
|
$gateway->title = $settings['title'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update description.
|
||||||
|
if ( isset( $request['description'] ) ) {
|
||||||
|
$settings['description'] = $request['description'];
|
||||||
|
$gateway->description = $settings['description'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update options.
|
||||||
|
$gateway->settings = $settings;
|
||||||
|
update_option( $gateway->get_option_key(), apply_filters( 'woocommerce_gateway_' . $gateway->id . '_settings_values', $settings, $gateway ) );
|
||||||
|
|
||||||
|
// Update order.
|
||||||
|
if ( isset( $request['order'] ) ) {
|
||||||
|
$order = (array) get_option( 'woocommerce_gateway_order' );
|
||||||
|
$order[ $gateway->id ] = $request['order'];
|
||||||
|
update_option( 'woocommerce_gateway_order', $order );
|
||||||
|
$gateway->order = absint( $request['order'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
$gateway = $this->prepare_item_for_response( $gateway, $request );
|
||||||
|
return rest_ensure_response( $gateway );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a gateway based on the current request object.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_REST_Response|null
|
||||||
|
*/
|
||||||
|
public function get_gateway( $request ) {
|
||||||
|
$gateway = null;
|
||||||
|
$payment_gateways = WC()->payment_gateways->payment_gateways();
|
||||||
|
foreach ( $payment_gateways as $payment_gateway_id => $payment_gateway ) {
|
||||||
|
if ( $request['id'] !== $payment_gateway_id ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$payment_gateway->id = $payment_gateway_id;
|
||||||
|
$gateway = $payment_gateway;
|
||||||
|
}
|
||||||
|
return $gateway;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a payment gateway for response.
|
||||||
|
*
|
||||||
|
* @param WC_Payment_Gateway $gateway Payment gateway object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response $response Response data.
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $gateway, $request ) {
|
||||||
|
$order = (array) get_option( 'woocommerce_gateway_order' );
|
||||||
|
$item = array(
|
||||||
|
'id' => $gateway->id,
|
||||||
|
'title' => $gateway->title,
|
||||||
|
'description' => $gateway->description,
|
||||||
|
'order' => isset( $order[ $gateway->id ] ) ? $order[ $gateway->id ] : '',
|
||||||
|
'enabled' => ( 'yes' === $gateway->enabled ),
|
||||||
|
'method_title' => $gateway->get_method_title(),
|
||||||
|
'method_description' => $gateway->get_method_description(),
|
||||||
|
'settings' => $this->get_settings( $gateway ),
|
||||||
|
);
|
||||||
|
|
||||||
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||||
|
$data = $this->add_additional_fields_to_object( $item, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
$response->add_links( $this->prepare_links( $gateway, $request ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter payment gateway objects returned from the REST API.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Response $response The response object.
|
||||||
|
* @param WC_Payment_Gateway $gateway Payment gateway object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
*/
|
||||||
|
return apply_filters( 'woocommerce_rest_prepare_payment_gateway', $response, $gateway, $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return settings associated with this payment gateway.
|
||||||
|
*
|
||||||
|
* @param WC_Payment_Gateway $gateway Gateway data.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_settings( $gateway ) {
|
||||||
|
$settings = array();
|
||||||
|
$gateway->init_form_fields();
|
||||||
|
foreach ( $gateway->form_fields as $id => $field ) {
|
||||||
|
// Make sure we at least have a title and type.
|
||||||
|
if ( empty( $field['title'] ) || empty( $field['type'] ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Ignore 'title' settings/fields -- they are UI only.
|
||||||
|
if ( 'title' === $field['type'] ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Ignore 'enabled' and 'description' which get included elsewhere.
|
||||||
|
if ( in_array( $id, array( 'enabled', 'description' ), true ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$data = array(
|
||||||
|
'id' => $id,
|
||||||
|
'label' => empty( $field['label'] ) ? $field['title'] : $field['label'],
|
||||||
|
'description' => empty( $field['description'] ) ? '' : $field['description'],
|
||||||
|
'type' => $field['type'],
|
||||||
|
'value' => empty( $gateway->settings[ $id ] ) ? '' : $gateway->settings[ $id ],
|
||||||
|
'default' => empty( $field['default'] ) ? '' : $field['default'],
|
||||||
|
'tip' => empty( $field['description'] ) ? '' : $field['description'],
|
||||||
|
'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'],
|
||||||
|
);
|
||||||
|
if ( ! empty( $field['options'] ) ) {
|
||||||
|
$data['options'] = $field['options'];
|
||||||
|
}
|
||||||
|
$settings[ $id ] = $data;
|
||||||
|
}
|
||||||
|
return $settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare links for the request.
|
||||||
|
*
|
||||||
|
* @param WC_Payment_Gateway $gateway Payment gateway object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function prepare_links( $gateway, $request ) {
|
||||||
|
$links = array(
|
||||||
|
'self' => array(
|
||||||
|
'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $gateway->id ) ),
|
||||||
|
),
|
||||||
|
'collection' => array(
|
||||||
|
'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $links;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the payment gateway schema, conforming to JSON Schema.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => 'payment_gateway',
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Payment gateway ID.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'title' => array(
|
||||||
|
'description' => __( 'Payment gateway title on checkout.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'description' => array(
|
||||||
|
'description' => __( 'Payment gateway description on checkout.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'order' => array(
|
||||||
|
'description' => __( 'Payment gateway sort order.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'absint',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'enabled' => array(
|
||||||
|
'description' => __( 'Payment gateway enabled status.', 'woocommerce' ),
|
||||||
|
'type' => 'boolean',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'method_title' => array(
|
||||||
|
'description' => __( 'Payment gateway method title.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'method_description' => array(
|
||||||
|
'description' => __( 'Payment gateway method description.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'settings' => array(
|
||||||
|
'description' => __( 'Payment gateway settings.', 'woocommerce' ),
|
||||||
|
'type' => 'object',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'A unique identifier for the setting.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'label' => array(
|
||||||
|
'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'description' => array(
|
||||||
|
'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'type' => array(
|
||||||
|
'description' => __( 'Type of setting.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'value' => array(
|
||||||
|
'description' => __( 'Setting value.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'default' => array(
|
||||||
|
'description' => __( 'Default value for the setting.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'tip' => array(
|
||||||
|
'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'placeholder' => array(
|
||||||
|
'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get any query params needed.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_collection_params() {
|
||||||
|
return array(
|
||||||
|
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Product Attribute Terms controller
|
||||||
|
*
|
||||||
|
* Handles requests to the products/attributes/<attribute_id>/terms endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Product Attribute Terms controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Product_Attribute_Terms_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Product_Attribute_Terms_V2_Controller extends WC_REST_Product_Attribute_Terms_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Product Attributes controller
|
||||||
|
*
|
||||||
|
* Handles requests to the products/attributes endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Product Attributes controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Product_Attributes_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Product_Attributes_V2_Controller extends WC_REST_Product_Attributes_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
}
|
|
@ -0,0 +1,212 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Product Categories controller
|
||||||
|
*
|
||||||
|
* Handles requests to the products/categories endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Product Categories controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Product_Categories_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Product_Categories_V2_Controller extends WC_REST_Product_Categories_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a single product category output for response.
|
||||||
|
*
|
||||||
|
* @param WP_Term $item Term object.
|
||||||
|
* @param WP_REST_Request $request Request instance.
|
||||||
|
* @return WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $item, $request ) {
|
||||||
|
// Get category display type.
|
||||||
|
$display_type = get_woocommerce_term_meta( $item->term_id, 'display_type' );
|
||||||
|
|
||||||
|
// Get category order.
|
||||||
|
$menu_order = get_woocommerce_term_meta( $item->term_id, 'order' );
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'id' => (int) $item->term_id,
|
||||||
|
'name' => $item->name,
|
||||||
|
'slug' => $item->slug,
|
||||||
|
'parent' => (int) $item->parent,
|
||||||
|
'description' => $item->description,
|
||||||
|
'display' => $display_type ? $display_type : 'default',
|
||||||
|
'image' => null,
|
||||||
|
'menu_order' => (int) $menu_order,
|
||||||
|
'count' => (int) $item->count,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get category image.
|
||||||
|
$image_id = get_woocommerce_term_meta( $item->term_id, 'thumbnail_id' );
|
||||||
|
if ( $image_id ) {
|
||||||
|
$attachment = get_post( $image_id );
|
||||||
|
|
||||||
|
$data['image'] = array(
|
||||||
|
'id' => (int) $image_id,
|
||||||
|
'date_created' => wc_rest_prepare_date_response( $attachment->post_date ),
|
||||||
|
'date_created_gmt' => wc_rest_prepare_date_response( $attachment->post_date_gmt ),
|
||||||
|
'date_modified' => wc_rest_prepare_date_response( $attachment->post_modified ),
|
||||||
|
'date_modified_gmt' => wc_rest_prepare_date_response( $attachment->post_modified_gmt ),
|
||||||
|
'src' => wp_get_attachment_url( $image_id ),
|
||||||
|
'title' => get_the_title( $attachment ),
|
||||||
|
'alt' => get_post_meta( $image_id, '_wp_attachment_image_alt', true ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||||
|
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
$response->add_links( $this->prepare_links( $item, $request ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter a term item returned from the API.
|
||||||
|
*
|
||||||
|
* Allows modification of the term data right before it is returned.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Response $response The response object.
|
||||||
|
* @param object $item The original term object.
|
||||||
|
* @param WP_REST_Request $request Request used to generate the response.
|
||||||
|
*/
|
||||||
|
return apply_filters( "woocommerce_rest_prepare_{$this->taxonomy}", $response, $item, $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Category schema, conforming to JSON Schema.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => $this->taxonomy,
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'name' => array(
|
||||||
|
'description' => __( 'Category name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'slug' => array(
|
||||||
|
'description' => __( 'An alphanumeric identifier for the resource unique to its type.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_title',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'parent' => array(
|
||||||
|
'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'description' => array(
|
||||||
|
'description' => __( 'HTML description of the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'wp_filter_post_kses',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'display' => array(
|
||||||
|
'description' => __( 'Category archive display type.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'default' => 'default',
|
||||||
|
'enum' => array( 'default', 'products', 'subcategories', 'both' ),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'image' => array(
|
||||||
|
'description' => __( 'Image data.', 'woocommerce' ),
|
||||||
|
'type' => 'object',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Image ID.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'date_created' => array(
|
||||||
|
'description' => __( "The date the image was created, in the site's timezone.", 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_created_gmt' => array(
|
||||||
|
'description' => __( 'The date the image was created, as GMT.', 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_modified' => array(
|
||||||
|
'description' => __( "The date the image was last modified, in the site's timezone.", 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_modified_gmt' => array(
|
||||||
|
'description' => __( 'The date the image was last modified, as GMT.', 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'src' => array(
|
||||||
|
'description' => __( 'Image URL.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'format' => 'uri',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'title' => array(
|
||||||
|
'description' => __( 'Image name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'alt' => array(
|
||||||
|
'description' => __( 'Image alternative text.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'menu_order' => array(
|
||||||
|
'description' => __( 'Menu order, used to custom sort the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'count' => array(
|
||||||
|
'description' => __( 'Number of published products for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,199 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Product Reviews Controller
|
||||||
|
*
|
||||||
|
* Handles requests to /products/<product_id>/reviews.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Product Reviews Controller Class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Product_Reviews_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Product_Reviews_V2_Controller extends WC_REST_Product_Reviews_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route base.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $rest_base = 'products/(?P<product_id>[\d]+)/reviews';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the routes for product reviews.
|
||||||
|
*/
|
||||||
|
public function register_routes() {
|
||||||
|
parent::register_routes();
|
||||||
|
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base . '/batch', array(
|
||||||
|
'args' => array(
|
||||||
|
'product_id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the variable product.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::EDITABLE,
|
||||||
|
'callback' => array( $this, 'batch_items' ),
|
||||||
|
'permission_callback' => array( $this, 'batch_items_permissions_check' ),
|
||||||
|
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_batch_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given request has access to batch manage product reviews.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_Error|boolean
|
||||||
|
*/
|
||||||
|
public function batch_items_permissions_check( $request ) {
|
||||||
|
if ( ! wc_rest_check_post_permissions( 'product', 'batch' ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a single product review output for response.
|
||||||
|
*
|
||||||
|
* @param WP_Comment $review Product review object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response $response Response data.
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $review, $request ) {
|
||||||
|
$data = array(
|
||||||
|
'id' => (int) $review->comment_ID,
|
||||||
|
'date_created' => wc_rest_prepare_date_response( $review->comment_date ),
|
||||||
|
'date_created_gmt' => wc_rest_prepare_date_response( $review->comment_date_gmt ),
|
||||||
|
'review' => $review->comment_content,
|
||||||
|
'rating' => (int) get_comment_meta( $review->comment_ID, 'rating', true ),
|
||||||
|
'name' => $review->comment_author,
|
||||||
|
'email' => $review->comment_author_email,
|
||||||
|
'verified' => wc_review_is_from_verified_owner( $review->comment_ID ),
|
||||||
|
);
|
||||||
|
|
||||||
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||||
|
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
|
||||||
|
// Wrap the data in a response object.
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
$response->add_links( $this->prepare_links( $review, $request ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter product reviews object returned from the REST API.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Response $response The response object.
|
||||||
|
* @param WP_Comment $review Product review object used to create response.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
*/
|
||||||
|
return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bulk create, update and delete items.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return array Of WP_Error or WP_REST_Response.
|
||||||
|
*/
|
||||||
|
public function batch_items( $request ) {
|
||||||
|
$items = array_filter( $request->get_params() );
|
||||||
|
$params = $request->get_url_params();
|
||||||
|
$product_id = $params['product_id'];
|
||||||
|
$body_params = array();
|
||||||
|
|
||||||
|
foreach ( array( 'update', 'create', 'delete' ) as $batch_type ) {
|
||||||
|
if ( ! empty( $items[ $batch_type ] ) ) {
|
||||||
|
$injected_items = array();
|
||||||
|
foreach ( $items[ $batch_type ] as $item ) {
|
||||||
|
$injected_items[] = is_array( $item ) ? array_merge( array( 'product_id' => $product_id ), $item ) : $item;
|
||||||
|
}
|
||||||
|
$body_params[ $batch_type ] = $injected_items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$request = new WP_REST_Request( $request->get_method() );
|
||||||
|
$request->set_body_params( $body_params );
|
||||||
|
|
||||||
|
return parent::batch_items( $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Product Review's schema, conforming to JSON Schema.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => 'product_review',
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'review' => array(
|
||||||
|
'description' => __( 'The content of the review.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'date_created' => array(
|
||||||
|
'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'date_created_gmt' => array(
|
||||||
|
'description' => __( 'The date the review was created, as GMT.', 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'rating' => array(
|
||||||
|
'description' => __( 'Review rating (0 to 5).', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'name' => array(
|
||||||
|
'description' => __( 'Reviewer name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'email' => array(
|
||||||
|
'description' => __( 'Reviewer email.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'verified' => array(
|
||||||
|
'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ),
|
||||||
|
'type' => 'boolean',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Product Shipping Classes controller
|
||||||
|
*
|
||||||
|
* Handles requests to the products/shipping_classes endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Product Shipping Classes controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Product_Shipping_Classes_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Product_Shipping_Classes_V2_Controller extends WC_REST_Product_Shipping_Classes_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Product Tags controller
|
||||||
|
*
|
||||||
|
* Handles requests to the products/tags endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Product Tags controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Product_Tags_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Product_Tags_V2_Controller extends WC_REST_Product_Tags_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Reports controller
|
||||||
|
*
|
||||||
|
* Handles requests to the reports/sales endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Report Sales controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Report_Sales_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Report_Sales_V2_Controller extends WC_REST_Report_Sales_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Reports controller
|
||||||
|
*
|
||||||
|
* Handles requests to the reports/top_sellers endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Report Top Sellers controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Report_Top_Sellers_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Report_Top_Sellers_V2_Controller extends WC_REST_Report_Top_Sellers_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Reports controller
|
||||||
|
*
|
||||||
|
* Handles requests to the reports endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Reports controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Reports_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Reports_V2_Controller extends WC_REST_Reports_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
}
|
|
@ -0,0 +1,581 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Setting Options controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /settings/$group/$setting endpoints.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Setting Options controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Setting_Options_V2_Controller extends WC_REST_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WP REST API namespace/version.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route base.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $rest_base = 'settings/(?P<group_id>[\w-]+)';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register routes.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public function register_routes() {
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base, array(
|
||||||
|
'args' => array(
|
||||||
|
'group' => array(
|
||||||
|
'description' => __( 'Settings group ID.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_items' ),
|
||||||
|
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base . '/batch', array(
|
||||||
|
'args' => array(
|
||||||
|
'group' => array(
|
||||||
|
'description' => __( 'Settings group ID.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::EDITABLE,
|
||||||
|
'callback' => array( $this, 'batch_items' ),
|
||||||
|
'permission_callback' => array( $this, 'update_items_permissions_check' ),
|
||||||
|
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_batch_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base . '/(?P<id>[\w-]+)', array(
|
||||||
|
'args' => array(
|
||||||
|
'group' => array(
|
||||||
|
'description' => __( 'Settings group ID.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_item' ),
|
||||||
|
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::EDITABLE,
|
||||||
|
'callback' => array( $this, 'update_item' ),
|
||||||
|
'permission_callback' => array( $this, 'update_items_permissions_check' ),
|
||||||
|
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a single setting.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_Error|WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function get_item( $request ) {
|
||||||
|
$setting = $this->get_setting( $request['group_id'], $request['id'] );
|
||||||
|
|
||||||
|
if ( is_wp_error( $setting ) ) {
|
||||||
|
return $setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = $this->prepare_item_for_response( $setting, $request );
|
||||||
|
|
||||||
|
return rest_ensure_response( $response );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all settings in a group.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_Error|WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function get_items( $request ) {
|
||||||
|
$settings = $this->get_group_settings( $request['group_id'] );
|
||||||
|
|
||||||
|
if ( is_wp_error( $settings ) ) {
|
||||||
|
return $settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
foreach ( $settings as $setting_obj ) {
|
||||||
|
$setting = $this->prepare_item_for_response( $setting_obj, $request );
|
||||||
|
$setting = $this->prepare_response_for_collection( $setting );
|
||||||
|
if ( $this->is_setting_type_valid( $setting['type'] ) ) {
|
||||||
|
$data[] = $setting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rest_ensure_response( $data );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all settings in a group.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param string $group_id Group ID.
|
||||||
|
* @return array|WP_Error
|
||||||
|
*/
|
||||||
|
public function get_group_settings( $group_id ) {
|
||||||
|
if ( empty( $group_id ) ) {
|
||||||
|
return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$settings = apply_filters( 'woocommerce_settings-' . $group_id, array() );
|
||||||
|
|
||||||
|
if ( empty( $settings ) ) {
|
||||||
|
return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$filtered_settings = array();
|
||||||
|
foreach ( $settings as $setting ) {
|
||||||
|
$option_key = $setting['option_key'];
|
||||||
|
$setting = $this->filter_setting( $setting );
|
||||||
|
$default = isset( $setting['default'] ) ? $setting['default'] : '';
|
||||||
|
// Get the option value.
|
||||||
|
if ( is_array( $option_key ) ) {
|
||||||
|
$option = get_option( $option_key[0] );
|
||||||
|
$setting['value'] = isset( $option[ $option_key[1] ] ) ? $option[ $option_key[1] ] : $default;
|
||||||
|
} else {
|
||||||
|
$admin_setting_value = WC_Admin_Settings::get_option( $option_key, $default );
|
||||||
|
$setting['value'] = $admin_setting_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( 'multi_select_countries' === $setting['type'] ) {
|
||||||
|
$setting['options'] = WC()->countries->get_countries();
|
||||||
|
$setting['type'] = 'multiselect';
|
||||||
|
} elseif ( 'single_select_country' === $setting['type'] ) {
|
||||||
|
$setting['type'] = 'select';
|
||||||
|
$setting['options'] = $this->get_countries_and_states();
|
||||||
|
}
|
||||||
|
|
||||||
|
$filtered_settings[] = $setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $filtered_settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of countries and states for use in the base location setting.
|
||||||
|
*
|
||||||
|
* @since 3.0.7
|
||||||
|
* @return array Array of states and countries.
|
||||||
|
*/
|
||||||
|
private function get_countries_and_states() {
|
||||||
|
$countries = WC()->countries->get_countries();
|
||||||
|
if ( ! $countries ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$output = array();
|
||||||
|
|
||||||
|
foreach ( $countries as $key => $value ) {
|
||||||
|
$states = WC()->countries->get_states( $key );
|
||||||
|
if ( $states ) {
|
||||||
|
foreach ( $states as $state_key => $state_value ) {
|
||||||
|
$output[ $key . ':' . $state_key ] = $value . ' - ' . $state_value;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$output[ $key ] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get setting data.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param string $group_id Group ID.
|
||||||
|
* @param string $setting_id Setting ID.
|
||||||
|
* @return stdClass|WP_Error
|
||||||
|
*/
|
||||||
|
public function get_setting( $group_id, $setting_id ) {
|
||||||
|
if ( empty( $setting_id ) ) {
|
||||||
|
return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$settings = $this->get_group_settings( $group_id );
|
||||||
|
|
||||||
|
if ( is_wp_error( $settings ) ) {
|
||||||
|
return $settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
$array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id );
|
||||||
|
|
||||||
|
if ( empty( $array_key ) ) {
|
||||||
|
return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$setting = $settings[ $array_key[0] ];
|
||||||
|
|
||||||
|
if ( ! $this->is_setting_type_valid( $setting['type'] ) ) {
|
||||||
|
return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bulk create, update and delete items.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return array Of WP_Error or WP_REST_Response.
|
||||||
|
*/
|
||||||
|
public function batch_items( $request ) {
|
||||||
|
// Get the request params.
|
||||||
|
$items = array_filter( $request->get_params() );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since our batch settings update is group-specific and matches based on the route,
|
||||||
|
* we inject the URL parameters (containing group) into the batch items
|
||||||
|
*/
|
||||||
|
if ( ! empty( $items['update'] ) ) {
|
||||||
|
$to_update = array();
|
||||||
|
foreach ( $items['update'] as $item ) {
|
||||||
|
$to_update[] = array_merge( $request->get_url_params(), $item );
|
||||||
|
}
|
||||||
|
$request = new WP_REST_Request( $request->get_method() );
|
||||||
|
$request->set_body_params( array( 'update' => $to_update ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::batch_items( $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a single setting in a group.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_Error|WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function update_item( $request ) {
|
||||||
|
$setting = $this->get_setting( $request['group_id'], $request['id'] );
|
||||||
|
|
||||||
|
if ( is_wp_error( $setting ) ) {
|
||||||
|
return $setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_callable( array( $this, 'validate_setting_' . $setting['type'] . '_field' ) ) ) {
|
||||||
|
$value = $this->{'validate_setting_' . $setting['type'] . '_field'}( $request['value'], $setting );
|
||||||
|
} else {
|
||||||
|
$value = $this->validate_setting_text_field( $request['value'], $setting );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_wp_error( $value ) ) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_array( $setting['option_key'] ) ) {
|
||||||
|
$setting['value'] = $value;
|
||||||
|
$option_key = $setting['option_key'];
|
||||||
|
$prev = get_option( $option_key[0] );
|
||||||
|
$prev[ $option_key[1] ] = $request['value'];
|
||||||
|
update_option( $option_key[0], $prev );
|
||||||
|
} else {
|
||||||
|
$update_data = array();
|
||||||
|
$update_data[ $setting['option_key'] ] = $value;
|
||||||
|
$setting['value'] = $value;
|
||||||
|
WC_Admin_Settings::save_fields( array( $setting ), $update_data );
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = $this->prepare_item_for_response( $setting, $request );
|
||||||
|
|
||||||
|
return rest_ensure_response( $response );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a single setting object for response.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param object $item Setting object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response $response Response data.
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $item, $request ) {
|
||||||
|
unset( $item['option_key'] );
|
||||||
|
$data = $this->filter_setting( $item );
|
||||||
|
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, empty( $request['context'] ) ? 'view' : $request['context'] );
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
$response->add_links( $this->prepare_links( $data['id'], $request['group_id'] ) );
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare links for the request.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param string $setting_id Setting ID.
|
||||||
|
* @param string $group_id Group ID.
|
||||||
|
* @return array Links for the given setting.
|
||||||
|
*/
|
||||||
|
protected function prepare_links( $setting_id, $group_id ) {
|
||||||
|
$base = str_replace( '(?P<group_id>[\w-]+)', $group_id, $this->rest_base );
|
||||||
|
$links = array(
|
||||||
|
'self' => array(
|
||||||
|
'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $base, $setting_id ) ),
|
||||||
|
),
|
||||||
|
'collection' => array(
|
||||||
|
'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $links;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes sure the current user has access to READ the settings APIs.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WP_REST_Request $request Full data about the request.
|
||||||
|
* @return WP_Error|boolean
|
||||||
|
*/
|
||||||
|
public function get_items_permissions_check( $request ) {
|
||||||
|
if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes sure the current user has access to WRITE the settings APIs.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WP_REST_Request $request Full data about the request.
|
||||||
|
* @return WP_Error|boolean
|
||||||
|
*/
|
||||||
|
public function update_items_permissions_check( $request ) {
|
||||||
|
if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters out bad values from the settings array/filter so we
|
||||||
|
* only return known values via the API.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param array $setting Settings.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function filter_setting( $setting ) {
|
||||||
|
$setting = array_intersect_key(
|
||||||
|
$setting,
|
||||||
|
array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) )
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( empty( $setting['options'] ) ) {
|
||||||
|
unset( $setting['options'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( 'image_width' === $setting['type'] ) {
|
||||||
|
$setting = $this->cast_image_width( $setting );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For image_width, Crop can return "0" instead of false -- so we want
|
||||||
|
* to make sure we return these consistently the same we accept them.
|
||||||
|
*
|
||||||
|
* @todo remove in 4.0
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param array $setting Settings.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function cast_image_width( $setting ) {
|
||||||
|
foreach ( array( 'default', 'value' ) as $key ) {
|
||||||
|
if ( isset( $setting[ $key ] ) ) {
|
||||||
|
$setting[ $key ]['width'] = intval( $setting[ $key ]['width'] );
|
||||||
|
$setting[ $key ]['height'] = intval( $setting[ $key ]['height'] );
|
||||||
|
$setting[ $key ]['crop'] = (bool) $setting[ $key ]['crop'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for allowed keys for each setting response.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param string $key Key to check.
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function allowed_setting_keys( $key ) {
|
||||||
|
return in_array(
|
||||||
|
$key, array(
|
||||||
|
'id',
|
||||||
|
'label',
|
||||||
|
'description',
|
||||||
|
'default',
|
||||||
|
'tip',
|
||||||
|
'placeholder',
|
||||||
|
'type',
|
||||||
|
'options',
|
||||||
|
'value',
|
||||||
|
'option_key',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boolean for if a setting type is a valid supported setting type.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param string $type Type.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function is_setting_type_valid( $type ) {
|
||||||
|
return in_array(
|
||||||
|
$type, array(
|
||||||
|
'text', // Validates with validate_setting_text_field.
|
||||||
|
'email', // Validates with validate_setting_text_field.
|
||||||
|
'number', // Validates with validate_setting_text_field.
|
||||||
|
'color', // Validates with validate_setting_text_field.
|
||||||
|
'password', // Validates with validate_setting_text_field.
|
||||||
|
'textarea', // Validates with validate_setting_textarea_field.
|
||||||
|
'select', // Validates with validate_setting_select_field.
|
||||||
|
'multiselect', // Validates with validate_setting_multiselect_field.
|
||||||
|
'radio', // Validates with validate_setting_radio_field (-> validate_setting_select_field).
|
||||||
|
'checkbox', // Validates with validate_setting_checkbox_field.
|
||||||
|
'image_width', // Validates with validate_setting_image_width_field.
|
||||||
|
'thumbnail_cropping', // Validates with validate_setting_text_field.
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the settings schema, conforming to JSON Schema.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => 'setting',
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'A unique identifier for the setting.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_title',
|
||||||
|
),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'label' => array(
|
||||||
|
'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'description' => array(
|
||||||
|
'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'value' => array(
|
||||||
|
'description' => __( 'Setting value.', 'woocommerce' ),
|
||||||
|
'type' => 'mixed',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'default' => array(
|
||||||
|
'description' => __( 'Default value for the setting.', 'woocommerce' ),
|
||||||
|
'type' => 'mixed',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'tip' => array(
|
||||||
|
'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'placeholder' => array(
|
||||||
|
'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'type' => array(
|
||||||
|
'description' => __( 'Type of setting.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox', 'thumbnail_cropping' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'options' => array(
|
||||||
|
'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ),
|
||||||
|
'type' => 'object',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,232 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Settings controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /settings endpoints.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Settings controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Settings_V2_Controller extends WC_REST_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WP REST API namespace/version.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route base.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $rest_base = 'settings';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register routes.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
public function register_routes() {
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base, array(
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_items' ),
|
||||||
|
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all settings groups items.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_Error|WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function get_items( $request ) {
|
||||||
|
$groups = apply_filters( 'woocommerce_settings_groups', array() );
|
||||||
|
if ( empty( $groups ) ) {
|
||||||
|
return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$defaults = $this->group_defaults();
|
||||||
|
$filtered_groups = array();
|
||||||
|
foreach ( $groups as $group ) {
|
||||||
|
$sub_groups = array();
|
||||||
|
foreach ( $groups as $_group ) {
|
||||||
|
if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) {
|
||||||
|
$sub_groups[] = $_group['id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$group['sub_groups'] = $sub_groups;
|
||||||
|
|
||||||
|
$group = wp_parse_args( $group, $defaults );
|
||||||
|
if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) {
|
||||||
|
$group_obj = $this->filter_group( $group );
|
||||||
|
$group_data = $this->prepare_item_for_response( $group_obj, $request );
|
||||||
|
$group_data = $this->prepare_response_for_collection( $group_data );
|
||||||
|
|
||||||
|
$filtered_groups[] = $group_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = rest_ensure_response( $filtered_groups );
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare links for the request.
|
||||||
|
*
|
||||||
|
* @param string $group_id Group ID.
|
||||||
|
* @return array Links for the given group.
|
||||||
|
*/
|
||||||
|
protected function prepare_links( $group_id ) {
|
||||||
|
$base = '/' . $this->namespace . '/' . $this->rest_base;
|
||||||
|
$links = array(
|
||||||
|
'options' => array(
|
||||||
|
'href' => rest_url( trailingslashit( $base ) . $group_id ),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $links;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a report sales object for serialization.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param array $item Group object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response $response Response data.
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $item, $request ) {
|
||||||
|
$context = empty( $request['context'] ) ? 'view' : $request['context'];
|
||||||
|
$data = $this->add_additional_fields_to_object( $item, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
$response->add_links( $this->prepare_links( $item['id'] ) );
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters out bad values from the groups array/filter so we
|
||||||
|
* only return known values via the API.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param array $group Group.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function filter_group( $group ) {
|
||||||
|
return array_intersect_key(
|
||||||
|
$group,
|
||||||
|
array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for allowed keys for each group response.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param string $key Key to check.
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function allowed_group_keys( $key ) {
|
||||||
|
return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns default settings for groups. null means the field is required.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function group_defaults() {
|
||||||
|
return array(
|
||||||
|
'id' => null,
|
||||||
|
'label' => null,
|
||||||
|
'description' => '',
|
||||||
|
'parent_id' => '',
|
||||||
|
'sub_groups' => array(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes sure the current user has access to READ the settings APIs.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @param WP_REST_Request $request Full data about the request.
|
||||||
|
* @return WP_Error|boolean
|
||||||
|
*/
|
||||||
|
public function get_items_permissions_check( $request ) {
|
||||||
|
if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the groups schema, conforming to JSON Schema.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => 'setting_group',
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'label' => array(
|
||||||
|
'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'description' => array(
|
||||||
|
'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'parent_id' => array(
|
||||||
|
'description' => __( 'ID of parent grouping.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'sub_groups' => array(
|
||||||
|
'description' => __( 'IDs for settings sub groups.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,231 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API WC Shipping Methods controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /shipping_methods endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shipping methods controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Shipping_Methods_V2_Controller extends WC_REST_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route base.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $rest_base = 'shipping_methods';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the route for /shipping_methods and /shipping_methods/<method>
|
||||||
|
*/
|
||||||
|
public function register_routes() {
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base, array(
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_items' ),
|
||||||
|
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||||
|
'args' => $this->get_collection_params(),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base . '/(?P<id>[\w-]+)', array(
|
||||||
|
'args' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_item' ),
|
||||||
|
'permission_callback' => array( $this, 'get_item_permissions_check' ),
|
||||||
|
'args' => array(
|
||||||
|
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a given request has permission to view shipping methods.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_Error|boolean
|
||||||
|
*/
|
||||||
|
public function get_items_permissions_check( $request ) {
|
||||||
|
if ( ! wc_rest_check_manager_permissions( 'shipping_methods', 'read' ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given request has access to read a shipping method.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_Error|boolean
|
||||||
|
*/
|
||||||
|
public function get_item_permissions_check( $request ) {
|
||||||
|
if ( ! wc_rest_check_manager_permissions( 'shipping_methods', 'read' ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get shipping methods.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_Error|WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function get_items( $request ) {
|
||||||
|
$wc_shipping = WC_Shipping::instance();
|
||||||
|
$response = array();
|
||||||
|
foreach ( $wc_shipping->get_shipping_methods() as $id => $shipping_method ) {
|
||||||
|
$method = $this->prepare_item_for_response( $shipping_method, $request );
|
||||||
|
$method = $this->prepare_response_for_collection( $method );
|
||||||
|
$response[] = $method;
|
||||||
|
}
|
||||||
|
return rest_ensure_response( $response );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a single Shipping Method.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_REST_Response|WP_Error
|
||||||
|
*/
|
||||||
|
public function get_item( $request ) {
|
||||||
|
$wc_shipping = WC_Shipping::instance();
|
||||||
|
$methods = $wc_shipping->get_shipping_methods();
|
||||||
|
if ( empty( $methods[ $request['id'] ] ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_shipping_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$method = $methods[ $request['id'] ];
|
||||||
|
$response = $this->prepare_item_for_response( $method, $request );
|
||||||
|
|
||||||
|
return rest_ensure_response( $response );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a shipping method for response.
|
||||||
|
*
|
||||||
|
* @param WC_Shipping_Method $method Shipping method object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response $response Response data.
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $method, $request ) {
|
||||||
|
$data = array(
|
||||||
|
'id' => $method->id,
|
||||||
|
'title' => $method->method_title,
|
||||||
|
'description' => $method->method_description,
|
||||||
|
);
|
||||||
|
|
||||||
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||||
|
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
|
||||||
|
// Wrap the data in a response object.
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
$response->add_links( $this->prepare_links( $method, $request ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter shipping methods object returned from the REST API.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Response $response The response object.
|
||||||
|
* @param WC_Shipping_Method $method Shipping method object used to create response.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
*/
|
||||||
|
return apply_filters( 'woocommerce_rest_prepare_shipping_method', $response, $method, $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare links for the request.
|
||||||
|
*
|
||||||
|
* @param WC_Shipping_Method $method Shipping method object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function prepare_links( $method, $request ) {
|
||||||
|
$links = array(
|
||||||
|
'self' => array(
|
||||||
|
'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $method->id ) ),
|
||||||
|
),
|
||||||
|
'collection' => array(
|
||||||
|
'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $links;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the shipping method schema, conforming to JSON Schema.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => 'shipping_method',
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Method ID.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'title' => array(
|
||||||
|
'description' => __( 'Shipping method title.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'description' => array(
|
||||||
|
'description' => __( 'Shipping method description.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get any query params needed.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_collection_params() {
|
||||||
|
return array(
|
||||||
|
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,190 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Shipping Zone Locations controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /shipping/zones/<id>/locations endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Shipping Zone Locations class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Shipping_Zones_Controller_Base
|
||||||
|
*/
|
||||||
|
class WC_REST_Shipping_Zone_Locations_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the routes for Shipping Zone Locations.
|
||||||
|
*/
|
||||||
|
public function register_routes() {
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)/locations', array(
|
||||||
|
'args' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique ID for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_items' ),
|
||||||
|
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::EDITABLE,
|
||||||
|
'callback' => array( $this, 'update_items' ),
|
||||||
|
'permission_callback' => array( $this, 'update_items_permissions_check' ),
|
||||||
|
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all Shipping Zone Locations.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_REST_Response|WP_Error
|
||||||
|
*/
|
||||||
|
public function get_items( $request ) {
|
||||||
|
$zone = $this->get_zone( (int) $request['id'] );
|
||||||
|
|
||||||
|
if ( is_wp_error( $zone ) ) {
|
||||||
|
return $zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
$locations = $zone->get_zone_locations();
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
foreach ( $locations as $location_obj ) {
|
||||||
|
$location = $this->prepare_item_for_response( $location_obj, $request );
|
||||||
|
$location = $this->prepare_response_for_collection( $location );
|
||||||
|
$data[] = $location;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rest_ensure_response( $data );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update all Shipping Zone Locations.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_REST_Response|WP_Error
|
||||||
|
*/
|
||||||
|
public function update_items( $request ) {
|
||||||
|
$zone = $this->get_zone( (int) $request['id'] );
|
||||||
|
|
||||||
|
if ( is_wp_error( $zone ) ) {
|
||||||
|
return $zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( 0 === $zone->get_id() ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_shipping_zone_locations_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$raw_locations = $request->get_json_params();
|
||||||
|
$locations = array();
|
||||||
|
|
||||||
|
foreach ( (array) $raw_locations as $raw_location ) {
|
||||||
|
if ( empty( $raw_location['code'] ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$type = ! empty( $raw_location['type'] ) ? sanitize_text_field( $raw_location['type'] ) : 'country';
|
||||||
|
|
||||||
|
if ( ! in_array( $type, array( 'postcode', 'state', 'country', 'continent' ), true ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$locations[] = array(
|
||||||
|
'code' => sanitize_text_field( $raw_location['code'] ),
|
||||||
|
'type' => sanitize_text_field( $type ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$zone->set_locations( $locations );
|
||||||
|
$zone->save();
|
||||||
|
|
||||||
|
return $this->get_items( $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare the Shipping Zone Location for the REST response.
|
||||||
|
*
|
||||||
|
* @param array $item Shipping Zone Location.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response $response
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $item, $request ) {
|
||||||
|
$context = empty( $request['context'] ) ? 'view' : $request['context'];
|
||||||
|
$data = $this->add_additional_fields_to_object( $item, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
|
||||||
|
// Wrap the data in a response object.
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
$response->add_links( $this->prepare_links( (int) $request['id'] ) );
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare links for the request.
|
||||||
|
*
|
||||||
|
* @param int $zone_id Given Shipping Zone ID.
|
||||||
|
* @return array Links for the given Shipping Zone Location.
|
||||||
|
*/
|
||||||
|
protected function prepare_links( $zone_id ) {
|
||||||
|
$base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id;
|
||||||
|
$links = array(
|
||||||
|
'collection' => array(
|
||||||
|
'href' => rest_url( $base . '/locations' ),
|
||||||
|
),
|
||||||
|
'describes' => array(
|
||||||
|
'href' => rest_url( $base ),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $links;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Shipping Zone Locations schema, conforming to JSON Schema
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => 'shipping_zone_location',
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'code' => array(
|
||||||
|
'description' => __( 'Shipping zone location code.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'type' => array(
|
||||||
|
'description' => __( 'Shipping zone location type.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'default' => 'country',
|
||||||
|
'enum' => array(
|
||||||
|
'postcode',
|
||||||
|
'state',
|
||||||
|
'country',
|
||||||
|
'continent',
|
||||||
|
),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,541 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Shipping Zone Methods controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /shipping/zones/<id>/methods endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Shipping Zone Methods class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Shipping_Zones_Controller_Base
|
||||||
|
*/
|
||||||
|
class WC_REST_Shipping_Zone_Methods_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the routes for Shipping Zone Methods.
|
||||||
|
*/
|
||||||
|
public function register_routes() {
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base . '/(?P<zone_id>[\d]+)/methods', array(
|
||||||
|
'args' => array(
|
||||||
|
'zone_id' => array(
|
||||||
|
'description' => __( 'Unique ID for the zone.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_items' ),
|
||||||
|
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::CREATABLE,
|
||||||
|
'callback' => array( $this, 'create_item' ),
|
||||||
|
'permission_callback' => array( $this, 'create_item_permissions_check' ),
|
||||||
|
'args' => array_merge(
|
||||||
|
$this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array(
|
||||||
|
'method_id' => array(
|
||||||
|
'required' => true,
|
||||||
|
'readonly' => false,
|
||||||
|
'description' => __( 'Shipping method ID.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base . '/(?P<zone_id>[\d]+)/methods/(?P<instance_id>[\d]+)', array(
|
||||||
|
'args' => array(
|
||||||
|
'zone_id' => array(
|
||||||
|
'description' => __( 'Unique ID for the zone.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
'instance_id' => array(
|
||||||
|
'description' => __( 'Unique ID for the instance.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_item' ),
|
||||||
|
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::EDITABLE,
|
||||||
|
'callback' => array( $this, 'update_item' ),
|
||||||
|
'permission_callback' => array( $this, 'update_items_permissions_check' ),
|
||||||
|
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::DELETABLE,
|
||||||
|
'callback' => array( $this, 'delete_item' ),
|
||||||
|
'permission_callback' => array( $this, 'delete_items_permissions_check' ),
|
||||||
|
'args' => array(
|
||||||
|
'force' => array(
|
||||||
|
'default' => false,
|
||||||
|
'type' => 'boolean',
|
||||||
|
'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a single Shipping Zone Method.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_REST_Response|WP_Error
|
||||||
|
*/
|
||||||
|
public function get_item( $request ) {
|
||||||
|
$zone = $this->get_zone( $request['zone_id'] );
|
||||||
|
|
||||||
|
if ( is_wp_error( $zone ) ) {
|
||||||
|
return $zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
$instance_id = (int) $request['instance_id'];
|
||||||
|
$methods = $zone->get_shipping_methods();
|
||||||
|
$method = false;
|
||||||
|
|
||||||
|
foreach ( $methods as $method_obj ) {
|
||||||
|
if ( $instance_id === $method_obj->instance_id ) {
|
||||||
|
$method = $method_obj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( false === $method ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->prepare_item_for_response( $method, $request );
|
||||||
|
|
||||||
|
return rest_ensure_response( $data );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all Shipping Zone Methods.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_REST_Response|WP_Error
|
||||||
|
*/
|
||||||
|
public function get_items( $request ) {
|
||||||
|
$zone = $this->get_zone( $request['zone_id'] );
|
||||||
|
|
||||||
|
if ( is_wp_error( $zone ) ) {
|
||||||
|
return $zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
$methods = $zone->get_shipping_methods();
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
foreach ( $methods as $method_obj ) {
|
||||||
|
$method = $this->prepare_item_for_response( $method_obj, $request );
|
||||||
|
$data[] = $method;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rest_ensure_response( $data );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new shipping zone method instance.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_REST_Request|WP_Error
|
||||||
|
*/
|
||||||
|
public function create_item( $request ) {
|
||||||
|
$method_id = $request['method_id'];
|
||||||
|
$zone = $this->get_zone( $request['zone_id'] );
|
||||||
|
if ( is_wp_error( $zone ) ) {
|
||||||
|
return $zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
$instance_id = $zone->add_shipping_method( $method_id );
|
||||||
|
$methods = $zone->get_shipping_methods();
|
||||||
|
$method = false;
|
||||||
|
foreach ( $methods as $method_obj ) {
|
||||||
|
if ( $instance_id === $method_obj->instance_id ) {
|
||||||
|
$method = $method_obj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( false === $method ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( 'Resource cannot be created.', 'woocommerce' ), array( 'status' => 500 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$method = $this->update_fields( $instance_id, $method, $request );
|
||||||
|
if ( is_wp_error( $method ) ) {
|
||||||
|
return $method;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->prepare_item_for_response( $method, $request );
|
||||||
|
return rest_ensure_response( $data );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a shipping method instance.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_Error|boolean
|
||||||
|
*/
|
||||||
|
public function delete_item( $request ) {
|
||||||
|
$zone = $this->get_zone( $request['zone_id'] );
|
||||||
|
if ( is_wp_error( $zone ) ) {
|
||||||
|
return $zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
$instance_id = (int) $request['instance_id'];
|
||||||
|
$force = $request['force'];
|
||||||
|
|
||||||
|
$methods = $zone->get_shipping_methods();
|
||||||
|
$method = false;
|
||||||
|
|
||||||
|
foreach ( $methods as $method_obj ) {
|
||||||
|
if ( $instance_id === $method_obj->instance_id ) {
|
||||||
|
$method = $method_obj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( false === $method ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$method = $this->update_fields( $instance_id, $method, $request );
|
||||||
|
if ( is_wp_error( $method ) ) {
|
||||||
|
return $method;
|
||||||
|
}
|
||||||
|
|
||||||
|
$request->set_param( 'context', 'view' );
|
||||||
|
$response = $this->prepare_item_for_response( $method, $request );
|
||||||
|
|
||||||
|
// Actually delete.
|
||||||
|
if ( $force ) {
|
||||||
|
$zone->delete_shipping_method( $instance_id );
|
||||||
|
} else {
|
||||||
|
return new WP_Error( 'rest_trash_not_supported', __( 'Shipping methods do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires after a product review is deleted via the REST API.
|
||||||
|
*
|
||||||
|
* @param object $method
|
||||||
|
* @param WP_REST_Response $response The response data.
|
||||||
|
* @param WP_REST_Request $request The request sent to the API.
|
||||||
|
*/
|
||||||
|
do_action( 'rest_delete_product_review', $method, $response, $request );
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update A Single Shipping Zone Method.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_REST_Response|WP_Error
|
||||||
|
*/
|
||||||
|
public function update_item( $request ) {
|
||||||
|
$zone = $this->get_zone( $request['zone_id'] );
|
||||||
|
if ( is_wp_error( $zone ) ) {
|
||||||
|
return $zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
$instance_id = (int) $request['instance_id'];
|
||||||
|
$methods = $zone->get_shipping_methods();
|
||||||
|
$method = false;
|
||||||
|
|
||||||
|
foreach ( $methods as $method_obj ) {
|
||||||
|
if ( $instance_id === $method_obj->instance_id ) {
|
||||||
|
$method = $method_obj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( false === $method ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( 'Resource does not exist.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$method = $this->update_fields( $instance_id, $method, $request );
|
||||||
|
if ( is_wp_error( $method ) ) {
|
||||||
|
return $method;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->prepare_item_for_response( $method, $request );
|
||||||
|
return rest_ensure_response( $data );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates settings, order, and enabled status on create.
|
||||||
|
*
|
||||||
|
* @param int $instance_id Instance ID.
|
||||||
|
* @param WC_Shipping_Method $method Shipping method data.
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
*
|
||||||
|
* @return WC_Shipping_Method
|
||||||
|
*/
|
||||||
|
public function update_fields( $instance_id, $method, $request ) {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
// Update settings if present.
|
||||||
|
if ( isset( $request['settings'] ) ) {
|
||||||
|
$method->init_instance_settings();
|
||||||
|
$instance_settings = $method->instance_settings;
|
||||||
|
$errors_found = false;
|
||||||
|
foreach ( $method->get_instance_form_fields() as $key => $field ) {
|
||||||
|
if ( isset( $request['settings'][ $key ] ) ) {
|
||||||
|
if ( is_callable( array( $this, 'validate_setting_' . $field['type'] . '_field' ) ) ) {
|
||||||
|
$value = $this->{'validate_setting_' . $field['type'] . '_field'}( $request['settings'][ $key ], $field );
|
||||||
|
} else {
|
||||||
|
$value = $this->validate_setting_text_field( $request['settings'][ $key ], $field );
|
||||||
|
}
|
||||||
|
if ( is_wp_error( $value ) ) {
|
||||||
|
$errors_found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$instance_settings[ $key ] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $errors_found ) {
|
||||||
|
return new WP_Error( 'rest_setting_value_invalid', __( 'An invalid setting value was passed.', 'woocommerce' ), array( 'status' => 400 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
update_option( $method->get_instance_option_key(), apply_filters( 'woocommerce_shipping_' . $method->id . '_instance_settings_values', $instance_settings, $method ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update order.
|
||||||
|
if ( isset( $request['order'] ) ) {
|
||||||
|
$wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'method_order' => absint( $request['order'] ) ), array( 'instance_id' => absint( $instance_id ) ) );
|
||||||
|
$method->method_order = absint( $request['order'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update if this method is enabled or not.
|
||||||
|
if ( isset( $request['enabled'] ) ) {
|
||||||
|
if ( $wpdb->update( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'is_enabled' => $request['enabled'] ), array( 'instance_id' => absint( $instance_id ) ) ) ) {
|
||||||
|
do_action( 'woocommerce_shipping_zone_method_status_toggled', $instance_id, $method->id, $request['zone_id'], $request['enabled'] );
|
||||||
|
$method->enabled = ( true === $request['enabled'] ? 'yes' : 'no' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $method;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare the Shipping Zone Method for the REST response.
|
||||||
|
*
|
||||||
|
* @param array $item Shipping Zone Method.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response $response
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $item, $request ) {
|
||||||
|
$method = array(
|
||||||
|
'id' => $item->instance_id,
|
||||||
|
'instance_id' => $item->instance_id,
|
||||||
|
'title' => $item->instance_settings['title'],
|
||||||
|
'order' => $item->method_order,
|
||||||
|
'enabled' => ( 'yes' === $item->enabled ),
|
||||||
|
'method_id' => $item->id,
|
||||||
|
'method_title' => $item->method_title,
|
||||||
|
'method_description' => $item->method_description,
|
||||||
|
'settings' => $this->get_settings( $item ),
|
||||||
|
);
|
||||||
|
|
||||||
|
$context = empty( $request['context'] ) ? 'view' : $request['context'];
|
||||||
|
$data = $this->add_additional_fields_to_object( $method, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
|
||||||
|
// Wrap the data in a response object.
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
$response->add_links( $this->prepare_links( $request['zone_id'], $item->instance_id ) );
|
||||||
|
|
||||||
|
$response = $this->prepare_response_for_collection( $response );
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return settings associated with this shipping zone method instance.
|
||||||
|
*
|
||||||
|
* @param WC_Shipping_Method $item Shipping method data.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_settings( $item ) {
|
||||||
|
$item->init_instance_settings();
|
||||||
|
$settings = array();
|
||||||
|
foreach ( $item->get_instance_form_fields() as $id => $field ) {
|
||||||
|
$data = array(
|
||||||
|
'id' => $id,
|
||||||
|
'label' => $field['title'],
|
||||||
|
'description' => empty( $field['description'] ) ? '' : $field['description'],
|
||||||
|
'type' => $field['type'],
|
||||||
|
'value' => $item->instance_settings[ $id ],
|
||||||
|
'default' => empty( $field['default'] ) ? '' : $field['default'],
|
||||||
|
'tip' => empty( $field['description'] ) ? '' : $field['description'],
|
||||||
|
'placeholder' => empty( $field['placeholder'] ) ? '' : $field['placeholder'],
|
||||||
|
);
|
||||||
|
if ( ! empty( $field['options'] ) ) {
|
||||||
|
$data['options'] = $field['options'];
|
||||||
|
}
|
||||||
|
$settings[ $id ] = $data;
|
||||||
|
}
|
||||||
|
return $settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare links for the request.
|
||||||
|
*
|
||||||
|
* @param int $zone_id Given Shipping Zone ID.
|
||||||
|
* @param int $instance_id Given Shipping Zone Method Instance ID.
|
||||||
|
* @return array Links for the given Shipping Zone Method.
|
||||||
|
*/
|
||||||
|
protected function prepare_links( $zone_id, $instance_id ) {
|
||||||
|
$base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id;
|
||||||
|
$links = array(
|
||||||
|
'self' => array(
|
||||||
|
'href' => rest_url( $base . '/methods/' . $instance_id ),
|
||||||
|
),
|
||||||
|
'collection' => array(
|
||||||
|
'href' => rest_url( $base . '/methods' ),
|
||||||
|
),
|
||||||
|
'describes' => array(
|
||||||
|
'href' => rest_url( $base ),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $links;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Shipping Zone Methods schema, conforming to JSON Schema
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => 'shipping_zone_method',
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Shipping method instance ID.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'instance_id' => array(
|
||||||
|
'description' => __( 'Shipping method instance ID.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'title' => array(
|
||||||
|
'description' => __( 'Shipping method customer facing title.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'order' => array(
|
||||||
|
'description' => __( 'Shipping method sort order.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'enabled' => array(
|
||||||
|
'description' => __( 'Shipping method enabled status.', 'woocommerce' ),
|
||||||
|
'type' => 'boolean',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'method_id' => array(
|
||||||
|
'description' => __( 'Shipping method ID.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'method_title' => array(
|
||||||
|
'description' => __( 'Shipping method title.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'method_description' => array(
|
||||||
|
'description' => __( 'Shipping method description.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'settings' => array(
|
||||||
|
'description' => __( 'Shipping method settings.', 'woocommerce' ),
|
||||||
|
'type' => 'object',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'A unique identifier for the setting.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'label' => array(
|
||||||
|
'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'description' => array(
|
||||||
|
'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'type' => array(
|
||||||
|
'description' => __( 'Type of setting.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'value' => array(
|
||||||
|
'description' => __( 'Setting value.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'default' => array(
|
||||||
|
'description' => __( 'Default value for the setting.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'tip' => array(
|
||||||
|
'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'placeholder' => array(
|
||||||
|
'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,304 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Shipping Zones controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /shipping/zones endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Shipping Zones class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Shipping_Zones_Controller_Base
|
||||||
|
*/
|
||||||
|
class WC_REST_Shipping_Zones_V2_Controller extends WC_REST_Shipping_Zones_Controller_Base {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the routes for Shipping Zones.
|
||||||
|
*/
|
||||||
|
public function register_routes() {
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base, array(
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_items' ),
|
||||||
|
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::CREATABLE,
|
||||||
|
'callback' => array( $this, 'create_item' ),
|
||||||
|
'permission_callback' => array( $this, 'create_item_permissions_check' ),
|
||||||
|
'args' => array_merge(
|
||||||
|
$this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array(
|
||||||
|
'name' => array(
|
||||||
|
'required' => true,
|
||||||
|
'type' => 'string',
|
||||||
|
'description' => __( 'Shipping zone name.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base . '/(?P<id>[\d-]+)', array(
|
||||||
|
'args' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique ID for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_item' ),
|
||||||
|
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::EDITABLE,
|
||||||
|
'callback' => array( $this, 'update_item' ),
|
||||||
|
'permission_callback' => array( $this, 'update_items_permissions_check' ),
|
||||||
|
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::DELETABLE,
|
||||||
|
'callback' => array( $this, 'delete_item' ),
|
||||||
|
'permission_callback' => array( $this, 'delete_items_permissions_check' ),
|
||||||
|
'args' => array(
|
||||||
|
'force' => array(
|
||||||
|
'default' => false,
|
||||||
|
'type' => 'boolean',
|
||||||
|
'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a single Shipping Zone.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_REST_Response|WP_Error
|
||||||
|
*/
|
||||||
|
public function get_item( $request ) {
|
||||||
|
$zone = $this->get_zone( $request->get_param( 'id' ) );
|
||||||
|
|
||||||
|
if ( is_wp_error( $zone ) ) {
|
||||||
|
return $zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $zone->get_data();
|
||||||
|
$data = $this->prepare_item_for_response( $data, $request );
|
||||||
|
$data = $this->prepare_response_for_collection( $data );
|
||||||
|
|
||||||
|
return rest_ensure_response( $data );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all Shipping Zones.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function get_items( $request ) {
|
||||||
|
$rest_of_the_world = WC_Shipping_Zones::get_zone_by( 'zone_id', 0 );
|
||||||
|
|
||||||
|
$zones = WC_Shipping_Zones::get_zones();
|
||||||
|
array_unshift( $zones, $rest_of_the_world->get_data() );
|
||||||
|
$data = array();
|
||||||
|
|
||||||
|
foreach ( $zones as $zone_obj ) {
|
||||||
|
$zone = $this->prepare_item_for_response( $zone_obj, $request );
|
||||||
|
$zone = $this->prepare_response_for_collection( $zone );
|
||||||
|
$data[] = $zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rest_ensure_response( $data );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a single Shipping Zone.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_REST_Request|WP_Error
|
||||||
|
*/
|
||||||
|
public function create_item( $request ) {
|
||||||
|
$zone = new WC_Shipping_Zone( null );
|
||||||
|
|
||||||
|
if ( ! is_null( $request->get_param( 'name' ) ) ) {
|
||||||
|
$zone->set_zone_name( $request->get_param( 'name' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! is_null( $request->get_param( 'order' ) ) ) {
|
||||||
|
$zone->set_zone_order( $request->get_param( 'order' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$zone->save();
|
||||||
|
|
||||||
|
if ( $zone->get_id() !== 0 ) {
|
||||||
|
$request->set_param( 'id', $zone->get_id() );
|
||||||
|
$response = $this->get_item( $request );
|
||||||
|
$response->set_status( 201 );
|
||||||
|
$response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id() ) ) );
|
||||||
|
return $response;
|
||||||
|
} else {
|
||||||
|
return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce' ), array( 'status' => 500 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a single Shipping Zone.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_REST_Request|WP_Error
|
||||||
|
*/
|
||||||
|
public function update_item( $request ) {
|
||||||
|
$zone = $this->get_zone( $request->get_param( 'id' ) );
|
||||||
|
|
||||||
|
if ( is_wp_error( $zone ) ) {
|
||||||
|
return $zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( 0 === $zone->get_id() ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce' ), array( 'status' => 403 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$zone_changed = false;
|
||||||
|
|
||||||
|
if ( ! is_null( $request->get_param( 'name' ) ) ) {
|
||||||
|
$zone->set_zone_name( $request->get_param( 'name' ) );
|
||||||
|
$zone_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! is_null( $request->get_param( 'order' ) ) ) {
|
||||||
|
$zone->set_zone_order( $request->get_param( 'order' ) );
|
||||||
|
$zone_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $zone_changed ) {
|
||||||
|
$zone->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->get_item( $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a single Shipping Zone.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_REST_Request|WP_Error
|
||||||
|
*/
|
||||||
|
public function delete_item( $request ) {
|
||||||
|
$zone = $this->get_zone( $request->get_param( 'id' ) );
|
||||||
|
|
||||||
|
if ( is_wp_error( $zone ) ) {
|
||||||
|
return $zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
$force = $request['force'];
|
||||||
|
|
||||||
|
$response = $this->get_item( $request );
|
||||||
|
|
||||||
|
if ( $force ) {
|
||||||
|
$zone->delete();
|
||||||
|
} else {
|
||||||
|
return new WP_Error( 'rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare the Shipping Zone for the REST response.
|
||||||
|
*
|
||||||
|
* @param array $item Shipping Zone.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response $response
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $item, $request ) {
|
||||||
|
$data = array(
|
||||||
|
'id' => (int) $item['id'],
|
||||||
|
'name' => $item['zone_name'],
|
||||||
|
'order' => (int) $item['zone_order'],
|
||||||
|
);
|
||||||
|
|
||||||
|
$context = empty( $request['context'] ) ? 'view' : $request['context'];
|
||||||
|
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
|
||||||
|
// Wrap the data in a response object.
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
$response->add_links( $this->prepare_links( $data['id'] ) );
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare links for the request.
|
||||||
|
*
|
||||||
|
* @param int $zone_id Given Shipping Zone ID.
|
||||||
|
* @return array Links for the given Shipping Zone.
|
||||||
|
*/
|
||||||
|
protected function prepare_links( $zone_id ) {
|
||||||
|
$base = '/' . $this->namespace . '/' . $this->rest_base;
|
||||||
|
$links = array(
|
||||||
|
'self' => array(
|
||||||
|
'href' => rest_url( trailingslashit( $base ) . $zone_id ),
|
||||||
|
),
|
||||||
|
'collection' => array(
|
||||||
|
'href' => rest_url( $base ),
|
||||||
|
),
|
||||||
|
'describedby' => array(
|
||||||
|
'href' => rest_url( trailingslashit( $base ) . $zone_id . '/locations' ),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $links;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Shipping Zones schema, conforming to JSON Schema
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => 'shipping_zone',
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'name' => array(
|
||||||
|
'description' => __( 'Shipping zone name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'order' => array(
|
||||||
|
'description' => __( 'Shipping zone order.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,557 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API WC System Status Tools Controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /system_status/tools/* endpoints.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 3.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* System status tools controller.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route base.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $rest_base = 'system_status/tools';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the routes for /system_status/tools/*.
|
||||||
|
*/
|
||||||
|
public function register_routes() {
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base, array(
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_items' ),
|
||||||
|
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||||
|
'args' => $this->get_collection_params(),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
register_rest_route(
|
||||||
|
$this->namespace, '/' . $this->rest_base . '/(?P<id>[\w-]+)', array(
|
||||||
|
'args' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::READABLE,
|
||||||
|
'callback' => array( $this, 'get_item' ),
|
||||||
|
'permission_callback' => array( $this, 'get_item_permissions_check' ),
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::EDITABLE,
|
||||||
|
'callback' => array( $this, 'update_item' ),
|
||||||
|
'permission_callback' => array( $this, 'update_item_permissions_check' ),
|
||||||
|
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
|
||||||
|
),
|
||||||
|
'schema' => array( $this, 'get_public_item_schema' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a given request has permission to view system status tools.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_Error|boolean
|
||||||
|
*/
|
||||||
|
public function get_items_permissions_check( $request ) {
|
||||||
|
if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a given request has permission to view a specific system status tool.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_Error|boolean
|
||||||
|
*/
|
||||||
|
public function get_item_permissions_check( $request ) {
|
||||||
|
if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a given request has permission to execute a specific system status tool.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_Error|boolean
|
||||||
|
*/
|
||||||
|
public function update_item_permissions_check( $request ) {
|
||||||
|
if ( ! wc_rest_check_manager_permissions( 'system_status', 'edit' ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of available tools for use in the system status section.
|
||||||
|
* 'button' becomes 'action' in the API.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_tools() {
|
||||||
|
$tools = array(
|
||||||
|
'clear_transients' => array(
|
||||||
|
'name' => __( 'WooCommerce transients', 'woocommerce' ),
|
||||||
|
'button' => __( 'Clear transients', 'woocommerce' ),
|
||||||
|
'desc' => __( 'This tool will clear the product/shop transients cache.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
'clear_expired_transients' => array(
|
||||||
|
'name' => __( 'Expired transients', 'woocommerce' ),
|
||||||
|
'button' => __( 'Clear transients', 'woocommerce' ),
|
||||||
|
'desc' => __( 'This tool will clear ALL expired transients from WordPress.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
'delete_orphaned_variations' => array(
|
||||||
|
'name' => __( 'Orphaned variations', 'woocommerce' ),
|
||||||
|
'button' => __( 'Delete orphaned variations', 'woocommerce' ),
|
||||||
|
'desc' => __( 'This tool will delete all variations which have no parent.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
'clear_expired_download_permissions' => array(
|
||||||
|
'name' => __( 'Used-up download permissions', 'woocommerce' ),
|
||||||
|
'button' => __( 'Clean up download permissions', 'woocommerce' ),
|
||||||
|
'desc' => __( 'This tool will delete expired download permissions and permissions with 0 remaining downloads.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
'add_order_indexes' => array(
|
||||||
|
'name' => __( 'Order address indexes', 'woocommerce' ),
|
||||||
|
'button' => __( 'Index orders', 'woocommerce' ),
|
||||||
|
'desc' => __( 'This tool will add address indexes to orders that do not have them yet. This improves order search results.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
'recount_terms' => array(
|
||||||
|
'name' => __( 'Term counts', 'woocommerce' ),
|
||||||
|
'button' => __( 'Recount terms', 'woocommerce' ),
|
||||||
|
'desc' => __( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
'reset_roles' => array(
|
||||||
|
'name' => __( 'Capabilities', 'woocommerce' ),
|
||||||
|
'button' => __( 'Reset capabilities', 'woocommerce' ),
|
||||||
|
'desc' => __( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
'clear_sessions' => array(
|
||||||
|
'name' => __( 'Clear customer sessions', 'woocommerce' ),
|
||||||
|
'button' => __( 'Clear', 'woocommerce' ),
|
||||||
|
'desc' => sprintf(
|
||||||
|
'<strong class="red">%1$s</strong> %2$s',
|
||||||
|
__( 'Note:', 'woocommerce' ),
|
||||||
|
__( 'This tool will delete all customer session data from the database, including current carts and saved carts in the database.', 'woocommerce' )
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'install_pages' => array(
|
||||||
|
'name' => __( 'Create default WooCommerce pages', 'woocommerce' ),
|
||||||
|
'button' => __( 'Create pages', 'woocommerce' ),
|
||||||
|
'desc' => sprintf(
|
||||||
|
'<strong class="red">%1$s</strong> %2$s',
|
||||||
|
__( 'Note:', 'woocommerce' ),
|
||||||
|
__( 'This tool will install all the missing WooCommerce pages. Pages already defined and set up will not be replaced.', 'woocommerce' )
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'delete_taxes' => array(
|
||||||
|
'name' => __( 'Delete WooCommerce tax rates', 'woocommerce' ),
|
||||||
|
'button' => __( 'Delete tax rates', 'woocommerce' ),
|
||||||
|
'desc' => sprintf(
|
||||||
|
'<strong class="red">%1$s</strong> %2$s',
|
||||||
|
__( 'Note:', 'woocommerce' ),
|
||||||
|
__( 'This option will delete ALL of your tax rates, use with caution. This action cannot be reversed.', 'woocommerce' )
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'reset_tracking' => array(
|
||||||
|
'name' => __( 'Reset usage tracking', 'woocommerce' ),
|
||||||
|
'button' => __( 'Reset', 'woocommerce' ),
|
||||||
|
'desc' => __( 'This will reset your usage tracking settings, causing it to show the opt-in banner again and not sending any data.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
'regenerate_thumbnails' => array(
|
||||||
|
'name' => __( 'Regenerate shop thumbnails', 'woocommerce' ),
|
||||||
|
'button' => __( 'Regenerate', 'woocommerce' ),
|
||||||
|
'desc' => __( 'This will regenerate all shop thumbnails to match your theme and/or image settings.', 'woocommerce' ),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Jetpack does the image resizing heavy lifting so you don't have to.
|
||||||
|
if ( ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) ) || ! apply_filters( 'woocommerce_background_image_regeneration', true ) ) {
|
||||||
|
unset( $tools['regenerate_thumbnails'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
return apply_filters( 'woocommerce_debug_tools', $tools );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of system status tools.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Full details about the request.
|
||||||
|
* @return WP_Error|WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function get_items( $request ) {
|
||||||
|
$tools = array();
|
||||||
|
foreach ( $this->get_tools() as $id => $tool ) {
|
||||||
|
$tools[] = $this->prepare_response_for_collection(
|
||||||
|
$this->prepare_item_for_response(
|
||||||
|
array(
|
||||||
|
'id' => $id,
|
||||||
|
'name' => $tool['name'],
|
||||||
|
'action' => $tool['button'],
|
||||||
|
'description' => $tool['desc'],
|
||||||
|
), $request
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = rest_ensure_response( $tools );
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a single tool.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_Error|WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function get_item( $request ) {
|
||||||
|
$tools = $this->get_tools();
|
||||||
|
if ( empty( $tools[ $request['id'] ] ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
$tool = $tools[ $request['id'] ];
|
||||||
|
return rest_ensure_response(
|
||||||
|
$this->prepare_item_for_response(
|
||||||
|
array(
|
||||||
|
'id' => $request['id'],
|
||||||
|
'name' => $tool['name'],
|
||||||
|
'action' => $tool['button'],
|
||||||
|
'description' => $tool['desc'],
|
||||||
|
), $request
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update (execute) a tool.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request Request data.
|
||||||
|
* @return WP_Error|WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function update_item( $request ) {
|
||||||
|
$tools = $this->get_tools();
|
||||||
|
if ( empty( $tools[ $request['id'] ] ) ) {
|
||||||
|
return new WP_Error( 'woocommerce_rest_system_status_tool_invalid_id', __( 'Invalid tool ID.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$tool = $tools[ $request['id'] ];
|
||||||
|
$tool = array(
|
||||||
|
'id' => $request['id'],
|
||||||
|
'name' => $tool['name'],
|
||||||
|
'action' => $tool['button'],
|
||||||
|
'description' => $tool['desc'],
|
||||||
|
);
|
||||||
|
|
||||||
|
$execute_return = $this->execute_tool( $request['id'] );
|
||||||
|
$tool = array_merge( $tool, $execute_return );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires after a WooCommerce REST system status tool has been executed.
|
||||||
|
*
|
||||||
|
* @param array $tool Details about the tool that has been executed.
|
||||||
|
* @param WP_REST_Request $request The current WP_REST_Request object.
|
||||||
|
*/
|
||||||
|
do_action( 'woocommerce_rest_insert_system_status_tool', $tool, $request );
|
||||||
|
|
||||||
|
$request->set_param( 'context', 'edit' );
|
||||||
|
$response = $this->prepare_item_for_response( $tool, $request );
|
||||||
|
return rest_ensure_response( $response );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a tool item for serialization.
|
||||||
|
*
|
||||||
|
* @param array $item Object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response $response Response data.
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $item, $request ) {
|
||||||
|
$context = empty( $request['context'] ) ? 'view' : $request['context'];
|
||||||
|
$data = $this->add_additional_fields_to_object( $item, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
$response->add_links( $this->prepare_links( $item['id'] ) );
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the system status tools schema, conforming to JSON Schema.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => 'system_status_tool',
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'A unique identifier for the tool.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_title',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'name' => array(
|
||||||
|
'description' => __( 'Tool name.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'action' => array(
|
||||||
|
'description' => __( 'What running the tool will do.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'description' => array(
|
||||||
|
'description' => __( 'Tool description.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'success' => array(
|
||||||
|
'description' => __( 'Did the tool run successfully?', 'woocommerce' ),
|
||||||
|
'type' => 'boolean',
|
||||||
|
'context' => array( 'edit' ),
|
||||||
|
),
|
||||||
|
'message' => array(
|
||||||
|
'description' => __( 'Tool return message.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'sanitize_text_field',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare links for the request.
|
||||||
|
*
|
||||||
|
* @param string $id ID.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function prepare_links( $id ) {
|
||||||
|
$base = '/' . $this->namespace . '/' . $this->rest_base;
|
||||||
|
$links = array(
|
||||||
|
'item' => array(
|
||||||
|
'href' => rest_url( trailingslashit( $base ) . $id ),
|
||||||
|
'embeddable' => true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $links;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get any query params needed.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_collection_params() {
|
||||||
|
return array(
|
||||||
|
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actually executes a tool.
|
||||||
|
*
|
||||||
|
* @param string $tool Tool.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function execute_tool( $tool ) {
|
||||||
|
global $wpdb;
|
||||||
|
$ran = true;
|
||||||
|
switch ( $tool ) {
|
||||||
|
case 'clear_transients':
|
||||||
|
wc_delete_product_transients();
|
||||||
|
wc_delete_shop_order_transients();
|
||||||
|
WC_Cache_Helper::get_transient_version( 'shipping', true );
|
||||||
|
$message = __( 'Product transients cleared', 'woocommerce' );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'clear_expired_transients':
|
||||||
|
/* translators: %d: amount of expired transients */
|
||||||
|
$message = sprintf( __( '%d transients rows cleared', 'woocommerce' ), wc_delete_expired_transients() );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'delete_orphaned_variations':
|
||||||
|
// Delete orphans.
|
||||||
|
$result = absint(
|
||||||
|
$wpdb->query(
|
||||||
|
"DELETE products
|
||||||
|
FROM {$wpdb->posts} products
|
||||||
|
LEFT JOIN {$wpdb->posts} wp ON wp.ID = products.post_parent
|
||||||
|
WHERE wp.ID IS NULL AND products.post_type = 'product_variation';"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/* translators: %d: amount of orphaned variations */
|
||||||
|
$message = sprintf( __( '%d orphaned variations deleted', 'woocommerce' ), $result );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'clear_expired_download_permissions':
|
||||||
|
// Delete expired download permissions and ones with 0 downloads remaining.
|
||||||
|
$result = absint(
|
||||||
|
$wpdb->query(
|
||||||
|
$wpdb->prepare(
|
||||||
|
"DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
|
||||||
|
WHERE ( downloads_remaining != '' AND downloads_remaining = 0 ) OR ( access_expires IS NOT NULL AND access_expires < %s )",
|
||||||
|
date( 'Y-m-d', current_time( 'timestamp' ) )
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/* translators: %d: amount of permissions */
|
||||||
|
$message = sprintf( __( '%d permissions deleted', 'woocommerce' ), $result );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'add_order_indexes':
|
||||||
|
/*
|
||||||
|
* Add billing and shipping address indexes containing the customer name for orders
|
||||||
|
* that don't have address indexes yet.
|
||||||
|
*/
|
||||||
|
$sql = "INSERT INTO {$wpdb->postmeta}( post_id, meta_key, meta_value )
|
||||||
|
SELECT post_id, '%s', GROUP_CONCAT( meta_value SEPARATOR ' ' )
|
||||||
|
FROM {$wpdb->postmeta}
|
||||||
|
WHERE meta_key IN ( '%s', '%s' )
|
||||||
|
AND post_id IN ( SELECT DISTINCT post_id FROM {$wpdb->postmeta}
|
||||||
|
WHERE post_id NOT IN ( SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key='%s' )
|
||||||
|
AND post_id IN ( SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key='%s' ) )
|
||||||
|
GROUP BY post_id";
|
||||||
|
$rows = $wpdb->query( $wpdb->prepare( $sql, '_billing_address_index', '_billing_first_name', '_billing_last_name', '_billing_address_index', '_billing_last_name' ) ); // WPCS: unprepared SQL ok.
|
||||||
|
$rows += $wpdb->query( $wpdb->prepare( $sql, '_shipping_address_index', '_shipping_first_name', '_shipping_last_name', '_shipping_address_index', '_shipping_last_name' ) ); // WPCS: unprepared SQL ok.
|
||||||
|
|
||||||
|
/* translators: %d: amount of indexes */
|
||||||
|
$message = sprintf( __( '%d indexes added', 'woocommerce' ), $rows );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'reset_roles':
|
||||||
|
// Remove then re-add caps and roles.
|
||||||
|
WC_Install::remove_roles();
|
||||||
|
WC_Install::create_roles();
|
||||||
|
$message = __( 'Roles successfully reset', 'woocommerce' );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'recount_terms':
|
||||||
|
$product_cats = get_terms(
|
||||||
|
'product_cat', array(
|
||||||
|
'hide_empty' => false,
|
||||||
|
'fields' => 'id=>parent',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
_wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false );
|
||||||
|
$product_tags = get_terms(
|
||||||
|
'product_tag', array(
|
||||||
|
'hide_empty' => false,
|
||||||
|
'fields' => 'id=>parent',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
_wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false );
|
||||||
|
$message = __( 'Terms successfully recounted', 'woocommerce' );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'clear_sessions':
|
||||||
|
$wpdb->query( "TRUNCATE {$wpdb->prefix}woocommerce_sessions" );
|
||||||
|
$result = absint( $wpdb->query( "DELETE FROM {$wpdb->usermeta} WHERE meta_key='_woocommerce_persistent_cart_" . get_current_blog_id() . "';" ) ); // WPCS: unprepared SQL ok.
|
||||||
|
wp_cache_flush();
|
||||||
|
/* translators: %d: amount of sessions */
|
||||||
|
$message = sprintf( __( 'Deleted all active sessions, and %d saved carts.', 'woocommerce' ), absint( $result ) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'install_pages':
|
||||||
|
WC_Install::create_pages();
|
||||||
|
$message = __( 'All missing WooCommerce pages successfully installed', 'woocommerce' );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'delete_taxes':
|
||||||
|
$wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;" );
|
||||||
|
$wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" );
|
||||||
|
WC_Cache_Helper::incr_cache_prefix( 'taxes' );
|
||||||
|
$message = __( 'Tax rates successfully deleted', 'woocommerce' );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'reset_tracking':
|
||||||
|
if ( ! class_exists( 'WC_Tracker' ) ) {
|
||||||
|
include_once WC_ABSPATH . 'includes/class-wc-tracker.php';
|
||||||
|
}
|
||||||
|
WC_Tracker::opt_out_request();
|
||||||
|
delete_option( 'woocommerce_allow_tracking' );
|
||||||
|
WC_Admin_Notices::add_notice( 'tracking' );
|
||||||
|
$message = __( 'Usage tracking settings successfully reset.', 'woocommerce' );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'regenerate_thumbnails':
|
||||||
|
WC_Regenerate_Images::queue_image_regeneration();
|
||||||
|
$message = __( 'Thumbnail regeneration has been scheduled to run in the background.', 'woocommerce' );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$tools = $this->get_tools();
|
||||||
|
if ( isset( $tools[ $tool ]['callback'] ) ) {
|
||||||
|
$callback = $tools[ $tool ]['callback'];
|
||||||
|
$return = call_user_func( $callback );
|
||||||
|
if ( is_string( $return ) ) {
|
||||||
|
$message = $return;
|
||||||
|
} elseif ( false === $return ) {
|
||||||
|
$callback_string = is_array( $callback ) ? get_class( $callback[0] ) . '::' . $callback[1] : $callback;
|
||||||
|
$ran = false;
|
||||||
|
/* translators: %s: callback string */
|
||||||
|
$message = sprintf( __( 'There was an error calling %s', 'woocommerce' ), $callback_string );
|
||||||
|
} else {
|
||||||
|
$message = __( 'Tool ran.', 'woocommerce' );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$ran = false;
|
||||||
|
$message = __( 'There was an error calling this tool. There is no callback present.', 'woocommerce' );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'success' => $ran,
|
||||||
|
'message' => $message,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Tax Classes controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /taxes/classes endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Tax Classes controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Tax_Classes_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Tax_Classes_V2_Controller extends WC_REST_Tax_Classes_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Taxes controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /taxes endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Taxes controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Taxes_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Taxes_V2_Controller extends WC_REST_Taxes_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
}
|
|
@ -0,0 +1,153 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Webhooks controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /webhooks/<webhook_id>/deliveries endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Webhook Deliveries controller class.
|
||||||
|
*
|
||||||
|
* @deprecated 3.3.0 Webhooks deliveries logs now uses logging system.
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Webhook_Deliveries_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Webhook_Deliveries_V2_Controller extends WC_REST_Webhook_Deliveries_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a single webhook delivery output for response.
|
||||||
|
*
|
||||||
|
* @param stdClass $log Delivery log object.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $log, $request ) {
|
||||||
|
$data = (array) $log;
|
||||||
|
|
||||||
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||||
|
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
|
||||||
|
// Wrap the data in a response object.
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
$response->add_links( $this->prepare_links( $log ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter webhook delivery object returned from the REST API.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Response $response The response object.
|
||||||
|
* @param stdClass $log Delivery log object used to create response.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
*/
|
||||||
|
return apply_filters( 'woocommerce_rest_prepare_webhook_delivery', $response, $log, $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Webhook's schema, conforming to JSON Schema.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => 'webhook_delivery',
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'duration' => array(
|
||||||
|
'description' => __( 'The delivery duration, in seconds.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'summary' => array(
|
||||||
|
'description' => __( 'A friendly summary of the response including the HTTP response code, message, and body.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'request_url' => array(
|
||||||
|
'description' => __( 'The URL where the webhook was delivered.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'format' => 'uri',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'request_headers' => array(
|
||||||
|
'description' => __( 'Request headers.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'request_body' => array(
|
||||||
|
'description' => __( 'Request body.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'response_code' => array(
|
||||||
|
'description' => __( 'The HTTP response code from the receiving server.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'response_message' => array(
|
||||||
|
'description' => __( 'The HTTP response message from the receiving server.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'response_headers' => array(
|
||||||
|
'description' => __( 'Array of the response headers from the receiving server.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'response_body' => array(
|
||||||
|
'description' => __( 'The response body from the receiving server.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_created' => array(
|
||||||
|
'description' => __( "The date the webhook delivery was logged, in the site's timezone.", 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_created_gmt' => array(
|
||||||
|
'description' => __( 'The date the webhook delivery was logged, as GMT.', 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,185 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* REST API Webhooks controller
|
||||||
|
*
|
||||||
|
* Handles requests to the /webhooks endpoint.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @since 2.6.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API Webhooks controller class.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/API
|
||||||
|
* @extends WC_REST_Webhooks_V1_Controller
|
||||||
|
*/
|
||||||
|
class WC_REST_Webhooks_V2_Controller extends WC_REST_Webhooks_V1_Controller {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'wc/v2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a single webhook output for response.
|
||||||
|
*
|
||||||
|
* @param int $id Webhook ID.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
* @return WP_REST_Response $response
|
||||||
|
*/
|
||||||
|
public function prepare_item_for_response( $id, $request ) {
|
||||||
|
$webhook = wc_get_webhook( $id );
|
||||||
|
|
||||||
|
if ( empty( $webhook ) || is_null( $webhook ) ) {
|
||||||
|
return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'id' => $webhook->get_id(),
|
||||||
|
'name' => $webhook->get_name(),
|
||||||
|
'status' => $webhook->get_status(),
|
||||||
|
'topic' => $webhook->get_topic(),
|
||||||
|
'resource' => $webhook->get_resource(),
|
||||||
|
'event' => $webhook->get_event(),
|
||||||
|
'hooks' => $webhook->get_hooks(),
|
||||||
|
'delivery_url' => $webhook->get_delivery_url(),
|
||||||
|
'date_created' => wc_rest_prepare_date_response( $webhook->get_date_created(), false ),
|
||||||
|
'date_created_gmt' => wc_rest_prepare_date_response( $webhook->get_date_created() ),
|
||||||
|
'date_modified' => wc_rest_prepare_date_response( $webhook->get_date_modified(), false ),
|
||||||
|
'date_modified_gmt' => wc_rest_prepare_date_response( $webhook->get_date_modified() ),
|
||||||
|
);
|
||||||
|
|
||||||
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||||
|
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||||
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
|
||||||
|
// Wrap the data in a response object.
|
||||||
|
$response = rest_ensure_response( $data );
|
||||||
|
|
||||||
|
$response->add_links( $this->prepare_links( $webhook->get_id(), $request ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter webhook object returned from the REST API.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Response $response The response object.
|
||||||
|
* @param WC_Webhook $webhook Webhook object used to create response.
|
||||||
|
* @param WP_REST_Request $request Request object.
|
||||||
|
*/
|
||||||
|
return apply_filters( "woocommerce_rest_prepare_{$this->post_type}", $response, $webhook, $request );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the default REST API version.
|
||||||
|
*
|
||||||
|
* @since 3.0.0
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function get_default_api_version() {
|
||||||
|
return 'wp_api_v2';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Webhook's schema, conforming to JSON Schema.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_item_schema() {
|
||||||
|
$schema = array(
|
||||||
|
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||||
|
'title' => 'webhook',
|
||||||
|
'type' => 'object',
|
||||||
|
'properties' => array(
|
||||||
|
'id' => array(
|
||||||
|
'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
|
||||||
|
'type' => 'integer',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'name' => array(
|
||||||
|
'description' => __( 'A friendly name for the webhook.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'status' => array(
|
||||||
|
'description' => __( 'Webhook status.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'default' => 'active',
|
||||||
|
'enum' => array( 'active', 'paused', 'disabled' ),
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'arg_options' => array(
|
||||||
|
'sanitize_callback' => 'wc_is_webhook_valid_topic',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'topic' => array(
|
||||||
|
'description' => __( 'Webhook topic.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
),
|
||||||
|
'resource' => array(
|
||||||
|
'description' => __( 'Webhook resource.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'event' => array(
|
||||||
|
'description' => __( 'Webhook event.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'hooks' => array(
|
||||||
|
'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce' ),
|
||||||
|
'type' => 'array',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
'items' => array(
|
||||||
|
'type' => 'string',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'delivery_url' => array(
|
||||||
|
'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'format' => 'uri',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'secret' => array(
|
||||||
|
'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce' ),
|
||||||
|
'type' => 'string',
|
||||||
|
'context' => array( 'edit' ),
|
||||||
|
),
|
||||||
|
'date_created' => array(
|
||||||
|
'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_created_gmt' => array(
|
||||||
|
'description' => __( 'The date the webhook was created, as GMT.', 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_modified' => array(
|
||||||
|
'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
'date_modified_gmt' => array(
|
||||||
|
'description' => __( 'The date the webhook was last modified, as GMT.', 'woocommerce' ),
|
||||||
|
'type' => 'date-time',
|
||||||
|
'context' => array( 'view', 'edit' ),
|
||||||
|
'readonly' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->add_additional_fields_schema( $schema );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue