Elementor Pro – Base Products Renderer

<?php
namespace ElementorProModulesWoocommerceClasses;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

abstract class Base_Products_Renderer extends WC_Shortcode_Products {

	public $query_results;

	/**
	 * Override original `get_content` that returns an HTML wrapper even if no results found.
	 *
	 * @return string Products HTML
	 */
	public function get_content() {


		/**
		 * Output an empty string if there are no results
		 * 
		 * The `get_content()` method triggers `get_query_results`, so it's
		 * actually being called twice in WooCommerce < 4.0.0
		 * 
		 * The `woocommerce_shortcode_products_query_results` hook was added
		 * in WooCommerce 4.0.0. It lets us cache the query counts
		 * so that only 1 products query needs to be executed.
		 */
		if ( function_exists( 'WC' ) && version_compare( WC()->version, '4.0.0', '>=' ) ) {
			add_filter( 'woocommerce_shortcode_products_query_results', [ $this, 'cache_query_results'] );
			$content = parent::get_content();
			remove_filter( 'woocommerce_shortcode_products_query_results', [ $this, 'cache_query_results'] );

			return empty( $this->query_results->total ) ? '' : $content;
		}

		// WooCommerce < 4.0.0
		$result = $this->get_query_results();

		if ( empty( $result->total ) ) {
			return '';
		}

		return parent::get_content();
	}


	/**
	 * Cache the query results so we don't need to run
	 * a separate query just to grab the total count
	 * 
	 * @return object Results data
	 */
	public function cache_query_results( $results ) {
		$this->query_results = $results;
		return $results;
	}
}