質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • WordPress

    8455questions

    WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

  • 検索

    105questions

    検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

Wordpress カスタムフィールドの値も絞り込み検索できるようにしたい

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 115

Wordpressの検索機能を実装しているのですが実現できず困っています。

2019/03/11-17:26
最新のソースコードに修正しました。

■実装したい事
1.フリーワード検索(実装済み)
2.クソノミー、ターム絞り込み検索(実装済み)
3.カスタムフィールドの絞り込み検索(未実装)

フリーワード検索は独立していていいのですが、投稿タイプ内でカテゴリ、カスタムフィールドを全て検索対象にして、
絞り込み検索できるようにしたいです。
タブでカテゴリの要素を出したものと複数のカスタムフィールドが混在している少しごちゃごちゃした検索項目の出し方です。

カスタムフィールド単体では検索にヒットするようになりましたが複数検索させるやり方がわかりません。

主に以下の参考サイトより自分の知識で出来る範囲で試してみましたが駄目でした。
https://www.webtoolnavi.com/wordpress-search-everything/
http://wpcj.net/1363
https://izizm.net/webizm/web-management/wordpress/1754/
http://kotori-blog.com/wordpress/refinement_search/
https://sheeplog.work/acf_custom_search_hudosan/

以下現時点でのソースです。
■search.php

<?php
$s = $_GET['s'];
$my_taxonomy = $_GET['my_taxonomy'];
$term_slug = $_GET['term_slug'];
$and_or = $_GET['and_or'];
$market = $_GET['market'];
$use = $_GET['use'];

if($term_slug){
    $tax_query[] = array(
        'taxonomy'=> $my_taxonomy,
        'terms'=> $term_slug,
        'include_children'=> false,
        'field'=> 'slug',
        'operator'=> $and_or
    );
}

$args = array(
    'tax_query' => $tax_query,
    's' => $s,
    'posts_per_page' => -1,
    'meta_query' => array(
        'relation'=>'OR',
        'market_car' => array(
            'value' => '$market[0]',
            'compare' => 'LIKE',
        ),
        'cat_use' => array(
            'value' => $use[0],
            'compare' => 'LIKE',
        ),
    )
);
$wp_query= null;
$the_query = new WP_Query( $args ); ?>
<?php if ( $the_query->have_posts() ) : ?>
<section id="archive_area">
    <ul class="item_list">
<!-- ループはじめ -->
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>

<li><a href="<?php the_permalink(); ?>">
    <p class="tl"><?php the_title(); ?></p>
</a></li>

<?php endwhile; ?>
<!-- ループおわり -->
    </ul>
</section>

<?php wp_reset_postdata(); ?>

<?php else : ?>
<p>お探しの記事はありませんでした。</p>
<?php endif; ?>


■searchform.php

