Skip to content

Instantly share code, notes, and snippets.

@dingo-d
Last active April 22, 2024 10:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dingo-d/7ec3a8e53cbab1d832682bee07703f20 to your computer and use it in GitHub Desktop.
Save dingo-d/7ec3a8e53cbab1d832682bee07703f20 to your computer and use it in GitHub Desktop.
WordPress search modification. Read the description!
<?php
/**
* Modification of the default WordPress search
*
* By default, the WordPress search is very rigid. It checks the post table's
* title, content and excerpt with a '%LIKE%' keyword. So the search is very
* limited.
* This will modify the search clause and do a fulltext search. For more information
* about fulltext you can read about it here: https://www.digitalocean.com/community/tutorials/how-to-improve-database-searches-with-full-text-search-in-mysql-5-6-on-ubuntu-16-04
*
* For it to work, your database has to support it, and you'll need to modify the tables
* you want to search through. You can do it with these SQL queries:
*
* ALTER TABLE wp_posts ADD FULLTEXT (post_title);
* ALTER TABLE wp_posts ADD FULLTEXT (post_content);
* ALTER TABLE wp_postmeta ADD FULLTEXT (meta_value);
*
* Depending on the content you have in those tables, it may take up to a minute to add
* FULLTEXT to those columns.
*
* What this modification does is that it uses fulltext to create a relevance to the search
* result, and order by that number.
*
* @package search-modification
*/
add_action( 'pre_get_posts','add_search_variable', 10 );
if ( ! function_exists( 'add_search_variable' ) ) {
/**
* Add query variable to search
*
* @param WP_Query $wp_query The WP_Query instance (passed by reference).
* @since 1.0.0
*/
function add_search_variable( $wp_query ) {
if ( ! is_admin() && $wp_query->is_main_query() ) {
if ( $wp_query->is_search ) {
$wp_query->set( 'query_id', 'distinct_query_id' );
$wp_query->set( 'post_status', 'publish' );
$wp_query->set( 'perm', 'readable' );
}
}
}
}
add_filter( 'posts_clauses', 'modify_search_query_clauses', 20, 2 );
if ( ! function_exists( 'modify_search_query_clauses' ) ) {
/**
* Filter for the search results query
*
* @param array $clauses Query clauses to modify.
* @param WP_Query $wp_query The WP_Query instance (passed by reference).
* @return array Modified query clauses.
*/
function modify_search_query_clauses( $clauses, $wp_query ) {
global $wpdb;
if ( ! is_admin() && ( is_search() || isset( $wp_query->query_vars['query_id'] ) && $wp_query->query_vars['query_id'] === 'distinct_query_id' ) ) {
$query_string = esc_html( $wp_query->query_vars['s'] );
if ( defined( 'ICL_LANGUAGE_CODE' ) ) {
$current_lang = ICL_LANGUAGE_CODE;
} else {
$current_lang = 'hr';
}
$clauses['distinct'] = "DISTINCT {$wpdb->posts}.*,";
$clauses['fields'] = " GREATEST(
COALESCE(MATCH ({$wpdb->posts}.post_title) AGAINST ('\"{$query_string}\" @4' IN BOOLEAN MODE), 1) * 100,
COALESCE(MATCH ({$wpdb->posts}.post_content) AGAINST ('\"{$query_string}\" @4' IN BOOLEAN MODE), 1),
COALESCE(MATCH ({$wpdb->postmeta}.meta_value) AGAINST ('\"{$query_string}\" @4' IN BOOLEAN MODE), 1)
) AS score";
$clauses['join'] = "LEFT JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id";
$clauses['where'] = "AND ({$wpdb->posts}.post_type = 'post'
OR {$wpdb->posts}.post_type = 'page'
OR {$wpdb->posts}.post_type = 'faq-type')
AND {$wpdb->posts}.post_type != 'wpcf7_contact_form'
AND {$wpdb->posts}.post_type != 'revision'
AND (
MATCH ({$wpdb->posts}.post_title) AGAINST ('\"{$query_string}\" @4' IN BOOLEAN MODE) > 0 OR
MATCH ({$wpdb->posts}.post_content) AGAINST ('\"{$query_string}\" @4' IN BOOLEAN MODE) > 0 OR
MATCH ({$wpdb->postmeta}.meta_value) AGAINST ('\"{$query_string}\" @4' IN BOOLEAN MODE) > 0
)
AND {$wpdb->posts}.post_status = 'publish'";
$clauses['orderby'] = 'score DESC';
}
return $clauses;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment