Automattic\WooCommerce\Blocks\BlockTypes
RelatedProducts{} │ WC 1.0
RelatedProducts class.
No Hooks.
Usage
$RelatedProducts = new RelatedProducts(); // use class methods
Methods
- public build_query( $query )
- protected get_block_type_style()
- private get_related_products_ids( $product_per_page = 5 )
- protected initialize()
- private is_related_products_block( $block )
- protected register_block_type_assets()
- public render_block( string $content, array $block )
- public update_query( $pre_render, $parsed_block )
RelatedProducts{} RelatedProducts{} code WC 9.4.2
class RelatedProducts extends AbstractBlock { /** * Block name. * * @var string */ protected $block_name = 'related-products'; /** * The Block with its attributes before it gets rendered * * @var array */ protected $parsed_block; /** * Initialize this block type. * * - Hook into WP lifecycle. * - Register the block with WordPress. * - Hook into pre_render_block to update the query. */ protected function initialize() { parent::initialize(); add_filter( 'pre_render_block', array( $this, 'update_query' ), 10, 2 ); add_filter( 'render_block', array( $this, 'render_block' ), 10, 2 ); } /** * It isn't necessary register block assets because it is a server side block. */ protected function register_block_type_assets() { return null; } /** * Get the frontend style handle for this block type. * * @return null */ protected function get_block_type_style() { return null; } /** * Update the query for the product query block. * * @param string|null $pre_render The pre-rendered content. Default null. * @param array $parsed_block The block being rendered. */ public function update_query( $pre_render, $parsed_block ) { if ( 'core/query' !== $parsed_block['blockName'] ) { return $pre_render; } $this->parsed_block = $parsed_block; if ( ProductQuery::is_woocommerce_variation( $parsed_block ) && 'woocommerce/related-products' === $parsed_block['attrs']['namespace'] ) { // Set this so that our product filters can detect if it's a PHP template. add_filter( 'query_loop_block_query_vars', array( $this, 'build_query' ), 10, 1 ); } return $pre_render; } /** * Return a custom query based on attributes, filters and global WP_Query. * * @param WP_Query $query The WordPress Query. * @return array */ public function build_query( $query ) { $parsed_block = $this->parsed_block; if ( ! $this->is_related_products_block( $parsed_block ) ) { return $query; } $related_products_ids = $this->get_related_products_ids( $query['posts_per_page'] ); if ( count( $related_products_ids ) < 1 ) { return array(); } return array( 'post_type' => 'product', 'post__in' => $related_products_ids, 'post_status' => 'publish', 'posts_per_page' => $query['posts_per_page'], ); } /** * If there are no related products, return an empty string. * * @param string $content The block content. * @param array $block The block. * * @return string The block content. */ public function render_block( string $content, array $block ) { if ( ! $this->is_related_products_block( $block ) ) { return $content; } // If there are no related products, render nothing. $related_products_ids = $this->get_related_products_ids(); if ( count( $related_products_ids ) < 1 ) { return ''; } return $content; } /** * Determines whether the block is a related products block. * * @param array $block The block. * * @return bool Whether the block is a related products block. */ private function is_related_products_block( $block ) { if ( ProductQuery::is_woocommerce_variation( $block ) && isset( $block['attrs']['namespace'] ) && 'woocommerce/related-products' === $block['attrs']['namespace'] ) { return true; } return false; } /** * Get related products ids. * The logic is copied from the core function woocommerce_related_products. https://github.com/woocommerce/woocommerce/blob/ca49caabcba84ce9f60a03c6d3534ec14b350b80/plugins/woocommerce/includes/wc-template-functions.php/#L2039-L2074 * * @param number $product_per_page Products per page. * @return array Products ids. */ private function get_related_products_ids( $product_per_page = 5 ) { global $post; $product = wc_get_product( $post->ID ); $related_products = array_filter( array_map( 'wc_get_product', wc_get_related_products( $product->get_id(), $product_per_page, $product->get_upsell_ids() ) ), 'wc_products_array_filter_visible' ); $related_products = wc_products_array_orderby( $related_products, 'rand', 'desc' ); $related_product_ids = array_map( function( $product ) { return $product->get_id(); }, $related_products ); return $related_product_ids; } }