Skip to content

Commit

Permalink
Exclude exact matches with minus in front.
Browse files Browse the repository at this point in the history
  • Loading branch information
doekenorg committed Mar 20, 2024
1 parent a883856 commit 1ebabb2
Showing 1 changed file with 45 additions and 5 deletions.
50 changes: 45 additions & 5 deletions includes/widgets/search-widget/class-search-widget.php
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,6 @@ public function gf_query_filter( &$query, $view, $request ) {
* We feed these into an new GF_Query and tack them onto the current object.
*/
$search_criteria = $this->filter_entries( array(), null, array( 'id' => $view->ID ), true /** force search_criteria */ );

/**
* Call any userland filters that they might have.
*/
Expand All @@ -920,6 +919,21 @@ public function gf_query_filter( &$query, $view, $request ) {
return;
}

$exclude_global_search_words = [];

foreach ( $search_criteria['field_filters'] as $i => $criterion ) {
if (
! empty( $criterion['key'] ?? null )
|| 'not contains' !== ( $criterion['operator'] ?? '' )
) {
continue;
}

$exclude_global_search_words[] = $criterion['value'];
unset($search_criteria['field_filters'][$i]);
}


$widgets = $view->widgets->by_id( $this->widget_id );
if ( $widgets->count() ) {
$widgets = $widgets->all();
Expand Down Expand Up @@ -1113,10 +1127,35 @@ public function gf_query_filter( &$query, $view, $request ) {
*/
$query_parts = $query->_introspect();

if ($exclude_global_search_words) {
global $wpdb;
$extra_conditions[] = new GF_Query_Condition(new GF_Query_Call(
'NOT EXISTS',
[
sprintf(
'SELECT 1 FROM `%s` WHERE `form_id` = %d AND `entry_id` = `%s`.`id` AND (%s)',
GFFormsModel::get_entry_meta_table_name(),
$view->form ? $view->form->ID : 0,
$query->_alias( null, $view->form ? $view->form->ID : 0 ),
implode( ' OR ', array_map( static function ( string $word ) use ( $wpdb ) {
return $wpdb->prepare( '`meta_value` LIKE "%%%s%%"', $word );
}, $exclude_global_search_words ) )
)
]
));
}


/**
* Combine the parts as a new WHERE clause.
*/
$where = call_user_func_array( '\GF_Query_Condition::_and', array_merge( array( $query_parts['where'] ), $search_conditions, $extra_conditions ) );
$where = \GF_Query_Condition::_and(
...array_merge(
[$query_parts['where']],
$search_conditions,
$extra_conditions
)
);
$query->where( $where );
}

Expand Down Expand Up @@ -2298,15 +2337,16 @@ private function get_criteria_from_query( string $query, bool $split_words ): ar
$quotation_marks = $this->get_quotation_marks();

$regex = sprintf(
'/(%s)(?<word>.*?)(%s)/m',
'/(?<match>(\+|\-))?(%s)(?<word>.*?)(%s)/m',
implode( '|', self::preg_quote( $quotation_marks['opening'] ?? [] ) ),
implode( '|', self::preg_quote( $quotation_marks['closing'] ?? [] ) )
);

if ( preg_match_all( $regex, $query, $matches ) ) {
$query = str_replace( $matches[0], '', $query );
foreach ( $matches['word'] as $exact_word ) {
$words[] = [ 'operator' => 'contains', 'value' => $exact_word ];
foreach ( $matches['word'] as $i => $exact_word ) {
$operator = '-' === $matches['match'][ $i ] ? 'not contains' : 'contains';
$words[] = [ 'operator' => $operator, 'value' => $exact_word ];
}
}

Expand Down

0 comments on commit 1ebabb2

Please sign in to comment.