J'ai besoin de faire un WP_Query
avec un LIKE
sur le post_title
.
J'ai commencé avec ce WP_Query
régulier:
$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 j'attends, mais j'utilise la <?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
régulière 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?
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 en tant qu'argument wpse18703_title
(ou de changer le nom en un nom plus court).
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;
Je voulais mettre à jour ce code sur lequel vous avez travaillé pour wordpress 4.0 et versions supérieures, car esc_sql () est obsolète dans la version 4.0.
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 pareil.
De plus, je tiens à préciser que vous pouvez utiliser s variable dans les arguments de WP_Query pour transmettre les termes de recherche, ce qui permettra également de rechercher le titre du message, je crois.
Comme ça:
$args = array(
'post_type' => 'post',
's' => $search_term,
'post_status' => 'publish',
'orderby' => 'title',
'order' => 'ASC'
);
$wp_query = new WP_Query($args);
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 );
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',
);
Maintenant, vous pouvez 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 );
s
?Le paramètre s
est disponible:
$args = array(
's' => $search_term,
);
Lors de l'ajout du terme de recherche dans le paramètre s
, la recherche sera effectuée dans le titre de l'article, le aussi cherchera dans le contenu de l'article.
title
qui a été ajouté avec WP 4.4?Passer 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 de hello
ne renverra pas de message avec le titre Hello World
ou Hello
.
En me basant sur d’autres réponses que j’ai devant moi, pour offrir une certaine souplesse dans la situation où vous souhaitez rechercher un article contenant un mot dans un méta-champ OR dans le titre du message, 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);