From d1f5d3be2e73100ec4b8a5cb026ca93715e45e91 Mon Sep 17 00:00:00 2001 From: Doeke Norg Date: Wed, 20 Mar 2024 17:00:25 +0100 Subject: [PATCH] Exclude unquoted + unit tests --- .../search-widget/class-search-widget.php | 19 ++++---- .../GravityView_Widget_Search_Test.php | 46 +++++++++++++++---- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/includes/widgets/search-widget/class-search-widget.php b/includes/widgets/search-widget/class-search-widget.php index 981f4cbac2..f97b7364b3 100644 --- a/includes/widgets/search-widget/class-search-widget.php +++ b/includes/widgets/search-widget/class-search-widget.php @@ -1127,9 +1127,9 @@ public function gf_query_filter( &$query, $view, $request ) { */ $query_parts = $query->_introspect(); - if ($exclude_global_search_words) { + if ( $exclude_global_search_words ) { global $wpdb; - $extra_conditions[] = new GF_Query_Condition(new GF_Query_Call( + $extra_conditions[] = new GF_Query_Condition( new GF_Query_Call( 'NOT EXISTS', [ sprintf( @@ -1142,7 +1142,7 @@ public function gf_query_filter( &$query, $view, $request ) { }, $exclude_global_search_words ) ) ) ] - )); + ) ); } @@ -2351,16 +2351,19 @@ private function get_criteria_from_query( string $query, bool $split_words ): ar } if ( $query && $split_words ) { - foreach ( preg_split( '/\s+/', $query ) as $word ) { + foreach ( preg_split( '/\s+/', $query ) as $value ) { + $is_exclude = '-' === ($value[0] ?? ''); $words[] = [ - 'operator' => 'contains', - 'value' => $word, + 'operator' => $is_exclude ? 'not contains' : 'contains', + 'value' => $is_exclude ? substr( $value, 1 ) : $value, ]; } } elseif ( $query ) { + $is_exclude = '-' === ($query[0] ?? ''); + $value = preg_replace( '/\s+/', ' ', $query ); $words[] = [ - 'operator' => 'contains', - 'value' => preg_replace( '/\s+/', ' ', $query ), + 'operator' => $is_exclude ? 'not contains' : 'contains', + 'value' => $is_exclude ? substr( $value, 1 ) : $value, ]; } diff --git a/tests/unit-tests/GravityView_Widget_Search_Test.php b/tests/unit-tests/GravityView_Widget_Search_Test.php index ccbaa22d4c..f22459bef5 100644 --- a/tests/unit-tests/GravityView_Widget_Search_Test.php +++ b/tests/unit-tests/GravityView_Widget_Search_Test.php @@ -97,17 +97,31 @@ private function _test_word_splitting() { $_GET = [ 'gv_search' => '" space " "another one" and two' ]; - $search_criteria_split_exact = [ - 'field_filters' => [ - 'mode' => 'any', - [ 'key' => null, 'value' => ' space ', 'operator' => 'contains' ], - [ 'key' => null, 'value' => 'another one', 'operator' => 'contains' ], - [ 'key' => null, 'value' => 'and', 'operator' => 'contains' ], - [ 'key' => null, 'value' => 'two', 'operator' => 'contains' ], - ] - ]; + $this->assertEquals( + [ + 'field_filters' => [ + 'mode' => 'any', + [ 'key' => null, 'value' => ' space ', 'operator' => 'contains' ], + [ 'key' => null, 'value' => 'another one', 'operator' => 'contains' ], + [ 'key' => null, 'value' => 'and', 'operator' => 'contains' ], + [ 'key' => null, 'value' => 'two', 'operator' => 'contains' ], + ] + ], + $this->widget->filter_entries( array(), null, $args, true ) + ); - $this->assertEquals( $search_criteria_split_exact, $this->widget->filter_entries( array(), null, $args, true ) ); + $_GET = [ 'gv_search' => '-"excluded spaces" -another' ]; + + $this->assertEquals( + [ + 'field_filters' => [ + 'mode' => 'any', + [ 'key' => null, 'value' => 'excluded spaces', 'operator' => 'not contains' ], + [ 'key' => null, 'value' => 'another', 'operator' => 'not contains' ], + ] + ], + $this->widget->filter_entries( array(), null, $args, true ) + ); $_GET = array( 'gv_search' => '%20with%20%20spaces' @@ -1408,6 +1422,18 @@ public function test_search_all_basic() { $entries = $view->get_entries()->fetch()->all(); $this->assertCount( 2, $entries ); + $_GET['gv_search'] = 'hello world'; + $entries = $view->get_entries()->fetch()->all(); + $this->assertCount( 3, $entries ); + + $_GET['gv_search'] = '"hello world"'; + $entries = $view->get_entries()->fetch()->all(); + $this->assertCount( 1, $entries ); + + $_GET['gv_search'] = 'hello -world'; + $entries = $view->get_entries()->fetch()->all(); + $this->assertCount( 1, $entries ); + $_GET = array(); }