web-dev-qa-db-ja.com

WP_Queryを使用してこのデータベースクエリを検索結果として実行する方法はありますか

検索をカスタマイズするための4つのオプションのドロップダウンボックスを持つ検索ボックスを作成しました。

  • 一般的なデフォルト検索、フィルタなし
  • カスタム投稿タイプ専用の投稿タイトルに従ったカスタム検索。
  • カスタム投稿タイプ専用の投稿コンテンツに従ったカスタム検索。
  • カスタム投稿タイプの場合のみ、投稿に添付されたメタ値に従ったカスタム検索。

これを処理するために検索ボックスを構築しました。 functions.phpファイルでは次のようになります。

function r3_search_form( $form ) {
    $form = '<form role="search" method="get" id="top_nav_search" action="' . home_url( '/' ) . '" >
    <div>

        <label class="screen-reader-text" for="type">' . __('Type of Search:') . '</label>
        <select name="type" id="ic_search_type" >
            <option value="all">General Search |search full site contents|</option>
            <option value="name">Mineral Name |search the approved name for the mineral|</option>
            <option value="loc">Locality |search by mine name, district, state, or country|</option>
            <option value="detail">Description |search the description of the mineral|</option>
        </select>
        <label class="screen-reader-text" for="s">' . __('Search Form:') . '</label>
        <input type="text" value="' . get_search_query() . '" name="s" id="s" />
        <input type="submit" id="searchsubmit" value="'. esc_attr__('Search') .'" />
    </div>
    </form>';

    return $form;
}

add_filter( 'get_search_form', 'r3_search_form' );

この検索ボックスを使用すると、末尾に次のようなクエリ文字列を含むURLが返されます。?type=loc&s=Arizona。デフォルトの検索で返されるものから追加のパラメータtypeを1つだけ追加したことに気付くでしょう。

これが私がやろうとしていることです。検索結果に応じて、次のMySQLクエリのいずれかのように動作するようにメインクエリを変更する必要があります。

  1. SELECT * FROM wp_posts、wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_idとwp_postmeta.meta_key wp_posts.post_date BY = '_custom_meta_key' AND LIKE '%の$のSEARCH_TERM%' AND wp_posts.post_type wp_postmeta.meta_value = 'カスタムポストタイプ' ORDER DESC

  2. SELECT * FROM wp_postsどこwp_posts.post_title LIKE '%$ search_term%' AND wp_posts.post_type = 'カスタム投稿タイプ' ORDER BY wp_posts.post_date DESC

私は2年前からWordPressフォーラムでこの記事を見つけました: http://wordpress.org/support/topic/query-posts-by-custom-fields-value

これは私が達成したいことにかなり近づいています、しかし私の質問はWPデータベースクラス($ wpdb)を使用せずにWP_Queryループ内でこれを排他的に行う方法があるかどうかです。

この要求を処理するためにfunctions.phpファイルのtypeパラメータに従ってスイッチ付きのpre-get-postフィルタ関数を設定しましたが、WP_Queryクラスだけを使用して上記のようにクエリを実行することはできません。できますか?ありがとう。

2
Brent

まあ、おそらく私が達成しようとしていたものに対するWP_Queryクラスに答えが見つかりませんでした。以下は、functions.phpファイルにプラグインした最終コードです。最終的に、WP_Queryファイルにあるwp_includes/query.phpクラスを検索しました。私が発見したのは、クエリをジャンプして変更できるフィルターアクセスポイントが多数あることです。データベースに送信されたMySQLクエリの検索部分を変更できるposts_searchフィルターがあることがわかりました。さらに包括的なposts_whereフィルターがあり、MySQLクエリをさらに変更できました。

Googleグループの@Scribuが、受信クエリでvar_dumpを実行して、使用しているフィルターが変更したいクエリの一部にアクセスできるかどうかを確認するように勧めてくれてありがとう。

