Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Add: Cross-sells for the Store API Cart response. #6635

Merged
merged 11 commits into from
Jul 13, 2022
Merged
1 change: 1 addition & 0 deletions src/StoreApi/SchemaController.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public function __construct( ExtendSchema $extend ) {
Schemas\V1\CartCouponSchema::IDENTIFIER => Schemas\V1\CartCouponSchema::class,
Schemas\V1\CartFeeSchema::IDENTIFIER => Schemas\V1\CartFeeSchema::class,
Schemas\V1\CartItemSchema::IDENTIFIER => Schemas\V1\CartItemSchema::class,
Schemas\V1\CrossSellsItemSchema::IDENTIFIER => Schemas\V1\CrossSellsItemSchema::class,
Schemas\V1\CartSchema::IDENTIFIER => Schemas\V1\CartSchema::class,
Schemas\V1\CartExtensionsSchema::IDENTIFIER => Schemas\V1\CartExtensionsSchema::class,
Schemas\V1\CheckoutSchema::IDENTIFIER => Schemas\V1\CheckoutSchema::class,
Expand Down
2 changes: 2 additions & 0 deletions src/StoreApi/Schemas/ExtendSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use Automattic\WooCommerce\StoreApi\Schemas\V1\CartItemSchema;
use Automattic\WooCommerce\StoreApi\Schemas\V1\CartSchema;
use Automattic\WooCommerce\StoreApi\Schemas\V1\CheckoutSchema;
use Automattic\WooCommerce\StoreApi\Schemas\V1\CrossSellsItemSchema;
use Automattic\WooCommerce\StoreApi\Schemas\V1\ProductSchema;
use Automattic\WooCommerce\StoreApi\Formatters;

Expand All @@ -25,6 +26,7 @@ final class ExtendSchema {
*/
private $endpoints = [
CartItemSchema::IDENTIFIER,
CrossSellsItemSchema::IDENTIFIER,
CartSchema::IDENTIFIER,
CheckoutSchema::IDENTIFIER,
ProductSchema::IDENTIFIER,
Expand Down
22 changes: 22 additions & 0 deletions src/StoreApi/Schemas/V1/CartSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ class CartSchema extends AbstractSchema {
*/
public $coupon_schema;

/**
* Cross-sells item schema instance.
*
* @var CrossSellsItemSchema
*/
public $cross_sells_item_schema;

/**
* Fee schema instance.
*
Expand Down Expand Up @@ -84,6 +91,7 @@ class CartSchema extends AbstractSchema {
public function __construct( ExtendSchema $extend, SchemaController $controller ) {
parent::__construct( $extend, $controller );
$this->item_schema = $this->controller->get( CartItemSchema::IDENTIFIER );
$this->cross_sells_item_schema = $this->controller->get( CrossSellsItemSchema::IDENTIFIER );
$this->coupon_schema = $this->controller->get( CartCouponSchema::IDENTIFIER );
$this->fee_schema = $this->controller->get( CartFeeSchema::IDENTIFIER );
$this->shipping_rate_schema = $this->controller->get( CartShippingRateSchema::IDENTIFIER );
Expand Down Expand Up @@ -155,6 +163,16 @@ public function get_properties() {
'context' => [ 'view', 'edit' ],
'readonly' => true,
],
'cross_sells' => [
'description' => __( 'List of cross-sells items related to cart items.', 'woo-gutenberg-products-block' ),
'type' => 'array',
'context' => [ 'view', 'edit' ],
'readonly' => true,
'items' => [
'type' => 'object',
'properties' => $this->force_schema_readonly( $this->cross_sells_item_schema->get_properties() ),
],
],
'needs_payment' => [
'description' => __( 'True if the cart needs payment. False for carts with only free products and no shipping costs.', 'woo-gutenberg-products-block' ),
'type' => 'boolean',
Expand Down Expand Up @@ -323,6 +341,9 @@ public function get_item_response( $cart ) {
// Get shipping packages to return in the response from the cart.
$shipping_packages = $has_calculated_shipping ? $controller->get_shipping_packages() : [];

// Get visible cross sells products.
$cross_sells = array_filter( array_map( 'wc_get_product', $cart->get_cross_sells() ), 'wc_products_array_filter_visible' );

return [
'coupons' => $this->get_item_responses_from_schema( $this->coupon_schema, $cart->get_applied_coupons() ),
'shipping_rates' => $this->get_item_responses_from_schema( $this->shipping_rate_schema, $shipping_packages ),
Expand All @@ -331,6 +352,7 @@ public function get_item_response( $cart ) {
'items' => $this->get_item_responses_from_schema( $this->item_schema, $cart->get_cart() ),
'items_count' => $cart->get_cart_contents_count(),
'items_weight' => wc_get_weight( $cart->get_cart_contents_weight(), 'g' ),
'cross_sells' => $this->get_item_responses_from_schema( $this->cross_sells_item_schema, $cross_sells ),
'needs_payment' => $cart->needs_payment(),
'needs_shipping' => $cart->needs_shipping(),
'has_calculated_shipping' => $has_calculated_shipping,
Expand Down
62 changes: 62 additions & 0 deletions src/StoreApi/Schemas/V1/CrossSellsItemSchema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php
wavvves marked this conversation as resolved.
Show resolved Hide resolved
namespace Automattic\WooCommerce\StoreApi\Schemas\V1;

/**
* CrossSellsItemSchema class.
*/
class CrossSellsItemSchema extends ProductSchema {

/**
* The schema item name.
*
* @var string
*/
protected $title = 'cart_cross_sells_item';

/**
* The schema item identifier.
*
* @var string
*/
const IDENTIFIER = 'cart-cross-sells-item';

/**
* Cross-sells schema properties.
*
* @return array
*/
public function get_properties() {
$properties = parent::get_properties();

return [
'id' => $properties['id'],
'name' => $properties['name'],
'permalink' => $properties['permalink'],
'prices' => $properties['prices'],
'images' => $properties['images'],
'average_rating' => $properties['average_rating'],
self::EXTENDING_KEY => $this->get_extended_schema( self::IDENTIFIER ),
];
wavvves marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Converts a WooCommerce product into an object suitable for the response.
*
* @param \WC_Product $product Cross-sell product.
*
* @return array
*/
public function get_item_response( $product ) {

return [
'id' => $product->get_id(),
'name' => $this->prepare_html_response( $product->get_title() ),
'permalink' => $product->get_permalink(),
'prices' => (object) $this->prepare_product_price_response( $product ),
'average_rating' => (string) $product->get_average_rating(),
'images' => $this->get_images( $product ),
self::EXTENDING_KEY => $this->get_extended_data( self::IDENTIFIER ),
];
wavvves marked this conversation as resolved.
Show resolved Hide resolved
}

}