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

Commit

Permalink
Fixes image response, Removes the 'visible' property from the variati…
Browse files Browse the repository at this point in the history
…ons 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.
  • Loading branch information
justinshreve authored Jun 1, 2017
1 parent c939719 commit db1c191
Show file tree
Hide file tree
Showing 2 changed files with 291 additions and 10 deletions.
296 changes: 287 additions & 9 deletions api/class-wc-rest-dev-product-variations-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,303 @@ class WC_REST_Dev_Product_Variations_Controller extends WC_REST_Product_Variatio
*/
protected $namespace = 'wc/v3';

/**
* Prepare a single variation output for response.
*
* @param WC_Data $object Object data.
* @param WP_REST_Request $request Request object.
* @return WP_REST_Response
*/
public function prepare_object_for_response( $object, $request ) {
$data = array(
'id' => $object->get_id(),
'date_created' => wc_rest_prepare_date_response( $object->get_date_created(), false ),
'date_created_gmt' => wc_rest_prepare_date_response( $object->get_date_created() ),
'date_modified' => wc_rest_prepare_date_response( $object->get_date_modified(), false ),
'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ),
'description' => wc_format_content( $object->get_description() ),
'permalink' => $object->get_permalink(),
'sku' => $object->get_sku(),
'price' => $object->get_price(),
'regular_price' => $object->get_regular_price(),
'sale_price' => $object->get_sale_price(),
'date_on_sale_from' => wc_rest_prepare_date_response( $object->get_date_on_sale_from(), false ),
'date_on_sale_from_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_from() ),
'date_on_sale_to' => wc_rest_prepare_date_response( $object->get_date_on_sale_to(), false ),
'date_on_sale_to_gmt' => wc_rest_prepare_date_response( $object->get_date_on_sale_to() ),
'on_sale' => $object->is_on_sale(),
'status' => $object->get_status(),
'purchasable' => $object->is_purchasable(),
'virtual' => $object->is_virtual(),
'downloadable' => $object->is_downloadable(),
'downloads' => $this->get_downloads( $object ),
'download_limit' => '' !== $object->get_download_limit() ? (int) $object->get_download_limit() : -1,
'download_expiry' => '' !== $object->get_download_expiry() ? (int) $object->get_download_expiry() : -1,
'tax_status' => $object->get_tax_status(),
'tax_class' => $object->get_tax_class(),
'manage_stock' => $object->managing_stock(),
'stock_quantity' => $object->get_stock_quantity(),
'in_stock' => $object->is_in_stock(),
'backorders' => $object->get_backorders(),
'backorders_allowed' => $object->backorders_allowed(),
'backordered' => $object->is_on_backorder(),
'weight' => $object->get_weight(),
'dimensions' => array(
'length' => $object->get_length(),
'width' => $object->get_width(),
'height' => $object->get_height(),
),
'shipping_class' => $object->get_shipping_class(),
'shipping_class_id' => $object->get_shipping_class_id(),
'image' => $this->get_image( $object ),
'attributes' => $this->get_attributes( $object ),
'menu_order' => $object->get_menu_order(),
'meta_data' => $object->get_meta_data(),
);

$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
$data = $this->add_additional_fields_to_object( $data, $request );
$data = $this->filter_response_by_context( $data, $context );
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $object, $request ) );

/**
* Filter the data for a response.
*
* The dynamic portion of the hook name, $this->post_type,
* refers to object type being prepared for the response.
*
* @param WP_REST_Response $response The response object.
* @param WC_Data $object Object data.
* @param WP_REST_Request $request Request object.
*/
return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request );
}