しかし、最終的にはすべての強力なposts_requestフィルターにアクセスして、完全なMySQLクエリ文字列を取得し、クエリリクエストのコアを引き出して、必要な3つのクエリのいずれかに従って置換できるようにすることにしました実行します。動的に設定されるクエリの機能を損なわないように、クエリの開始と終了をトリミングして変数に保存しました。

検索フォームは次のとおりです。

function my_search_form( $form ) {
    (isset($_REQUEST['type']))? $ic_sType = $_REQUEST['type'] : $ic_sType = '';


    $ic_selectOpts = array(
        'all' =>'General Search [search full site contents]',
        'name'=>'Mineral Name [search the approved name for the mineral]',
        'detail'=>'Description [search the description of the mineral]',
        'loc'=>'Locality [search by mine name, district, state, or country]'
    );

    $form = '<form role="search" method="get" id="top_nav_search" action="' . home_url( '/' ) . '" >
    <div>


        <label class="screen-reader-text" for="type">' . __('Type of Search:') . '</label>

        <select name="type" id="my_search_type" >';
        foreach($my_selectOpts as $myso_key => $myso_val){
            $form .= "<option value='$myso_key'";
            if($myso_key === $my_sType) $form .= "selected='selected'";
            $form .= ">$myso_val</option>";
        }

        $form .= '</select>
        <label class="screen-reader-text" for="s">' . __('Search Form:') . '</label>
        <input type="text" value="' . get_search_query() . '" name="s" id="s" />
        <input type="submit" id="searchsubmit" value="'. esc_attr__('Search') .'" />
    </div>
    </form>';

    return $form;
}

add_filter( 'get_search_form', 'my_search_form' );

次に、検索結果フィルターを示します。

function my_search_results($query){

    if(isset($_REQUEST['type']) && isset($_REQUEST['s']) && ($_REQUEST['type'] !== 'all')){

        $myType = $_REQUEST['type'];
        $mySearch = $_REQUEST['s'];

        $qBegin = str_replace(strstr($query, "FROM" ), '', $query). ' FROM';

        //echo '<br>the qBegin string: '. $qBegin;

        $qEnd = strrchr($query, "ORDER BY" );
        //echo '<br>the qEnd string:' . $qEnd;

        switch ($myType){

            case 'name': //Title search

                $query = $qBegin. ' wp_posts WHERE 1=1 AND wp_posts.post_title LIKE "%'.$icSearch.'%" AND wp_posts.post_type = "mineral" AND (wp_posts.post_password = "") AND(wp_posts.post_status = "publish") '.$qEnd;

                break;

            case 'loc': //Location Search

                $query = $qBegin. ' wp_posts,wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_id AND 1=1 AND wp_postmeta.meta_key = "_location_meta" AND wp_postmeta.meta_value LIKE "%'.$icSearch.'%" AND wp_posts.post_type = "mineral" AND (wp_posts.post_password = "") AND(wp_posts.post_status = "publish") '.$qEnd;

                break;

            case 'detail': //Details Search

                $query = $qBegin. ' wp_posts WHERE 1=1 AND wp_posts.post_content LIKE "%'.$icSearch.'%" AND wp_posts.post_type = "mineral" AND (wp_posts.post_password = "") AND(wp_posts.post_status = "publish") '.$qEnd;

                break;

            default: 

                break;
        }

    } 

    return $query;

}
add_filter( 'posts_request', 'my_search_results');

うまくいけば、これは他の人の助けになります。

2
Brent

実行前にwp_queryをフォーマットするためにactionフックを使用します。 アクション参照pre get post wp_queryの詳細については[meta_query]にカスタムフィールドフィルタオプションを追加する必要があります。コーデックス関数のドキュメント。

コーデックスからの変更例:

    function meta_add( &$query ) {
    if ( /*search result page */ ) {
        $query->set( 'meta_query', array(/*assoc of the filter */) );
    }
}
add_action( 'pre_get_posts', 'meta_add' );

それがあなたを助けてくれることを願っています

0
xiarnousx