Update API resource classes

Change method naming to snake_case and implement initial
`current_user_can()` permission checks
This commit is contained in:
Max Rice 2013-11-10 19:29:36 -05:00
parent 9c7791e3d8
commit a13a95e452
6 changed files with 537 additions and 339 deletions

View File

@ -29,24 +29,29 @@ class WC_API_Coupons extends WC_API_Resource {
* @param array $routes
* @return array
*/
public function registerRoutes( $routes ) {
public function register_routes( $routes ) {
# GET|POST /coupons
$routes[ $this->base ] = array(
array( array( $this, 'getCoupons' ), WC_API_Server::READABLE ),
array( array( $this, 'createCoupon' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ),
array( array( $this, 'get_coupons' ), WC_API_Server::READABLE ),
array( array( $this, 'create_coupon' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ),
);
# GET /coupons/count
$routes[ $this->base . '/count'] = array(
array( array( $this, 'getCouponsCount' ), WC_API_Server::READABLE ),
array( array( $this, 'get_coupons_count' ), WC_API_Server::READABLE ),
);
# GET|PUT|DELETE /coupons/<id>
$routes[ $this->base . '/(?P<id>\d+)' ] = array(
array( array( $this, 'getCoupon' ), WC_API_Server::READABLE ),
array( array( $this, 'editCoupon' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ),
array( array( $this, 'deleteCoupon' ), WC_API_Server::DELETABLE ),
array( array( $this, 'get_coupon' ), WC_API_Server::READABLE ),
array( array( $this, 'edit_coupon' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ),
array( array( $this, 'delete_coupon' ), WC_API_Server::DELETABLE ),
);
# GET /coupons/<code> TODO: should looking up coupon codes containing spaces or dashes be supported? OR all-digit coupon codes
$routes[ $this->base . '/(?P<code>\w+)' ] = array(
array( array( $this, 'get_coupon_by_code' ), WC_API_Server::READABLE ),
);
return $routes;
@ -55,36 +60,27 @@ class WC_API_Coupons extends WC_API_Resource {
/**
* Get all coupons
*
* @TODO should we support an extra "code" param for lookup instead of "q" which searches both title & description?
*
* @since 2.1
* @param string $fields
* @param string $created_at_min
* @param string $created_at_max
* @param string $q search terms
* @param int $limit coupons per response
* @param int $offset
* @param array $filter
* @return array
*/
public function getCoupons( $fields = null, $created_at_min = null, $created_at_max = null, $q = null, $limit = null, $offset = null ) {
public function get_coupons( $fields = null, $filter = array() ) {
$request_args = array(
'created_at_min' => $created_at_min,
'created_at_max' => $created_at_max,
'q' => $q,
'limit' => $limit,
'offset' => $offset,
);
$query = $this->queryCoupons( $request_args );
$query = $this->query_coupons( $filter );
$coupons = array();
foreach( $query->posts as $coupon_id ) {
$coupons[] = $this->getCoupon( $coupon_id, $fields );
if ( ! $this->is_readable( $coupon_id ) )
continue;
$coupons[] = $this->get_coupon( $coupon_id, $fields );
}
$this->server->query_navigation_headers( $query );
return array( 'coupons' => $coupons );
}
@ -94,25 +90,29 @@ class WC_API_Coupons extends WC_API_Resource {
* @since 2.1
* @param int $id the coupon ID
* @param string $fields fields to include in response
* @return array
* @return array|WP_Error
*/
public function getCoupon( $id, $fields = null ) {
public function get_coupon( $id, $fields = null ) {
global $wpdb;
$id = $this->validate_request( $id, 'shop_coupon', 'read' );
if ( is_wp_error( $id ) )
return $id;
// get the coupon code
$code = $wpdb->get_var( $wpdb->prepare( "SELECT post_title FROM $wpdb->posts WHERE id = %s AND post_type = 'shop_coupon' AND post_status = 'publish'", $id ) );
if ( ! $code )
return new WP_Error( 'wc_api_invalid_coupon_id', __( 'Invalid coupon ID', 'woocommerce' ), array( 'status' => 404 ) );
if ( is_null( $code ) )
return new WP_Error( 'woocommerce_api_invalid_coupon_id', __( 'Invalid coupon ID', 'woocommerce' ), array( 'status' => 404 ) );
$coupon = new WC_Coupon( $code );
// TODO: how to implement coupon meta?
$coupon_data = array(
'id' => $coupon->id,
'code' => $coupon->code,
'type' => $coupon->type,
'amount' => $coupon->amount, // TODO: should this be formatted?
'amount' => (string) number_format( $coupon->amount, 2 ),
'individual_use' => $coupon->individual_use,
'product_ids' => $coupon->product_ids,
'exclude_product_ids' => $coupon->exclude_product_ids,
@ -137,17 +137,36 @@ class WC_API_Coupons extends WC_API_Resource {
* Get the total number of coupons
*
* @since 2.1
* @param string $created_at_min
* @param string $created_at_max
* @param array $filter
* @return array
*/
public function getCouponsCount( $created_at_min = null, $created_at_max = null ) {
public function get_coupons_count( $filter = array() ) {
$query = $this->queryCoupons( array( 'created_at_min' => $created_at_min, 'created_at_max' => $created_at_max ) );
$query = $this->query_coupons( $filter );
// TODO: permissions?
return array( 'count' => $query->found_posts );
}
/**
* Get the coupon for the given code
*
* @param string $code the coupon code
* @param string $fields fields to include in response
* @return int|WP_Error
*/
public function get_coupon_by_code( $code, $fields = null ) {
global $wpdb;
$id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM $wpdb->posts WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish'", $code ) );
if ( is_null( $id ) )
return new WP_Error( 'woocommerce_api_invalid_coupon_code', __( 'Invalid coupon code', 'woocommerce' ), array( 'status' => 404 ) );
return $this->get_coupon( $id, $fields );
}
/**
* Create a coupon
*
@ -155,7 +174,9 @@ class WC_API_Coupons extends WC_API_Resource {
* @param array $data
* @return array
*/
public function createCoupon( $data ) {
public function create_coupon( $data ) {
// TODO: permissions check
// TODO: implement - what's the minimum set of data required?
@ -170,10 +191,15 @@ class WC_API_Coupons extends WC_API_Resource {
* @param array $data
* @return array
*/
public function editCoupon( $id, $data ) {
public function edit_coupon( $id, $data ) {
$id = $this->validate_request( $id, 'shop_coupon', 'edit' );
if ( is_wp_error( $id ) )
return $id;
// TODO: implement
return $this->getCoupon( $id );
return $this->get_coupon( $id );
}
/**
@ -184,9 +210,14 @@ class WC_API_Coupons extends WC_API_Resource {
* @param bool $force true to permanently delete coupon, false to move to trash
* @return array
*/
public function deleteCoupon( $id, $force = false ) {
public function delete_coupon( $id, $force = false ) {
return $this->deleteResource( $id, 'coupon', ( 'true' === $force ) );
$id = $this->validate_request( $id, 'shop_coupon', 'delete' );
if ( is_wp_error( $id ) )
return $id;
return $this->delete( $id, 'shop_coupon', ( 'true' === $force ) );
}
/**
@ -194,21 +225,18 @@ class WC_API_Coupons extends WC_API_Resource {
*
* @since 2.1
* @param array $args request arguments for filtering query
* @return array
* @return WP_Query
*/
private function queryCoupons( $args ) {
private function query_coupons( $args ) {
// set base query arguments
$query_args = array(
'fields' => 'ids',
'post_type' => 'shop_coupon',
'post_status' => 'publish',
'orderby' => 'title',
);
$query_args = $this->mergeQueryArgs( $query_args, $args );
// TODO: navigation/total count headers for pagination
$query_args = $this->merge_query_args( $query_args, $args );
return new WP_Query( $query_args );
}

View File

@ -35,7 +35,8 @@ class WC_API_Customers extends WC_API_Resource {
parent::__construct( $server );
// add customer data to order responses
add_filter( 'woocommerce_api_order_response', array( $this, 'addCustomerData' ), 10, 2 );
add_filter( 'woocommerce_api_order_response', array( $this, 'add_customer_data' ), 10, 2 );
// modify WP_User_Query to support created_at date filtering
add_action( 'pre_user_query', array( $this, 'modify_user_query' ) );
}
@ -52,29 +53,29 @@ class WC_API_Customers extends WC_API_Resource {
* @param array $routes
* @return array
*/
public function registerRoutes( $routes ) {
public function register_routes( $routes ) {
# GET|POST /customers
$routes[ $this->base ] = array(
array( array( $this, 'getCustomers' ), WC_API_SERVER::READABLE ),
array( array( $this, 'createCustomer' ), WC_API_SERVER::CREATABLE | WC_API_SERVER::ACCEPT_DATA ),
array( array( $this, 'get_customers' ), WC_API_SERVER::READABLE ),
array( array( $this, 'create_customer' ), WC_API_SERVER::CREATABLE | WC_API_SERVER::ACCEPT_DATA ),
);
# GET /customers/count
$routes[ $this->base . '/count'] = array(
array( array( $this, 'getCustomersCount' ), WC_API_SERVER::READABLE ),
array( array( $this, 'get_customers_count' ), WC_API_SERVER::READABLE ),
);
# GET|PUT|DELETE /customers/<id>
$routes[ $this->base . '/(?P<id>\d+)' ] = array(
array( array( $this, 'getCustomer' ), WC_API_SERVER::READABLE ),
array( array( $this, 'editCustomer' ), WC_API_SERVER::EDITABLE | WC_API_SERVER::ACCEPT_DATA ),
array( array( $this, 'deleteCustomer' ), WC_API_SERVER::DELETABLE ),
array( array( $this, 'get_customer' ), WC_API_SERVER::READABLE ),
array( array( $this, 'edit_customer' ), WC_API_SERVER::EDITABLE | WC_API_SERVER::ACCEPT_DATA ),
array( array( $this, 'delete_customer' ), WC_API_SERVER::DELETABLE ),
);
# GET /customers/<id>/orders
$routes[ $this->base . '/(?P<id>\d+)/orders' ] = array(
array( array( $this, 'getCustomerOrders' ), WC_API_SERVER::READABLE ),
array( array( $this, 'get_customer_orders' ), WC_API_SERVER::READABLE ),
);
return $routes;
@ -83,60 +84,48 @@ class WC_API_Customers extends WC_API_Resource {
/**
* Get all customers
*
* @TODO support created_at_min/created_at_max with pre_user_query filter
*
* @since 2.1
* @param array $fields
* @param string $q search terms
* @param int $limit coupons per response
* @param int $offset
* @param array $filter
* @return array
*/
public function getCustomers( $fields = null, $q = null, $limit = null, $offset = null ) {
public function get_customers( $fields = null, $filter = array() ) {
$request_args = array(
'q' => $q,
'limit' => $limit,
'offset' => $offset,
);
$query = $this->queryCustomers( $request_args );
$query = $this->query_customers( $filter );
$customers = array();
foreach( $query->results as $user_id ) {
$customers[] = $this->getCustomer( $user_id, $fields );
if ( ! $this->is_readable( $user_id ) )
continue;
$customers[] = $this->get_customer( $user_id, $fields );
}
// TODO: add navigation/total count headers for pagination
return array( 'customers' => $customers );
}
/**
* Get the customer for the given ID
*
* @TODO: implement customer meta
*
* @since 2.1
* @param int $id the customer ID
* @param string $fields
* @return array
*/
public function getCustomer( $id, $fields = null ) {
public function get_customer( $id, $fields = null ) {
global $wpdb;
$id = absint( $id );
$id = $this->validate_request( $id, 'customer', 'read' );
if ( empty( $id ) )
return new WP_Error( 'woocommerce_api_invalid_id', __( 'Invalid customer ID', 'woocommerce' ), array( 'status' => 404 ) );
if ( is_wp_error( $id ) )
return $id;
// non-existent IDs return a valid WP_User object with the user ID = 0
$customer = new WP_User( $id );
if ( 0 === $customer->ID )
return new WP_Error( 'woocommerce_api_invalid_customer', __( 'Invalid customer', 'woocommerce' ), array( 'status' => 404 ) );
// get info about user's last order
$last_order = $wpdb->get_row( "SELECT id, post_date
FROM $wpdb->posts AS posts
@ -157,7 +146,7 @@ class WC_API_Customers extends WC_API_Resource {
'last_order_id' => is_object( $last_order ) ? $last_order->id : null,
'last_order_date' => is_object( $last_order ) ? $last_order->post_date : null,
'orders_count' => $customer->_order_count,
'total_spent' => $customer->_money_spent,
'total_spent' => (string) number_format( $customer->_money_spent, 2 ),
'avatar_url' => $this->get_avatar_url( $customer->customer_email ),
'billing_address' => array(
'first_name' => $customer->billing_first_name,
@ -191,14 +180,15 @@ class WC_API_Customers extends WC_API_Resource {
/**
* Get the total number of customers
*
* @TODO support created_at_min/created_at_max with pre_user_query filter
*
* @since 2.1
* @param array $filter
* @return array
*/
public function getCustomersCount() {
public function get_customers_count( $filter = array() ) {
$query = $this->queryCustomers();
$query = $this->query_customers( $filter );
// TODO: permissions?
return array( 'count' => $query->get_total() );
}
@ -211,10 +201,12 @@ class WC_API_Customers extends WC_API_Resource {
* @param array $data
* @return array
*/
public function createCustomer( $data ) {
public function create_customer( $data ) {
// TODO: implement - what's the minimum set of data required?
// woocommerce_create_new_customer()
if ( ! current_user_can( 'create_users' ) )
return new WP_Error( 'woocommerce_api_user_cannot_create_customer', __( 'You do not have permission to create this customer', 'woocommerce' ), array( 'status' => 401 ) );
// TODO: implement - woocommerce_create_new_customer()
return array();
}
@ -227,10 +219,16 @@ class WC_API_Customers extends WC_API_Resource {
* @param array $data
* @return array
*/
public function editCustomer( $id, $data ) {
public function edit_customer( $id, $data ) {
$id = $this->validate_request( $id, 'customer', 'edit' );
if ( ! is_wp_error( $id ) )
return $id;
// TODO: implement
return $this->getCustomer( $id );
return $this->get_customer( $id );
}
/**
@ -240,43 +238,40 @@ class WC_API_Customers extends WC_API_Resource {
* @param int $id the customer ID
* @return array
*/
public function deleteCustomer( $id ) {
public function delete_customer( $id ) {
return $this->deleteResource( $id, 'customer' );
$id = $this->validate_request( $id, 'customer', 'delete' );
if ( ! is_wp_error( $id ) )
return $id;
return $this->delete( $id, 'customer' );
}
/**
* Get the orders for a customer
*
* @TODO should this support the same parameters as getOrders call? e.g. fields, created_at, pagination, etc
*
* @since 2.1
* @param int $id the customer ID
* @param string $fields fields to include in response
* @return array
*/
public function getCustomerOrders( $id ) {
public function get_customer_orders( $id, $fields = null ) {
global $wpdb;
// TODO: DRY this along with duplicate code in getCustomer()
$id = absint( $id );
$id = $this->validate_request( $id, 'customer', 'read' );
if ( empty( $id ) )
return new WP_Error( 'woocommerce_api_invalid_id', __( 'Invalid customer ID', 'woocommerce' ), array( 'status' => 404 ) );
if ( is_wp_error( $id ) )
return $id;
// non-existent IDs return a valid WP_User object with the user ID = 0
$customer = new WP_User( $id );
if ( 0 === $customer->ID )
return new WP_Error( 'woocommerce_api_invalid_customer', __( 'Invalid customer', 'woocommerce' ), array( 'status' => 404 ) );
$order_ids = $wpdb->get_col( "SELECT id
$order_ids = $wpdb->get_col( $wpdb->prepare( "SELECT id
FROM $wpdb->posts AS posts
LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id
WHERE meta.meta_key = '_customer_user'
AND meta.meta_value = {$id}
AND meta.meta_value = '%s'
AND posts.post_type = 'shop_order'
AND posts.post_status = 'publish'
" );
", $id ) );
if ( empty( $order_ids ) )
return array( 'orders' => array() );
@ -284,7 +279,7 @@ class WC_API_Customers extends WC_API_Resource {
$orders = array();
foreach ( $order_ids as $order_id ) {
$orders[] = WC()->api->WC_API_Orders->getOrder( $order_id );
$orders[] = WC()->api->WC_API_Orders->get_order( $order_id, $fields );
}
return array( 'orders' => $orders );
@ -297,18 +292,15 @@ class WC_API_Customers extends WC_API_Resource {
* @param array $args request arguments for filtering query
* @return array
*/
private function queryCustomers( $args = array() ) {
private function query_customers( $args = array() ) {
// set base query arguments
$query_args = array(
'fields' => 'ID',
'role' => 'customer',
'orderby' => 'registered',
'order' => 'DESC',
);
// TODO: refactor WP_API_Base::mergeQueryVars to support user query args
if ( ! empty( $args['q'] ) )
$query_args['search'] = $args['q'];
@ -318,7 +310,6 @@ class WC_API_Customers extends WC_API_Resource {
if ( ! empty( $args['offset'] ) )
$query_args['offset'] = $args['offset'];
// TODO: navigation/total count headers for pagination
if ( ! empty( $args['created_at_min'] ) )
$this->created_at_min = $args['created_at_min'];
@ -333,14 +324,12 @@ class WC_API_Customers extends WC_API_Resource {
/**
* Add customer data to orders
*
* @TODO should guest orders return more than 'guest'?
*
* @since 2.1
* @param $order_data
* @param $order
*
* @return array
*/
public function addCustomerData( $order_data, $order ) {
public function add_customer_data( $order_data, $order ) {
if ( 0 == $order->customer_user ) {
@ -348,7 +337,7 @@ class WC_API_Customers extends WC_API_Resource {
} else {
$order_data['customer'] = $this->getCustomer( $order->customer_user );
$order_data['customer'] = $this->get_customer( $order->customer_user );
}
return $order_data;
@ -373,6 +362,7 @@ class WC_API_Customers extends WC_API_Resource {
* Wrapper for @see get_avatar() which doesn't simply return
* the URL so we need to pluck it from the HTML img tag
*
* @since 2.1
* @param string $email the customer's email
* @return string the URL to the customer's avatar
*/
@ -382,9 +372,72 @@ class WC_API_Customers extends WC_API_Resource {
$dom->loadHTML( get_avatar( $email ) );
$url = $dom->getElementsByTagName('img')->item(0)->getAttribute('src');
$url = $dom->getElementsByTagName( 'img' )->item( 0 )->getAttribute( 'src' );
return ( ! empty( $url ) ) ? $url : null;
}
/**
* Validate the request by checking:
*
* 1) the ID is a valid integer
* 2) the ID returns a valid WP_User
* 3) the current user has the proper permissions
*
* @since 2.1
* @see WC_API_Resource::validate_request()
* @param string|int $id the customer ID
* @param string $type the request type, unused because this method overrides the parent class
* @param string $context the context of the request, either `read`, `edit` or `delete`
* @return int|WP_Error valid user ID or WP_Error if any of the checks fails
*/
protected function validate_request( $id, $type, $context ) {
$id = absint( $id );
// validate ID
if ( empty( $id ) )
return new WP_Error( 'woocommerce_api_invalid_customer_id', __( 'Invalid customer ID', 'woocommerce' ), array( 'status' => 404 ) );
// non-existent IDs return a valid WP_User object with the user ID = 0
$customer = new WP_User( $id );
if ( 0 === $customer->ID )
return new WP_Error( 'woocommerce_api_invalid_customer', __( 'Invalid customer', 'woocommerce' ), array( 'status' => 404 ) );
// validate permissions
switch ( $context ) {
case 'read':
if ( ! current_user_can( 'list_users' ) )
return new WP_Error( 'woocommerce_api_user_cannot_read_customer', __( 'You do not have permission to read this customer', 'woocommerce' ), array( 'status' => 401 ) );
break;
case 'edit':
if ( ! current_user_can( 'edit_users' ) )
return new WP_Error( 'woocommerce_api_user_cannot_edit_customer', __( 'You do not have permission to edit this customer', 'woocommerce' ), array( 'status' => 401 ) );
break;
case 'delete':
if ( ! current_user_can( 'delete_users' ) )
return new WP_Error( 'woocommerce_api_user_cannot_delete_customer', __( 'You do not have permission to delete this customer', 'woocommerce' ), array( 'status' => 401 ) );
break;
}
return $id;
}
/**
* Check if the current user can read users
*
* @since 2.1
* @see WC_API_Resource::is_readable()
* @param int|WP_Post $post unused
* @return bool true if the current user can read users, false otherwise
*/
protected function is_readable( $post ) {
return current_user_can( 'list_users' );
}
}

View File

@ -20,7 +20,7 @@ class WC_API_Orders extends WC_API_Resource {
/**
* Register the routes for this class
*
* GET|POST /orders
* GET /orders
* GET /orders/count
* GET|PUT|DELETE /orders/<id>
* GET /orders/<id>/notes
@ -29,29 +29,28 @@ class WC_API_Orders extends WC_API_Resource {
* @param array $routes
* @return array
*/
public function registerRoutes( $routes ) {
public function register_routes( $routes ) {
# GET|POST /orders
# GET /orders
$routes[ $this->base ] = array(
array( array( $this, 'getOrders' ), WC_API_Server::READABLE ),
array( array( $this, 'createOrder' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ),
array( array( $this, 'get_orders' ), WC_API_Server::READABLE ),
);
# GET /orders/count
$routes[ $this->base . '/count'] = array(
array( array( $this, 'getOrdersCount' ), WC_API_Server::READABLE ),
array( array( $this, 'get_orders_count' ), WC_API_Server::READABLE ),
);
# GET|PUT|DELETE /orders/<id>
$routes[ $this->base . '/(?P<id>\d+)' ] = array(
array( array( $this, 'getOrder' ), WC_API_Server::READABLE ),
array( array( $this, 'editOrder' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ),
array( array( $this, 'deleteOrder' ), WC_API_Server::DELETABLE ),
array( array( $this, 'get_order' ), WC_API_Server::READABLE ),
array( array( $this, 'edit_order' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ),
array( array( $this, 'delete_order' ), WC_API_Server::DELETABLE ),
);
# GET /orders/<id>/notes
$routes[ $this->base . '/(?P<id>\d+)/notes' ] = array(
array( array( $this, 'getOrderNotes' ), WC_API_Server::READABLE ),
array( array( $this, 'get_order_notes' ), WC_API_Server::READABLE ),
);
return $routes;
@ -61,39 +60,27 @@ class WC_API_Orders extends WC_API_Resource {
* Get all orders
*
* @since 2.1
* @param array $fields
* @param string $fields
* @param array $filter
* @param string $status
* @param string $created_at_min
* @param string $created_at_max
* @param string $updated_at_min
* @param string $updated_at_max
* @param string $q search terms
* @param int $limit coupons per response
* @param int $offset
* @return array
*/
public function getOrders( $fields = array(), $status = null, $created_at_min = null, $created_at_max = null, $updated_at_min = null, $updated_at_max = null, $q = null, $limit = null, $offset = null ) {
public function get_orders( $fields = null, $filter = array(), $status = null ) {
$request_args = array(
'status' => $status,
'created_at_min' => $created_at_min,
'created_at_max' => $created_at_max,
'updated_at_min' => $updated_at_min,
'updated_at_max' => $updated_at_max,
'q' => $q,
'limit' => $limit,
'offset' => $offset,
);
if ( ! empty( $status ) )
$filter['status'] = $status;
$query = $this->queryOrders( $request_args );
$query = $this->query_orders( $filter );
$orders = array();
foreach( $query->posts as $order_id ) {
$orders[] = $this->getOrder( $order_id, $fields );
$orders[] = $this->get_order( $order_id, $fields );
}
$this->server->query_navigation_headers( $query );
return array( 'orders' => $orders );
}
@ -106,20 +93,16 @@ class WC_API_Orders extends WC_API_Resource {
* @param array $fields
* @return array
*/
public function getOrder( $id, $fields = null ) {
public function get_order( $id, $fields = null ) {
$id = absint( $id );
// ensure order ID is valid & user has permission to read
$id = $this->validate_request( $id, 'shop_order', 'read' );
if ( empty( $id ) )
return new WP_Error( 'woocommerce_api_invalid_id', __( 'Invalid order ID', 'woocommerce' ), array( 'status' => 404 ) );
if ( is_wp_error( $id ) )
return $id;
// invalid IDs return a valid WC_Order object with customer_user equal to a blank string
$order = new WC_Order( $id );
// TODO: check post type instead or abstract into generic object/permissions check in base class @see self::getOrderNotes()
if ( '' === $order->customer_user )
return new WP_Error( 'woocommerce_api_invalid_order', __( 'Invalid order', 'woocommerce' ), array( 'status' => 404 ) );
$order_data = array(
'id' => $order->id,
'order_number' => $order->get_order_number(),
@ -128,15 +111,15 @@ class WC_API_Orders extends WC_API_Resource {
'completed_at' => $order->completed_date,
'status' => $order->status,
'currency' => $order->order_currency,
'total' => $order->get_total(),
'total_line_items_quantity' => $order->get_item_count(),
'total_tax' => $order->get_total_tax(),
'total_shipping' => $order->get_total_shipping(),
'cart_tax' => $order->get_cart_tax(),
'shipping_tax' => $order->get_shipping_tax(),
'total_discount' => $order->get_total_discount(),
'cart_discount' => $order->get_cart_discount(),
'order_discount' => $order->get_order_discount(),
'total' => (string) $order->get_total(),
'total_line_items_quantity' => (string) $order->get_item_count(),
'total_tax' => (string) $order->get_total_tax(),
'total_shipping' => (string) $order->get_total_shipping(),
'cart_tax' => (string) $order->get_cart_tax(),
'shipping_tax' => (string) $order->get_shipping_tax(),
'total_discount' => (string) $order->get_total_discount(),
'cart_discount' => (string) $order->get_cart_discount(),
'order_discount' => (string) $order->get_order_discount(),
'shipping_methods' => $order->get_shipping_method(),
'payment_details' => array(
'method_id' => $order->payment_method,
@ -181,10 +164,10 @@ class WC_API_Orders extends WC_API_Resource {
$order_data['line_items'][] = array(
'id' => $item_id,
'subtotal' => $order->get_line_subtotal( $item ),
'total' => $order->get_line_total( $item ),
'total_tax' => $order->get_line_tax( $item ),
'quantity' => $item['qty'],
'subtotal' => (string) $order->get_line_subtotal( $item ),
'total' => (string) $order->get_line_total( $item ),
'total_tax' => (string) $order->get_line_tax( $item ),
'quantity' => (string) $item['qty'],
'tax_class' => ( ! empty( $item['tax_class'] ) ) ? $item['tax_class'] : null,
'name' => $item['name'],
'product_id' => ( isset( $product->variation_id ) ) ? $product->variation_id : $product->id,
@ -199,7 +182,7 @@ class WC_API_Orders extends WC_API_Resource {
'id' => $shipping_item_id,
'method_id' => $shipping_item['method_id'],
'method_title' => $shipping_item['name'],
'total' => $shipping_item['cost'],
'total' => (string) number_format( $shipping_item['cost'], 2 )
);
}
@ -209,7 +192,7 @@ class WC_API_Orders extends WC_API_Resource {
$order_data['tax_lines'][] = array(
'code' => $tax_code,
'title' => $tax->label,
'total' => $tax->amount,
'total' => (string) $tax->amount,
'compound' => (bool) $tax->is_compound,
);
}
@ -221,8 +204,8 @@ class WC_API_Orders extends WC_API_Resource {
'id' => $fee_item_id,
'title' => $fee_item['name'],
'tax_class' => ( ! empty( $fee_item['tax_class'] ) ) ? $fee_item['tax_class'] : null,
'total' => $order->get_line_total( $fee_item ),
'total_tax' => $order->get_line_tax( $fee_item ),
'total' => (string) $order->get_line_total( $fee_item ),
'total_tax' => (string) $order->get_line_tax( $fee_item ),
);
}
@ -232,7 +215,7 @@ class WC_API_Orders extends WC_API_Resource {
$order_data['coupon_lines'] = array(
'id' => $coupon_item_id,
'code' => $coupon_item['name'],
'amount' => $coupon_item['discount_amount'],
'amount' => (string) number_format( $coupon_item['discount_amount'], 2),
);
}
@ -251,40 +234,21 @@ class WC_API_Orders extends WC_API_Resource {
*
* @since 2.1
* @param string $status
* @param string $created_at_min
* @param string $created_at_max
* @param string $updated_at_min
* @param string $updated_at_max
* @param array $filter
* @return array
*/
public function getOrdersCount( $status = null, $created_at_min = null, $created_at_max = null, $updated_at_min = null, $updated_at_max = null ) {
public function get_orders_count( $status = null, $filter = array() ) {
$request_args = array(
'status' => $status,
'created_at_min' => $created_at_min,
'created_at_max' => $created_at_max,
'updated_at_min' => $updated_at_min,
'updated_at_max' => $updated_at_max,
);
if ( ! empty( $status ) )
$filter['status'] = $status;
$query = $this->queryOrders( $request_args );
$query = $this->query_orders( $filter );
// TODO: permissions?
return array( 'count' => $query->found_posts );
}
/**
* Create an order
*
* @since 2.1
* @param array $data
* @return array
*/
public function createOrder( $data ) {
// TODO: implement - a woocommerce_create_new_order() function would be great
return array();
}
/**
* Edit an order
@ -294,11 +258,16 @@ class WC_API_Orders extends WC_API_Resource {
* @param array $data
* @return array
*/
public function editOrder( $id, $data ) {
public function edit_order( $id, $data ) {
$id = $this->validate_request( $id, 'shop_order', 'write' );
if ( is_wp_error( $id ) )
return $id;
// TODO: implement
return $this->getOrder( $id );
return $this->get_order( $id );
}
/**
@ -309,9 +278,11 @@ class WC_API_Orders extends WC_API_Resource {
* @param bool $force true to permanently delete order, false to move to trash
* @return array
*/
public function deleteOrder( $id, $force = false ) {
public function delete_order( $id, $force = false ) {
return $this->deleteResource( $id, 'order', ( 'true' === $force ) );
$id = $this->validate_request( $id, 'shop_order', 'delete' );
return $this->delete( $id, 'order', ( 'true' === $force ) );
}
/**
@ -319,17 +290,13 @@ class WC_API_Orders extends WC_API_Resource {
* @param $id
* @return mixed
*/
public function getOrderNotes( $id ) {
public function get_order_notes( $id ) {
$id = absint( $id );
// ensure ID is valid order ID
$id = $this->validate_request( $id, 'order', 'read' );
if ( empty( $id ) )
return new WP_Error( 'woocommerce_api_invalid_id', __( 'Invalid order ID', 'woocommerce' ), array( 'status' => 404 ) );
$post = get_post( $id, ARRAY_A );
if ( 'shop_order' !== $post['post_type'] )
return new WP_Error( 'woocommerce_api_invalid_order', __( 'Invalid order', 'woocommerce' ), array( 'status' => 404 ) );
if ( is_wp_error( $id ) )
return $id;
$args = array(
'post_id' => $id,
@ -337,7 +304,6 @@ class WC_API_Orders extends WC_API_Resource {
'type' => 'order_note'
);
remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments', 10, 1 ) );
$notes = get_comments( $args );
@ -349,7 +315,7 @@ class WC_API_Orders extends WC_API_Resource {
foreach ( $notes as $note ) {
$order_notes[] = array(
'created_at' => $note->comment_date,
'created_at' => $note->comment_date_gmt, // TODO: date formatting
'note' => $note->comment_content,
'customer_note' => get_comment_meta( $note->comment_ID, 'is_customer_note', true ) ? true : false,
);
@ -363,9 +329,9 @@ class WC_API_Orders extends WC_API_Resource {
*
* @since 2.1
* @param array $args request arguments for filtering query
* @return array
* @return WP_Query
*/
private function queryOrders( $args ) {
private function query_orders( $args ) {
// set base query arguments
$query_args = array(
@ -382,15 +348,15 @@ class WC_API_Orders extends WC_API_Resource {
$query_args['tax_query'] = array(
array(
'taxonomy' => 'shop_order_status',
'field' => 'slug',
'terms' => $statuses,
'field' => 'slug',
'terms' => $statuses,
),
);
unset( $args['status'] );
}
$query_args = $this->mergeQueryArgs( $query_args, $args );
// TODO: navigation/total count headers for pagination
$query_args = $this->merge_query_args( $query_args, $args );
return new WP_Query( $query_args );
}

View File

@ -20,7 +20,7 @@ class WC_API_Products extends WC_API_Resource {
/**
* Register the routes for this class
*
* GET|POST /products
* GET /products
* GET /products/count
* GET|PUT|DELETE /products/<id>
* GET /products/<id>/reviews
@ -29,29 +29,28 @@ class WC_API_Products extends WC_API_Resource {
* @param array $routes
* @return array
*/
public function registerRoutes( $routes ) {
public function register_routes( $routes ) {
# GET|POST /products
# GET /products
$routes[ $this->base ] = array(
array( array( $this, 'getProducts' ), WC_API_Server::READABLE ),
array( array( $this, 'createProduct' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ),
array( array( $this, 'get_products' ), WC_API_Server::READABLE ),
);
# GET /products/count
$routes[ $this->base . '/count'] = array(
array( array( $this, 'getProductsCount' ), WC_API_Server::READABLE ),
array( array( $this, 'get_products_count' ), WC_API_Server::READABLE ),
);
# GET|PUT|DELETE /products/<id>
$routes[ $this->base . '/(?P<id>\d+)' ] = array(
array( array( $this, 'getProduct' ), WC_API_Server::READABLE ),
array( array( $this, 'editProduct' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ),
array( array( $this, 'deleteProduct' ), WC_API_Server::DELETABLE ),
array( array( $this, 'get_product' ), WC_API_Server::READABLE ),
array( array( $this, 'edit_product' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ),
array( array( $this, 'delete_product' ), WC_API_Server::DELETABLE ),
);
# GET /products/<id>/reviews
$routes[ $this->base . '/(?P<id>\d+)/reviews' ] = array(
array( array( $this, 'getProductReviews' ), WC_API_Server::READABLE ),
array( array( $this, 'get_product_reviews' ), WC_API_Server::READABLE ),
);
return $routes;
@ -61,35 +60,30 @@ class WC_API_Products extends WC_API_Resource {
* Get all products
*
* @since 2.1
* @param array $fields
* @param string $fields
* @param string $type
* @param string $created_at_min
* @param string $created_at_max
* @param string $q search terms
* @param int $limit coupons per response
* @param int $offset
* @param array $filter
* @return array
*/
public function getProducts( $fields = null, $type = null, $created_at_min = null, $created_at_max = null, $q = null, $limit = null, $offset = null ) {
public function get_products( $fields = null, $type = null, $filter = array() ) {
$request_args = array(
'type' => $type,
'created_at_min' => $created_at_min,
'created_at_max' => $created_at_max,
'q' => $q,
'limit' => $limit,
'offset' => $offset,
);
if ( ! empty( $type ) )
$filter['type'] = $type;
$query = $this->queryProducts( $request_args );
$query = $this->query_products( $filter );
$products = array();
foreach( $query->posts as $product_id ) {
$products[] = $this->getProduct( $product_id, $fields );
if ( ! $this->is_readable( $product_id ) )
continue;
$products[] = $this->get_product( $product_id, $fields );
}
$this->server->query_navigation_headers( $query );
return array( 'products' => $products );
}
@ -101,18 +95,15 @@ class WC_API_Products extends WC_API_Resource {
* @param string $fields
* @return array
*/
public function getProduct( $id, $fields = null ) {
public function get_product( $id, $fields = null ) {
$id = absint( $id );
$id = $this->validate_request( $id, 'product', 'read' );
if ( empty( $id ) )
return new WP_Error( 'woocommerce_api_invalid_id', __( 'Invalid product ID', 'woocommerce' ), array( 'status' => 404 ) );
if ( is_wp_error( $id ) )
return $id;
$product = get_product( $id );
if ( 'product' !== $product->get_post_data()->post_type )
return new WP_Error( 'woocommerce_api_invalid_product', __( 'Invalid product', 'woocommerce' ), array( 'status' => 404 ) );
$product_data = array(
'id' => $product->id
);
@ -125,38 +116,21 @@ class WC_API_Products extends WC_API_Resource {
*
* @since 2.1
* @param string $type
* @param string $created_at_min
* @param string $created_at_max
* @param array $filter
* @return array
*/
public function getProductsCount( $type = null, $created_at_min = null, $created_at_max = null ) {
public function get_products_count( $type = null, $filter = array() ) {
$request_args = array(
'type' => $type,
'created_at_min' => $created_at_min,
'created_at_max' => $created_at_max,
);
if ( ! empty( $type ) )
$filter['type'] = $type;
$query = $this->queryProducts( $request_args );
// TODO: permissions?
$query = $this->query_products( $filter );
return array( 'count' => $query->found_posts );
}
/**
* Create a product
*
* @since 2.1
* @param array $data
* @return array
*/
public function createProduct( $data ) {
// TODO: implement - what's the minimum set of data required? woocommerce_create_product() would be nice
return array();
}
/**
* Edit a product
*
@ -165,11 +139,16 @@ class WC_API_Products extends WC_API_Resource {
* @param array $data
* @return array
*/
public function editProduct( $id, $data ) {
public function edit_product( $id, $data ) {
$id = $this->validate_request( $id, 'product', 'edit' );
if ( is_wp_error( $id ) )
return $id;
// TODO: implement
return $this->getProduct( $id );
return $this->get_product( $id );
}
/**
@ -180,9 +159,14 @@ class WC_API_Products extends WC_API_Resource {
* @param bool $force true to permanently delete order, false to move to trash
* @return array
*/
public function deleteProduct( $id, $force = false ) {
public function delete_product( $id, $force = false ) {
return $this->deleteResource( $id, 'product', ( 'true' === $force ) );
$id = $this->validate_request( $id, 'product', 'delete' );
if ( is_wp_error( $id ) )
return $id;
return $this->delete( $id, 'product', ( 'true' === $force ) );
}
/**
@ -190,7 +174,14 @@ class WC_API_Products extends WC_API_Resource {
* @param $id
* @return mixed
*/
public function getProductReviews( $id ) {
public function get_product_reviews( $id ) {
$id = $this->validate_request( $id, 'product', 'read' );
if ( is_wp_error( $id ) )
return $id;
// TODO: implement
return array();
}
@ -200,9 +191,9 @@ class WC_API_Products extends WC_API_Resource {
*
* @since 2.1
* @param array $args request arguments for filtering query
* @return array
* @return WP_Query
*/
private function queryProducts( $args ) {
private function query_products( $args ) {
// set base query arguments
$query_args = array(
@ -213,12 +204,23 @@ class WC_API_Products extends WC_API_Resource {
'meta_query' => array(),
);
if ( ! empty( $args['type'] ) ) {
$query_args['tax_query'] = array(
array(
'taxonomy' => 'product_type',
'field' => 'slug',
'terms' => $args['type'],
),
);
unset( $args['type'] );
}
// TODO: some param to show hidden products, but hide by default
$query_args['meta_query'][] = WC()->query->visibility_meta_query();
$query_args = $this->mergeQueryArgs( $query_args, $args );
// TODO: navigation/total count headers for pagination
$query_args = $this->merge_query_args( $query_args, $args );
return new WP_Query( $query_args );
}

View File

@ -28,16 +28,16 @@ class WC_API_Reports extends WC_API_Resource {
* @param array $routes
* @return array
*/
public function registerRoutes( $routes ) {
public function register_routes( $routes ) {
# GET /reports
$routes[ $this->base ] = array(
array( array( $this, 'getReports' ), WC_API_Server::READABLE ),
array( array( $this, 'get_reports' ), WC_API_Server::READABLE ),
);
# GET /reports/sales
$routes[ $this->base . '/sales'] = array(
array( array( $this, 'getSalesReport' ), WC_API_Server::READABLE ),
array( array( $this, 'get_sales_report' ), WC_API_Server::READABLE ),
);
return $routes;
@ -50,7 +50,7 @@ class WC_API_Reports extends WC_API_Resource {
* @since 2.1
* @return array
*/
public function getReports() {
public function get_reports() {
return array( 'reports' => array( 'sales' ) );
}
@ -62,7 +62,7 @@ class WC_API_Reports extends WC_API_Resource {
* @since 2.1
* @return array
*/
public function getSalesReport() {
public function get_sales_report() {
// TODO: implement - DRY by abstracting the report classes?

View File

@ -32,17 +32,75 @@ class WC_API_Resource {
$this->server = $server;
// automatically register routes for sub-classes
add_filter( 'woocommerce_api_endpoints', array( $this, 'registerRoutes' ) );
add_filter( 'woocommerce_api_endpoints', array( $this, 'register_routes' ) );
// remove fields from responses when requests specify certain fields
// note these are hooked at a later priority so data added via filters (e.g. customer data to the order response)
// still has the fields filtered properly
add_filter( 'woocommerce_api_order_response', array( $this, 'filterFields' ), 20, 3 );
add_filter( 'woocommerce_api_coupon_response', array( $this, 'filterFields' ), 20, 3 );
add_filter( 'woocommerce_api_customer_response', array( $this, 'filterFields' ), 20, 3 );
add_filter( 'woocommerce_api_product_response', array( $this, 'filterFields' ), 20, 3 );
foreach ( array( 'order', 'coupon', 'customer', 'product', 'report' ) as $resource ) {
add_filter( "woocommerce_api_{$resource}_response", array( $this, 'maybe_add_meta' ), 15, 2 );
add_filter( "woocommerce_api_{$resource}_response", array( $this, 'filter_response_fields' ), 20, 3 );
}
}
/**
* Validate the request by checking:
*
* 1) the ID is a valid integer
* 2) the ID returns a valid post object and matches the provided post type
* 3) the current user has the proper permissions to read/edit/delete the post
*
* @since 2.1
* @param string|int $id the post ID
* @param string $type the post type, either `shop_order`, `shop_coupon`, or `product`
* @param string $context the context of the request, either `read`, `edit` or `delete`
* @return int|WP_Error valid post ID or WP_Error if any of the checks fails
*/
protected function validate_request( $id, $type, $context ) {
if ( 'shop_order' === $type || 'shop_coupon' === $type )
$resource_name = str_replace( 'shop_', '', $type );
else
$resource_name = $type;
$id = absint( $id );
// validate ID
if ( empty( $id ) )
return new WP_Error( "woocommerce_api_invalid_{$resource_name}_id", sprintf( __( 'Invalid %s ID', 'woocommerce' ), $type ), array( 'status' => 404 ) );
// only custom post types have per-post type/permission checks
if ( 'customer' !== $type ) {
$post = get_post( $id, ARRAY_A );
// validate post type
if ( $type !== $post['post_type'] )
return new WP_Error( "woocommerce_api_invalid_{$resource_name}", sprintf( __( 'Invalid %s', 'woocommerce' ), $resource_name ), array( 'status' => 404 ) );
// validate permissions
switch ( $context ) {
case 'read':
if ( ! $this->is_readable( $post ) )
return new WP_Error( "woocommerce_api_user_cannot_read_{$resource_name}", sprintf( __( 'You do not have permission to read this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) );
break;
case 'edit':
if ( ! $this->is_editable( $post ) )
return new WP_Error( "woocommerce_api_user_cannot_edit_{$resource_name}", sprintf( __( 'You do not have permission to edit this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) );
break;
case 'delete':
if ( ! $this->is_deletable( $post ) )
return new WP_Error( "woocommerce_api_user_cannot_delete_{$resource_name}", sprintf( __( 'You do not have permission to delete this %s', 'woocommerce' ), $resource_name ), array( 'status' => 401 ) );
break;
}
}
return $id;
}
/**
* Add common request arguments to argument list before WP_Query is run
@ -52,25 +110,32 @@ class WC_API_Resource {
* @param array $request_args arguments provided in the request
* @return array
*/
protected function mergeQueryArgs( $base_args, $request_args ) {
protected function merge_query_args( $base_args, $request_args ) {
$args = array();
// TODO: updated_at_min, updated_at_max,s date formatting
// TODO: WP 3.7 is required to support date args
if ( ! empty( $request_args['created_at_min'] ) || ! empty( $request_args['created_at_max'] ) ) {
// TODO: convert all dates from provided timezone into UTC
// TODO: return all dates in provided timezone, else UTC
// date
if ( ! empty( $request_args['created_at_min'] ) || ! empty( $request_args['created_at_max'] ) || ! empty( $request_args['updated_at_min'] ) || ! empty( $request_args['updated_at_max'] ) ) {
$args['date_query'] = array(
array(
'inclusive' => true,
)
);
$args['date_query'] = array();
// resources created after specified date
if ( ! empty( $request_args['created_at_min'] ) )
$args['date_query'] = array_merge( $args['date_query'], array( 'after' => $request_args['created_at_min'] ) );
$args['date_query'][] = array( 'column' => 'post_date_gmt', 'after' => $request_args['created_at_min'], 'inclusive' => true );
// resources created before specified date
if ( ! empty( $request_args['created_at_max'] ) )
$args['date_query'] = array_merge( $args['date_query'], array( 'before' => $request_args['created_at_min'] ) );
$args['date_query'][] = array( 'column' => 'post_date_gmt', 'before' => $request_args['created_at_max'], 'inclusive' => true );
// resources updated after specified date
if ( ! empty( $request_args['updated_at_min'] ) )
$args['date_query'][] = array( 'column' => 'post_modified_gmt', 'after' => $request_args['updated_at_min'], 'inclusive' => true );
// resources updated before specified date
if ( ! empty( $request_args['updated_at_max'] ) )
$args['date_query'][] = array( 'column' => 'post_modified_gmt', 'before' => $request_args['updated_at_max'], 'inclusive' => true );
}
// search
@ -85,9 +150,35 @@ class WC_API_Resource {
if ( ! empty( $request_args['offset'] ) )
$args['offset'] = $request_args['offset'];
// resource page
if ( empty( $request_args['page'] ) )
$args['paged'] = 1;
else
$args['paged'] = absint( $request_args['page'] );
return array_merge( $base_args, $args );
}
/**
* Add meta to resources when requested by the client. Meta is added as a top-level
* `<resource_name>_meta` attribute (e.g. `order_meta`) as a list of key/value pairs.
*
* @since 2.1
* @param array $data the resource data
* @param object $resource the resource object (e.g WC_Order)
* @return mixed
*/
public function maybe_add_meta( $data, $resource ) {
if ( isset( $this->server->params['GET']['filter']['meta'] ) && 'true' === $this->server->params['GET']['filter']['meta'] ) {
// TODO: implement
}
return $data;
}
/**
* Restrict the fields included in the response if the request specified certain only certain fields should be returned
*
@ -99,7 +190,7 @@ class WC_API_Resource {
* @param array|string the requested list of fields to include in the response
* @return mixed
*/
public function filterFields( $data, $resource, $fields ) {
public function filter_response_fields( $data, $resource, $fields ) {
if ( empty( $fields ) )
return $data;
@ -118,20 +209,18 @@ class WC_API_Resource {
/**
* Delete a given resource
*
* @see WP_JSON_Posts::deletePost
*
* @since 2.1
* @param int $id the resource ID
* @param string $type the type of resource, either `order`,`coupon`, `product`, or `customer`
* @param string $type the resource post type, or `customer`
* @param bool $force true to permanently delete resource, false to move to trash (not supported for `customer`)
* @return array|WP_Error
*/
protected function deleteResource( $id, $type, $force = false ) {
protected function delete( $id, $type, $force = false ) {
$id = absint( $id );
if ( empty( $id ) )
return new WP_Error( 'woocommerce_api_invalid_id', sprintf( __( 'Invalid %s ID', 'woocommerce' ), $type ), array( 'status' => 404 ) );
if ( 'shop_order' === $type || 'shop_coupon' === $type )
$resource_name = str_replace( 'shop_', '', $type );
else
$resource_name = $type;
if ( 'customer' === $type ) {
@ -146,33 +235,93 @@ class WC_API_Resource {
// delete order/coupon/product
$post = get_post( $id, ARRAY_A );
// TODO: check if provided $type is the same as $post['post_type']
if ( empty( $post['ID'] ) )
return new WP_Error( 'woocommerce_api_invalid_id', sprintf( __( 'Invalid % ID', 'woocommerce' ), $type ), array( 'status' => 404 ) );
$post_type = get_post_type_object( $post['post_type'] );
if ( ! current_user_can( $post_type->cap->delete_post, $id ) )
return new WP_Error( "woocommerce_api_user_cannot_delete_{$type}", sprintf( __( 'You do not have permission to delete this %s', 'woocommerce' ), $type ), array( 'status' => 401 ) );
$result = ( $force ) ? wp_delete_post( $id, true ) : wp_trash_post( $id );
if ( ! $result )
return new WP_Error( "woocommerce_api_cannot_delete_{$type}", sprintf( __( 'The %s cannot be deleted', 'woocommerce' ), $type ), array( 'status' => 500 ) );
return new WP_Error( "woocommerce_api_cannot_delete_{$resource_name}", sprintf( __( 'This %s cannot be deleted', 'woocommerce' ), $resource_name ), array( 'status' => 500 ) );
if ( $force ) {
return array( 'message' => sprintf( __( 'Permanently deleted %s', 'woocommerce' ), $type ) );
return array( 'message' => sprintf( __( 'Permanently deleted %s', 'woocommerce' ), $resource_name ) );
} else {
$this->server->send_status( '202' );
return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), $type ) );
return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), $resource_name ) );
}
}
}
/**
* Checks if the given post is readable by the current user
*
* @since 2.1
* @see WC_API_Resource::check_permission()
* @param WP_Post|int $post
* @return bool
*/
protected function is_readable( $post ) {
return $this->check_permission( $post, 'read' );
}
/**
* Checks if the given post is editable by the current user
*
* @since 2.1
* @see WC_API_Resource::check_permission()
* @param WP_Post|int $post
* @return bool
*/
protected function is_editable( $post ) {
return $this->check_permission( $post, 'edit' );
}
/**
* Checks if the given post is deletable by the current user
*
* @since 2.1
* @see WC_API_Resource::check_permission()
* @param WP_Post|int $post
* @return bool
*/
protected function is_deletable( $post ) {
return $this->check_permission( $post, 'delete' );
}
/**
* Checks the permissions for the current user given a post and context
*
* @since 2.1
* @param WP_Post|int $post
* @param string $context the type of permission to check, either `read`, `write`, or `delete`
* @return bool true if the current user has the permissions to perform the context on the post
*/
private function check_permission( $post, $context ) {
if ( ! is_a( $post, 'WP_Post' ) )
$post = get_post( $post, ARRAY_A );
if ( is_null( $post ) )
return false;
$post_type = get_post_type_object( $post['post_type'] );
if ( 'read' === $context )
return current_user_can( $post_type->cap->read_post, $post['ID'] );
elseif ( 'edit' === $context )
return current_user_can( $post_type->cap->edit_post, $post['ID'] );
elseif ( 'delete' === $context )
return current_user_can( $post_type->cap->delete_post, $post['ID'] );
else
return false;
}
}