/**
* Prepare a single variation for create or update.
*
* @param WP_REST_Request $request Request object.
* @param bool $creating If is creating a new object.
* @return WP_Error|WC_Data
*/
protected function prepare_object_for_database( $request, $creating = false ) {
if ( isset( $request['id'] ) ) {
$variation = wc_get_product( absint( $request['id'] ) );
} else {
$variation = new WC_Product_Variation();
}

$variation->set_parent_id( absint( $request['product_id'] ) );

// Status.
if ( isset( $request['status'] ) ) {
$variation->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' );
}

// SKU.
if ( isset( $request['sku'] ) ) {
$variation->set_sku( wc_clean( $request['sku'] ) );
}

// Thumbnail.
if ( isset( $request['image'] ) ) {
if ( is_array( $request['image'] ) ) {
$image = $request['image'];
$variation = $this->set_product_images( $variation, array( $image ) );
} else {
$variation->set_image_id( '' );
}
}

// Virtual variation.
if ( isset( $request['virtual'] ) ) {
$variation->set_virtual( $request['virtual'] );
}

// Downloadable variation.
if ( isset( $request['downloadable'] ) ) {
$variation->set_downloadable( $request['downloadable'] );
}

// Downloads.
if ( $variation->get_downloadable() ) {
// Downloadable files.
if ( isset( $request['downloads'] ) && is_array( $request['downloads'] ) ) {
$variation = $this->save_downloadable_files( $variation, $request['downloads'] );
}

// Download limit.
if ( isset( $request['download_limit'] ) ) {
$variation->set_download_limit( $request['download_limit'] );
}

// Download expiry.
if ( isset( $request['download_expiry'] ) ) {
$variation->set_download_expiry( $request['download_expiry'] );
}
}

// Shipping data.
$variation = $this->save_product_shipping_data( $variation, $request );

// Stock handling.
if ( isset( $request['manage_stock'] ) ) {
$variation->set_manage_stock( $request['manage_stock'] );
}

if ( isset( $request['in_stock'] ) ) {
$variation->set_stock_status( true === $request['in_stock'] ? 'instock' : 'outofstock' );
}

if ( isset( $request['backorders'] ) ) {
$variation->set_backorders( $request['backorders'] );
}

if ( $variation->get_manage_stock() ) {
if ( isset( $request['stock_quantity'] ) ) {
$variation->set_stock_quantity( $request['stock_quantity'] );
} elseif ( isset( $request['inventory_delta'] ) ) {
$stock_quantity = wc_stock_amount( $variation->get_stock_quantity() );
$stock_quantity += wc_stock_amount( $request['inventory_delta'] );
$variation->set_stock_quantity( $stock_quantity );
}
} else {
$variation->set_backorders( 'no' );
$variation->set_stock_quantity( '' );
}

// Regular Price.
if ( isset( $request['regular_price'] ) ) {
$variation->set_regular_price( $request['regular_price'] );
}

// Sale Price.
if ( isset( $request['sale_price'] ) ) {
$variation->set_sale_price( $request['sale_price'] );
}

if ( isset( $request['date_on_sale_from'] ) ) {
$variation->set_date_on_sale_from( $request['date_on_sale_from'] );
}

if ( isset( $request['date_on_sale_from_gmt'] ) ) {
$variation->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null );
}

if ( isset( $request['date_on_sale_to'] ) ) {
$variation->set_date_on_sale_to( $request['date_on_sale_to'] );
}

if ( isset( $request['date_on_sale_to_gmt'] ) ) {
$variation->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null );
}

// Tax class.
if ( isset( $request['tax_class'] ) ) {
$variation->set_tax_class( $request['tax_class'] );
}

// Description.
if ( isset( $request['description'] ) ) {
$variation->set_description( wp_kses_post( $request['description'] ) );
}

// Update taxonomies.
if ( isset( $request['attributes'] ) ) {
$attributes = array();
$parent = wc_get_product( $variation->get_parent_id() );
$parent_attributes = $parent->get_attributes();

foreach ( $request['attributes'] as $attribute ) {
$attribute_id = 0;
$attribute_name = '';

// Check ID for global attributes or name for product attributes.
if ( ! empty( $attribute['id'] ) ) {
$attribute_id = absint( $attribute['id'] );
$attribute_name = wc_attribute_taxonomy_name_by_id( $attribute_id );
} elseif ( ! empty( $attribute['name'] ) ) {
$attribute_name = sanitize_title( $attribute['name'] );
}

if ( ! $attribute_id && ! $attribute_name ) {
continue;
}

if ( ! isset( $parent_attributes[ $attribute_name ] ) || ! $parent_attributes[ $attribute_name ]->get_variation() ) {
continue;
}

$attribute_key = sanitize_title( $parent_attributes[ $attribute_name ]->get_name() );
$attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : '';

if ( $parent_attributes[ $attribute_name ]->is_taxonomy() ) {
// If dealing with a taxonomy, we need to get the slug from the name posted to the API.
$term = get_term_by( 'name', $attribute_value, $attribute_name );

if ( $term && ! is_wp_error( $term ) ) {
$attribute_value = $term->slug;
} else {
$attribute_value = sanitize_title( $attribute_value );
}
}

$attributes[ $attribute_key ] = $attribute_value;
}

$variation->set_attributes( $attributes );
}

