web-dev-qa-db-ja.com

メタキー/メタ値でのみ検索

私はほとんどこれにいます。

Functions.phpに私はこれがあります:

function base_home_product_post_type( $query ) {

    if($query->is_search() && $_POST['box'] == 'sku') {
        $query->query_vars['post_type'] = 'product';
        $query->query_vars['meta_key'] = 'sku';
        $query->query_vars['meta_value'] = $query->query_vars['s'];
        return;
    }

}
add_action('pre_get_posts', 'base_home_product_post_type', 1);

そしてそれはそれが言ったことを行います。 meta_key 'sku'で検索文字列を検索します。ここでの問題は、デフォルトでは、WordPressから返されるクエリオブジェクトにもこれが含まれ、デフォルトでpost_titlepost_contentをクエリすることです。

SELECT SQL_CALC_FOUND_ROWS  whirl_2_posts.ID FROM whirl_2_posts  INNER JOIN whirl_2_postmeta ON (whirl_2_posts.ID = whirl_2_postmeta.post_id) WHERE 1=1  AND (((whirl_2_posts.post_title LIKE '%__SEARCH_STRING__%')  OR (whirl_2_posts.post_content LIKE '%__SEARCH_STRING__%')))

私が "sku"値だけを探しているとき、私は本当にそれが欲しくないので、私はposts_whereとこのようなかなり醜いREGEXを使ってそれを削除しようとしました(警告、ハッキーとバギー):

function get_rid_of_titles($search) {
    if(is_search() && $_POST['box'] == 'sku') {
    $search = preg_filter('|AND\s\({3}\w*\.post_title\sLIKE\s\'\%[^%]*\%\'\) OR \(\w*\.post_content\sLIKE\s\'\%[^%]*\%\'\){3}\s|', '', $search);
    }
    return $search;
}
add_filter('posts_where','get_rid_of_titles');

しかし、幸運にも。このケースでカスタム値を検索する方法を私に教えてもらえますか。

_ソリューション_

以下の@kaiserのおかげで、私はこれがうまくいった。

function get_rid_of_titles($search) {

    if(is_search() && $_POST['box'] == 'sku') {

          $sku = $_POST['s'];          // get search string
          $needle = "LIKE '%$sku%'";   // search only for LIKE '%_SEARCH_STRING_%'. This is a multisite environment, so involving table names directly is a bad idea
          $replace = "LIKE '%'";       // replace it with SQL Wildcard so any title and any content are welcome
          $count = 2;                  // only the first 2 occurrencies which happen to be post_title and post_content
          return str_replace($needle,$replace,$search, $count);

    }
}
add_filter('posts_where','get_rid_of_titles');
4
moraleida

2つのことができます。

A)postmetaテーブルのみを検索するSQLクエリで検索を置き換えます(JOINが含まれていないため高速です。結果を表示するときは、後でIDを使って投稿を取得できます)。

B)WHERE 1=1の直後の文字列を分割し、後の部分を削除します。単純なreturn str_replace( $query_part_below, '', $search );を使うことができます。

 AND (
    (whirl_2_posts.post_title LIKE '%__SEARCH_STRING__%')  
    OR (whirl_2_posts.post_content LIKE '%__SEARCH_STRING__%')
)

押し込む前に、正しく$wpdb->prepare()を実行してください。

2
kaiser