From d9fbaa5ec362f9393aee40ebf625b23a372366ca Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 14 Dec 2022 14:08:39 +0000 Subject: [PATCH] Force method/pickup in the checkout layout (https://github.com/woocommerce/woocommerce-blocks/pull/7910) --- .../cart-checkout-shared/use-forced-layout.ts | 57 ++++++++++++++++++- .../src/BlockTypes/Checkout.php | 12 ++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout-shared/use-forced-layout.ts b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout-shared/use-forced-layout.ts index 72183567f0c..9b0fa88c338 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout-shared/use-forced-layout.ts +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout-shared/use-forced-layout.ts @@ -122,7 +122,62 @@ export const useForcedLayout = ( { .select( 'core/block-editor' ) .getBlocks( clientId ); - // If there are NO inner blocks, sync with the given template. + const { innerBlocks, registeredBlockTypes } = useSelect( + ( select ) => { + return { + innerBlocks: + select( 'core/block-editor' ).getBlocks( clientId ), + registeredBlockTypes: currentRegisteredBlocks.current.map( + ( blockName ) => getBlockType( blockName ) + ), + }; + }, + [ clientId, currentRegisteredBlocks.current ] + ); + + const appendBlock = useCallback( + ( block, position ) => { + const newBlock = createBlock( block.name ); + insertBlock( newBlock, position, clientId, false ); + }, + // We need to skip insertBlock here due to a cache issue in wordpress.com that causes an infinite loop, see https://github.com/Automattic/wp-calypso/issues/66092 for an expanded doc. + // eslint-disable-next-line react-hooks/exhaustive-deps + [ clientId ] + ); + + const lockedBlockTypes = useMemo( + () => + registeredBlockTypes.filter( + ( block: Block | undefined ) => block && isBlockLocked( block ) + ), + [ registeredBlockTypes ] + ) as Block[]; + + /** + * If the current inner blocks differ from the registered blocks, push the differences. + */ + useLayoutEffect( () => { + if ( ! clientId ) { + return; + } + + // If there are NO inner blocks, sync with the given template. + if ( + innerBlocks.length === 0 && + currentDefaultTemplate.current.length > 0 + ) { + const nextBlocks = createBlocksFromInnerBlocksTemplate( + currentDefaultTemplate.current + ); + if ( ! isEqual( nextBlocks, innerBlocks ) ) { + replaceInnerBlocks( clientId, nextBlocks ); + return; + } + } + + // Find registered locked blocks missing from Inner Blocks and append them. + lockedBlockTypes.forEach( ( block ) => { + // If the locked block type is already in the layout, we can skip this one. if ( innerBlocks.length === 0 && currentDefaultTemplate.current.length > 0 diff --git a/plugins/woocommerce-blocks/src/BlockTypes/Checkout.php b/plugins/woocommerce-blocks/src/BlockTypes/Checkout.php index 7cc63aa629f..91db65a3d7a 100644 --- a/plugins/woocommerce-blocks/src/BlockTypes/Checkout.php +++ b/plugins/woocommerce-blocks/src/BlockTypes/Checkout.php @@ -146,6 +146,18 @@ class Checkout extends AbstractBlock { $content = preg_replace( $regex_for_order_summary, $order_summary_with_inner_blocks, $content ); } + /** + * Add the Local Pickup toggle to checkouts missing this forced template. + */ + $local_pickup_inner_blocks = '
' . PHP_EOL . PHP_EOL . '
' . PHP_EOL . PHP_EOL . '$0'; + $has_local_pickup_regex = '//mi'; + $has_local_pickup = preg_match( $has_local_pickup_regex, $content ); + + if ( ! $has_local_pickup ) { + $shipping_address_block_regex = '/<\/div>/mi'; + $content = preg_replace( $shipping_address_block_regex, $local_pickup_inner_blocks, $content ); + } + return $content; }