Skip to content
This repository was archived by the owner on Oct 4, 2019. It is now read-only.

Commit db1c191

Browse files
author
Justin Shreve
authored
Fixes image response, Removes the 'visible' property from the variations endpoint and adds status (#4)
* Removes the 'visible' property from the variations endpoint and adds 'status'. See woocommerce/woocommerce#15216 * Don't return parent image when no variation image is set.
1 parent c939719 commit db1c191

File tree

2 files changed

+291
-10
lines changed

2 files changed

+291
-10
lines changed

api/class-wc-rest-dev-product-variations-controller.php

Lines changed: 287 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,303 @@ class WC_REST_Dev_Product_Variations_Controller extends WC_REST_Product_Variatio
2828
*/
2929
protected $namespace = 'wc/v3';
3030

31+
/**
32+
* Prepare a single variation output for response.
33+
*
34+
* @param WC_Data $object Object data.
35+
* @param WP_REST_Request $request Request object.
36+
* @return WP_REST_Response
37+
*/
38+
public function prepare_object_for_response( $object, $request ) {
39+
$data = array(
40+
'id' => $object->get_id(),
41+
'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ),
42+
'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ),
43+
'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ),
44+
'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ),
45+
'description' => wc_format_content( $object->get_description() ),
46+
'permalink' => $object->get_permalink(),
47+
'sku' => $object->get_sku(),
48+
'price' => $object->get_price(),
49+
'regular_price' => $object->get_regular_price(),
50+
'sale_price' => $object->get_sale_price(),
51+
'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ),
52+
'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ),
53+
'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ),
54+
'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ),
55+
'on_sale' => $object->is_on_sale(),
56+
'status' => $object->get_status(),
57+
'purchasable' => $object->is_purchasable(),
58+
'virtual' => $object->is_virtual(),
59+
'downloadable' => $object->is_downloadable(),
60+
'downloads' => $this->get_downloads( $object ),
61+
'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1,
62+
'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1,
63+
'tax_status' => $object->get_tax_status(),
64+
'tax_class' => $object->get_tax_class(),
65+
'manage_stock' => $object->managing_stock(),
66+
'stock_quantity' => $object->get_stock_quantity(),
67+
'in_stock' => $object->is_in_stock(),
68+
'backorders' => $object->get_backorders(),
69+
'backorders_allowed' => $object->backorders_allowed(),
70+
'backordered' => $object->is_on_backorder(),
71+
'weight' => $object->get_weight(),
72+
'dimensions' => array(
73+
'length' => $object->get_length(),
74+
'width' => $object->get_width(),
75+
'height' => $object->get_height(),
76+
),
77+
'shipping_class' => $object->get_shipping_class(),
78+
'shipping_class_id' => $object->get_shipping_class_id(),
79+
'image' => $this->get_image( $object ),
80+
'attributes' => $this->get_attributes( $object ),
81+
'menu_order' => $object->get_menu_order(),
82+
'meta_data' => $object->get_meta_data(),
83+
);
84+
85+
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
86+
$data = $this->add_additional_fields_to_object( $data, $request );
87+
$data = $this->filter_response_by_context( $data, $context );
88+
$response = rest_ensure_response( $data );
89+
$response->add_links( $this->prepare_links( $object, $request ) );
90+
91+
/**
92+
* Filter the data for a response.
93+
*
94+
* The dynamic portion of the hook name, $this->post_type,
95+
* refers to object type being prepared for the response.
96+
*
97+
* @param WP_REST_Response $response The response object.
98+
* @param WC_Data $object Object data.
99+
* @param WP_REST_Request $request Request object.
100+
*/
101+
return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request );
102+
}
103+
104+
/**
105+
* Prepare a single variation for create or update.
106+
*
107+
* @param WP_REST_Request $request Request object.
108+
* @param bool $creating If is creating a new object.
109+
* @return WP_Error|WC_Data
110+
*/
111+
protected function prepare_object_for_database( $request, $creating = false ) {
112+
if ( isset( $request['id'] ) ) {
113+
$variation = wc_get_product( absint( $request['id'] ) );
114+
} else {
115+
$variation = new WC_Product_Variation();
116+
}
117+
118+
$variation->set_parent_id( absint( $request['product_id'] ) );
119+
120+
// Status.
121+
if ( isset( $request['status'] ) ) {
122+
$variation->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' );
123+
}
124+
125+
// SKU.
126+
if ( isset( $request['sku'] ) ) {
127+
$variation->set_sku( wc_clean( $request['sku'] ) );
128+
}
129+
130+
// Thumbnail.
131+
if ( isset( $request['image'] ) ) {
132+
if ( is_array( $request['image'] ) ) {
133+
$image = $request['image'];
134+
$variation = $this->set_product_images( $variation, array( $image ) );
135+
} else {
136+
$variation->set_image_id( '' );
137+
}
138+
}
139+
140+
// Virtual variation.
141+
if ( isset( $request['virtual'] ) ) {
142+
$variation->set_virtual( $request['virtual'] );
143+
}
144+
145+
// Downloadable variation.
146+
if ( isset( $request['downloadable'] ) ) {
147+
$variation->set_downloadable( $request['downloadable'] );
148+
}
149+
150+
// Downloads.
151+
if ( $variation->get_downloadable() ) {
152+
// Downloadable files.
153+
if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) {
154+
$variation = $this->save_downloadable_files( $variation, $request['downloads'] );
155+
}
156+
157+
// Download limit.
158+
if ( isset( $request['download_limit'] ) ) {
159+
$variation->set_download_limit( $request['download_limit'] );
160+
}
161+
162+
// Download expiry.
163+
if ( isset( $request['download_expiry'] ) ) {
164+
$variation->set_download_expiry( $request['download_expiry'] );
165+
}
166+
}
167+
168+
// Shipping data.
169+
$variation = $this->save_product_shipping_data( $variation, $request );
170+
171+
// Stock handling.
172+
if ( isset( $request['manage_stock'] ) ) {
173+
$variation->set_manage_stock( $request['manage_stock'] );
174+
}
175+
176+
if ( isset( $request['in_stock'] ) ) {
177+
$variation->set_stock_status( true === $request['in_stock'] ? 'instock' : 'outofstock' );
178+
}
179+
180+
if ( isset( $request['backorders'] ) ) {
181+
$variation->set_backorders( $request['backorders'] );
182+
}
183+
184+
if ( $variation->get_manage_stock() ) {
185+
if ( isset( $request['stock_quantity'] ) ) {
186+
$variation->set_stock_quantity( $request['stock_quantity'] );
187+
} elseif ( isset( $request['inventory_delta'] ) ) {
188+
$stock_quantity = wc_stock_amount( $variation->get_stock_quantity() );
189+
$stock_quantity += wc_stock_amount( $request['inventory_delta'] );
190+
$variation->set_stock_quantity( $stock_quantity );
191+
}
192+
} else {
193+
$variation->set_backorders( 'no' );
194+
$variation->set_stock_quantity( '' );
195+
}
196+
197+
// Regular Price.
198+
if ( isset( $request['regular_price'] ) ) {
199+
$variation->set_regular_price( $request['regular_price'] );
200+
}
201+
202+
// Sale Price.
203+
if ( isset( $request['sale_price'] ) ) {
204+
$variation->set_sale_price( $request['sale_price'] );
205+
}
206+
207+
if ( isset( $request['date_on_sale_from'] ) ) {
208+
$variation->set_date_on_sale_from( $request['date_on_sale_from'] );
209+
}
210+
211+
if ( isset( $request['date_on_sale_from_gmt'] ) ) {
212+
$variation->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null );
213+
}
214+
215+
if ( isset( $request['date_on_sale_to'] ) ) {
216+
$variation->set_date_on_sale_to( $request['date_on_sale_to'] );
217+
}
218+
219+
if ( isset( $request['date_on_sale_to_gmt'] ) ) {
220+
$variation->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null );
221+
}
222+
223+
// Tax class.
224+
if ( isset( $request['tax_class'] ) ) {
225+
$variation->set_tax_class( $request['tax_class'] );
226+
}
227+
228+
// Description.
229+
if ( isset( $request['description'] ) ) {
230+
$variation->set_description( wp_kses_post( $request['description'] ) );
231+
}
232+
233+
// Update taxonomies.
234+
if ( isset( $request['attributes'] ) ) {
235+
$attributes = array();
236+
$parent = wc_get_product( $variation->get_parent_id() );
237+
$parent_attributes = $parent->get_attributes();
238+
239+
foreach ( $request['attributes'] as $attribute ) {
240+
$attribute_id = 0;
241+
$attribute_name = '';
242+
243+
// Check ID for global attributes or name for product attributes.
244+
if ( ! empty( $attribute['id'] ) ) {
245+
$attribute_id = absint( $attribute['id'] );
246+
$attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id );
247+
} elseif ( ! empty( $attribute['name'] ) ) {
248+
$attribute_name = sanitize_title( $attribute['name'] );
249+
}
250+
251+
if ( ! $attribute_id && ! $attribute_name ) {
252+
continue;
253+
}
254+
255+
if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) {
256+
continue;
257+
}
258+
259+
$attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() );
260+
$attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : '';
261+
262+
if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) {
263+
// If dealing with a taxonomy, we need to get the slug from the name posted to the API.
264+
$term = get_term_by( 'name', $attribute_value, $attribute_name );
265+
266+
if ( $term && ! is_wp_error( $term ) ) {
267+
$attribute_value = $term->slug;
268+
} else {
269+
$attribute_value = sanitize_title( $attribute_value );
270+
}
271+
}
272+
273+
$attributes[ $attribute_key ] = $attribute_value;
274+
}
275+
276+
$variation->set_attributes( $attributes );
277+
}
278+
279+
// Menu order.
280+
if ( $request['menu_order'] ) {
281+
$variation->set_menu_order( $request['menu_order'] );
282+
}
283+
284+
// Meta data.
285+
if ( is_array( $request['meta_data'] ) ) {
286+
foreach ( $request['meta_data'] as $meta ) {
287+
$variation->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' );
288+
}
289+
}
290+
291+
/**
292+
* Filters an object before it is inserted via the REST API.
293+
*
294+
* The dynamic portion of the hook name, `$this->post_type`,
295+
* refers to the object type slug.
296+
*
297+
* @param WC_Data $variation Object object.
298+
* @param WP_REST_Request $request Request object.
299+
* @param bool $creating If is creating a new object.
300+
*/
301+
return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating );
302+
}
303+
31304
/**
32305
* Get the image for a product variation.
33306
*
34307
* @param WC_Product_Variation $variation Variation
35308
* @return array
36309
*/
37-
protected function get_images( $variation ) {
310+
protected function get_image( $variation ) {
311+
if ( ! has_post_thumbnail( $variation->get_id() ) ) {
312+
return;
313+
}
314+
38315
$attachment_id = $variation->get_image_id();
39316
$attachment_post = get_post( $attachment_id );
40317
if ( is_null( $attachment_post ) ) {
41-
$image = array();
318+
return;
42319
}
43320

44321
$attachment = wp_get_attachment_image_src( $attachment_id, 'full' );
45322
if ( ! is_array( $attachment ) ) {
46-
$image = array();
323+
return;
47324
}
48325

49326
if ( ! isset ( $image ) ) {
50-
$image = array(
327+
return array(
51328
'id' => (int) $attachment_id,
52329
'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ),
53330
'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ),
@@ -59,7 +336,7 @@ protected function get_images( $variation ) {
59336
);
60337
}
61338

62-
return array( $image );
339+
return;
63340
}
64341

65342
/**
@@ -152,10 +429,11 @@ public function get_item_schema() {
152429
'context' => array( 'view', 'edit' ),
153430
'readonly' => true,
154431
),
155-
'visible' => array(
156-
'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ),
157-
'type' => 'boolean',
158-
'default' => true,
432+
'status' => array(
433+
'description' => __( 'Variation status.', 'woocommerce' ),
434+
'type' => 'string',
435+
'default' => 'publish',
436+
'enum' => array_keys( get_post_statuses() ),
159437
'context' => array( 'view', 'edit' ),
160438
),
161439
'purchasable' => array(

tests/unit-tests/product-variations.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ public function test_update_variation() {
169169
$this->assertEquals( 10, $variation['regular_price'] );
170170
$this->assertEmpty( $variation['sale_price'] );
171171
$this->assertEquals( 'small', $variation['attributes'][0]['option'] );
172+
$this->assertEquals( 'publish', $variation['status'] );
172173

173174
$request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id );
174175
$request->set_body_params( array(
@@ -177,6 +178,7 @@ public function test_update_variation() {
177178
'description' => 'O_O',
178179
'image' => array( 'position' => 0, 'src' => 'https://cldup.com/Dr1Bczxq4q.png', 'alt' => 'test upload image' ),
179180
'attributes' => array( array( 'name' => 'pa_size', 'option' => 'medium' ) ),
181+
'status' => 'private',
180182
) );
181183
$response = $this->server->dispatch( $request );
182184
$variation = $response->get_data();
@@ -189,6 +191,7 @@ public function test_update_variation() {
189191
$this->assertEquals( 'medium', $variation['attributes'][0]['option'] );
190192
$this->assertContains( 'Dr1Bczxq4q', $variation['image']['src'] );
191193
$this->assertContains( 'test upload image', $variation['image']['alt'] );
194+
$this->assertEquals( 'private', $variation['status'] );
192195
$product->delete( true );
193196
}
194197

@@ -356,13 +359,13 @@ public function test_variation_schema() {
356359
$this->assertArrayHasKey( 'date_on_sale_from', $properties );
357360
$this->assertArrayHasKey( 'date_on_sale_to', $properties );
358361
$this->assertArrayHasKey( 'on_sale', $properties );
359-
$this->assertArrayHasKey( 'visible', $properties );
360362
$this->assertArrayHasKey( 'purchasable', $properties );
361363
$this->assertArrayHasKey( 'virtual', $properties );
362364
$this->assertArrayHasKey( 'downloadable', $properties );
363365
$this->assertArrayHasKey( 'downloads', $properties );
364366
$this->assertArrayHasKey( 'download_limit', $properties );
365367
$this->assertArrayHasKey( 'download_expiry', $properties );
368+
$this->assertArrayHasKey( 'status', $properties );
366369
$this->assertArrayHasKey( 'tax_status', $properties );
367370
$this->assertArrayHasKey( 'tax_class', $properties );
368371
$this->assertArrayHasKey( 'manage_stock', $properties );

0 commit comments

Comments
 (0)