Recherche qui va chercher dans le champ personnalisé, le titre de l'article et le contenu de l'article
1 réponses
- votes
-
- 2013-05-17
Premièrement,n'utilisezpas
query_posts
.Deuxièmement,vouspouvezpasser unparamètre
s
pourtirer lemeilleurparti du chemin.$program_search = 'test'; $args = array( 'post_type' => 'program', 's' => $program_search, 'meta_query' => array( array( 'key' => 'keywords', 'value' => $program_search, 'compare' => 'LIKE' ), ) ); $t = new WP_Query($args); var_dump($t->request);
Ceparamètre
s
met enplace lesmécanismes de recherche ordinaireset letitreet le contenu sont recherchés. Si vous regardez cette requêtegénérée,vous verrez ...SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) WHERE 1=1 AND (((wp_posts.post_title LIKE '%test%') OR (wp_posts.post_content LIKE '%test%'))) AND (wp_posts.post_password = '') AND wp_posts.post_type = 'program' AND (wp_posts.post_status = 'publish') AND ((wp_postmeta.meta_key = 'keywords' AND CAST(wp_postmeta.meta_value AS CHAR) LIKE '%test%')) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 5
C'esttout ce que vous voulez. Saufindication contraire,la
LIMIT
est la limite définie dans wp-admin-> Settings-> General. Il y a cependant unproblème.AND ((wp_postmeta.meta_key = 'keywords' AND CAST(wp_postmeta.meta_value AS CHAR) LIKE '%test%'))
Je suispresque sûr que vous voulez que ce soit
OR ((wp_postmeta.meta_key ...
et vous le voulez vraiment avec lepost_title
et lepost_content
aussi. Quelque chose comme ceci:AND ( ( (wp_posts.post_title LIKE '%test%') OR (wp_posts.post_content LIKE '%test%') OR (wp_postmeta.meta_key = 'keywords' AND CAST(wp_postmeta.meta_value AS CHAR) LIKE '%test%') ) )
WP_Query
ne leferapas,nous devons donc lefaire avec quelquesfiltres. Preuve de concept:function add_join_wpse_99849($joins) { global $wpdb; return $joins . " INNER JOIN {$wpdb->postmeta} ON ({$wpdb->posts}.ID = {$wpdb->postmeta}.post_id)"; } function alter_search_wpse_99849($search,$qry) { global $wpdb; $add = $wpdb->prepare("({$wpdb->postmeta}.meta_key = 'keywords' AND CAST({$wpdb->postmeta}.meta_value AS CHAR) LIKE '%%%s%%')",$qry->get('s')); $pat = '|\(\((.+)\)\)|'; $search = preg_replace($pat,'(($1 OR '.$add.'))',$search); return $search; } $program_search = 'test'; $args = array( 'post_type' => 'program', 's' => $program_search ); add_filter('posts_join','add_join_wpse_99849'); add_filter('posts_search','alter_search_wpse_99849',1,2); $t = new WP_Query($args); remove_filter('posts_join','add_join_wpse_99849'); remove_filter('posts_search','alter_search_wpse_99849',1,2); // dump some data var_dump($t->request); var_dump($t->posts);
Notez quej'ai complètement omis la
meta_query
et quej'ai largement dupliqué lafonctionnalité. C'estpour éviter que ceAND
gênantne soitgénéré.Vous appliquezet supprimezimmédiatement cesfiltres afin qu'ilsn'interfèrent avec aucune autre requête. Ilexiste d'autresmoyens degarder lefiltre à l'écart ou d'autres requêtes. Une de cesméthodesest décriteici . Vouspouvez également ajouter le
remove_filter
au rappeladd_filter
pour qu'ils se suppriment automatiquement.First, don't use
query_posts
.Second, you can pass an
s
parameter to get most of the way there.$program_search = 'test'; $args = array( 'post_type' => 'program', 's' => $program_search, 'meta_query' => array( array( 'key' => 'keywords', 'value' => $program_search, 'compare' => 'LIKE' ), ) ); $t = new WP_Query($args); var_dump($t->request);
That
s
parameter kicks the ordinary search mechanisms into place and the title and the content gets searched. If you look at that generated query you will see...SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) WHERE 1=1 AND (((wp_posts.post_title LIKE '%test%') OR (wp_posts.post_content LIKE '%test%'))) AND (wp_posts.post_password = '') AND wp_posts.post_type = 'program' AND (wp_posts.post_status = 'publish') AND ((wp_postmeta.meta_key = 'keywords' AND CAST(wp_postmeta.meta_value AS CHAR) LIKE '%test%')) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 5
That is most of what you want. The
LIMIT
unless otherwise specified is the limit set at wp-admin->Settings->General. There is a problem though.AND ((wp_postmeta.meta_key = 'keywords' AND CAST(wp_postmeta.meta_value AS CHAR) LIKE '%test%'))
I am pretty sure you want that to be
OR ((wp_postmeta.meta_key ...
and you really want it up with thepost_title
and thepost_content
too. Something like this:AND ( ( (wp_posts.post_title LIKE '%test%') OR (wp_posts.post_content LIKE '%test%') OR (wp_postmeta.meta_key = 'keywords' AND CAST(wp_postmeta.meta_value AS CHAR) LIKE '%test%') ) )
WP_Query
won't do that so we have to make it with some filters. Proof of concept:function add_join_wpse_99849($joins) { global $wpdb; return $joins . " INNER JOIN {$wpdb->postmeta} ON ({$wpdb->posts}.ID = {$wpdb->postmeta}.post_id)"; } function alter_search_wpse_99849($search,$qry) { global $wpdb; $add = $wpdb->prepare("({$wpdb->postmeta}.meta_key = 'keywords' AND CAST({$wpdb->postmeta}.meta_value AS CHAR) LIKE '%%%s%%')",$qry->get('s')); $pat = '|\(\((.+)\)\)|'; $search = preg_replace($pat,'(($1 OR '.$add.'))',$search); return $search; } $program_search = 'test'; $args = array( 'post_type' => 'program', 's' => $program_search ); add_filter('posts_join','add_join_wpse_99849'); add_filter('posts_search','alter_search_wpse_99849',1,2); $t = new WP_Query($args); remove_filter('posts_join','add_join_wpse_99849'); remove_filter('posts_search','alter_search_wpse_99849',1,2); // dump some data var_dump($t->request); var_dump($t->posts);
Notice that I left out the
meta_query
altogether and largely duplicated the functionality. That is to keep that troublesomeAND
from being generated.You are applying and immediately removing those filters so they do not interfere with any other queries. There are other ways to keep the filter out of the way or other queries. One such method is outlined here. You can also add the
remove_filter
to theadd_filter
callback to have them automatically remover themselves.-
Pouvez-vousexpliquerpourquoine PAS utiliser query_posts?Can you explain why NOT to use query_posts?
- 0
- 2018-10-12
- Lee
Je cherche unmoyen d'effectuer une rechercheet,lors de la recherche,il vérifie un champpersonnalisénommé "mots-clés",letitre dumessageet le contenu dumessage. Si l'un de ces champs a des résultats comme ce que l'utilisateur recherche,il affichera letype depublicationpersonnalisé (programmes) dans lapage de résultats.
Jen'aipasbesoin d'aidepour le résultat de l'affichagefinal (ilfait actuellement ce queje veux qu'ilfasse),maisje doisfaireen sorte qu'il vérifie lestrois champs (titre de l'article,contenu de l'articleet champpersonnalisé).mots-clés),et si l'un d'entreeux a un résultat similaire à celui recherché,il affiche les résultats. C'est le code quej'aijusqu'àprésent. Ilne recherche actuellement que dans le champpersonnalisé desmots clés: