diff --git a/includes/classes/Elasticsearch.php b/includes/classes/Elasticsearch.php index ba2ed13c33..95d4a4ea8a 100644 --- a/includes/classes/Elasticsearch.php +++ b/includes/classes/Elasticsearch.php @@ -313,7 +313,7 @@ public function query( $index, $type, $query, $query_args, $query_object = null ( Utils\is_epio() && ! empty( $query_args['s'] ) && - ! is_admin() && + Utils\is_integrated_request( 'search' ) && ! isset( $_GET['post_type'] ) // phpcs:ignore WordPress.Security.NonceVerification ), $query_args diff --git a/includes/classes/Feature/Autosuggest/Autosuggest.php b/includes/classes/Feature/Autosuggest/Autosuggest.php index 8ef86a05aa..9199fd70e1 100644 --- a/includes/classes/Feature/Autosuggest/Autosuggest.php +++ b/includes/classes/Feature/Autosuggest/Autosuggest.php @@ -222,7 +222,7 @@ public function mapping( $mapping ) { * @return array */ public function set_fuzziness( $fuzziness, $search_fields, $args ) { - if ( ! is_admin() && ! empty( $args['s'] ) ) { + if ( Utils\is_integrated_request( $this->slug, [ 'public' ] ) && ! empty( $args['s'] ) ) { return 'auto'; } return $fuzziness; @@ -237,7 +237,7 @@ public function set_fuzziness( $fuzziness, $search_fields, $args ) { * @return array $query adjusted ES Query arguments */ public function adjust_fuzzy_fields( $query, $post_type, $args ) { - if ( ! is_admin() && ! empty( $args['s'] ) ) { + if ( Utils\is_integrated_request( $this->slug, [ 'public' ] ) && ! empty( $args['s'] ) ) { /** * Filter autosuggest ngram fields * @@ -912,4 +912,3 @@ public function epio_autosuggest_health_check_info( $debug_info ) { return $debug_info; } } - diff --git a/includes/classes/Feature/Documents/Documents.php b/includes/classes/Feature/Documents/Documents.php index 3c765f070b..30a184e86b 100644 --- a/includes/classes/Feature/Documents/Documents.php +++ b/includes/classes/Feature/Documents/Documents.php @@ -11,6 +11,7 @@ use ElasticPress\Elasticsearch as Elasticsearch; use ElasticPress\FeatureRequirementsStatus as FeatureRequirementsStatus; use ElasticPress\Indexables as Indexables; +use ElasticPress\Utils as Utils; /** * Documents feature class. @@ -114,7 +115,7 @@ public function attachments_mapping( $mapping ) { * @since 2.3 */ public function setup_document_search( $query ) { - if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { + if ( ! Utils\is_integrated_request( $this->slug, [ 'public', 'ajax' ] ) ) { return; } @@ -517,5 +518,3 @@ public function filter_attachment_post_type_weights( $weights, $post_type ) { return $weights; } } - - diff --git a/includes/classes/Feature/ProtectedContent/ProtectedContent.php b/includes/classes/Feature/ProtectedContent/ProtectedContent.php index b3d269fe61..84101fce22 100644 --- a/includes/classes/Feature/ProtectedContent/ProtectedContent.php +++ b/includes/classes/Feature/ProtectedContent/ProtectedContent.php @@ -45,18 +45,12 @@ public function __construct() { public function setup() { add_filter( 'ep_indexable_post_status', [ $this, 'get_statuses' ] ); add_filter( 'ep_indexable_post_types', [ $this, 'post_types' ], 10, 1 ); + add_filter( 'ep_admin_wp_query_integration', '__return_true' ); + add_action( 'pre_get_posts', [ $this, 'integrate' ] ); if ( Features::factory()->get_registered_feature( 'comments' )->is_active() ) { add_filter( 'ep_indexable_comment_status', [ $this, 'get_comment_statuses' ] ); - } - - if ( is_admin() ) { - add_filter( 'ep_admin_wp_query_integration', '__return_true' ); - add_action( 'pre_get_posts', [ $this, 'integrate' ] ); - - if ( Features::factory()->get_registered_feature( 'comments' )->is_active() ) { - add_action( 'pre_get_comments', [ $this, 'integrate_comments_query' ] ); - } + add_action( 'pre_get_comments', [ $this, 'integrate_comments_query' ] ); } } @@ -114,6 +108,9 @@ public function post_types( $post_types ) { * @since 2.1 */ public function integrate( $query ) { + if ( ! Utils\is_integrated_request( $this->slug, [ 'admin' ] ) ) { + return; + } // Lets make sure this doesn't interfere with the CLI if ( defined( 'WP_CLI' ) && WP_CLI ) { @@ -190,6 +187,10 @@ public function integrate( $query ) { * @since 3.6.0 */ public function integrate_comments_query( $comment_query ) { + if ( ! Utils\is_integrated_request( $this->slug, [ 'admin' ] ) ) { + return; + } + // Lets make sure this doesn't interfere with the CLI if ( defined( 'WP_CLI' ) && WP_CLI ) { return; @@ -289,4 +290,3 @@ public function requirements_status() { return $status; } } - diff --git a/includes/classes/Feature/Search/Search.php b/includes/classes/Feature/Search/Search.php index 7e6b9bd786..835d8013e9 100644 --- a/includes/classes/Feature/Search/Search.php +++ b/includes/classes/Feature/Search/Search.php @@ -10,6 +10,7 @@ use ElasticPress\Feature as Feature; use ElasticPress\Indexables as Indexables; +use ElasticPress\Utils as Utils; /** * Search feature class @@ -88,40 +89,6 @@ public function setup() { * @since 3.0 */ public function search_setup() { - /** - * By default EP will not integrate on admin or ajax requests. Since admin-ajax.php is - * technically an admin request, there is some weird logic here. If we are doing ajax - * and ep_ajax_wp_query_integration is filtered true, then we skip the next admin check. - */ - - /** - * Filter to integrate with admin queries - * - * @hook ep_admin_wp_query_integration - * @param {bool} $integrate True to integrate - * @return {bool} New value - */ - $admin_integration = apply_filters( 'ep_admin_wp_query_integration', false ); - - if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { - /** - * Filter to integrate with admin ajax queries - * - * @hook ep_ajax_wp_query_integration - * @param {bool} $integrate True to integrate - * @return {bool} New value - */ - if ( ! apply_filters( 'ep_ajax_wp_query_integration', false ) ) { - return; - } else { - $admin_integration = true; - } - } - - if ( is_admin() && ! $admin_integration ) { - return; - } - add_filter( 'ep_elasticpress_enabled', [ $this, 'integrate_search_queries' ], 10, 2 ); add_filter( 'ep_formatted_args', [ $this, 'weight_recent' ], 11, 2 ); add_filter( 'ep_query_post_type', [ $this, 'filter_query_post_type_for_search' ], 10, 2 ); @@ -194,9 +161,6 @@ public function add_search_highlight_tags( $formatted_args, $args ) { return $formatted_args; } - /** This filter is documented in search_setup() method. */ - $should_send_in_ajax = ( defined( 'DOING_AJAX' ) && DOING_AJAX ) && apply_filters( 'ep_ajax_wp_query_integration', false ); - /** * Filter whether to add the `highlight` clause in the query or not. * @@ -209,10 +173,7 @@ public function add_search_highlight_tags( $formatted_args, $args ) { */ $add_highlight_clause = apply_filters( 'ep_highlight_should_add_clause', - ( - ( ! is_admin() || $should_send_in_ajax ) && - ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) - ), + Utils\is_integrated_request( 'highlighting', [ 'public' ] ), $formatted_args, $args ); @@ -607,6 +568,10 @@ public function output_feature_box_long() { * @return bool */ public function integrate_search_queries( $enabled, $query ) { + if ( ! Utils\is_integrated_request( $this->slug ) ) { + return; + } + if ( ! is_a( $query, 'WP_Query' ) ) { return $enabled; } diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php index d05c88e397..455899d1f6 100644 --- a/includes/classes/Feature/Search/Weighting.php +++ b/includes/classes/Feature/Search/Weighting.php @@ -9,6 +9,7 @@ use ElasticPress\Features; use ElasticPress\Indexable\Post\Post; +use ElasticPress\Utils as Utils; /** * Controls search weighting and search fields dashboard @@ -564,7 +565,7 @@ public function do_weighting( $formatted_args, $args ) { */ $weight_config = apply_filters( 'ep_weighting_configuration_for_search', $weight_config, $args ); - if ( ! is_admin() && ! empty( $args['s'] ) ) { + if ( Utils\is_integrated_request( 'weighting' ) && ! empty( $args['s'] ) ) { /* * This section splits up the single query clause for all post types into separate nested clauses (one for each post type) * which then get combined into one result set. By having separate clauses for each post type, we can then diff --git a/includes/classes/Feature/WooCommerce/WooCommerce.php b/includes/classes/Feature/WooCommerce/WooCommerce.php index 3ed654328c..f8c5e3ee70 100644 --- a/includes/classes/Feature/WooCommerce/WooCommerce.php +++ b/includes/classes/Feature/WooCommerce/WooCommerce.php @@ -11,6 +11,7 @@ use ElasticPress\Feature as Feature; use ElasticPress\FeatureRequirementsStatus as FeatureRequirementsStatus; use ElasticPress\Indexables as Indexables; +use ElasticPress\Utils as Utils; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. @@ -950,31 +951,7 @@ protected function should_integrate_with_query( $query ) { return false; } - /** - * Filter to integrate with admin queries - * - * @hook ep_admin_wp_query_integration - * @param {bool} $integrate True to integrate - * @return {bool} New value - */ - $admin_integration = apply_filters( 'ep_admin_wp_query_integration', false ); - - if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { - /** - * Filter to integrate with admin ajax queries - * - * @hook ep_ajax_wp_query_integration - * @param {bool} $integrate True to integrate - * @return {bool} New value - */ - if ( ! apply_filters( 'ep_ajax_wp_query_integration', false ) ) { - return false; - } else { - $admin_integration = true; - } - } - - if ( is_admin() && ! $admin_integration ) { + if ( ! Utils\is_integrated_request( $this->slug ) ) { return false; } diff --git a/includes/utils.php b/includes/utils.php index 577988ccda..9baab22d43 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -537,3 +537,99 @@ function get_indexing_status() { return $index_status; } + +/** + * Check if queries for the current request are going to be integrated with + * ElasticPress. + * + * Public requests and REST API requests are integrated by default, but admin + * requests will only be integrated in if the `ep_admin_wp_query_integration` + * filter returns `true`, and and admin-ajax.php requests will only be + * integrated if the `ep_ajax_wp_query_integration` filter returns `true`. + * + * If specific types of requests are passed, true will only be returned if the + * current request also matches one of the passed types. + * + * This function is used by features to determine whether they should hook into + * the current request. + * + * @param string $context Slug of the feature that is performing the check. + * Passed to the `ep_is_integrated_request` filter. + * @param string[] $types Which types of request to check. Any of 'admin', + * 'ajax', 'public', and 'rest'. Defaults to all + * types. + * @return bool Whether the current request supports ElasticPress integration + * and is of a given type. + * + * @since 3.6.0 + */ +function is_integrated_request( $context, $types = [] ) { + if ( empty( $types ) ) { + $types = [ 'admin', 'ajax', 'public', 'rest' ]; + } + + $is_admin_request = is_admin(); + $is_ajax_request = defined( 'DOING_AJAX' ) && DOING_AJAX; + $is_rest_request = defined( 'REST_REQUEST' ) && REST_REQUEST; + $is_integrated_admin_request = false; + $is_integrated_ajax_request = false; + $is_integrated_public_request = false; + $is_integrated_rest_request = false; + + if ( $is_admin_request && ! $is_ajax_request && in_array( 'admin', $types, true ) ) { + + /** + * Filter whether to integrate with admin queries. + * + * @hook ep_admin_wp_query_integration + * @param bool $integrate True to integrate. + * @return bool New value. + */ + $is_integrated_admin_request = apply_filters( 'ep_admin_wp_query_integration', false ); + } + + if ( $is_ajax_request && in_array( 'ajax', $types, true ) ) { + + /** + * Filter to integrate with admin ajax queries. + * + * @hook ep_ajax_wp_query_integration + * @param bool $integrate True to integrate. + * @return bool New value. + */ + $is_integrated_ajax_request = apply_filters( 'ep_ajax_wp_query_integration', false ); + } + + if ( $is_rest_request && in_array( 'rest', $types, true ) ) { + $is_integrated_rest_request = true; + } + + if ( ! $is_admin_request && ! $is_ajax_request && ! $is_rest_request && in_array( 'public', $types, true ) ) { + $is_integrated_public_request = true; + } + + /** + * Is the current request any of the supported requests. + */ + $is_integrated = ( + $is_integrated_admin_request || + $is_integrated_ajax_request || + $is_integrated_public_request || + $is_integrated_rest_request + ); + + /** + * Filter whether the queries for the current request should be integrated. + * + * @hook ep_is_integrated_request + * @param bool $is_integrated Whether queries for the request will be + * integrated. + * @param string $context Context for the original check. Usually the + * slug of the feature doing the check. + * @param array $types Which requests types are being checked. + * @return bool Whether queries for the request will be integrated. + * + * @since 3.6.2 + */ + return apply_filters( 'ep_is_integrated_request', $is_integrated, $context, $types ); +} diff --git a/tests/php/indexables/TestPost.php b/tests/php/indexables/TestPost.php index 7379ee703e..154172dbfe 100644 --- a/tests/php/indexables/TestPost.php +++ b/tests/php/indexables/TestPost.php @@ -60,6 +60,11 @@ public function setUp() { public function tearDown() { parent::tearDown(); + // Unset current_screen so is_admin() is reset. + if ( isset( $GLOBALS['current_screen'] ) ) { + unset( $GLOBALS['current_screen'] ); + } + // make sure no one attached to this remove_filter( 'ep_sync_terms_allow_hierarchy', array( $this, 'ep_allow_multiple_level_terms_sync' ), 100 ); $this->fired_actions = array();