* Include shipping and billing address data in cart schema

* update cart hook (and data api) with new properties from endpoint

* add use-shipping-address hook and implement in use-shipping-rates

* update usages of useShippingRates through code

* update tests for use-shipping-rates

* update use-payment-method-interface and typedef to remove country field

This is provided reliably via the shippingAddress now.

* restore pluck comparison to effect.

Also added some clarification docs for why `iniitalAddress` is not included in the effect dependencies.

* remove billingAddress from cart schema

* clear city and postcode when changing country

* Update REST Api schemas aftere rebase

- CustomerSchema no longer exists
- Added ShippingAddressSchema implemented by Cart and Order schemas
- fix broken js because of bad merge conflict resolution.

* remove duplicate keys
This commit is contained in:
Darren Ethier 2020-03-13 15:04:03 -04:00 committed by GitHub
parent 5d1d8f0394
commit 80f692404f
16 changed files with 267 additions and 149 deletions

View File

@ -66,6 +66,8 @@ const AddressForm = ( {
...values, ...values,
country: newValue, country: newValue,
state: '', state: '',
city: '',
postcode: '',
} ) } )
} }
required={ field.required } required={ field.required }

View File

@ -14,7 +14,6 @@ import { previewCart } from '@woocommerce/resource-previews';
*/ */
const defaultCartData = { const defaultCartData = {
cartCoupons: [], cartCoupons: [],
shippingRates: [],
cartItems: [], cartItems: [],
cartItemsCount: 0, cartItemsCount: 0,
cartItemsWeight: 0, cartItemsWeight: 0,
@ -22,6 +21,18 @@ const defaultCartData = {
cartTotals: {}, cartTotals: {},
cartIsLoading: true, cartIsLoading: true,
cartErrors: [], cartErrors: [],
shippingAddress: {
first_name: '',
last_name: '',
company: '',
address_1: '',
address_2: '',
city: '',
state: '',
postcode: '',
country: '',
},
shippingRates: [],
}; };
/** /**
@ -43,7 +54,7 @@ export const useStoreCart = ( options = { shouldSelect: true } ) => {
const results = useSelect( const results = useSelect(
( select ) => { ( select ) => {
if ( ! shouldSelect ) { if ( ! shouldSelect ) {
return null; return defaultCartData;
} }
if ( isEditor ) { if ( isEditor ) {
@ -70,6 +81,7 @@ export const useStoreCart = ( options = { shouldSelect: true } ) => {
return { return {
cartCoupons: cartData.coupons, cartCoupons: cartData.coupons,
shippingRates: cartData.shippingRates, shippingRates: cartData.shippingRates,
shippingAddress: cartData.shippingAddress,
cartItems: cartData.items, cartItems: cartData.items,
cartItemsCount: cartData.itemsCount, cartItemsCount: cartData.itemsCount,
cartItemsWeight: cartData.itemsWeight, cartItemsWeight: cartData.itemsWeight,
@ -81,8 +93,5 @@ export const useStoreCart = ( options = { shouldSelect: true } ) => {
}, },
[ shouldSelect ] [ shouldSelect ]
); );
if ( results === null ) {
return defaultCartData;
}
return results; return results;
}; };

View File

@ -169,9 +169,6 @@ export const usePaymentMethodInterface = () => {
orderLoading, orderLoading,
cartTotal: currentCartTotal.current, cartTotal: currentCartTotal.current,
currency: getCurrencyFromPriceResponse( cartTotals ), currency: getCurrencyFromPriceResponse( cartTotals ),
// @todo need to pass along the default country set for the site
// if it's available.
country: '',
cartTotalItems: currentCartTotals.current, cartTotalItems: currentCartTotals.current,
displayPricesIncludingTax: DISPLAY_CART_PRICES_INCLUDING_TAX, displayPricesIncludingTax: DISPLAY_CART_PRICES_INCLUDING_TAX,
appliedCoupons, appliedCoupons,

View File

@ -1,2 +1,3 @@
export * from './use-select-shipping-rate'; export * from './use-select-shipping-rate';
export * from './use-shipping-rates'; export * from './use-shipping-rates';
export * from './use-shipping-address';

View File

@ -0,0 +1,39 @@
/**
* External dependencies
*/
import { useDispatch } from '@wordpress/data';
import { useEffect, useState } from '@wordpress/element';
import isShallowEqual from '@wordpress/is-shallow-equal';
import { useDebounce } from 'use-debounce';
import { CART_STORE_KEY as storeKey } from '@woocommerce/block-data';
/**
* Internal dependencies
*/
import { useStoreCart } from '../cart/use-store-cart';
import { pluckAddress } from '../../utils';
const shouldUpdateStore = ( oldAddress, newAddress ) =>
! isShallowEqual( pluckAddress( oldAddress ), pluckAddress( newAddress ) );
export const useShippingAddress = () => {
const { shippingAddress: initialAddress } = useStoreCart();
const [ shippingAddress, setShippingAddress ] = useState( initialAddress );
const [ debouncedShippingAddress ] = useDebounce( shippingAddress, 400 );
const { updateShippingAddress } = useDispatch( storeKey );
// Note, we're intentionally not using initialAddress as a dependency here
// so that the stale (previous) value is being used for comparison.
useEffect( () => {
if (
debouncedShippingAddress.country &&
shouldUpdateStore( initialAddress, debouncedShippingAddress )
) {
updateShippingAddress( debouncedShippingAddress );
}
}, [ debouncedShippingAddress ] );
return {
shippingAddress,
setShippingAddress,
};
};

View File

@ -1,24 +1,19 @@
/** /**
* External dependencies * External dependencies
*/ */
import { useSelect, useDispatch } from '@wordpress/data'; import { useSelect } from '@wordpress/data';
import { useReducer, useEffect } from '@wordpress/element';
import isShallowEqual from '@wordpress/is-shallow-equal';
import { useDebounce } from 'use-debounce';
import { CART_STORE_KEY as storeKey } from '@woocommerce/block-data'; import { CART_STORE_KEY as storeKey } from '@woocommerce/block-data';
/** /**
* Internal dependencies * Internal dependencies
*/ */
import { useStoreCart } from '../cart/use-store-cart'; import { useStoreCart } from '../cart/use-store-cart';
import { pluckAddress } from '../../utils'; import { useShippingAddress } from '../shipping/use-shipping-address';
/** /**
* This is a custom hook that is wired up to the `wc/store/cart/shipping-rates` route. * This is a custom hook that is wired up to the `wc/store/cart/shipping-rates` route.
* Given a a set of default fields keys, this will handle shipping form state and load * Given a a set of default fields keys, this will handle shipping form state and load
* new rates when certain fields change. * new rates when certain fields change.
* *
* @param {Array} addressFieldsKeys an array containing default fields keys.
*
* @return {Object} This hook will return an object with three properties: * @return {Object} This hook will return an object with three properties:
* - {Boolean} shippingRatesLoading A boolean indicating whether the shipping * - {Boolean} shippingRatesLoading A boolean indicating whether the shipping
* rates are still loading or not. * rates are still loading or not.
@ -27,39 +22,13 @@ import { pluckAddress } from '../../utils';
* - {Object} shippingAddress An object containing shipping address. * - {Object} shippingAddress An object containing shipping address.
* - {Object} shippingAddress True when address data exists. * - {Object} shippingAddress True when address data exists.
*/ */
export const useShippingRates = ( addressFieldsKeys ) => { export const useShippingRates = () => {
const { cartErrors, shippingRates } = useStoreCart(); const { cartErrors, shippingRates } = useStoreCart();
const initialAddress = shippingRates[ 0 ]?.destination || {}; const { shippingAddress, setShippingAddress } = useShippingAddress();
addressFieldsKeys.forEach( ( key ) => {
initialAddress[ key ] = initialAddress[ key ] || '';
} );
const shippingAddressReducer = ( state, address ) => ( {
...state,
...address,
} );
const [ shippingAddress, setShippingAddress ] = useReducer(
shippingAddressReducer,
initialAddress
);
const [ debouncedShippingAddress ] = useDebounce( shippingAddress, 400 );
const shippingRatesLoading = useSelect( const shippingRatesLoading = useSelect(
( select ) => select( storeKey ).areShippingRatesLoading(), ( select ) => select( storeKey ).areShippingRatesLoading(),
[] []
); );
const { updateShippingAddress } = useDispatch( storeKey );
useEffect( () => {
if (
! isShallowEqual(
pluckAddress( debouncedShippingAddress ),
pluckAddress( initialAddress )
) &&
debouncedShippingAddress.country
) {
updateShippingAddress( debouncedShippingAddress );
}
}, [ debouncedShippingAddress ] );
return { return {
shippingRates, shippingRates,
shippingAddress, shippingAddress,

View File

@ -38,9 +38,8 @@ describe( 'useShippingRates', () => {
</RegistryProvider> </RegistryProvider>
); );
const defaultFieldsConfig = [ 'country', 'state', 'city', 'postcode' ];
const getTestComponent = () => () => { const getTestComponent = () => () => {
const items = useShippingRates( defaultFieldsConfig ); const items = useShippingRates();
return <div { ...items } />; return <div { ...items } />;
}; };
@ -50,6 +49,12 @@ describe( 'useShippingRates', () => {
itemsCount: 123, itemsCount: 123,
itemsWeight: 123, itemsWeight: 123,
needsShipping: false, needsShipping: false,
shippingAddress: {
country: '',
state: '',
city: '',
postcode: '',
},
shippingRates: [ shippingRates: [
{ {
shippingRates: [ { foo: 'bar' } ], shippingRates: [ { foo: 'bar' } ],
@ -94,9 +99,7 @@ describe( 'useShippingRates', () => {
} ); } );
const { shippingAddress } = getProps( renderer ); const { shippingAddress } = getProps( renderer );
expect( shippingAddress ).toStrictEqual( expect( shippingAddress ).toStrictEqual( mockCartData.shippingAddress );
mockCartData.shippingRates[ 0 ].destination
);
// rerender // rerender
act( () => { act( () => {
renderer.update( getWrappedComponents( TestComponent ) ); renderer.update( getWrappedComponents( TestComponent ) );

View File

@ -89,7 +89,7 @@ const Block = ( {
shippingRatesLoading, shippingRatesLoading,
shippingAddress: shippingFields, shippingAddress: shippingFields,
setShippingAddress: setShippingFields, setShippingAddress: setShippingFields,
} = useShippingRates( Object.keys( addressFields ) ); } = useShippingRates();
return ( return (
<CheckoutProvider isEditor={ isEditor }> <CheckoutProvider isEditor={ isEditor }>

View File

@ -47,6 +47,17 @@ const reducer = (
cartData: { cartData: {
coupons: [], coupons: [],
shippingRates: [], shippingRates: [],
shippingAddress: {
first_name: '',
last_name: '',
company: '',
address_1: '',
address_2: '',
city: '',
state: '',
postcode: '',
country: '',
},
items: [], items: [],
itemsCount: 0, itemsCount: 0,
itemsWeight: 0, itemsWeight: 0,

View File

@ -179,13 +179,17 @@
/** /**
* @typedef {Object} CartData * @typedef {Object} CartData
* *
* @property {Array} coupons Coupons applied to cart. * @property {Array} coupons Coupons applied to cart.
* @property {Array} shippingRates array of selected shipping rates * @property {Array} shippingRates Array of selected shipping
* @property {Array} items Items in the cart. * rates.
* @property {number} itemsCount Number of items in the cart. * @property {CartShippingAddress} shippingAddress Shipping address for the
* @property {number} itemsWeight Weight of items in the cart. * cart.
* @property {boolean} needsShipping True if the cart needs shipping. * @property {Array} items Items in the cart.
* @property {CartTotals} totals Cart total amounts. * @property {number} itemsCount Number of items in the cart.
* @property {number} itemsWeight Weight of items in the cart.
* @property {boolean} needsShipping True if the cart needs
* shipping.
* @property {CartTotals} totals Cart total amounts.
*/ */
/** /**

View File

@ -1,19 +1,32 @@
/** /**
* @typedef {import('./cart').CartData} CartData * @typedef {import('./cart').CartData} CartData
* @typedef {import('./cart').CartBillingAddress} CartBillingAddress
* @typedef {import('./cart').CartShippingAddress} CartShippingAddress
*/ */
/** /**
* @typedef {Object} StoreCart * @typedef {Object} StoreCart
* *
* @property {Array} cartCoupons An array of coupons applied to the cart. * @property {Array} cartCoupons An array of coupons applied
* @property {Array} shippingRates array of selected shipping rates * to the cart.
* @property {Array} cartItems An array of items in the cart. * @property {Array} shippingRates array of selected shipping
* @property {number} cartItemsCount The number of items in the cart. * rates
* @property {number} cartItemsWeight The weight of all items in the cart. * @property {CartShippingAddress} shippingAddress Shipping address for the
* @property {boolean} cartNeedsShipping True when the cart will require shipping. * cart.
* @property {Object} cartTotals Cart and line total amounts. * @property {Array} cartItems An array of items in the
* @property {boolean} cartIsLoading True when cart data is being loaded. * cart.
* @property {Array} cartErrors An array of errors thrown by the cart. * @property {number} cartItemsCount The number of items in the
* cart.
* @property {number} cartItemsWeight The weight of all items in
* the cart.
* @property {boolean} cartNeedsShipping True when the cart will
* require shipping.
* @property {Object} cartTotals Cart and line total
* amounts.
* @property {boolean} cartIsLoading True when cart data is
* being loaded.
* @property {Array} cartErrors An array of errors thrown
* by the cart.
*/ */
/** /**

View File

@ -130,10 +130,6 @@
* @property {CartTotalItem} cartTotal The total item for * @property {CartTotalItem} cartTotal The total item for
* the cart. * the cart.
* @property {SiteCurrency} currency Currency object. * @property {SiteCurrency} currency Currency object.
* @property {string} country ISO country code
* for the default
* country for the
* site.
* @property {CartTotalItem[]} cartTotalItems The various subtotal * @property {CartTotalItem[]} cartTotalItems The various subtotal
* amounts. * amounts.
* @property {boolean} displayPricesIncludingTax True means that the * @property {boolean} displayPricesIncludingTax True means that the

View File

@ -28612,7 +28612,7 @@
} }
}, },
"woocommerce": { "woocommerce": {
"version": "git+https://github.com/woocommerce/woocommerce.git#fb1001b14a90b3020ca8000e424c955845142f5c", "version": "git+https://github.com/woocommerce/woocommerce.git#6f2b232fc7fa53417691a742a419147bb0134a5c",
"from": "git+https://github.com/woocommerce/woocommerce.git", "from": "git+https://github.com/woocommerce/woocommerce.git",
"dev": true, "dev": true,
"requires": { "requires": {

View File

@ -31,7 +31,7 @@ class CartSchema extends AbstractSchema {
*/ */
public function get_properties() { public function get_properties() {
return [ return [
'coupons' => [ 'coupons' => [
'description' => __( 'List of applied cart coupons.', 'woo-gutenberg-products-block' ), 'description' => __( 'List of applied cart coupons.', 'woo-gutenberg-products-block' ),
'type' => 'array', 'type' => 'array',
'context' => [ 'view', 'edit' ], 'context' => [ 'view', 'edit' ],
@ -41,7 +41,7 @@ class CartSchema extends AbstractSchema {
'properties' => $this->force_schema_readonly( ( new CartCouponSchema() )->get_properties() ), 'properties' => $this->force_schema_readonly( ( new CartCouponSchema() )->get_properties() ),
], ],
], ],
'shipping_rates' => [ 'shipping_rates' => [
'description' => __( 'List of available shipping rates for the cart.', 'woo-gutenberg-products-block' ), 'description' => __( 'List of available shipping rates for the cart.', 'woo-gutenberg-products-block' ),
'type' => 'array', 'type' => 'array',
'context' => [ 'view', 'edit' ], 'context' => [ 'view', 'edit' ],
@ -51,7 +51,17 @@ class CartSchema extends AbstractSchema {
'properties' => $this->force_schema_readonly( ( new CartShippingRateSchema() )->get_properties() ), 'properties' => $this->force_schema_readonly( ( new CartShippingRateSchema() )->get_properties() ),
], ],
], ],
'items' => [ 'shipping_address' => [
'description' => __( 'Current set shipping address for the customer.', 'woo-gutenberg-products-block' ),
'type' => 'object',
'context' => [ 'view', 'edit' ],
'readonly' => true,
'items' => [
'type' => 'object',
'properties' => $this->force_schema_readonly( ( new ShippingAddressSchema() )->get_properties() ),
],
],
'items' => [
'description' => __( 'List of cart items.', 'woo-gutenberg-products-block' ), 'description' => __( 'List of cart items.', 'woo-gutenberg-products-block' ),
'type' => 'array', 'type' => 'array',
'context' => [ 'view', 'edit' ], 'context' => [ 'view', 'edit' ],
@ -61,25 +71,25 @@ class CartSchema extends AbstractSchema {
'properties' => $this->force_schema_readonly( ( new CartItemSchema() )->get_properties() ), 'properties' => $this->force_schema_readonly( ( new CartItemSchema() )->get_properties() ),
], ],
], ],
'items_count' => [ 'items_count' => [
'description' => __( 'Number of items in the cart.', 'woo-gutenberg-products-block' ), 'description' => __( 'Number of items in the cart.', 'woo-gutenberg-products-block' ),
'type' => 'integer', 'type' => 'integer',
'context' => [ 'view', 'edit' ], 'context' => [ 'view', 'edit' ],
'readonly' => true, 'readonly' => true,
], ],
'items_weight' => [ 'items_weight' => [
'description' => __( 'Total weight (in grams) of all products in the cart.', 'woo-gutenberg-products-block' ), 'description' => __( 'Total weight (in grams) of all products in the cart.', 'woo-gutenberg-products-block' ),
'type' => 'number', 'type' => 'number',
'context' => [ 'view', 'edit' ], 'context' => [ 'view', 'edit' ],
'readonly' => true, 'readonly' => true,
], ],
'needs_shipping' => [ 'needs_shipping' => [
'description' => __( 'True if the cart needs shipping. False for carts with only digital goods or stores with no shipping methods set-up.', 'woo-gutenberg-products-block' ), 'description' => __( 'True if the cart needs shipping. False for carts with only digital goods or stores with no shipping methods set-up.', 'woo-gutenberg-products-block' ),
'type' => 'boolean', 'type' => 'boolean',
'context' => [ 'view', 'edit' ], 'context' => [ 'view', 'edit' ],
'readonly' => true, 'readonly' => true,
], ],
'totals' => [ 'totals' => [
'description' => __( 'Cart total amounts provided using the smallest unit of the currency.', 'woo-gutenberg-products-block' ), 'description' => __( 'Cart total amounts provided using the smallest unit of the currency.', 'woo-gutenberg-products-block' ),
'type' => 'object', 'type' => 'object',
'context' => [ 'view', 'edit' ], 'context' => [ 'view', 'edit' ],
@ -183,20 +193,22 @@ class CartSchema extends AbstractSchema {
* @return array * @return array
*/ */
public function get_item_response( $cart ) { public function get_item_response( $cart ) {
$controller = new CartController(); $controller = new CartController();
$cart_coupon_schema = new CartCouponSchema(); $cart_coupon_schema = new CartCouponSchema();
$cart_item_schema = new CartItemSchema(); $cart_item_schema = new CartItemSchema();
$shipping_rate_schema = new CartShippingRateSchema(); $shipping_rate_schema = new CartShippingRateSchema();
$context = 'edit'; $shipping_address_schema = ( new ShippingAddressSchema() )->get_item_response( WC()->customer );
$context = 'edit';
return [ return [
'coupons' => array_values( array_map( [ $cart_coupon_schema, 'get_item_response' ], array_filter( $cart->get_applied_coupons() ) ) ), 'coupons' => array_values( array_map( [ $cart_coupon_schema, 'get_item_response' ], array_filter( $cart->get_applied_coupons() ) ) ),
'shipping_rates' => array_values( array_map( [ $shipping_rate_schema, 'get_item_response' ], $controller->get_shipping_packages() ) ), 'shipping_rates' => array_values( array_map( [ $shipping_rate_schema, 'get_item_response' ], $controller->get_shipping_packages() ) ),
'items' => array_values( array_map( [ $cart_item_schema, 'get_item_response' ], array_filter( $cart->get_cart() ) ) ), 'shipping_address' => $shipping_address_schema,
'items_count' => $cart->get_cart_contents_count(), 'items' => array_values( array_map( [ $cart_item_schema, 'get_item_response' ], array_filter( $cart->get_cart() ) ) ),
'items_weight' => wc_get_weight( $cart->get_cart_contents_weight(), 'g' ), 'items_count' => $cart->get_cart_contents_count(),
'needs_shipping' => $cart->needs_shipping(), 'items_weight' => wc_get_weight( $cart->get_cart_contents_weight(), 'g' ),
'totals' => (object) array_merge( 'needs_shipping' => $cart->needs_shipping(),
'totals' => (object) array_merge(
$this->get_store_currency_response(), $this->get_store_currency_response(),
[ [
'total_items' => $this->prepare_money_response( $cart->get_subtotal(), wc_get_price_decimals() ), 'total_items' => $this->prepare_money_response( $cart->get_subtotal(), wc_get_price_decimals() ),

View File

@ -219,53 +219,7 @@ class OrderSchema extends AbstractSchema {
'description' => __( 'Shipping address.', 'woo-gutenberg-products-block' ), 'description' => __( 'Shipping address.', 'woo-gutenberg-products-block' ),
'type' => 'object', 'type' => 'object',
'context' => [ 'view', 'edit' ], 'context' => [ 'view', 'edit' ],
'properties' => [ 'properties' => $this->force_schema_readonly( ( new ShippingAddressSchema() )->get_properties() ),
'first_name' => [
'description' => __( 'First name', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'last_name' => [
'description' => __( 'Last name', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'company' => [
'description' => __( 'Company', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'address_1' => [
'description' => __( 'Address', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'address_2' => [
'description' => __( 'Apartment, suite, etc.', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'city' => [
'description' => __( 'City', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'state' => [
'description' => __( 'State/County code, or name of the state, county, province, or district.', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'postcode' => [
'description' => __( 'Postal code', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'country' => [
'description' => __( 'Country/Region code in ISO 3166-1 alpha-2 format.', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
],
], ],
'coupons' => [ 'coupons' => [
'description' => __( 'List of applied coupons.', 'woo-gutenberg-products-block' ), 'description' => __( 'List of applied coupons.', 'woo-gutenberg-products-block' ),
@ -422,19 +376,7 @@ class OrderSchema extends AbstractSchema {
'phone' => $order->get_billing_phone(), 'phone' => $order->get_billing_phone(),
] ]
), ),
'shipping_address' => (object) $this->prepare_html_response( 'shipping_address' => ( new ShippingAddressSchema() )->get_item_response( $order ),
[
'first_name' => $order->get_shipping_first_name(),
'last_name' => $order->get_shipping_last_name(),
'company' => $order->get_shipping_company(),
'address_1' => $order->get_shipping_address_1(),
'address_2' => $order->get_shipping_address_2(),
'city' => $order->get_shipping_city(),
'state' => $order->get_shipping_state(),
'postcode' => $order->get_shipping_postcode(),
'country' => $order->get_shipping_country(),
]
),
'coupons' => array_values( array_map( [ $order_coupon_schema, 'get_item_response' ], $order->get_items( 'coupon' ) ) ), 'coupons' => array_values( array_map( [ $order_coupon_schema, 'get_item_response' ], $order->get_items( 'coupon' ) ) ),
'items' => array_values( array_map( [ $order_item_schema, 'get_item_response' ], $order->get_items( 'line_item' ) ) ), 'items' => array_values( array_map( [ $order_item_schema, 'get_item_response' ], $order->get_items( 'line_item' ) ) ),
'totals' => (object) array_merge( 'totals' => (object) array_merge(

View File

@ -0,0 +1,120 @@
<?php
/**
* Shipping Address Schema.
*
* @package WooCommerce/Blocks
*/
namespace Automattic\WooCommerce\Blocks\RestApi\StoreApi\Schemas;
defined( 'ABSPATH' ) || exit;
use Automattic\WooCommerce\Blocks\RestApi\Routes;
/**
* ShippingAddressSchema class.
*
* Provides a generic shipping address schema for composition in other schemas.
*
* @since 2.5.0
*/
class ShippingAddressSchema extends AbstractSchema {
/**
* The schema item name.
*
* @var string
*/
protected $title = 'shipping_address';
/**
* Term properties.
*
* @return array
*/
public function get_properties() {
return [
'first_name' => [
'description' => __( 'First name', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'last_name' => [
'description' => __( 'Last name', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'company' => [
'description' => __( 'Company', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'address_1' => [
'description' => __( 'Address', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'address_2' => [
'description' => __( 'Apartment, suite, etc.', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'city' => [
'description' => __( 'City', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'state' => [
'description' => __( 'State/County code, or name of the state, county, province, or district.', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'postcode' => [
'description' => __( 'Postal code', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
'country' => [
'description' => __( 'Country/Region code in ISO 3166-1 alpha-2 format.', 'woo-gutenberg-products-block' ),
'type' => 'string',
'context' => [ 'view', 'edit' ],
],
];
}
/**
* Convert a term object into an object suitable for the response.
*
* @param \WC_Order|\WC_Customer $address An object with shipping address.
*
* @throws RouteException When the invalid object types are provided.
* @return stdClass
*/
public function get_item_response( $address ) {
if ( ( $address instanceof \WC_Customer || $address instanceof \WC_Order ) ) {
return (object) $this->prepare_html_response(
[
'first_name' => $address->get_shipping_first_name(),
'last_name' => $address->get_shipping_last_name(),
'company' => $address->get_shipping_company(),
'address_1' => $address->get_shipping_address_1(),
'address_2' => $address->get_shipping_address_2(),
'city' => $address->get_shipping_city(),
'state' => $address->get_shipping_state(),
'postcode' => $address->get_shipping_postcode(),
'country' => $address->get_shipping_country(),
]
);
}
throw new RouteException(
'invalid_object_type',
sprintf(
/* translators: Placeholders are class and method names */
__( '%1$s requires an instance of %2$s or %3$s for the address', 'woo-gutenberg-products-block' ),
'ShippingAddress::get_item_response',
'WC_Customer',
'WC_Order'
),
500
);
}
}