diff --git a/includes/classes/Feature/Autosuggest/Autosuggest.php b/includes/classes/Feature/Autosuggest/Autosuggest.php index 1b9eea9b9..d77f4cdbc 100644 --- a/includes/classes/Feature/Autosuggest/Autosuggest.php +++ b/includes/classes/Feature/Autosuggest/Autosuggest.php @@ -180,7 +180,7 @@ public function mapping( $mapping ) { * @return array */ public function set_fuzziness( $fuzziness, $search_fields, $args ) { - if ( Utils\is_integrated_request( $this->slug, [ 'public' ] ) && ! empty( $args['s'] ) ) { + if ( Utils\is_integrated_request( $this->slug, $this->get_contexts() ) && ! empty( $args['s'] ) ) { return 'auto'; } return $fuzziness; @@ -195,7 +195,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 ( ! Utils\is_integrated_request( $this->slug, [ 'public' ] ) || empty( $args['s'] ) ) { + if ( ! Utils\is_integrated_request( $this->slug, $this->get_contexts() ) || empty( $args['s'] ) ) { return $query; } @@ -926,4 +926,22 @@ public function delete_cached_query() { 'ElasticPress 4.7.0' ); } + + /** + * Get the contexts for autosuggest. + * + * @since 5.1.0 + * @return array + */ + protected function get_contexts() : array { + /** + * Filter contexts for autosuggest. + * + * @hook ep_autosuggest_contexts + * @since 5.1.0 + * @param {array} $contexts Contexts for autosuggest + * @return {array} New contexts + */ + return apply_filters( 'ep_autosuggest_contexts', [ 'public', 'ajax' ] ); + } } diff --git a/includes/utils.php b/includes/utils.php index 1d6d5aa53..be0f5bc7d 100644 --- a/includes/utils.php +++ b/includes/utils.php @@ -675,7 +675,7 @@ function is_integrated_request( $context, $types = [] ) { } $is_admin_request = is_admin(); - $is_ajax_request = defined( 'DOING_AJAX' ) && DOING_AJAX; + $is_ajax_request = wp_doing_ajax(); $is_rest_request = defined( 'REST_REQUEST' ) && REST_REQUEST; $is_integrated_admin_request = false; $is_integrated_ajax_request = false; diff --git a/tests/php/features/TestAutosuggest.php b/tests/php/features/TestAutosuggest.php index 796c821a2..d4bfa8b56 100644 --- a/tests/php/features/TestAutosuggest.php +++ b/tests/php/features/TestAutosuggest.php @@ -321,4 +321,200 @@ public function test_get_settings_schema() { $settings_keys ); } + + /** + * Test whether autosuggest ngram fields apply to the search query when AJAX integration and weighting is enabled. + * + * @since 5.1.0 + * @group autosuggest + */ + public function test_autosuggest_ngram_fields_for_ajax_request() { + add_filter( 'wp_doing_ajax', '__return_true' ); + add_filter( 'ep_ajax_wp_query_integration', '__return_true' ); + add_filter( 'ep_enable_do_weighting', '__return_true' ); + + $this->get_feature()->setup(); + + $this->ep_factory->post->create( + array( + 'post_title' => 'search me', + 'post_type' => 'post', + ) + ); + + ElasticPress\Elasticsearch::factory()->refresh_indices(); + + add_filter( + 'ep_query_request_path', + function( $path, $index, $type, $query, $query_args, $query_object ) { + $fields = $query['query']['function_score']['query']['bool']['should'][0]['bool']['must'][0]['bool']['should'][1]['multi_match']['fields']; + + $this->assertContains( 'term_suggest^1', $fields ); + $this->assertContains( 'post_title.suggest^1', $fields ); + return $path; + }, + 10, + 6 + ); + + $query = new \WP_Query( + array( + 's' => 'search me', + 'ep_integrate' => true, + ) + ); + + $this->assertTrue( $query->elasticsearch_success ); + $this->assertEquals( 1, $query->found_posts ); + } + + /** + * Test whether autosuggest ngram fields do not apply to the search query when `ep_autosuggest_contexts` is only set to public. + * + * @since 5.1.0 + * @group autosuggest + */ + public function test_autosuggest_ngram_fields_for_ajax_request_negative() { + add_filter( 'wp_doing_ajax', '__return_true' ); + add_filter( 'ep_ajax_wp_query_integration', '__return_true' ); + add_filter( 'ep_enable_do_weighting', '__return_true' ); + + $autosuggest_context = function() { + return [ 'public' ]; + }; + + add_filter( 'ep_autosuggest_contexts', $autosuggest_context ); + + $this->get_feature()->setup(); + + $this->ep_factory->post->create( + array( + 'post_title' => 'search me', + 'post_type' => 'post', + ) + ); + + ElasticPress\Elasticsearch::factory()->refresh_indices(); + + add_filter( + 'ep_query_request_path', + function( $path, $index, $type, $query, $query_args, $query_object ) { + $fields = $query['query']['function_score']['query']['bool']['should'][0]['bool']['must'][0]['bool']['should'][1]['multi_match']['fields']; + + $this->assertNotContains( 'term_suggest^1', $fields ); + $this->assertNotContains( 'post_title.suggest^1', $fields ); + return $path; + }, + 10, + 6 + ); + + $query = new \WP_Query( + array( + 's' => 'search me', + 'ep_integrate' => true, + ) + ); + + $this->assertTrue( $query->elasticsearch_success ); + $this->assertEquals( 1, $query->found_posts ); + } + + /** + * Test whether fuzziness is set to `auto` for AJAX calls. + * + * @since 5.1.0 + * @group autosuggest + */ + public function test_fuziness_with_type_auto_set_for_ajax_call() { + add_filter( 'wp_doing_ajax', '__return_true' ); + add_filter( 'ep_ajax_wp_query_integration', '__return_true' ); + + $algorithm = function() { + return 'default'; + }; + add_filter( 'ep_search_algorithm_version', $algorithm ); + + $this->get_feature()->setup(); + + $this->ep_factory->post->create( + array( + 'post_title' => 'search me', + 'post_type' => 'post', + ) + ); + + ElasticPress\Elasticsearch::factory()->refresh_indices(); + + add_filter( + 'ep_query_request_path', + function( $path, $index, $type, $query, $query_args, $query_object ) { + $this->assertEquals( 'auto', $query['query']['function_score']['query']['bool']['should'][2]['multi_match']['fuzziness'] ); + return $path; + }, + 10, + 6 + ); + + $query = new \WP_Query( + array( + 's' => 'search me', + 'ep_integrate' => true, + ) + ); + + $this->assertTrue( $query->elasticsearch_success ); + } + + /** + * Test whether fuzziness is not set to `auto` for AJAX calls when `ep_autosuggest_contexts` is only set to public. + * + * @since 5.1.0 + * @group autosuggest + */ + public function test_fuziness_with_type_auto_set_for_ajax_call_negative() { + add_filter( 'wp_doing_ajax', '__return_true' ); + add_filter( 'ep_ajax_wp_query_integration', '__return_true' ); + + $algorithm = function() { + return 'default'; + }; + add_filter( 'ep_search_algorithm_version', $algorithm ); + + $autosuggest_context = function() { + return [ 'public' ]; + }; + add_filter( 'ep_autosuggest_contexts', $autosuggest_context ); + + $this->get_feature()->setup(); + + $this->ep_factory->post->create( + array( + 'post_title' => 'search me', + 'post_type' => 'post', + ) + ); + + ElasticPress\Elasticsearch::factory()->refresh_indices(); + + add_filter( + 'ep_query_request_path', + function( $path, $index, $type, $query, $query_args, $query_object ) { + $this->assertNotEquals( 'auto', $query['query']['function_score']['query']['bool']['should'][2]['multi_match']['fuzziness'] ); + return $path; + }, + 10, + 6 + ); + + $query = new \WP_Query( + array( + 's' => 'search me', + 'ep_integrate' => true, + ) + ); + + $this->assertTrue( $query->elasticsearch_success ); + + } }