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

Enable Compatibility Layer for Product Collection #10332

Merged
merged 12 commits into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/BlockTypes/AddToCartForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ protected function render( $attributes, $content, $block ) {

$classname = $attributes['className'] ?? '';
$classes_and_styles = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes );
$product_classname = $is_descendent_of_single_product_block ? 'product' : '';
$product_classname = $is_descendent_of_single_product_block ? 'product' : '';

$form = sprintf(
'<div class="wp-block-add-to-cart-form %1$s %2$s %3$s" style="%4$s">%5$s</div>',
Expand Down
166 changes: 117 additions & 49 deletions src/Templates/ArchiveProductTemplatesCompatibility.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,20 @@ public function inject_hooks( $block_content, $block ) {

$block_name = $block['blockName'];

if ( $this->is_null_post_template( $block ) ) {
$block_name = self::LOOP_ITEM_ID;
}

$block_hooks = array_filter(
$this->hook_data,
function( $hook ) use ( $block_name ) {
return $hook['block_name'] === $block_name;
return in_array( $block_name, $hook['block_names'], true );
}
);

// We want to inject hooks to the core/post-template block only when the products exist:
// We want to inject hooks to the core/post-template or product template block only when the products exist:
// https://github.com/woocommerce/woocommerce-blocks/issues/9463.
if ( 'core/post-template' === $block_name && ! empty( $block_content ) ) {
if ( $this->is_post_or_product_template( $block_name ) && ! empty( $block_content ) ) {
$this->restore_default_hooks();
$content = sprintf(
'%1$s%2$s%3$s',
Expand All @@ -93,24 +97,13 @@ function( $hook ) use ( $block_name ) {
return $content;
}

/**
* The core/post-template has two different block names:
* - core/post-template when the wrapper is rendered.
* - core/null when the loop item is rendered.
*/
if (
'core/null' === $block_name &&
isset( $block['attrs']['__woocommerceNamespace'] ) &&
'woocommerce/product-query/product-template' === $block['attrs']['__woocommerceNamespace']
) {
$block_name = self::LOOP_ITEM_ID;
}

$supported_blocks = array_map(
function( $hook ) {
return $hook['block_name'];
},
array_values( $this->hook_data )
$supported_blocks = array_merge(
...array_map(
kmanijak marked this conversation as resolved.
Show resolved Hide resolved
function( $hook ) {
return $hook['block_names'];
},
array_values( $this->hook_data )
)
);

if ( ! in_array( $block_name, $supported_blocks, true ) ) {
Expand Down Expand Up @@ -182,60 +175,60 @@ function( $hook ) {
protected function set_hook_data() {
$this->hook_data = array(
'woocommerce_before_main_content' => array(
'block_name' => 'core/query',
'position' => 'before',
'hooked' => array(
'block_names' => array( 'core/query', 'woocommerce/product-collection' ),
kmanijak marked this conversation as resolved.
Show resolved Hide resolved
'position' => 'before',
'hooked' => array(
'woocommerce_output_content_wrapper' => 10,
'woocommerce_breadcrumb' => 20,
),
),
'woocommerce_after_main_content' => array(
'block_name' => 'core/query',
'position' => 'after',
'hooked' => array(
'block_names' => array( 'core/query', 'woocommerce/product-collection' ),
'position' => 'after',
'hooked' => array(
'woocommerce_output_content_wrapper_end' => 10,
),
),
'woocommerce_before_shop_loop_item_title' => array(
'block_name' => 'core/post-title',
'position' => 'before',
'hooked' => array(
'block_names' => array( 'core/post-title' ),
'position' => 'before',
'hooked' => array(
'woocommerce_show_product_loop_sale_flash' => 10,
'woocommerce_template_loop_product_thumbnail' => 10,
),
),
'woocommerce_shop_loop_item_title' => array(
'block_name' => 'core/post-title',
'position' => 'after',
'hooked' => array(
'block_names' => array( 'core/post-title' ),
'position' => 'after',
'hooked' => array(
'woocommerce_template_loop_product_title' => 10,
),
),
'woocommerce_after_shop_loop_item_title' => array(
'block_name' => 'core/post-title',
'position' => 'after',
'hooked' => array(
'block_names' => array( 'core/post-title' ),
'position' => 'after',
'hooked' => array(
'woocommerce_template_loop_rating' => 5,
'woocommerce_template_loop_price' => 10,
),
),
'woocommerce_before_shop_loop_item' => array(
'block_name' => self::LOOP_ITEM_ID,
'position' => 'before',
'hooked' => array(
'block_names' => array( self::LOOP_ITEM_ID ),
'position' => 'before',
'hooked' => array(
'woocommerce_template_loop_product_link_open' => 10,
),
),
'woocommerce_after_shop_loop_item' => array(
'block_name' => self::LOOP_ITEM_ID,
'position' => 'after',
'hooked' => array(
'block_names' => array( self::LOOP_ITEM_ID ),
'position' => 'after',
'hooked' => array(
'woocommerce_template_loop_product_link_close' => 5,
'woocommerce_template_loop_add_to_cart' => 10,
),
),
'woocommerce_before_shop_loop' => array(
'block_name' => 'core/post-template',
'block_names' => array( 'core/post-template', 'woocommerce/product-template' ),
'position' => 'before',
'hooked' => array(
'woocommerce_output_all_notices' => 10,
Expand All @@ -249,7 +242,7 @@ protected function set_hook_data() {
),
),
'woocommerce_after_shop_loop' => array(
'block_name' => 'core/post-template',
'block_names' => array( 'core/post-template', 'woocommerce/product-template' ),
'position' => 'after',
'hooked' => array(
'woocommerce_pagination' => 10,
Expand All @@ -259,7 +252,7 @@ protected function set_hook_data() {
),
),
'woocommerce_no_products_found' => array(
'block_name' => 'core/query-no-results',
'block_names' => array( 'core/query-no-results' ),
'position' => 'before',
'hooked' => array(
'wc_no_products_found' => 10,
Expand All @@ -269,9 +262,9 @@ protected function set_hook_data() {
),
),
'woocommerce_archive_description' => array(
'block_name' => 'core/term-description',
'position' => 'before',
'hooked' => array(
'block_names' => array( 'core/term-description' ),
'position' => 'before',
'hooked' => array(
'woocommerce_taxonomy_archive_description' => 10,
'woocommerce_product_archive_description' => 10,
),
Expand All @@ -294,7 +287,7 @@ private function is_archive_template() {
*/
private function inner_blocks_walker( &$block ) {
if (
$this->is_products_block_with_inherit_query( $block )
$this->is_products_block_with_inherit_query( $block ) || $this->is_product_collection_block_with_inherit_query( $block )
) {
$this->inject_attribute( $block );
$this->remove_default_hooks();
Expand All @@ -321,6 +314,69 @@ private function restore_default_hooks() {
}
}

/**
* Check if block is within the product-query namespace
*
* @param array $block Parsed block data.
*/
private function is_block_within_namespace( $block ) {
$attributes = $block['attrs'];

return isset( $attributes['__woocommerceNamespace'] ) && 'woocommerce/product-query/product-template' === $attributes['__woocommerceNamespace'];
}

/**
* Check if block has isInherited attribute asigned
*
* @param array $block Parsed block data.
*/
private function is_block_inherited( $block ) {
$attributes = $block['attrs'];

$outcome = isset( $attributes['isInherited'] ) && 1 === $attributes['isInherited'];

return $outcome;
}

/**
* The core/post-template has two different block names:
* - core/post-template when the wrapper is rendered.
* - core/null when the loop item is rendered.
*
* @param array $block Parsed block data.
*/
private function is_null_post_template( $block ) {
$block_name = $block['blockName'];

return 'core/null' === $block_name && ( $this->is_block_inherited( $block ) || $this->is_block_within_namespace( $block ) );
}

/**
* Check if block is a Post template
*
* @param string $block_name Block name.
*/
private function is_post_template( $block_name ) {
return 'core/post-template' === $block_name;
}

/**
* Check if block is a Product Template
*
* @param string $block_name Block name.
*/
private function is_product_template( $block_name ) {
return 'woocommerce/product-template' === $block_name;
}

/**
* Check if block is eaither a Post template or Product Template
*
* @param string $block_name Block name.
*/
private function is_post_or_product_template( $block_name ) {
return $this->is_post_template( $block_name ) || $this->is_product_template( $block_name );
}

/**
* Check if the block is a Products block that inherits query from template.
Expand All @@ -335,6 +391,18 @@ private function is_products_block_with_inherit_query( $block ) {
$block['attrs']['query']['inherit'];
}

/**
* Check if the block is a Product Collection block that inherits query from template.
*
* @param array $block Parsed block data.
*/
private function is_product_collection_block_with_inherit_query( $block ) {
return 'woocommerce/product-collection' === $block['blockName'] &&
isset( $block['attrs']['query']['inherit'] ) &&
$block['attrs']['query']['inherit'];
}


/**
* Recursively inject the custom attribute to all nested blocks.
*
Expand Down