<form role="search" method="get" id="searchform" class="search-form" action="<?php echo home_url('/test/'); ?>">

    <div class="free_serach">
        <div class="input_box">
            <input type="text" class="field" name="s" id="s" placeholder="入力してください。" value="<?php the_search_query(); ?>">
            <input type="image" src="<?php echo site_url(); ?>/wp-content/uploads/product/ico_search_01.png" class="submit" name="submit" value="検索">
        </div>
    </div>
    <section id="tabArea">
        <?php
        $my_taxonomy = 'test_cat';
        $cat_args = array(
            'parent' => 0, //トップレベルのタームのみ
            'hierarchical' => 0 //子タームを含めない
        );
        $i = 0;
        $terms = get_terms($my_taxonomy,$cat_args);

        ?>
        <ul id="tabMenu">
            <li><a href="#cat00" class="open">カテゴリ01</a></li>
            <li><a href="#cat01">カスタムフィールド01</a></li>
            <li><a href="#cat02">カスタムフィールド02</a></li>
        </ul>
        <!-- フォームの追加はじめ -->
        <div id="cat00">
            <div class="btn_box">
            <?php
                foreach( $terms as $term ):
                $child_cats = get_terms($my_taxonomy,'hierarchical=0&hide_empty=1&parent='.$term -> term_id);
                if($child_cats):
            ?>

                <?php
                    foreach($child_cats as $child_cat):
                ?>
                <?php
                    $child_cat_name = esc_html($child_cat -> name);
                    $target_cat_slug = esc_html($child_cat->slug);
                ?>
                <label><input type="checkbox" name="term_slug[]" value="<?php echo $child_cat->slug; ?>"><span><?php echo $child_cat->name; ?></span></label>
                <?php endforeach;?>

            <?php endif; ?>
            <?php wp_reset_postdata(); ?>
            <?php endforeach; ?>
            </div>
        </div>
        <div id="cat01">
            <div class="btn_box">
                <label><input type="checkbox" name="market[]" value="market_01"><span>カスタムフィールドの項目</span></label>
                <label><input type="checkbox" name="market[]" value="market_02"><span>カスタムフィールドの項目</span></label>
                <label><input type="checkbox" name="market[]" value="market_03"><span>カスタムフィールドの項目</span></label>
                <label><input type="checkbox" name="market[]" value="market_04"><span>カスタムフィールドの項目</span></label>
            </div>
        </div>
        <div id="cat02">
            <div class="btn_box">
                <label><input type="checkbox" name="use[]" value="use_01"><span>カスタムフィールドの項目</span></label>
                <label><input type="checkbox" name="use[]" value="use_02"><span>カスタムフィールドの項目</span></label>
                <label><input type="checkbox" name="use[]" value="use_03"><span>カスタムフィールドの項目</span></label>
                <label><input type="checkbox" name="use[]" value="use_04"><span>カスタムフィールドの項目</span></label>
            </div>
        </div>
        <input type="hidden" name="my_taxonomy" value="<?php echo $my_taxonomy ?>">
        <select name="and_or" id="and_or">
            <option value="AND">AND</option>
            <option value="IN">OR</option>
        </select>
        <!-- フォームの追加おわり -->
        <input type="submit" class="search-submit" value="<?php echo esc_attr_x( 'Search', 'submit button' ) ?>" />
        <input type="hidden" name="post_type" id="post_type" value="product">

    </section>
</form>


■Advanced Custom Fields登録例

フィールド名:cf_market
market_01 : テキスト01
market_02 : テキスト02
market_03 : テキスト03
market_04 : テキスト04

フィールド名:cf_use
use_01 : テキスト01
use_02 : テキスト02
use_03 : テキスト03
use_04 : テキスト04

不足情報等ありましたら何なりとお申し付け下さい。
すみませんが反応して頂けたらとても助かります。
どうぞよろしくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

+1

詳細まで拝見していませんが、今のコードを少し変えて $args のキー meta_query を $args の直下に移動すると機能するようになるのではないかと思います。

if($term_slug){
    $tax_query[] = array(
        'taxonomy'=> $my_taxonomy,
        'terms'=> $term_slug,
        'include_children'=> false,
        'field'=> 'slug',
        'operator'=> $and_or,
-        'meta_query' => array(
-           array( 'key'=>'cf_market',
-            'value'=>$market[0],
-            'compare'=>'like',
-            ),
-           'relation'=>'AND'
-   )
    );
}
$args = array(
    'tax_query' => $tax_query,
    's' => $s,
    'posts_per_page' => -1
+    'meta_query' => array(
+       array(
+           'key' => 'cf_market',
+           'value' => $market[0],
+           'compare' => 'like',
+       ),
+       'relation' => 'AND',
+    )
);

変更後のコードに対して私の手元で動作確認をしているわけではないので、上のコードが正しく動くとはかぎりません。コピペするのではなく、アイデアだけ参考にしていただければと思います。

ちなみに WP_Query の使い方については Codex 上でとても詳しく説明されているので一度目を通されてみてください :D

追記 2019/03/14

単体では検索にヒットしますが、確かに複数指定するとヒットしません。
引き続き調べながら作業しますが、ループ処理に関してヒントとなるものはありますでしょうか?

上 ↑ でご紹介した Codex のページはご覧になりましたか?そこにそのままズバリなヒントが載っていますので、もしまだお読みになっていなければ読んでみてください。

上 ↑ の Codex のページの該当箇所をかんたんに解説しますね。 2 つの例が紹介されています。

$args = array(
  'post_type'  => 'product',
  'meta_query' => array(
    'relation' => 'OR',
    array(
      'key'     => 'color',
      'value'   => 'blue',
      'compare' => 'NOT LIKE',
    ),
    array(
      'key'     => 'price',
      'value'   => array( 20, 100 ),
      'type'    => 'numeric',
      'compare' => 'BETWEEN',
    ),
  ),
);
$query = new WP_Query( $args );

