Repository: 10up/ElasticPress (PHP)

Issue:
BUG: No mapping found for [popularity] in order to sort on
### Describe the bug

Under certain circumstances for WooCommerce stores, ElasticPress will integrate a WP_Query that is not the main query, causing an error `No mapping found for [popularity] in order to sort on`

### Steps to Reproduce

Place the following snippet anywhere:
```php
$wc_query = new \WP_Query(
	[
		'post_type'   => 'product',
		'orderby'     => 'popularity',
		'product_cat' => 'test',
	]
);
```

### Screenshots, screen recording, code snippet

_No response_

### Environment information

_No response_

### WordPress and ElasticPress information

_No response_

### Code of Conduct

- [X] I agree to follow this project's Code of Conduct


Discussion: This is fixed in #3502 (see 6834542)

In the meantime, users facing this problem can drop the following snippet in a custom plugin or their theme's functions.php file:

```php
/**
 * Translate WooCommerce `price` and `popularity` fields in orderby clauses.
 *
 * This should be removed if using versions of ElasticPress newer than 4.6.1
 *
 * @see https://github.com/10up/ElasticPress/issues/3535
 * @param \WP_Query $query The WP Query
 */
function ep_custom_fix_woocommerce_fields_sort_translation( $query ) {
	if ( ! is_plugin_active( 'elasticpress/elasticpress.php' ) || ! defined( 'EP_VERSION' ) ) {
		return;
	}

	if ( version_compare( EP_VERSION, '4.6.1', '>' ) ) {
		_deprecated_function( __METHOD__, 'EP 4.6.1', 'This function is not needed anymore.' );
		return;
	}

	$orderby = $query->get( 'orderby', '' );
	if ( ! in_array( $orderby, [ 'price', 'popularity' ], true ) ) {
		return;
	}

	$orderby_field = ( 'price' === $orderby ) ?
		'meta._price.double date' :
		'meta.total_sales.double date';
	$query->set( 'orderby', $orderby_field );
}
add_action( 'pre_get_posts', 'ep_custom_fix_woocommerce_fields_sort_translation' );
```
The underlying issue (why these queries are integrated) is [here](https://github.com/10up/ElasticPress/blob/683454238784fca827fbc47edbacc77c27226b18/includes/classes/Feature/WooCommerce/Products.php#L626-L637):

```php
	public function should_integrate_with_query( \WP_Query $query ) : bool {
		/**
		 * Check for taxonomies
		 */
		$supported_taxonomies = $this->get_supported_taxonomies();
		$tax_query            = $query->get( 'tax_query', [] );
		$taxonomies_queried   = array_merge(
			array_column( $tax_query, 'taxonomy' ),
			array_keys( $query->query_vars )
		);
		if ( ! empty( array_intersect( $supported_taxonomies, $taxonomies_queried ) ) ) {
			return true;
		}
```

Basically, any WP_Query with a taxonomy that is supported by the WooCommerce feature will be integrated. Do we want to change that criteria?
We will remove the automatic integration and keep it only for main queries and searches. 



Fix (patch):
diff --git a/includes/classes/Feature/WooCommerce/Products.php b/includes/classes/Feature/WooCommerce/Products.php
index c415ed5fd6..08ffda2396 100644
--- a/includes/classes/Feature/WooCommerce/Products.php
+++ b/includes/classes/Feature/WooCommerce/Products.php
@@ -617,12 +617,24 @@ public function translate_args( $query ) {
 	}
 
 	/**
-	 * Determines whether or not ES should be integrating with the provided query
+	 * Determines whether or not ES should be integrating with the provided query.
+	 *
+	 * A product-related query will be integrated if:
+	 * * Is the main query OR is a search OR has `ep_integrate` set as true
+	 * * Is querying a supported taxonomy like product attributes
+	 * * Is querying a supported post type like `product`
 	 *
 	 * @param \WP_Query $query Query we might integrate with
 	 * @return bool
 	 */
 	public function should_integrate_with_query( \WP_Query $query ) : bool {
+		$has_ep_integrate = isset( $query->query_vars['ep_integrate'] ) && filter_var( $query->query_vars['ep_integrate'], FILTER_VALIDATE_BOOLEAN );
+		$is_search        = '' !== $this->woocommerce->get_search_term( $query );
+
+		if ( ! $query->is_main_query() && ! $is_search && ! $has_ep_integrate ) {
+			return false;
+		}
+
 		/**
 		 * Check for taxonomies
 		 */