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

Commit 1cff6c6

Browse files
author
Justin Shreve
committed
Removes the 'visible' property from the variations endpoint and adds 'status'.
See woocommerce/woocommerce#15216
1 parent c939719 commit 1cff6c6

File tree

2 files changed

+286
-5
lines changed

2 files changed

+286
-5
lines changed

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

Lines changed: 282 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,283 @@ 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' => current( $this->get_images( $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+
if ( is_array( $image ) ) {
135+
$image['position'] = 0;
136+
}
137+
138+
$variation = $this->set_product_images( $variation, array( $image ) );
139+
} else {
140+
$variation->set_image_id( '' );
141+
}
142+
}
143+
144+
// Virtual variation.
145+
if ( isset( $request['virtual'] ) ) {
146+
$variation->set_virtual( $request['virtual'] );
147+
}
148+
149+
// Downloadable variation.
150+
if ( isset( $request['downloadable'] ) ) {
151+
$variation->set_downloadable( $request['downloadable'] );
152+
}
153+
154+
// Downloads.
155+
if ( $variation->get_downloadable() ) {
156+
// Downloadable files.
157+
if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) {
158+
$variation = $this->save_downloadable_files( $variation, $request['downloads'] );
159+
}
160+
161+
// Download limit.
162+
if ( isset( $request['download_limit'] ) ) {
163+
$variation->set_download_limit( $request['download_limit'] );
164+
}
165+
166+
// Download expiry.
167+
if ( isset( $request['download_expiry'] ) ) {
168+
$variation->set_download_expiry( $request['download_expiry'] );
169+
}
170+
}
171+
172+
// Shipping data.
173+
$variation = $this->save_product_shipping_data( $variation, $request );
174+
175+
// Stock handling.
176+
if ( isset( $request['manage_stock'] ) ) {
177+
$variation->set_manage_stock( $request['manage_stock'] );
178+
}
179+
180+
if ( isset( $request['in_stock'] ) ) {
181+
$variation->set_stock_status( true === $request['in_stock'] ? 'instock' : 'outofstock' );
182+
}
183+
184+
if ( isset( $request['backorders'] ) ) {
185+
$variation->set_backorders( $request['backorders'] );
186+
}
187+
188+
if ( $variation->get_manage_stock() ) {
189+
if ( isset( $request['stock_quantity'] ) ) {
190+
$variation->set_stock_quantity( $request['stock_quantity'] );
191+
} elseif ( isset( $request['inventory_delta'] ) ) {
192+
$stock_quantity = wc_stock_amount( $variation->get_stock_quantity() );
193+
$stock_quantity += wc_stock_amount( $request['inventory_delta'] );
194+
$variation->set_stock_quantity( $stock_quantity );
195+
}
196+
} else {
197+
$variation->set_backorders( 'no' );
198+
$variation->set_stock_quantity( '' );
199+
}
200+
201+
// Regular Price.
202+
if ( isset( $request['regular_price'] ) ) {
203+
$variation->set_regular_price( $request['regular_price'] );
204+
}
205+
206+
// Sale Price.
207+
if ( isset( $request['sale_price'] ) ) {
208+
$variation->set_sale_price( $request['sale_price'] );
209+
}
210+
211+
if ( isset( $request['date_on_sale_from'] ) ) {
212+
$variation->set_date_on_sale_from( $request['date_on_sale_from'] );
213+
}
214+
215+
if ( isset( $request['date_on_sale_from_gmt'] ) ) {
216+
$variation->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null );
217+
}
218+
219+
if ( isset( $request['date_on_sale_to'] ) ) {
220+
$variation->set_date_on_sale_to( $request['date_on_sale_to'] );
221+
}
222+
223+
if ( isset( $request['date_on_sale_to_gmt'] ) ) {
224+
$variation->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null );
225+
}
226+
227+
// Tax class.
228+
if ( isset( $request['tax_class'] ) ) {
229+
$variation->set_tax_class( $request['tax_class'] );
230+
}
231+
232+
// Description.
233+
if ( isset( $request['description'] ) ) {
234+
$variation->set_description( wp_kses_post( $request['description'] ) );
235+
}
236+
237+
// Update taxonomies.
238+
if ( isset( $request['attributes'] ) ) {
239+
$attributes = array();
240+
$parent = wc_get_product( $variation->get_parent_id() );
241+
$parent_attributes = $parent->get_attributes();
242+
243+
foreach ( $request['attributes'] as $attribute ) {
244+
$attribute_id = 0;
245+
$attribute_name = '';
246+
247+
// Check ID for global attributes or name for product attributes.
248+
if ( ! empty( $attribute['id'] ) ) {
249+
$attribute_id = absint( $attribute['id'] );
250+
$attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id );
251+
} elseif ( ! empty( $attribute['name'] ) ) {
252+
$attribute_name = sanitize_title( $attribute['name'] );
253+
}
254+
255+
if ( ! $attribute_id && ! $attribute_name ) {
256+
continue;
257+
}
258+
259+
if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) {
260+
continue;
261+
}
262+
263+
$attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() );
264+
$attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : '';
265+
266+
if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) {
267+
// If dealing with a taxonomy, we need to get the slug from the name posted to the API.
268+
$term = get_term_by( 'name', $attribute_value, $attribute_name );
269+
270+
if ( $term && ! is_wp_error( $term ) ) {
271+
$attribute_value = $term->slug;
272+
} else {
273+
$attribute_value = sanitize_title( $attribute_value );
274+
}
275+
}
276+
277+
$attributes[ $attribute_key ] = $attribute_value;
278+
}
279+
280+
$variation->set_attributes( $attributes );
281+
}
282+
283+
// Menu order.
284+
if ( $request['menu_order'] ) {
285+
$variation->set_menu_order( $request['menu_order'] );
286+
}
287+
288+
// Meta data.
289+
if ( is_array( $request['meta_data'] ) ) {
290+
foreach ( $request['meta_data'] as $meta ) {
291+
$variation->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' );
292+
}
293+
}
294+
295+
/**
296+
* Filters an object before it is inserted via the REST API.
297+
*
298+
* The dynamic portion of the hook name, `$this->post_type`,
299+
* refers to the object type slug.
300+
*
301+
* @param WC_Data $variation Object object.
302+
* @param WP_REST_Request $request Request object.
303+
* @param bool $creating If is creating a new object.
304+
*/
305+
return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating );
306+
}
307+
31308
/**
32309
* Get the image for a product variation.
33310
*
@@ -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)