WP_Query avec “post_title LIKE 'quelque chose%' '?

39

Je dois faire un WP_Query avec un LIKE sur le post_title .

J'ai commencé avec ce WP_Query normal:

$wp_query = new WP_Query( 
    array (
        'post_type'        => 'wp_exposants',
        'posts_per_page'   => '1',
        'post_status'      => 'publish',
        'orderby'          => 'title', 
        'order'            => 'ASC',
        'paged'            => $paged
    )
); 

Mais ce que je veux réellement faire ressemble à ceci en SQL:

$query = "
        SELECT      *
        FROM        $wpdb->posts
        WHERE       $wpdb->posts.post_title LIKE '$param2%'
        AND         $wpdb->posts.post_type = 'wp_exposants'
        ORDER BY    $wpdb->posts.post_title
";
$wpdb->get_results($query);

La sortie affiche les résultats que je m'attendais, mais j'utilise le <?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?> habituel pour afficher les résultats.
Et cela ne fonctionne pas avec $wpdb->get_results() .

Comment puis-je atteindre ce que j'ai décrit ici?

    
posée Ludo 30.05.2011 - 14:11
la source

5 réponses

43

Je résoudrais ceci avec un filtre sur WP_Query . Celui qui détecte une variable de requête supplémentaire et l’utilise comme préfixe du titre.

add_filter( 'posts_where', 'wpse18703_posts_where', 10, 2 );
function wpse18703_posts_where( $where, &$wp_query )
{
    global $wpdb;
    if ( $wpse18703_title = $wp_query->get( 'wpse18703_title' ) ) {
        $where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'' . esc_sql( $wpdb->esc_like( $wpse18703_title ) ) . '%\'';
    }
    return $where;
}

De cette façon, vous pouvez toujours appeler WP_Query , il vous suffit de passer le titre sous forme d'argument wpse18703_title (ou de modifier le nom en un nom plus court).

    
réponse donnée Jan Fabry 30.05.2011 - 16:06
la source
15

Je voulais mettre à jour ce code sur lequel vous avez travaillé pour wordpress 4.0 et versions ultérieures, car esc_sql () est obsolète dans la version 4.0 supérieure.

function title_filter($where, &$wp_query){
    global $wpdb;

    if($search_term = $wp_query->get( 'search_prod_title' )){
        /*using the esc_like() in here instead of other esc_sql()*/
        $search_term = $wpdb->esc_like($search_term);
        $search_term = ' \'%' . $search_term . '%\'';
        $where .= ' AND ' . $wpdb->posts . '.post_title LIKE '.$search_term;
    }

    return $where;
}

Le reste est le même.

Je tiens également à préciser que vous pouvez utiliser la variable s dans les arguments de WP_Query pour transmettre les termes de recherche, ce qui permettra également de rechercher le titre de l'article, je crois.

Comme ceci:

$args = array(
    'post_type' => 'post',
    's' => $search_term,
    'post_status' => 'publish',
    'orderby'     => 'title', 
    'order'       => 'ASC'        
);
$wp_query = new WP_Query($args);
    
réponse donnée Ashan Jay 02.01.2015 - 06:36
la source
15

Simplifié:

function title_filter( $where, &$wp_query )
{
    global $wpdb;
    if ( $search_term = $wp_query->get( 'search_prod_title' ) ) {
        $where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . esc_sql( like_escape( $search_term ) ) . '%\'';
    }
    return $where;
}

$args = array(
    'post_type' => 'product',
    'posts_per_page' => $page_size,
    'paged' => $page,
    'search_prod_title' => $search_term,
    'post_status' => 'publish',
    'orderby'     => 'title', 
    'order'       => 'ASC'
);

add_filter( 'posts_where', 'title_filter', 10, 2 );
$wp_query = new WP_Query($args);
remove_filter( 'posts_where', 'title_filter', 10, 2 );
return $wp_query;
    
réponse donnée Rao 19.04.2013 - 15:24
la source
7

