Как мне искать WordPress по разным полям без плагина?


Я создаю свою собственную тему WordPress, и я хотел бы, чтобы мои поисковые запросы выполняли поиск сообщений по ключевым словам в названии, категориях, тегах и содержимом. На данный момент я считаю, что моя тема - это поиск только по ключевым словам в названии и содержании.

Как определить, какие поля в данный момент находятся в поиске? Как только я это определю, как мне изменить свой поисковый запрос, чтобы он выполнял поиск сообщений по полям, перечисленным выше?

Я пробовал что-то похожее на учебник ниже. Если просмотр кода из моей темы поможет вам ответить, дайте мне знать, какие файлы вам понадобятся, и я их опубликую.

<?php
/**
 * Extend WordPress search to include custom fields
 *
 * https://adambalee.com
 */

/**
 * Join posts and postmeta tables
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_join
 */
function cf_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {    
        $join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }

    return $join;
}
add_filter('posts_join', 'cf_search_join' );

/**
 * Modify the search query with posts_where
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_where
 */
function cf_search_where( $where ) {
    global $pagenow, $wpdb;

    if ( is_search() ) {
        $where = preg_replace(
            "/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
    }

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

/**
 * Prevent duplicates
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_distinct
 */
function cf_search_distinct( $where ) {
    global $wpdb;

    if ( is_search() ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );
Author: Nicolai, 2019-04-23

1 answers

Я нашел решение, которое позволяет мне искать сообщения по тегам и категориям, продолжая искать заголовок и контент. Это делает именно то, что я искал.

Кредит: https://rfmeier.net/include-category-and-post-tag-names-in-the-wordpress-search/

add_filter( 'posts_join', 'search_join', 10, 2 );
/**
 * Joins the terms, term_relationship, and term_taxonomy tables.
 *
 * @global $wpdb
 *
 * @param string $join The sql JOIN clause.
 * @param object $query The current WP_Query instance.
 *
 * @return string $join
 */
function search_join( $join, $query ) {

    global $wpdb;

    if ( is_main_query() && is_search() ) {

        $join .= "
        LEFT JOIN
        (
            {$wpdb->term_relationships}
            INNER JOIN
                {$wpdb->term_taxonomy} ON {$wpdb->term_taxonomy}.term_taxonomy_id = {$wpdb->term_relationships}.term_taxonomy_id
            INNER JOIN
                {$wpdb->terms} ON {$wpdb->terms}.term_id = {$wpdb->term_taxonomy}.term_id
        )
        ON {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id ";

    }

    return $join;

}

add_filter( 'posts_where', 'custom_posts_where', 10, 2 );
/**
 * Callback for WordPress 'posts_where' filter.
 *
 * Modify the where clause to include searches against a WordPress taxonomy.
 *
 * @global $wpdb
 *
 * @param string $where The where clause.
 * @param WP_Query $query The current WP_Query.
 *
 * @return string The where clause.
 */
function custom_posts_where( $where, $query ) {

    global $wpdb;

    if ( is_main_query() && is_search() ) {

        // get additional where clause for the user
        $user_where = custom_get_user_posts_where();

        $where .= " OR (
                        {$wpdb->term_taxonomy}.taxonomy IN( 'category', 'post_tag' )
                        AND
                        {$wpdb->terms}.name LIKE '%" . esc_sql( get_query_var( 's' ) ) . "%'
                        {$user_where}
                    )";

    }

    return $where;

}

function custom_get_user_posts_where() {

  global $wpdb;

  $user_id = get_current_user_id();
  $sql     = '';
  $status  = array( "'publish'" );

  if ( $user_id ) {

      $status[] = "'private'";

      $sql .= " AND {$wpdb->posts}.post_author = {$user_id}";

  }

  $sql .= " AND {$wpdb->posts}.post_status IN( " . implode( ',', $status ) . " ) ";

  return $sql;

}

add_filter( 'posts_groupby', 'custom_posts_groupby', 10, 2 );
/**
 * Callback for WordPress 'posts_groupby' filter.
 *
 * Set the GROUP BY clause to post IDs.
 *
 * @global $wpdb 
 *
 * @param string $groupby The GROUPBY caluse.
 * @param WP_Query $query The current WP_Query object.
 *
 * @return string The GROUPBY clause.
 */
function custom_posts_groupby( $groupby, $query ) {

  global $wpdb;

  if ( is_main_query() && is_search() ) {
      $groupby = "{$wpdb->posts}.ID";
  }

  return $groupby;

}
 1
Author: tpsReports, 2019-04-26 17:39:28