<?php
namespace Automattic\WooCommerce\StoreApi\Schemas\V1;
use Automattic\WooCommerce\StoreApi\Utilities\ProductItemTrait;
use Automattic\WooCommerce\StoreApi\Utilities\QuantityLimits;
/**
* CartItemSchema class.
*/
class CartItemSchema extends ItemSchema {
use ProductItemTrait;
/**
* The schema item name.
*
* @var string
*/
protected $title = 'cart_item';
/**
* The schema item identifier.
*
* @var string
*/
const IDENTIFIER = 'cart-item';
/**
* Convert a WooCommerce cart item to an object suitable for the response.
*
* @param array $cart_item Cart item array.
* @return array
*/
public function get_item_response( $cart_item ) {
$product = $cart_item['data'];
/**
* Filter the product permalink.
*
* This is a hook taken from the legacy cart/mini-cart templates that allows the permalink to be changed for a
* product. This is specific to the cart endpoint.
*
* @since 9.9.0
*
* @param string $product_permalink Product permalink.
* @param array $cart_item Cart item array.
* @param string $cart_item_key Cart item key.
*/
$product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $product->get_permalink(), $cart_item, $cart_item['key'] );
return [
'key' => $cart_item['key'],
'id' => $product->get_id(),
'type' => $product->get_type(),
'quantity' => wc_stock_amount( $cart_item['quantity'] ),
'quantity_limits' => (object) ( new QuantityLimits() )->get_cart_item_quantity_limits( $cart_item ),
'name' => $this->prepare_html_response( $product->get_title() ),
'short_description' => $this->prepare_html_response( wc_format_content( wp_kses_post( $product->get_short_description() ) ) ),
'description' => $this->prepare_html_response( wc_format_content( wp_kses_post( $product->get_description() ) ) ),
'sku' => $this->prepare_html_response( $product->get_sku() ),
'low_stock_remaining' => $this->get_low_stock_remaining( $product ),
'backorders_allowed' => (bool) $product->backorders_allowed(),
'show_backorder_badge' => (bool) $product->backorders_require_notification() && $product->is_on_backorder( $cart_item['quantity'] ),
'sold_individually' => $product->is_sold_individually(),
'permalink' => $product_permalink,
'images' => $this->get_images( $product ),
'variation' => $this->format_variation_data( $cart_item['variation'], $product ),
'item_data' => $this->get_item_data( $cart_item ),
'prices' => (object) $this->prepare_product_price_response( $product, get_option( 'woocommerce_tax_display_cart' ) ),
'totals' => (object) $this->prepare_currency_response(
[
'line_subtotal' => $this->prepare_money_response( $cart_item['line_subtotal'], wc_get_price_decimals() ),
'line_subtotal_tax' => $this->prepare_money_response( $cart_item['line_subtotal_tax'], wc_get_price_decimals() ),
'line_total' => $this->prepare_money_response( $cart_item['line_total'], wc_get_price_decimals() ),
'line_total_tax' => $this->prepare_money_response( $cart_item['line_tax'], wc_get_price_decimals() ),
]
),
'catalog_visibility' => $product->get_catalog_visibility(),
self::EXTENDING_KEY => $this->get_extended_data( self::IDENTIFIER, $cart_item ),
];
}
/**
* Format cart item data removing any HTML tag.
*
* @param array $cart_item Cart item array.
* @return array
*/
protected function get_item_data( $cart_item ) {
/**
* Filters cart item data.
*
* Filters the variation option name for custom option slugs.
*
* @since 4.3.0
*
* @internal Matches filter name in WooCommerce core.
*
* @param array $item_data Cart item data. Empty by default.
* @param array $cart_item Cart item array.
* @return array
*/
$item_data = apply_filters( 'woocommerce_get_item_data', array(), $cart_item );
$clean_item_data = [];
foreach ( $item_data as $data ) {
// We will check each piece of data in the item data element to ensure it is scalar. Extensions could add arrays
// to this, which would cause a fatal in wp_strip_all_tags. If it is not scalar, we will return an empty array,
// which will be filtered out in get_item_data (after this function has run).
foreach ( $data as $data_value ) {
if ( ! is_scalar( $data_value ) ) {
continue 2;
}
}
$clean_item_data[] = $this->format_item_data_element( $data );
}
return $clean_item_data;
}
/**
* Remove HTML tags from cart item data and set the `hidden` property to `__experimental_woocommerce_blocks_hidden`.
*
* @param array $item_data_element Individual element of a cart item data.
* @return array
*/
protected function format_item_data_element( $item_data_element ) {
if ( array_key_exists( '__experimental_woocommerce_blocks_hidden', $item_data_element ) ) {
$item_data_element['hidden'] = $item_data_element['__experimental_woocommerce_blocks_hidden'];
}
return array_map( 'wp_strip_all_tags', $item_data_element );
}
}