En me basant sur d’autres réponses que j’ai eues avant, pour offrir une flexibilité dans la situation où vous souhaitez rechercher un article qui contient un mot dans un champ méta OU dans le titre de l’article, je donne cette option via l’argument "title_filter_relation". Dans cette implémentation, je n'autorise que les entrées "OU" ou "ET" avec la valeur par défaut de "ET".

function title_filter($where, &$wp_query){
    global $wpdb;
    if($search_term = $wp_query->get( 'title_filter' )){
        $search_term = $wpdb->esc_like($search_term); //instead of esc_sql()
        $search_term = ' \'%' . $search_term . '%\'';
        $title_filter_relation = (strtoupper($wp_query->get( 'title_filter_relation'))=='OR' ? 'OR' : 'AND');
        $where .= ' '.$title_filter_relation.' ' . $wpdb->posts . '.post_title LIKE '.$search_term;
    }
    return $where;
}

Voici un exemple de code en action pour un type de message très simple "faq" où la question est le titre du message lui-même:

add_filter('posts_where','title_filter',10,2);
$s1 = new WP_Query( array(
    'post_type' => 'faq',
    'posts_per_page' => -1,
    'title_filter' => $q,
    'title_filter_relation' => 'OR',
    'post_status' => 'publish',
    'orderby'     => 'title', 
    'order'       => 'ASC',
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key' => 'faq_answer',
            'value' => $q,
            'compare' => 'LIKE'
        )
    )
));
remove_filter('posts_where','title_filter',10,2);
    
réponse donnée David Choy 29.04.2015 - 00:44
la source
5

Avec une solution vulnérable publiée ici, je viens avec une version un peu simplifiée et assainie.

Tout d'abord, nous créons une fonction pour le filtre posts_where qui vous permet d'afficher uniquement les publications correspondant à des conditions spécifiques:

function cc_post_title_filter($where, &$wp_query) {
    global $wpdb;
    if ( $search_term = $wp_query->get( 'cc_search_post_title' ) ) {
        $where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . $wpdb->esc_like( $search_term ) . '%\'';
    }
    return $where;
}

Maintenant, nous ajoutons cc_search_post_title dans nos arguments de requête:

$args = array(
    'cc_search_post_title' => $search_term, // search post title only
    'post_status' => 'publish',
);

Et enfin, enroulez le filtre autour de la requête:

add_filter( 'posts_where', 'cc_post_title_filter', 10, 2 );
$query = new WP_Query($args);
remove_filter( 'posts_where', 'cc_post_title_filter', 10 );

Utilisation de get_posts ()

Certaines fonctions récupérant des publications ne font pas de filtres. Par conséquent, les fonctions de filtre posts_where que vous attachez ne modifieront pas la requête. Si vous envisagez d'utiliser get_posts() pour interroger vos publications, vous devez définir suppress_filters sur false dans votre tableau d'arguments:

$args = array(
    'cc_search_post_title' => $search_term,
    'suppress_filters' => FALSE,
    'post_status' => 'publish',
);

Vous pouvez maintenant utiliser get_posts() :

add_filter( 'posts_where', 'cc_post_title_filter', 10, 2 );
$posts = get_posts($args);
remove_filter( 'posts_where', 'cc_post_title_filter', 10 );

Qu'en est-il du paramètre s ?

Le paramètre s est disponible:

$args = array(
    's' => $search_term,
);

Lors de l'ajout de votre terme de recherche dans le paramètre s work et qu'il recherchera le titre de l'article, il recherchera également le contenu de l'article.

Qu'en est-il du paramètre title ajouté avec WP 4.4?

Passage d'un terme de recherche dans le paramètre title :

$args = array(
    'title' => $search_term,
);

Est sensible à la casse et LIKE , pas %LIKE% . Cette recherche moyenne pour hello ne renverra pas de message avec le titre Hello World ou Hello .

    
réponse donnée Christine Cooper 19.04.2018 - 14:58
la source

Lire d'autres questions sur les étiquettes