ひとつめ ↑ は「 投稿タイプ product の投稿のうち、【カスタムフィールド color の値が blue ではないもの】と【カスタムフィールド price の値が 20 〜 100 の間のもの】 」を取得するサンプルです。

$args = array(
  'post_type'  => 'product',
  'meta_query' => array(
    'relation' => 'OR',
    array(
      'key'     => 'color',
      'value'   => 'orange',
      'compare' => '=',
    ),
    array(
      'relation' => 'AND',
      array(
        'key' => 'color',
        'value' => 'red',
        'compare' => '=',
      ),
      array(
        'key' => 'size',
        'value' => 'small',
        'compare' => '=',
      ),
    ),
  ),
);
$query = new WP_Query( $args );

ふたつめのこちら ↑ は「 投稿タイプ product の投稿のうち、【カスタムフィールド color が orange のもの】と【カスタムフィールド color が red でカスタムフィールド size が small のもの】 」を取得するサンプルです。

ロジックと実際のコードの構成を見比べて、ご自身の場合だとどのように書けばよいか、考えてみてください。

「ループ」というのは、クライアントから送られた market や use (いずれも配列)に対してループを回して、最終的に meta_query をこのような形で組むということです。

「ループ」と言いましたが、もし完全一致( = )での検索でよいのであれば、次のような感じで IN を使えばループを回さなくてもいけるかもしれません(あくまでもイメージです)。

$args = [
  // ...
];

$meta_query_market = [
  'key' => 'market',
  'value' => $market,
  'compare' => 'IN',
];

$meta_query_use = [
  'key' => 'use',
  'value' => $use,
  'compare' => 'IN',
];

$meta_query = [
  'relation' => 'AND',
  $meta_query_market,
  $meta_query_use,
];

$args['meta_query'] = $meta_query;

この説明でもどうもよくわからないなという場合は、 Codex をまずは丹念に読んでみることをおすすめします。というのと、これ以上は WordPress というよりは PHP の知識の問題だと思いますので、 PHP でのループの回し方等をお調べになってください。がんばってください :D

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/10 21:27

    ご回答ありがとうございます!助かります!
    この検索機能は実現したいので、ご指摘頂いた箇所を試行錯誤しながら試してみたいと思います。

    キャンセル

  • 2019/03/10 21:45

    最終的には複数指定された `market` に対して動作するようにされたいものと思います。それには `meta_query` の作成時にループを回す等する必要がありこの回答のコードそのままではいけませんが、(回答を参考に)まずは `market` のひとつめで絞り込みができるところまでを実現されて、その後に複数の `market` に対応する、という流れで進められるとよいかと思います。がんばってください :)

    キャンセル

  • 2019/03/11 00:40

    まずはひとつめでの動作確認が目標ですね。
    今週頑張ってみます!アドバイスありがとうございます。

    キャンセル

  • 2019/03/11 11:24

    ご指摘頂いたやり方でまずは一つのカスタムフィールドが検索にヒットするようになりました。
    ありがとうございます!
    それからもう一つuseというカスタムフィールドを作成してテストしました。
    単体では検索にヒットしますが、確かに複数指定するとヒットしません。
    引き続き調べながら作業しますが、ループ処理に関してヒントとなるものはありますでしょうか?
    ▽現在の'args'の中身です。
    $args = array(
    'tax_query' => $tax_query,
    's' => $s,
    'posts_per_page' => -1,
    'meta_query' => array(
    'relation'=>'OR',
    'cat_market' => array(
    'value' => $market[0],
    'compare'=>'like',
    ),
    'cat_use' => array(
    'value' => $use[0],
    'compare'=>'like',
    ),
    )
    );

    キャンセル

  • 2019/03/14 23:32

    ご質問「ループ処理に関してヒントとなるものはありますでしょうか?」に対する回答を、回答文に追記しました。ご覧になってみてくださいー

    キャンセル

  • 2019/03/18 15:08

    追記ありがとうございます!
    丁寧に解説頂き感謝です。参考にしながら取り組んでみたいと思います。

    キャンセル

同じタグがついた質問を見る

  • WordPress

    8455questions

    WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

  • 検索

    105questions

    検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。