web-dev-qa-db-fra.com

Comment utiliser WP_Query pour exécuter cette requête de base de données en tant que résultat de recherche?

J'ai créé une zone de recherche avec une liste déroulante de 4 options pour personnaliser la recherche:

  • Une recherche par défaut générale, pas de filtre
  • Une recherche personnalisée en fonction du titre de la publication pour un type de publication personnalisé uniquement.
  • Une recherche personnalisée en fonction du contenu de la publication pour un type de publication personnalisé uniquement.
  • Une recherche personnalisée en fonction de la méta-valeur attachée à une publication pour un type de publication personnalisé uniquement.

J'ai construit la boîte de recherche pour gérer cela. Cela ressemble à ceci dans le fichier 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' );

L'utilisation de cette zone de recherche renvoie une URL avec une chaîne de requête à la fin qui ressemble à ceci: ?type=loc&s=Arizona. Vous remarquerez que je n’ai ajouté qu’un paramètre supplémentaire type à partir duquel une recherche par défaut renverrait.

Voici ce que j'essaie de faire. En fonction du résultat de la recherche, je dois modifier la requête principale pour qu'elle se comporte comme l'une des requêtes MySQL suivantes:

  1. SÉLECTIONNEZ * wp_posts, wp_postmeta WHERE DESC

  2. SÉLECTIONNEZ * À PARTIR DE wp_posts WHERE

J'ai trouvé cette publication sur les forums WordPress d'il y a deux ans: http://wordpress.org/support/topic/query-posts-by-custom-fields-value

Ceci est assez proche de ce que je veux accomplir, mais ma question est de savoir s'il est possible de faire cela dans la boucle WP_Query exclusivement sans utiliser la classe de base de données WP ($ wpdb).

J'ai configuré une fonction de filtrage pre-get-post avec un commutateur conformément au paramètre type dans le fichier functions.php pour gérer cette requête, mais je ne parviens pas à exécuter la requête de la manière décrite ci-dessus à l'aide de la classe WP_Query. Cela peut-il être fait? Merci.

2
Brent

Eh bien, peut-être que la réponse dans la classe WP_Query ne correspond pas à ce que j'essayais d'accomplir. Vous trouverez ci-dessous le code final que j'ai branché dans mon fichier functions.php. J'ai finalement fini par rechercher la classe WP_Query trouvée dans le fichier wp_includes/query.php. Ce que j’ai découvert, c’est qu’il existe un certain nombre de points d’accès au filtre dans lesquels on peut sauter et modifier la requête. J'ai constaté qu'il existait un filtre posts_search qui me permettait de modifier la partie recherche de la requête MySQL envoyée à la base de données. Un filtre posts_where encore plus inclusif m'a permis de modifier davantage la requête MySQL.

Merci à @Scribu de Google Groupes de lui recommander de faire un var_dump sur la requête entrante pour voir si le filtre que j'utilisais me permettait d'accéder à la partie de la requête que je souhaitais modifier.

Cependant, j'ai finalement décidé d'accéder au tout puissant filtre posts_request qui m'a donné la chaîne de requête MySQL complète et m'a permis d'extraire le cœur de la requête et de le remplacer en fonction de l'une des trois requêtes que je devais exécuter. J'ai découpé et stocké dans des variables le début et la fin de la requête afin de ne pas empêcher la requête d'être définie de manière dynamique.

Voici le formulaire de recherche:

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' );

Et voici le filtre des résultats de la recherche:

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');

Espérons que cela aide quelqu'un d'autre.

2
Brent

vous utilisez l'action hook pour formater wp_query avant l'exécution. Regardez l'action de référence pré-post post vous devez mettre vos options de filtrage de champ personnalisé dans [meta_query]. pour plus de détails à ce sujet, consultez la documentation de la fonction codex de wp_query.

exemple modifié du codex:

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

espérons que cela vous aide

0
xiarnousx