Automattic\WooCommerce\Blocks\BlockTypes\ProductCollection
HandlerRegistry::register_core_collections │ public │ WC 1.0
Register core collection handlers.
Method of the class: HandlerRegistry{}
No Hooks.
Returns
null. Nothing (null).
Usage
$HandlerRegistry = new HandlerRegistry(); $HandlerRegistry->register_core_collections();
HandlerRegistry::register_core_collections() HandlerRegistry::register core collections code WC 10.3.6
public function register_core_collections() {
$this->register_collection_handlers(
'woocommerce/product-collection/hand-picked',
function ( $collection_args, $common_query_values, $query ) {
// For Hand-Picked collection, if no products are selected, we should return an empty result set.
// This ensures that the collection doesn't display any products until the user explicitly chooses them.
if ( empty( $query['handpicked_products'] ) ) {
return array(
'post__in' => array( -1 ),
);
}
}
);
$this->register_collection_handlers(
'woocommerce/product-collection/by-category',
function ( $collection_args, $common_query_values, $query ) {
// For Products by Category collection, if no category is selected, we should return an empty result set.
if ( empty( $query['taxonomies_query'] ) ) {
return array(
'post__in' => array( -1 ),
);
}
}
);
$this->register_collection_handlers(
'woocommerce/product-collection/by-tag',
function ( $collection_args, $common_query_values, $query ) {
// For Products by Tag collection, if no tag is selected, we should return an empty result set.
if ( empty( $query['taxonomies_query'] ) ) {
return array(
'post__in' => array( -1 ),
);
}
}
);
$this->register_collection_handlers(
'woocommerce/product-collection/related',
function ( $collection_args ) {
// No products should be shown if no related product reference is set.
if ( empty( $collection_args['relatedProductReference'] ) ) {
return array(
'post__in' => array( -1 ),
);
}
$category_callback = function () use ( $collection_args ) {
return $collection_args['relatedBy']['categories'];
};
$tag_callback = function () use ( $collection_args ) {
return $collection_args['relatedBy']['tags'];
};
add_filter( 'woocommerce_product_related_posts_relate_by_category', $category_callback, PHP_INT_MAX );
add_filter( 'woocommerce_product_related_posts_relate_by_tag', $tag_callback, PHP_INT_MAX );
$related_products = wc_get_related_products(
$collection_args['relatedProductReference'],
// Use a higher limit so that the result set contains enough products for the collection to subsequently filter.
100,
array(),
$collection_args['relatedBy']
);
remove_filter( 'woocommerce_product_related_posts_relate_by_category', $category_callback, PHP_INT_MAX );
remove_filter( 'woocommerce_product_related_posts_relate_by_tag', $tag_callback, PHP_INT_MAX );
if ( empty( $related_products ) ) {
return array(
'post__in' => array( -1 ),
);
}
// Have it filter the results to products related to the one provided.
return array(
'post__in' => $related_products,
);
},
function ( $collection_args, $query ) {
$product_reference = $query['productReference'] ?? null;
// Infer the product reference from the location if an explicit product is not set.
if ( empty( $product_reference ) ) {
$location = $collection_args['productCollectionLocation'];
if ( isset( $location['type'] ) && 'product' === $location['type'] ) {
$product_reference = $location['sourceData']['productId'];
}
}
$collection_args['relatedProductReference'] = $product_reference;
$collection_args['relatedBy'] = ! isset( $query['relatedBy'] ) ? array(
'categories' => true,
'tags' => true,
) : array(
'categories' => isset( $query['relatedBy']['categories'] ) && true === $query['relatedBy']['categories'],
'tags' => isset( $query['relatedBy']['tags'] ) && true === $query['relatedBy']['tags'],
);
return $collection_args;
},
function ( $collection_args, $query, $request ) {
$product_reference = $request->get_param( 'productReference' );
// In some cases the editor will send along block location context that we can infer the product reference from.
if ( empty( $product_reference ) ) {
$location = $collection_args['productCollectionLocation'];
if ( isset( $location['type'] ) && 'product' === $location['type'] ) {
$product_reference = $location['sourceData']['productId'];
}
}
$collection_args['relatedProductReference'] = $product_reference;
$related_by = $request->get_param( 'relatedBy' );
$collection_args['relatedBy'] = ! isset( $related_by ) ? array(
'categories' => true,
'tags' => true,
) : array(
'categories' => rest_sanitize_boolean( $related_by['categories'] ?? false ),
'tags' => rest_sanitize_boolean( $related_by['tags'] ?? false ),
);
return $collection_args;
}
);
$this->register_collection_handlers(
'woocommerce/product-collection/upsells',
function ( $collection_args ) {
$product_reference = $collection_args['upsellsProductReferences'] ?? null;
// No products should be shown if no upsells product reference is set.
if ( empty( $product_reference ) ) {
return array(
'post__in' => array( -1 ),
);
}
$products = array_map( 'wc_get_product', $product_reference );
if ( empty( $products ) ) {
return array(
'post__in' => array( -1 ),
);
}
$all_upsells = array_reduce(
$products,
function ( $acc, $product ) {
return array_merge(
$acc,
$product->get_upsell_ids()
);
},
array()
);
// Remove duplicates and product references. We don't want to display
// what's already in cart.
$unique_upsells = array_unique( $all_upsells );
$upsells = array_diff( $unique_upsells, $product_reference );
return array(
'post__in' => empty( $upsells ) ? array( -1 ) : $upsells,
);
},
function ( $collection_args, $query ) {
$product_references = isset( $query['productReference'] ) ? array( $query['productReference'] ) : null;
// Infer the product reference from the location if an explicit product is not set.
if ( empty( $product_references ) ) {
$location = $collection_args['productCollectionLocation'];
if ( isset( $location['type'] ) && 'product' === $location['type'] ) {
$product_references = array( $location['sourceData']['productId'] );
}
if ( isset( $location['type'] ) && 'cart' === $location['type'] ) {
$product_references = $location['sourceData']['productIds'];
}
if ( isset( $location['type'] ) && 'order' === $location['type'] ) {
$product_references = $this->get_product_ids_from_order( $location['sourceData']['orderId'] ?? 0 );
}
}
$collection_args['upsellsProductReferences'] = $product_references;
return $collection_args;
},
function ( $collection_args, $query, $request ) {
$product_reference = $request->get_param( 'productReference' );
// In some cases the editor will send along block location context that we can infer the product reference from.
if ( empty( $product_reference ) ) {
$location = $collection_args['productCollectionLocation'];
if ( isset( $location['type'] ) && 'product' === $location['type'] ) {
$product_reference = $location['sourceData']['productId'];
}
}
$collection_args['upsellsProductReferences'] = array( $product_reference );
return $collection_args;
}
);
$this->register_collection_handlers(
'woocommerce/product-collection/cross-sells',
function ( $collection_args ) {
$product_reference = $collection_args['crossSellsProductReferences'] ?? null;
// No products should be shown if no cross-sells product reference is set.
if ( empty( $product_reference ) ) {
return array(
'post__in' => array( -1 ),
);
}
$products = array_filter( array_map( 'wc_get_product', $product_reference ) );
if ( empty( $products ) ) {
return array(
'post__in' => array( -1 ),
);
}
$product_ids = array_map(
function ( $product ) {
return $product->get_id();
},
$products
);
$all_cross_sells = array_reduce(
$products,
function ( $acc, $product ) {
return array_merge(
$acc,
$product->get_cross_sell_ids()
);
},
array()
);
// Remove duplicates and product references. We don't want to display
// what's already in cart.
$unique_cross_sells = array_unique( $all_cross_sells );
$cross_sells = array_diff( $unique_cross_sells, $product_ids );
return array(
'post__in' => empty( $cross_sells ) ? array( -1 ) : $cross_sells,
);
},
function ( $collection_args, $query ) {
$product_references = isset( $query['productReference'] ) ? array( $query['productReference'] ) : null;
// Infer the product reference from the location if an explicit product is not set.
if ( empty( $product_references ) ) {
$location = $collection_args['productCollectionLocation'];
if ( isset( $location['type'] ) && 'product' === $location['type'] ) {
$product_references = array( $location['sourceData']['productId'] );
}
if ( isset( $location['type'] ) && 'cart' === $location['type'] ) {
$product_references = $location['sourceData']['productIds'];
}
if ( isset( $location['type'] ) && 'order' === $location['type'] ) {
$product_references = $this->get_product_ids_from_order( $location['sourceData']['orderId'] ?? 0 );
}
}
$collection_args['crossSellsProductReferences'] = $product_references;
return $collection_args;
},
function ( $collection_args, $query, $request ) {
$product_reference = $request->get_param( 'productReference' );
// In some cases the editor will send along block location context that we can infer the product reference from.
if ( empty( $product_reference ) ) {
$location = $collection_args['productCollectionLocation'];
if ( isset( $location['type'] ) && 'product' === $location['type'] ) {
$product_reference = $location['sourceData']['productId'];
}
}
$collection_args['crossSellsProductReferences'] = array( $product_reference );
return $collection_args;
}
);
return $this->collection_handler_store;
}