parent
c1854b26b9
commit
87ff36db12
|
@ -49,8 +49,8 @@ class WC_API_Coupons extends WC_API_Resource {
|
|||
array( array( $this, 'delete_coupon' ), WC_API_Server::DELETABLE ),
|
||||
);
|
||||
|
||||
# GET /coupons/code/<code>
|
||||
$routes[ $this->base . '/code/(?P<code>\w[\w\s\-]*)' ] = array( // note that coupon codes can contain spaces, dashes and underscores
|
||||
# GET /coupons/code/<code>, note that coupon codes can contain spaces, dashes and underscores
|
||||
$routes[ $this->base . '/code/(?P<code>\w[\w\s\-]*)' ] = array(
|
||||
array( array( $this, 'get_coupon_by_code' ), WC_API_Server::READABLE ),
|
||||
);
|
||||
|
||||
|
@ -108,11 +108,15 @@ class WC_API_Coupons extends WC_API_Resource {
|
|||
|
||||
$coupon = new WC_Coupon( $code );
|
||||
|
||||
$coupon_post = get_post( $coupon->id );
|
||||
|
||||
$coupon_data = array(
|
||||
'id' => $coupon->id,
|
||||
'code' => $coupon->code,
|
||||
'type' => $coupon->type,
|
||||
'amount' => (string) number_format( $coupon->amount, 2 ),
|
||||
'created_at' => $this->server->format_datetime( $coupon_post->post_date_gmt ),
|
||||
'updated_at' => $this->server->format_datetime( $coupon_post->post_modified_gmt ),
|
||||
'amount' => woocommerce_format_decimal( $coupon->amount ),
|
||||
'individual_use' => $coupon->individual_use,
|
||||
'product_ids' => $coupon->product_ids,
|
||||
'exclude_product_ids' => $coupon->exclude_product_ids,
|
||||
|
@ -120,7 +124,7 @@ class WC_API_Coupons extends WC_API_Resource {
|
|||
'usage_limit_per_user' => $coupon->usage_limit_per_user,
|
||||
'limit_usage_to_x_items' => $coupon->limit_usage_to_x_items,
|
||||
'usage_count' => $coupon->usage_count,
|
||||
'expiry_date' => $coupon->expiry_date,
|
||||
'expiry_date' => $this->server->format_datetime( $coupon->expiry_date ),
|
||||
'apply_before_tax' => $coupon->apply_before_tax(),
|
||||
'enable_free_shipping' => $coupon->enable_free_shipping(),
|
||||
'product_categories' => $coupon->product_categories,
|
||||
|
@ -200,6 +204,7 @@ class WC_API_Coupons extends WC_API_Resource {
|
|||
return $id;
|
||||
|
||||
// TODO: implement
|
||||
|
||||
return $this->get_coupon( $id );
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ class WC_API_Customers extends WC_API_Resource {
|
|||
$customers[] = $this->get_customer( $user_id, $fields );
|
||||
}
|
||||
|
||||
// TODO: add navigation/total count headers for pagination
|
||||
// TODO: add navigation/total count headers for pagination
|
||||
|
||||
return array( 'customers' => $customers );
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ class WC_API_Customers extends WC_API_Resource {
|
|||
$customer = new WP_User( $id );
|
||||
|
||||
// get info about user's last order
|
||||
$last_order = $wpdb->get_row( "SELECT id, post_date
|
||||
$last_order = $wpdb->get_row( "SELECT id, post_date_gmt
|
||||
FROM $wpdb->posts AS posts
|
||||
LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id
|
||||
WHERE meta.meta_key = '_customer_user'
|
||||
|
@ -138,15 +138,15 @@ class WC_API_Customers extends WC_API_Resource {
|
|||
|
||||
$customer_data = array(
|
||||
'id' => $customer->ID,
|
||||
'created_at' => $customer->user_registered,
|
||||
'created_at' => $this->server->format_datetime( $customer->user_registered ),
|
||||
'email' => $customer->user_email,
|
||||
'first_name' => $customer->first_name,
|
||||
'last_name' => $customer->last_name,
|
||||
'username' => $customer->user_login,
|
||||
'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' => (string) number_format( $customer->_money_spent, 2 ),
|
||||
'last_order_date' => is_object( $last_order ) ? $this->server->format_datetime( $last_order->post_date_gmt ) : null,
|
||||
'orders_count' => (int) $customer->_order_count,
|
||||
'total_spent' => woocommerce_format_decimal( $customer->_money_spent ),
|
||||
'avatar_url' => $this->get_avatar_url( $customer->customer_email ),
|
||||
'billing_address' => array(
|
||||
'first_name' => $customer->billing_first_name,
|
||||
|
@ -188,7 +188,8 @@ class WC_API_Customers extends WC_API_Resource {
|
|||
|
||||
$query = $this->query_customers( $filter );
|
||||
|
||||
// TODO: permissions?
|
||||
if ( ! current_user_can( 'list_users' ) )
|
||||
return new WP_Error( 'woocommerce_api_user_cannot_read_customer', __( 'You do not have permission to read customers', 'woocommerce' ), array( 'status' => 401 ) );
|
||||
|
||||
return array( 'count' => $query->get_total() );
|
||||
}
|
||||
|
@ -311,10 +312,10 @@ class WC_API_Customers extends WC_API_Resource {
|
|||
$query_args['offset'] = $args['offset'];
|
||||
|
||||
if ( ! empty( $args['created_at_min'] ) )
|
||||
$this->created_at_min = $args['created_at_min'];
|
||||
$this->created_at_min = $this->server->parse_datetime( $args['created_at_min'] );
|
||||
|
||||
if ( ! empty( $args['created_at_max'] ) )
|
||||
$this->created_at_max = $args['created_at_max'];
|
||||
$this->created_at_max = $this->server->parse_datetime( $args['created_at_max'] );
|
||||
|
||||
// TODO: support page argument - requires custom implementation as WP_User_Query has no built-in pagination like WP_Query
|
||||
|
||||
|
@ -352,10 +353,10 @@ class WC_API_Customers extends WC_API_Resource {
|
|||
public function modify_user_query( $query ) {
|
||||
|
||||
if ( $this->created_at_min )
|
||||
$query->query_where .= sprintf( " AND DATE(user_registered) >= '%s'", date( 'Y-m-d H:i:s', strtotime( $this->created_at_min ) ) ); // TODO: date formatting
|
||||
$query->query_where .= sprintf( " AND user_registered >= STR_TO_DATE( '%s', '%%Y-%%m-%%d %%h:%%i:%%s' )", esc_sql( $this->created_at_min ) );
|
||||
|
||||
if ( $this->created_at_max )
|
||||
$query->query_where .= sprintf( " AND DATE(user_registered) <= '%s'", date( 'Y-m-d H:i:s', strtotime( $this->created_at_max ) ) ); // TODO: date formatting
|
||||
$query->query_where .= sprintf( " AND user_registered <= STR_TO_DATE( '%s', '%%Y-%%m-%%d %%h:%%i:%%s' )", esc_sql( $this->created_at_max ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -61,7 +61,7 @@ class WC_API_JSON_Handler implements WC_API_Handler {
|
|||
|
||||
WC()->api->server->send_status( 400 );
|
||||
|
||||
$data = array( array( 'code' => 'woocommerce_api_json_callback_invalid', __( 'The JSONP callback function is invalid', 'woocommerce' ) ) );;
|
||||
$data = array( array( 'code' => 'woocommerce_api_json_callback_invalid', __( 'The JSONP callback function is invalid', 'woocommerce' ) ) );
|
||||
}
|
||||
|
||||
return $_GET['_jsonp'] . '(' . json_encode( $data ) . ')';
|
||||
|
|
|
@ -76,6 +76,9 @@ class WC_API_Orders extends WC_API_Resource {
|
|||
|
||||
foreach( $query->posts as $order_id ) {
|
||||
|
||||
if ( ! $this->is_readable( $order_id ) )
|
||||
continue;
|
||||
|
||||
$orders[] = $this->get_order( $order_id, $fields );
|
||||
}
|
||||
|
||||
|
@ -103,23 +106,25 @@ class WC_API_Orders extends WC_API_Resource {
|
|||
|
||||
$order = new WC_Order( $id );
|
||||
|
||||
$order_post = get_post( $id );
|
||||
|
||||
$order_data = array(
|
||||
'id' => $order->id,
|
||||
'order_number' => $order->get_order_number(),
|
||||
'created_at' => $order->order_date,
|
||||
'updated_at' => $order->modified_date,
|
||||
'completed_at' => $order->completed_date,
|
||||
'created_at' => $this->server->format_datetime( $order_post->post_date_gmt ),
|
||||
'updated_at' => $this->server->format_datetime( $order_post->post_modified_gmt ),
|
||||
'completed_at' => $this->server->format_datetime( $order->completed_date, true ),
|
||||
'status' => $order->status,
|
||||
'currency' => $order->order_currency,
|
||||
'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(),
|
||||
'total' => woocommerce_format_decimal( $order->get_total() ),
|
||||
'total_line_items_quantity' => $order->get_item_count(),
|
||||
'total_tax' => woocommerce_format_decimal( $order->get_total_tax() ),
|
||||
'total_shipping' => woocommerce_format_decimal( $order->get_total_shipping() ),
|
||||
'cart_tax' => woocommerce_format_decimal( $order->get_cart_tax() ),
|
||||
'shipping_tax' => woocommerce_format_decimal( $order->get_shipping_tax() ),
|
||||
'total_discount' => woocommerce_format_decimal( $order->get_total_discount() ),
|
||||
'cart_discount' => woocommerce_format_decimal( $order->get_cart_discount() ),
|
||||
'order_discount' => woocommerce_format_decimal( $order->get_order_discount() ),
|
||||
'shipping_methods' => $order->get_shipping_method(),
|
||||
'payment_details' => array(
|
||||
'method_id' => $order->payment_method,
|
||||
|
@ -169,10 +174,10 @@ class WC_API_Orders extends WC_API_Resource {
|
|||
|
||||
$order_data['line_items'][] = array(
|
||||
'id' => $item_id,
|
||||
'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'],
|
||||
'subtotal' => woocommerce_format_decimal( $order->get_line_subtotal( $item ) ),
|
||||
'total' => woocommerce_format_decimal( $order->get_line_total( $item ) ),
|
||||
'total_tax' => woocommerce_format_decimal( $order->get_line_tax( $item ) ),
|
||||
'quantity' => (int) $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,
|
||||
|
@ -187,7 +192,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' => (string) number_format( $shipping_item['cost'], 2 )
|
||||
'total' => woocommerce_format_decimal( $shipping_item['cost'] ),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -197,7 +202,7 @@ class WC_API_Orders extends WC_API_Resource {
|
|||
$order_data['tax_lines'][] = array(
|
||||
'code' => $tax_code,
|
||||
'title' => $tax->label,
|
||||
'total' => (string) $tax->amount,
|
||||
'total' => woocommerce_format_decimal( $tax->amount ),
|
||||
'compound' => (bool) $tax->is_compound,
|
||||
);
|
||||
}
|
||||
|
@ -209,8 +214,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' => (string) $order->get_line_total( $fee_item ),
|
||||
'total_tax' => (string) $order->get_line_tax( $fee_item ),
|
||||
'total' => woocommerce_format_decimal( $order->get_line_total( $fee_item ) ),
|
||||
'total_tax' => woocommerce_format_decimal( $order->get_line_tax( $fee_item ) ),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -220,7 +225,7 @@ class WC_API_Orders extends WC_API_Resource {
|
|||
$order_data['coupon_lines'] = array(
|
||||
'id' => $coupon_item_id,
|
||||
'code' => $coupon_item['name'],
|
||||
'amount' => (string) number_format( $coupon_item['discount_amount'], 2),
|
||||
'amount' => woocommerce_format_decimal( $coupon_item['discount_amount'] ),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -263,7 +268,7 @@ class WC_API_Orders extends WC_API_Resource {
|
|||
if ( is_wp_error( $id ) )
|
||||
return $id;
|
||||
|
||||
// TODO: implement
|
||||
// TODO: implement, especially for status change
|
||||
|
||||
return $this->get_order( $id );
|
||||
}
|
||||
|
@ -317,7 +322,7 @@ class WC_API_Orders extends WC_API_Resource {
|
|||
|
||||
$order_notes[] = array(
|
||||
'id' => $note->comment_ID,
|
||||
'created_at' => $note->comment_date_gmt, // TODO: date formatting
|
||||
'created_at' => $this->server->format_datetime( $note->comment_date_gmt ),
|
||||
'note' => $note->comment_content,
|
||||
'customer_note' => get_comment_meta( $note->comment_ID, 'is_customer_note', true ) ? true : false,
|
||||
);
|
||||
|
|
|
@ -208,7 +208,7 @@ class WC_API_Products extends WC_API_Resource {
|
|||
|
||||
$reviews[] = array(
|
||||
'id' => $comment->comment_ID,
|
||||
'created_at' => $comment->comment_date_gmt, // TODO: date formatting
|
||||
'created_at' => $this->server->format_datetime( $comment->comment_date_gmt ),
|
||||
'review' => $comment->comment_content,
|
||||
'rating' => get_comment_meta( $comment->comment_ID, 'rating', true ),
|
||||
'reviewer_name' => $comment->comment_author,
|
||||
|
@ -240,20 +240,19 @@ class WC_API_Products extends WC_API_Resource {
|
|||
|
||||
if ( ! empty( $args['type'] ) ) {
|
||||
|
||||
$types = explode( ',', $args['type'] );
|
||||
|
||||
$query_args['tax_query'] = array(
|
||||
array(
|
||||
'taxonomy' => 'product_type',
|
||||
'field' => 'slug',
|
||||
'terms' => $args['type'],
|
||||
'terms' => $types,
|
||||
),
|
||||
);
|
||||
|
||||
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->merge_query_args( $query_args, $args );
|
||||
|
||||
return new WP_Query( $query_args );
|
||||
|
@ -271,23 +270,23 @@ class WC_API_Products extends WC_API_Resource {
|
|||
return array(
|
||||
'title' => $product->get_title(),
|
||||
'id' => (int) $product->is_type( 'variation' ) ? $product->get_variation_id() : $product->id,
|
||||
'created_at' => $product->get_post_data()->post_date_gmt, // TODO: date formatting
|
||||
'updated_at' => $product->get_post_data()->post_modified_gmt, // TODO: date formatting
|
||||
'created_at' => $this->server->format_datetime( $product->get_post_data()->post_date_gmt ),
|
||||
'updated_at' => $this->server->format_datetime( $product->get_post_data()->post_modified_gmt ),
|
||||
'type' => $product->product_type,
|
||||
'status' => $product->get_post_data()->post_status,
|
||||
'downloadable' => $product->is_downloadable(),
|
||||
'virtual' => $product->is_virtual(),
|
||||
'permalink' => $product->get_permalink(),
|
||||
'sku' => $product->get_sku(),
|
||||
'price' => (string) $product->get_price(),
|
||||
'regular_price' => (string) $product->get_regular_price(),
|
||||
'sale_price' => (string) $product->get_sale_price(),
|
||||
'price' => woocommerce_format_decimal( $product->get_price() ),
|
||||
'regular_price' => woocommerce_format_decimal( $product->get_regular_price() ),
|
||||
'sale_price' => $product->get_sale_price() ? woocommerce_format_decimal( $product->get_sale_price() ) : null,
|
||||
'price_html' => $product->get_price_html(),
|
||||
'taxable' => $product->is_taxable(),
|
||||
'tax_status' => $product->get_tax_status(),
|
||||
'tax_class' => $product->get_tax_class(),
|
||||
'managing_stock' => $product->managing_stock(),
|
||||
'stock_quantity' => (string) $product->get_stock_quantity(),
|
||||
'stock_quantity' => (int) $product->get_stock_quantity(),
|
||||
'in_stock' => $product->is_in_stock(),
|
||||
'backorders_allowed' => $product->backorders_allowed(),
|
||||
'backordered' => $product->is_on_backorder(),
|
||||
|
@ -297,7 +296,7 @@ class WC_API_Products extends WC_API_Resource {
|
|||
'visible' => $product->is_visible(),
|
||||
'catalog_visibility' => $product->visibility,
|
||||
'on_sale' => $product->is_on_sale(),
|
||||
'weight' => $product->get_weight(),
|
||||
'weight' => $product->get_weight() ? woocommerce_format_decimal( $product->get_weight() ) : null,
|
||||
'dimensions' => array(
|
||||
'length' => $product->length,
|
||||
'width' => $product->width,
|
||||
|
@ -311,18 +310,18 @@ class WC_API_Products extends WC_API_Resource {
|
|||
'description' => apply_filters( 'the_content', $product->get_post_data()->post_content ),
|
||||
'short_description' => apply_filters( 'woocommerce_short_description', $product->get_post_data()->post_excerpt ),
|
||||
'reviews_allowed' => ( 'open' === $product->get_post_data()->comment_status ),
|
||||
'average_rating' => $product->get_average_rating(),
|
||||
'rating_count' => $product->get_rating_count(),
|
||||
'related_ids' => array_values( $product->get_related() ),
|
||||
'upsell_ids' => $product->get_upsells(),
|
||||
'cross_sell_ids' => $product->get_cross_sells(),
|
||||
'average_rating' => woocommerce_format_decimal( $product->get_average_rating() ),
|
||||
'rating_count' => (int) $product->get_rating_count(),
|
||||
'related_ids' => array_map( 'absint', array_values( $product->get_related() ) ),
|
||||
'upsell_ids' => array_map( 'absint', $product->get_upsells() ),
|
||||
'cross_sell_ids' => array_map( 'absint', $product->get_cross_sells() ),
|
||||
'categories' => wp_get_post_terms( $product->id, 'product_cat', array( 'fields' => 'names' ) ),
|
||||
'tags' => wp_get_post_terms( $product->id, 'product_tag', array( 'fields' => 'names' ) ),
|
||||
'images' => $this->get_images( $product ),
|
||||
'attributes' => $this->get_attributes( $product ),
|
||||
'downloads' => $this->get_downloads( $product ),
|
||||
'download_limit' => $product->download_limit,
|
||||
'download_expiry' => $product->download_expiry,
|
||||
'download_limit' => (int) $product->download_limit,
|
||||
'download_expiry' => (int) $product->download_expiry,
|
||||
'download_type' => $product->download_type,
|
||||
'purchase_note' => apply_filters( 'the_content', $product->purchase_note ),
|
||||
'variations' => array(),
|
||||
|
@ -350,25 +349,25 @@ class WC_API_Products extends WC_API_Resource {
|
|||
|
||||
$variations[] = array(
|
||||
'id' => $variation->get_variation_id(),
|
||||
'created_at' => $variation->get_post_data()->post_date_gmt, // TODO: date formatting
|
||||
'updated_at' => $variation->get_post_data()->post_modified_gmt, // TODO: date formatting
|
||||
'created_at' => $this->server->format_datetime( $variation->get_post_data()->post_date_gmt ),
|
||||
'updated_at' => $this->server->format_datetime( $variation->get_post_data()->post_modified_gmt ),
|
||||
'downloadable' => $variation->is_downloadable(),
|
||||
'virtual' => $variation->is_virtual(),
|
||||
'permalink' => $variation->get_permalink(),
|
||||
'sku' => $variation->get_sku(),
|
||||
'price' => (string) $variation->get_price(),
|
||||
'regular_price' => (string) $variation->get_regular_price(),
|
||||
'sale_price' => (string) $variation->get_sale_price(),
|
||||
'price' => woocommerce_format_decimal( $variation->get_price() ),
|
||||
'regular_price' => woocommerce_format_decimal( $variation->get_regular_price() ),
|
||||
'sale_price' => $variation->get_sale_price() ? woocommerce_format_decimal( $variation->get_sale_price() ) : null,
|
||||
'taxable' => $variation->is_taxable(),
|
||||
'tax_status' => $variation->get_tax_status(),
|
||||
'tax_class' => $variation->get_tax_class(),
|
||||
'stock_quantity' => (string) $variation->get_stock_quantity(),
|
||||
'stock_quantity' => (int) $variation->get_stock_quantity(),
|
||||
'in_stock' => $variation->is_in_stock(),
|
||||
'backordered' => $variation->is_on_backorder(),
|
||||
'purchaseable' => $variation->is_purchasable(),
|
||||
'visible' => $variation->variation_is_visible(),
|
||||
'on_sale' => $variation->is_on_sale(),
|
||||
'weight' => $variation->get_weight(),
|
||||
'weight' => $variation->get_weight() ? woocommerce_format_decimal( $variation->get_weight() ) : null,
|
||||
'dimensions' => array(
|
||||
'length' => $variation->length,
|
||||
'width' => $variation->width,
|
||||
|
@ -380,8 +379,8 @@ class WC_API_Products extends WC_API_Resource {
|
|||
'image' => $this->get_images( $variation ),
|
||||
'attributes' => $this->get_attributes( $variation ),
|
||||
'downloads' => $this->get_downloads( $variation ),
|
||||
'download_limit' => $product->download_limit,
|
||||
'download_expiry' => $product->download_expiry,
|
||||
'download_limit' => (int) $product->download_limit,
|
||||
'download_expiry' => (int) $product->download_expiry,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -438,7 +437,8 @@ class WC_API_Products extends WC_API_Resource {
|
|||
|
||||
$images[] = array(
|
||||
'id' => (int) $attachment_id,
|
||||
'created_at' => $attachment_post->post_date_gmt, // TODO: date formatting
|
||||
'created_at' => $this->server->format_datetime( $attachment_post->post_date_gmt ),
|
||||
'updated_at' => $this->server->format_datetime( $attachment_post->post_modified_gmt ),
|
||||
'src' => current( $attachment ),
|
||||
'title' => get_the_title( $attachment_id ),
|
||||
'alt' => get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ),
|
||||
|
@ -451,7 +451,8 @@ class WC_API_Products extends WC_API_Resource {
|
|||
|
||||
$images[] = array(
|
||||
'id' => 0,
|
||||
'created_at' => gmdate( 'Y-m-d H:i:s' ), // TODO: date formatting
|
||||
'created_at' => $this->server->format_datetime( time() ), // default to now
|
||||
'updated_at' => $this->server->format_datetime( time() ),
|
||||
'src' => woocommerce_placeholder_img_src(),
|
||||
'title' => __( 'Placeholder', 'woocommerce' ),
|
||||
'alt' => __( 'Placeholder', 'woocommerce' ),
|
||||
|
|
|
@ -156,6 +156,16 @@ class WC_API_Reports extends WC_API_Resource {
|
|||
'function' => 'SUM',
|
||||
'name' => 'total_shipping'
|
||||
),
|
||||
'_order_tax' => array(
|
||||
'type' => 'meta',
|
||||
'function' => 'SUM',
|
||||
'name' => 'total_tax'
|
||||
),
|
||||
'_order_shipping_tax' => array(
|
||||
'type' => 'meta',
|
||||
'function' => 'SUM',
|
||||
'name' => 'total_shipping_tax'
|
||||
),
|
||||
'ID' => array(
|
||||
'type' => 'post_data',
|
||||
'function' => 'COUNT',
|
||||
|
@ -245,61 +255,61 @@ class WC_API_Reports extends WC_API_Resource {
|
|||
}
|
||||
|
||||
$period_totals[ $time ] = array(
|
||||
'sales' => 0,
|
||||
'sales' => woocommerce_format_decimal( 0.00 ),
|
||||
'orders' => 0,
|
||||
'items' => 0,
|
||||
'tax' => 0,
|
||||
'shipping' => 0,
|
||||
'discount' => 0,
|
||||
'tax' => woocommerce_format_decimal( 0.00 ),
|
||||
'shipping' => woocommerce_format_decimal( 0.00 ),
|
||||
'discount' => woocommerce_format_decimal( 0.00 ),
|
||||
);
|
||||
}
|
||||
|
||||
// add total sales, total order count, total tax and total shipping for each period
|
||||
foreach ( $orders as $order ) {
|
||||
|
||||
$time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date) ) : date( 'Y-m', strtotime( $order->post_date ) );
|
||||
$time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) );
|
||||
|
||||
if ( ! isset( $period_totals[ $time ] ) )
|
||||
continue;
|
||||
|
||||
$period_totals[ $time ]['sales'] = $order->total_sales;
|
||||
$period_totals[ $time ]['orders'] = $order->total_orders;
|
||||
$period_totals[ $time ]['tax'] = 1;
|
||||
$period_totals[ $time ]['shipping'] = $order->total_shipping;
|
||||
$period_totals[ $time ]['sales'] = woocommerce_format_decimal( $order->total_sales );
|
||||
$period_totals[ $time ]['orders'] = (int) $order->total_orders;
|
||||
$period_totals[ $time ]['tax'] = woocommerce_format_decimal( $order->total_tax + $order->total_shipping_tax );
|
||||
$period_totals[ $time ]['shipping'] = woocommerce_format_decimal( $order->total_shipping );
|
||||
}
|
||||
|
||||
// add total order items for each period
|
||||
foreach ( $order_items as $order_item ) {
|
||||
|
||||
$time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order_item->post_date) ) : date( 'Y-m', strtotime( $order_item->post_date ) );
|
||||
$time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $order_item->post_date ) ) : date( 'Y-m', strtotime( $order_item->post_date ) );
|
||||
|
||||
if ( ! isset( $period_totals[ $time ] ) )
|
||||
continue;
|
||||
|
||||
$period_totals[ $time ]['items'] = $order_item->order_item_count;
|
||||
$period_totals[ $time ]['items'] = (int) $order_item->order_item_count;
|
||||
}
|
||||
|
||||
// add total discount for each period
|
||||
foreach ( $discounts as $discount ) {
|
||||
|
||||
$time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $discount->post_date) ) : date( 'Y-m', strtotime( $discount->post_date ) );
|
||||
$time = ( 'day' === $this->report->chart_groupby ) ? date( 'Y-m-d', strtotime( $discount->post_date ) ) : date( 'Y-m', strtotime( $discount->post_date ) );
|
||||
|
||||
if ( ! isset( $period_totals[ $time ] ) )
|
||||
continue;
|
||||
|
||||
$period_totals[ $time ]['discount'] = $discount->discount_amount;
|
||||
$period_totals[ $time ]['discount'] = woocommerce_format_decimal( $discount->discount_amount );
|
||||
}
|
||||
|
||||
$sales_data = array(
|
||||
'sales' => $totals->sales,
|
||||
'average' => (string) number_format( $totals->sales / ( $this->report->chart_interval + 1 ), 2 ),
|
||||
'orders' => absint( $totals->order_count ),
|
||||
'sales' => woocommerce_format_decimal( $totals->sales ),
|
||||
'average' => woocommerce_format_decimal( $totals->sales / ( $this->report->chart_interval + 1 ) ),
|
||||
'orders' => (int) $totals->order_count,
|
||||
'items' => $total_items,
|
||||
'tax' => (string) number_format( $totals->tax + $totals->shipping_tax, 2 ),
|
||||
'shipping' => $totals->shipping,
|
||||
'discount' => is_null( $total_discount ) ? 0 : $total_discount,
|
||||
'totals' => $period_totals,
|
||||
'tax' => woocommerce_format_decimal( $totals->tax + $totals->shipping_tax ),
|
||||
'shipping' => woocommerce_format_decimal( $totals->shipping ),
|
||||
'discount' => is_null( $total_discount ) ? woocommerce_format_decimal( 0.00 ) : woocommerce_format_decimal( $total_discount ),
|
||||
'totals_grouped_by' => $this->report->chart_groupby,
|
||||
'totals' => $period_totals,
|
||||
);
|
||||
|
||||
return apply_filters( 'woocommerce_api_sales_report_response', array( 'sales' => $sales_data ), 'sales', $fields, $this->report, $this->server );
|
||||
|
@ -325,17 +335,28 @@ class WC_API_Reports extends WC_API_Resource {
|
|||
if ( ! empty( $filter['date_min'] ) || ! empty( $filter['date_max'] ) ) {
|
||||
|
||||
// overwrite _GET to make use of WC_Admin_Report::calculate_current_range() for custom date ranges
|
||||
$_GET['start_date'] = $filter['date_min']; // TODO: date formatting?
|
||||
$_GET['end_date'] = $filter['date_max']; // TODO: date formatting
|
||||
$_GET['start_date'] = $this->server->parse_datetime( $filter['date_min'] );
|
||||
$_GET['end_date'] = isset( $filter['date_max'] ) ? $this->server->parse_datetime( $filter['date_max'] ) : null;
|
||||
|
||||
} else {
|
||||
|
||||
// default custom range to today
|
||||
$_GET['start_date'] = $_GET['end_date'] = date( 'Y-m-d', current_time( 'timestamp' ) );
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: handle invalid periods (e.g. `decade`)
|
||||
} else {
|
||||
|
||||
// ensure period is valid
|
||||
if ( ! in_array( $filter['period'], array( 'week', 'month', 'last_month', 'year' ) ) ) {
|
||||
$filter['period'] = 'week';
|
||||
}
|
||||
|
||||
// TODO: change WC_Admin_Report class to use "week" instead, as it's more consistent with other periods
|
||||
// allow "week" for period instead of "7day"
|
||||
if ( 'week' === $filter['period'] ) {
|
||||
$filter['period'] = '7day';
|
||||
}
|
||||
}
|
||||
|
||||
$this->report->calculate_current_range( $filter['period'] );
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ class WC_API_Resource {
|
|||
|
||||
$post = get_post( $id, ARRAY_A );
|
||||
|
||||
// TODO: redo this check, it's a bit janky
|
||||
// for checking permissions, product variations are the same as the product post type
|
||||
$post_type = ( 'product_variation' === $post['post_type'] ) ? 'product' : $post['post_type'];
|
||||
|
||||
// validate post type
|
||||
|
@ -117,8 +117,6 @@ class WC_API_Resource {
|
|||
|
||||
$args = array();
|
||||
|
||||
// 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'] ) ) {
|
||||
|
||||
|
@ -126,19 +124,19 @@ class WC_API_Resource {
|
|||
|
||||
// resources created after specified date
|
||||
if ( ! empty( $request_args['created_at_min'] ) )
|
||||
$args['date_query'][] = array( 'column' => 'post_date_gmt', 'after' => $request_args['created_at_min'], 'inclusive' => true );
|
||||
$args['date_query'][] = array( 'column' => 'post_date_gmt', 'after' => $this->server->parse_datetime( $request_args['created_at_min'] ), 'inclusive' => true );
|
||||
|
||||
// resources created before specified date
|
||||
if ( ! empty( $request_args['created_at_max'] ) )
|
||||
$args['date_query'][] = array( 'column' => 'post_date_gmt', 'before' => $request_args['created_at_max'], 'inclusive' => true );
|
||||
$args['date_query'][] = array( 'column' => 'post_date_gmt', 'before' => $this->server->parse_datetime( $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 );
|
||||
$args['date_query'][] = array( 'column' => 'post_modified_gmt', 'after' => $this->server->parse_datetime( $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 );
|
||||
$args['date_query'][] = array( 'column' => 'post_modified_gmt', 'before' => $this->server->parse_datetime( $request_args['updated_at_max'] ), 'inclusive' => true );
|
||||
}
|
||||
|
||||
// search
|
||||
|
|
|
@ -571,71 +571,72 @@ class WC_API_Server {
|
|||
}
|
||||
|
||||
/**
|
||||
* Parse an RFC3339 timestamp into a DateTime
|
||||
* Parse an RFC3339 datetime into a MySQl datetime
|
||||
*
|
||||
* @param string $date RFC3339 timestamp
|
||||
* @param boolean $force_utc Force UTC timezone instead of using the timestamp's TZ?
|
||||
* @return DateTime
|
||||
* Invalid dates default to unix epoch
|
||||
*
|
||||
* @since 2.1
|
||||
* @param string $datetime RFC3339 datetime
|
||||
* @return string MySQl datetime (YYYY-MM-DD HH:MM:SS)
|
||||
*/
|
||||
public function parse_date( $date, $force_utc = false ) {
|
||||
// Default timezone to the server's current one
|
||||
$timezone = self::get_timezone();
|
||||
if ( $force_utc ) {
|
||||
$date = preg_replace( '/[+-]\d+:?\d+$/', '+00:00', $date );
|
||||
public function parse_datetime( $datetime ) {
|
||||
|
||||
// Strip millisecond precision (a full stop followed by one or more digits)
|
||||
if ( strpos( $datetime, '.' ) !== false ) {
|
||||
$datetime = preg_replace( '/\.\d+/', '', $datetime );
|
||||
}
|
||||
|
||||
// default timezone to UTC
|
||||
$datetime = preg_replace( '/[+-]\d+:+\d+$/', '+00:00', $datetime );
|
||||
|
||||
try {
|
||||
|
||||
$datetime = new DateTime( $datetime, new DateTimeZone( 'UTC' ) );
|
||||
|
||||
} catch ( Exception $e ) {
|
||||
|
||||
$datetime = new DateTime( '@0' );
|
||||
|
||||
}
|
||||
|
||||
return $datetime->format( 'Y-m-d H:i:s' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a unix timestamp or MySQL datetime into an RFC3339 datetime
|
||||
*
|
||||
* @since 2.1
|
||||
* @param int|string $timestamp unix timestamp or MySQL datetime
|
||||
* @param bool $convert_to_utc
|
||||
* @return string RFC3339 datetime
|
||||
*/
|
||||
public function format_datetime( $timestamp, $convert_to_utc = false ) {
|
||||
|
||||
if ( $convert_to_utc ) {
|
||||
$timezone = new DateTimeZone( woocommerce_timezone_string() );
|
||||
} else {
|
||||
$timezone = new DateTimeZone( 'UTC' );
|
||||
}
|
||||
|
||||
// Strip millisecond precision (a full stop followed by one or more digits)
|
||||
if ( strpos( $date, '.' ) !== false ) {
|
||||
$date = preg_replace( '/\.\d+/', '', $date );
|
||||
try {
|
||||
|
||||
if ( is_numeric( $timestamp ) ) {
|
||||
$date = new DateTime( "@{$timestamp}" );
|
||||
} else {
|
||||
$date = new DateTime( $timestamp, $timezone );
|
||||
}
|
||||
|
||||
// convert to UTC by adjusting the time based on the offset of the site's timezone
|
||||
if ( $convert_to_utc ) {
|
||||
$date->modify( -1 * $date->getOffset() . ' seconds' );
|
||||
}
|
||||
|
||||
} catch ( Exception $e ) {
|
||||
|
||||
$date = new DateTime( '@0' );
|
||||
}
|
||||
$datetime = DateTime::createFromFormat( DateTime::RFC3339, $date ); // TODO: rewrite, PHP 5.3+ required for this
|
||||
|
||||
return $datetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a local date with its GMT equivalent, in MySQL datetime format
|
||||
*
|
||||
* @param string $date RFC3339 timestamp
|
||||
* @param boolean $force_utc Should we force UTC timestamp?
|
||||
* @return array Local and UTC datetime strings, in MySQL datetime format (Y-m-d H:i:s)
|
||||
*/
|
||||
public function get_date_with_gmt( $date, $force_utc = false ) {
|
||||
$datetime = $this->parse_date( $date, $force_utc );
|
||||
|
||||
$datetime->setTimezone( self::get_timezone() );
|
||||
$local = $datetime->format( 'Y-m-d H:i:s' );
|
||||
|
||||
$datetime->setTimezone( new DateTimeZone( 'UTC' ) );
|
||||
$utc = $datetime->format('Y-m-d H:i:s');
|
||||
|
||||
return array( $local, $utc );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the timezone object for the site
|
||||
*
|
||||
* @return DateTimeZone
|
||||
*/
|
||||
public function get_timezone() {
|
||||
static $zone = null;
|
||||
if ($zone !== null)
|
||||
return $zone;
|
||||
|
||||
$tzstring = get_option( 'timezone_string' );
|
||||
if ( ! $tzstring ) {
|
||||
// Create a UTC+- zone if no timezone string exists
|
||||
$current_offset = get_option( 'gmt_offset' );
|
||||
if ( 0 == $current_offset )
|
||||
$tzstring = 'UTC';
|
||||
elseif ($current_offset < 0)
|
||||
$tzstring = 'Etc/GMT' . $current_offset;
|
||||
else
|
||||
$tzstring = 'Etc/GMT+' . $current_offset;
|
||||
}
|
||||
$zone = new DateTimeZone( $tzstring );
|
||||
return $zone;
|
||||
return $date->format( 'Y-m-d\TH:i:s\Z' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -363,6 +363,51 @@ function woocommerce_time_format() {
|
|||
return apply_filters( 'woocommerce_time_format', get_option( 'time_format' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* WooCommerce Timezone - helper to retrieve the timezone string for a site until
|
||||
* a WP core method exists (see http://core.trac.wordpress.org/ticket/24730)
|
||||
*
|
||||
* Adapted from http://www.php.net/manual/en/function.timezone-name-from-abbr.php#89155
|
||||
*
|
||||
* @since 2.1
|
||||
* @access public
|
||||
* @return string a valid PHP timezone string for the site
|
||||
*/
|
||||
function woocommerce_timezone_string() {
|
||||
|
||||
// if site timezone string exists, return it
|
||||
if ( $timezone = get_option( 'timezone_string' ) )
|
||||
return $timezone;
|
||||
|
||||
// get UTC offset, if it isn't set then return UTC
|
||||
if ( 0 === ( $utc_offset = get_option( 'gmt_offset', 0 ) ) )
|
||||
return 'UTC';
|
||||
|
||||
// adjust UTC offset from hours to seconds
|
||||
$utc_offset *= 3600;
|
||||
|
||||
// attempt to guess the timezone string from the UTC offset
|
||||
$timezone = timezone_name_from_abbr( '', $utc_offset );
|
||||
|
||||
// last try, guess timezone string manually
|
||||
if ( false === $timezone ) {
|
||||
|
||||
$is_dst = date( 'I' );
|
||||
|
||||
foreach ( timezone_abbreviations_list() as $abbr ) {
|
||||
foreach ( $abbr as $city ) {
|
||||
|
||||
if ( $city['dst'] == $is_dst && $city['offset'] == $utc_offset ) {
|
||||
return $city['timezone_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fallback to UTC
|
||||
return 'UTC';
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'woocommerce_rgb_from_hex' ) ) {
|
||||
|
||||
/**
|
||||
|
@ -517,4 +562,4 @@ function wc_format_postcode( $postcode, $country ) {
|
|||
function wc_format_phone_number( $tel ) {
|
||||
$tel = str_replace( '.', '-', $tel );
|
||||
return $tel;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue