Merge pull request #10884 from woothemes/wp-api-batch

[REST API] Batch create, update and delete items
This commit is contained in:
Claudio Sanches 2016-05-11 16:22:54 -03:00
commit dac471273f
4 changed files with 199 additions and 54 deletions

View File

@ -0,0 +1,175 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Abstract Rest Controler Class
*
* @author WooThemes
* @category API
* @package WooCommerce/Abstracts
* @extends WC_REST_Controller
* @version 2.6.0
*/
abstract class WC_REST_Controller extends WP_REST_Controller {
/**
* Endpoint namespace.
*
* @var string
*/
protected $namespace = 'wc/v1';
/**
* Route base.
*
* @var string
*/
protected $rest_base = '';
/**
* Get normalized rest base.
*
* @return string
*/
protected function get_normalized_rest_base() {
return preg_replace( '/\(.*\)\//i', '', $this->rest_base );
}
/**
* Check batch limit.
*
* @param array $items Request items.
* @return bool|WP_Error
*/
protected function check_batch_limit( $items ) {
$limit = apply_filters( 'woocommerce_rest_batch_items_limit', 100, $this->get_normalized_rest_base() );
$total = 0;
if ( ! empty( $items['create'] ) ) {
$total += count( $items['create'] );
}
if ( ! empty( $items['update'] ) ) {
$total += count( $items['update'] );
}
if ( ! empty( $items['delete'] ) ) {
$total += count( $items['delete'] );
}
if ( $total > $limit ) {
return new WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), array( 'status' => 413 ) );
}
return true;
}
/**
* Bulk create, update and delete items.
*
* @param WP_REST_Request $request Full details about the request.
* @return array Of WP_Error or WP_REST_Response.
*/
public function batch_items( $request ) {
/** @var WP_REST_Server $wp_rest_server */
global $wp_rest_server;
// Get the request params.
$items = array_filter( $request->get_params() );
$response = array();
// Check batch limit.
$limit = $this->check_batch_limit( $items );
if ( is_wp_error( $limit ) ) {
return $limit;
}
if ( ! empty( $items['create'] ) ) {
foreach ( $items['create'] as $item ) {
$_item = new WP_REST_Request( 'POST' );
$_item->set_body_params( $item );
$_response = $this->create_item( $_item );
if ( is_wp_error( $_response ) ) {
$response['create'][] = array(
'id' => 0,
'error' => array( 'code' => $_response->get_error_code(), 'message' => $_response->get_error_message(), 'data' => $_response->get_error_data() ),
);
} else {
$response['create'][] = $wp_rest_server->response_to_data( $_response, '' );
}
}
}
if ( ! empty( $items['update'] ) ) {
foreach ( $items['update'] as $item ) {
$_item = new WP_REST_Request( 'PUT' );
$_item->set_body_params( $item );
$_response = $this->update_item( $_item );
if ( is_wp_error( $_response ) ) {
$response['update'][] = array(
'id' => $item['id'],
'error' => array( 'code' => $_response->get_error_code(), 'message' => $_response->get_error_message(), 'data' => $_response->get_error_data() ),
);
} else {
$response['update'][] = $wp_rest_server->response_to_data( $_response, '' );
}
}
}
if ( ! empty( $items['delete'] ) ) {
foreach ( $items['delete'] as $id ) {
$_item = new WP_REST_Request( 'DELETE' );
$_item->set_query_params( array( 'id' => $id, 'force' => true ) );
$_response = $this->delete_item( $_item );
if ( is_wp_error( $_response ) ) {
$response['delete'][] = array(
'id' => $id,
'error' => array( 'code' => $_response->get_error_code(), 'message' => $_response->get_error_message(), 'data' => $_response->get_error_data() ),
);
} else {
$response['delete'][] = $wp_rest_server->response_to_data( $_response, '' );
}
}
}
return $response;
}
/**
* Get the batch schema, conforming to JSON Schema.
*
* @return array
*/
public function get_public_batch_schema() {
$schema = array(
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'batch',
'type' => 'object',
'properties' => array(
'create' => array(
'description' => __( 'List of created resources.', 'woocommerce' ),
'type' => 'array',
'context' => array( 'view', 'edit' ),
),
'update' => array(
'description' => __( 'List of updated resources.', 'woocommerce' ),
'type' => 'array',
'context' => array( 'view', 'edit' ),
),
'delete' => array(
'description' => __( 'List of delete resources.', 'woocommerce' ),
'type' => 'array',
'context' => array( 'view', 'edit' ),
),
),
);
return $schema;
}
}

View File