// Menu order.
if ( $request['menu_order'] ) {
$variation->set_menu_order( $request['menu_order'] );
}

// Meta data.
if ( is_array( $request['meta_data'] ) ) {
foreach ( $request['meta_data'] as $meta ) {
$variation->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' );
}
}

/**
* Filters an object before it is inserted via the REST API.
*
* The dynamic portion of the hook name, `$this->post_type`,
* refers to the object type slug.
*
* @param WC_Data $variation Object object.
* @param WP_REST_Request $request Request object.
* @param bool $creating If is creating a new object.
*/
return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $variation, $request, $creating );
}

/**
* Get the image for a product variation.
*
* @param WC_Product_Variation $variation Variation
* @return array
*/
protected function get_images( $variation ) {
protected function get_image( $variation ) {
if ( ! has_post_thumbnail( $variation->get_id() ) ) {
return;
}

$attachment_id = $variation->get_image_id();
$attachment_post = get_post( $attachment_id );
if ( is_null( $attachment_post ) ) {
$image = array();
return;
}

$attachment = wp_get_attachment_image_src( $attachment_id, 'full' );
if ( ! is_array( $attachment ) ) {
$image = array();
return;
}

if ( ! isset ( $image ) ) {
$image = array(
return array(
'id' => (int) $attachment_id,
'date_created' => wc_rest_prepare_date_response( $attachment_post->post_date, false ),
'date_created_gmt' => wc_rest_prepare_date_response( strtotime( $attachment_post->post_date_gmt ) ),
Expand All @@ -59,7 +336,7 @@ protected function get_images( $variation ) {
);
}

return array( $image );
return;
}

/**
Expand Down Expand Up @@ -152,10 +429,11 @@ public function get_item_schema() {
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
'visible' => array(
'description' => __( "Define if the attribute is visible on the \"Additional information\" tab in the product's page.", 'woocommerce' ),
'type' => 'boolean',
'default' => true,
'status' => array(
'description' => __( 'Variation status.', 'woocommerce' ),
'type' => 'string',
'default' => 'publish',
'enum' => array_keys( get_post_statuses() ),
'context' => array( 'view', 'edit' ),
),
'purchasable' => array(
Expand Down
5 changes: 4 additions & 1 deletion tests/unit-tests/product-variations.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ public function test_update_variation() {
$this->assertEquals( 10, $variation['regular_price'] );
$this->assertEmpty( $variation['sale_price'] );
$this->assertEquals( 'small', $variation['attributes'][0]['option'] );
$this->assertEquals( 'publish', $variation['status'] );

$request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() . '/variations/' . $variation_id );
$request->set_body_params( array(
Expand All @@ -177,6 +178,7 @@ public function test_update_variation() {
'description' => 'O_O',
'image' => array( 'position' => 0, 'src' => 'https://cldup.com/Dr1Bczxq4q.png', 'alt' => 'test upload image' ),
'attributes' => array( array( 'name' => 'pa_size', 'option' => 'medium' ) ),
'status' => 'private',
) );
$response = $this->server->dispatch( $request );
$variation = $response->get_data();
Expand All @@ -189,6 +191,7 @@ public function test_update_variation() {
$this->assertEquals( 'medium', $variation['attributes'][0]['option'] );
$this->assertContains( 'Dr1Bczxq4q', $variation['image']['src'] );
$this->assertContains( 'test upload image', $variation['image']['alt'] );
$this->assertEquals( 'private', $variation['status'] );
$product->delete( true );
}

Expand Down Expand Up @@ -356,13 +359,13 @@ public function test_variation_schema() {
$this->assertArrayHasKey( 'date_on_sale_from', $properties );
$this->assertArrayHasKey( 'date_on_sale_to', $properties );
$this->assertArrayHasKey( 'on_sale', $properties );
$this->assertArrayHasKey( 'visible', $properties );
$this->assertArrayHasKey( 'purchasable', $properties );
$this->assertArrayHasKey( 'virtual', $properties );
$this->assertArrayHasKey( 'downloadable', $properties );
$this->assertArrayHasKey( 'downloads', $properties );
$this->assertArrayHasKey( 'download_limit', $properties );
$this->assertArrayHasKey( 'download_expiry', $properties );
$this->assertArrayHasKey( 'status', $properties );
$this->assertArrayHasKey( 'tax_status', $properties );
$this->assertArrayHasKey( 'tax_class', $properties );
$this->assertArrayHasKey( 'manage_stock', $properties );
Expand Down

0 comments on commit db1c191

Please sign in to comment.