diff --git a/assets/js/blocks/product-query/inspector-controls.tsx b/assets/js/blocks/product-query/inspector-controls.tsx index b48dc8bd229..177ade426f0 100644 --- a/assets/js/blocks/product-query/inspector-controls.tsx +++ b/assets/js/blocks/product-query/inspector-controls.tsx @@ -7,9 +7,10 @@ import { InspectorControls } from '@wordpress/block-editor'; import { useSelect, subscribe } from '@wordpress/data'; import { addFilter } from '@wordpress/hooks'; import { ProductQueryFeedbackPrompt } from '@woocommerce/editor-components/feedback-prompt'; -import { EditorBlock } from '@woocommerce/types'; +import { EditorBlock, isNumber } from '@woocommerce/types'; import { usePrevious } from '@woocommerce/base-hooks'; -import { isWpVersion } from '@woocommerce/settings'; +import { isWpVersion, getSettingWithCoercion } from '@woocommerce/settings'; +import { ProductQueryBlockQuery } from '@woocommerce/blocks/product-query/types'; import { FormTokenField, ToggleControl, @@ -125,6 +126,18 @@ export const WooInheritToggleControl = ( : props.attributes.query.inherit || false } onChange={ ( inherit ) => { + const inheritQuery: Partial< ProductQueryBlockQuery > = { + inherit, + }; + + if ( inherit ) { + inheritQuery.perPage = getSettingWithCoercion( + 'loop_shop_per_page', + 12, + isNumber + ); + } + if ( isCustomInheritGlobalQueryImplementationEnabled ) { return setQueryAttribute( props, { ...QUERY_DEFAULT_ATTRIBUTES.query, @@ -138,7 +151,7 @@ export const WooInheritToggleControl = ( setQueryAttribute( props, { ...props.defaultWooQueryParams, - inherit, + ...inheritQuery, // Restore the query object value before inherit was enabled. ...( inherit === false && { ...queryObjectBeforeInheritEnabled, diff --git a/assets/js/blocks/product-query/variations/product-query.tsx b/assets/js/blocks/product-query/variations/product-query.tsx index c409e31de0e..3cef34401b4 100644 --- a/assets/js/blocks/product-query/variations/product-query.tsx +++ b/assets/js/blocks/product-query/variations/product-query.tsx @@ -8,10 +8,14 @@ import { import { Icon } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { stacks } from '@woocommerce/icons'; -import { isWpVersion } from '@woocommerce/settings'; +import { isWpVersion, getSettingWithCoercion } from '@woocommerce/settings'; import { select, subscribe } from '@wordpress/data'; -import { QueryBlockAttributes } from '@woocommerce/blocks/product-query/types'; +import { + QueryBlockAttributes, + ProductQueryBlockQuery, +} from '@woocommerce/blocks/product-query/types'; import { isSiteEditorPage } from '@woocommerce/utils'; +import { isNumber } from '@woocommerce/types'; /** * Internal dependencies @@ -74,12 +78,26 @@ if ( isWpVersion( '6.1', '>=' ) ) { } if ( isSiteEditorPage( store ) ) { + const inherit = + ARCHIVE_PRODUCT_TEMPLATES.includes( currentTemplateId ); + + const inheritQuery: Partial< ProductQueryBlockQuery > = { + inherit, + }; + + if ( inherit ) { + inheritQuery.perPage = getSettingWithCoercion( + 'loop_shop_per_page', + 12, + isNumber + ); + } + const queryAttributes = { ...QUERY_DEFAULT_ATTRIBUTES, query: { ...QUERY_DEFAULT_ATTRIBUTES.query, - inherit: - ARCHIVE_PRODUCT_TEMPLATES.includes( currentTemplateId ), + ...inheritQuery, }, }; diff --git a/assets/js/blocks/product-template/edit.tsx b/assets/js/blocks/product-template/edit.tsx index d4885a01504..3101f30367b 100644 --- a/assets/js/blocks/product-template/edit.tsx +++ b/assets/js/blocks/product-template/edit.tsx @@ -17,6 +17,8 @@ import { Spinner } from '@wordpress/components'; import { store as coreStore } from '@wordpress/core-data'; import type { BlockEditProps } from '@wordpress/blocks'; import { ProductCollectionAttributes } from '@woocommerce/blocks/product-collection/types'; +import { getSettingWithCoercion } from '@woocommerce/settings'; +import { isNumber } from '@woocommerce/types'; const ProductTemplateInnerBlocks = () => { const innerBlocksProps = useInnerBlocksProps( @@ -102,6 +104,11 @@ const ProductTemplateEdit = ( { const [ { page } ] = queryContext; const [ activeBlockContextId, setActiveBlockContextId ] = useState(); const postType = 'product'; + const loopShopPerPage = getSettingWithCoercion( + 'loop_shop_per_page', + 12, + isNumber + ); const { products, blocks } = useSelect( ( select ) => { const { getEntityRecords, getTaxonomies } = select( coreStore ); @@ -121,6 +128,7 @@ const ProductTemplateEdit = ( { slug: templateSlug.replace( 'category-', '' ), } ); const query: Record< string, unknown > = { + postType, offset: perPage ? perPage * ( page - 1 ) + offset : 0, order, orderby: orderBy, @@ -171,6 +179,7 @@ const ProductTemplateEdit = ( { if ( templateCategory ) { query.categories = templateCategory[ 0 ]?.id; } + query.per_page = loopShopPerPage; } return { products: getEntityRecords( 'postType', postType, { diff --git a/src/BlockTypes/ProductCollection.php b/src/BlockTypes/ProductCollection.php index b91edb02059..85898a56c21 100644 --- a/src/BlockTypes/ProductCollection.php +++ b/src/BlockTypes/ProductCollection.php @@ -86,6 +86,21 @@ protected function initialize() { add_filter( 'rest_product_collection_params', array( $this, 'extend_rest_query_allowed_params' ), 10, 1 ); } + /** + * Extra data passed through from server to client for block. + * + * @param array $attributes Any attributes that currently are available from the block. + * Note, this will be empty in the editor context when the block is + * not in the post content on editor load. + */ + protected function enqueue_data( array $attributes = [] ) { + parent::enqueue_data( $attributes ); + + // The `loop_shop_per_page` filter can be found in WC_Query::product_query(). + // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment + $this->asset_data_registry->add( 'loop_shop_per_page', apply_filters( 'loop_shop_per_page', wc_get_default_products_per_row() * wc_get_default_product_rows_per_page() ), true ); + } + /** * Update the query for the product query block in Editor. * diff --git a/src/BlockTypes/ProductQuery.php b/src/BlockTypes/ProductQuery.php index 17ac3f16dd7..66741e0c9f4 100644 --- a/src/BlockTypes/ProductQuery.php +++ b/src/BlockTypes/ProductQuery.php @@ -129,6 +129,10 @@ protected function enqueue_data( array $attributes = [] ) { 'post_template_has_support_for_grid_view', $post_template_has_support_for_grid_view ); + + // The `loop_shop_per_page` filter can be found in WC_Query::product_query(). + // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment + $this->asset_data_registry->add( 'loop_shop_per_page', apply_filters( 'loop_shop_per_page', wc_get_default_products_per_row() * wc_get_default_product_rows_per_page() ), true ); } /**