@ -18,9 +18,9 @@ if ( ! defined( 'ABSPATH' ) ) {
* REST API Taxes controller class. * REST API Taxes controller class.
* *
* @package WooCommerce/API * @package WooCommerce/API
* @extends WP_REST_Controller * @extends WC_REST_Controller
*/ */
class WC_REST_Taxes_Controller extends WP_REST_Controller { class WC_REST_Taxes_Controller extends WC_REST_Controller {
/** /**
* Endpoint namespace. * Endpoint namespace.
@ -85,14 +85,14 @@ class WC_REST_Taxes_Controller extends WP_REST_Controller {
'schema' => array( $this, 'get_public_item_schema' ), 'schema' => array( $this, 'get_public_item_schema' ),
) ); ) );
register_rest_route( $this->namespace, '/' . $this->rest_base . '/update_items', array( register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array(
array( array(
'methods' => WP_REST_Server::EDITABLE, 'methods' => WP_REST_Server::EDITABLE,
'callback' => array( $this, 'update_items' ), 'callback' => array( $this, 'batch_items' ),
'permission_callback' => array( $this, 'update_item_permissions_check' ), 'permission_callback' => array( $this, 'batch_items_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
), ),
'schema' => array( $this, 'get_public_item_schema' ), 'schema' => array( $this, 'get_public_batch_schema' ),
) ); ) );
} }
@ -166,6 +166,20 @@ class WC_REST_Taxes_Controller extends WP_REST_Controller {
return true; return true;
} }
/**
* Check if a given request has access batch create, update and delete items.
*
* @param WP_REST_Request $request Full details about the request.
* @return boolean
*/
public function batch_items_permissions_check( $request ) {
if ( ! wc_rest_check_manager_permissions( 'settings', 'batch' ) ) {
return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to manipule this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
}
return true;
}
/** /**
* Get all taxes. * Get all taxes.
* *
@ -539,54 +553,6 @@ class WC_REST_Taxes_Controller extends WP_REST_Controller {
return $links; return $links;
} }
/**
* Bulk update or create items.
*
* @param WP_REST_Request $request Full details about the request.
* @return array Of WP_Error or WP_REST_Response.
*/
public function update_items( $request ) {
/** @var WP_REST_Server $wp_rest_server */
global $wp_rest_server;
// Get the request params.
$items = array_filter( $request->get_params() );
// Limit bulk operation.
$limit = apply_filters( 'woocommerce_rest_bulk_items_limit', 100, 'taxes' );
if ( count( $items ) > $limit ) {
return new WP_Error( 'woocommerce_rest_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), array( 'status' => 413 ) );
}
$response = array();
foreach ( $items as $item ) {
// Item exists.
if ( ! empty( $item['id'] ) ) {
$_item = new WP_REST_Request( 'PUT' );
$_item->set_body_params( $item );
$_response = $this->update_item( $_item );
// Item does not exist.
} else {
$_item = new WP_REST_Request( 'POST' );
$_item->set_body_params( $item );
$_response = $this->create_item( $_item );
}
if ( is_wp_error( $_response ) ) {
$response[] = array(
'id' => $item['id'],
'error' => array( 'code' => $_response->get_error_code(), 'message' => $_response->get_error_message(), 'data' => $_response->get_error_data() ),
);
} else {
$response[] = $wp_rest_server->response_to_data( $_response, '' );
}
}
return $response;
}
/** /**
* Get the Taxes schema, conforming to JSON Schema. * Get the Taxes schema, conforming to JSON Schema.
* *

View File

@ -376,6 +376,7 @@ class WC_API {
} }
// Abstract controllers. // Abstract controllers.
include_once( 'abstracts/abstract-wc-rest-controller.php' );
include_once( 'abstracts/abstract-wc-rest-posts-controller.php' ); include_once( 'abstracts/abstract-wc-rest-posts-controller.php' );
include_once( 'abstracts/abstract-wc-rest-terms-controller.php' ); include_once( 'abstracts/abstract-wc-rest-terms-controller.php' );

View File

@ -215,6 +215,7 @@ function wc_rest_check_post_permissions( $post_type, $context = 'read', $object_
'create' => 'publish_posts', 'create' => 'publish_posts',
'edit' => 'edit_post', 'edit' => 'edit_post',
'delete' => 'delete_post', 'delete' => 'delete_post',
'batch' => 'edit_post',
); );
if ( 'revision' === $post_type ) { if ( 'revision' === $post_type ) {
@ -242,6 +243,7 @@ function wc_rest_check_user_permissions( $context = 'read', $object_id = 0 ) {
'create' => 'edit_users', 'create' => 'edit_users',
'edit' => 'edit_users', 'edit' => 'edit_users',
'delete' => 'delete_users', 'delete' => 'delete_users',
'batch' => 'edit_users',
); );
$permission = current_user_can( $contexts[ $context ], $object_id ); $permission = current_user_can( $contexts[ $context ], $object_id );
@ -264,6 +266,7 @@ function wc_rest_check_product_term_permissions( $taxonomy, $context = 'read', $
'create' => 'edit_terms', 'create' => 'edit_terms',
'edit' => 'edit_terms', 'edit' => 'edit_terms',
'delete' => 'delete_terms', 'delete' => 'delete_terms',
'batch' => 'edit_terms',
); );
$cap = $contexts[ $context ]; $cap = $contexts[ $context ];