Comme beaucoup, la recherche de WordPress me pose des problèmes dès que je souhaite spécifier des éléments.
Par exemple, faire une recherche uniquement sur un champ ou inclure les custom post type etc.
Pour commencer, comment récupérer la recherche de l’utilisateur
$keyword = "%".sanitize_text_field( $_GET['s'] )."%"; // $_GET['s'] récupère la recherche de l'utilisateur // sanitize_text_field est une fonction de WP qui permet de nettoyer la chaîne de caractère // je rajoute un % de chaque côté de la recherche, car on va utiliser l'opérateur LIKE et je souhaite faire des recherches exacte
Ce qu’on va faire, c’est configuré nos requêtes SQL, récupérer les ids des posts et ensuite utiliser une fonction de WordPress pour récupérer les posts.
$wpdb->get_col ( $wpdb->prepare( "SELECT DISTINCT ID FROM {$wpdb->posts} WHERE post_status = 'publish' AND post_type IN ('post','page') AND post_title LIKE CONVERT(_utf8 '%s' USING utf8) COLLATE utf8_general_ci OR post_content LIKE CONVERT(_utf8 '%s' USING utf8) COLLATE utf8_general_ci", $keyword, $keyword ) );
– $wpdb->get_col : exécute une requête SELECT. Le résultat est un vecteur comprenant un élément par enregistrement pour le champ demandé
– $wpdb->prepare : protection contre les injections SQL pour les requêtes utilisant des paramètres
– DISTINCT permet d’éviter des redondances dans les résultats
– CONVERT(_utf8 ‘%s’ USING utf8) : permet de convertir l’élément de recherche en UTF8
– COLLATE utf8_general_ci : explication sur le site de MySQL (en englais)
– %S : est remplacé par notre variable $keyword (autrement dit : la recherche de l’utilisateur)
Ici, on va récupérer les ID des posts ou des pages uniquement si :
– le contenu est publié
– s’il s’agit d’un post ou d’une page
– que le titre correspond bien au terme de la recherche
– et/ou si le contenu correspond au terme de la recherche lui aussi
Et pour les métas ? c’est la même chose
$wpdb->get_col ( $wpdb->prepare( "SELECT DISTINCT post_id FROM {$wpdb->postmeta} WHERE meta_value LIKE CONVERT(_utf8 '%s' USING utf8) COLLATE utf8_general_ci", $keyword ) );
Du coup, pas besoin d’explication, on fait une recherche dans toutes les valeurs des métas.
$post_ids = array_unique( array_merge( $post_ids_meta, $post_ids_post ) ); // on fusionne les tableaux en 1 // et on supprime les doublons
On arrive à la fin 🙂
Il reste à compter si le tableau $post_ids a des valeurs. Si ce n’est pas le cas, c’est que la recherche ne retourne aucun résultat ^^
$args = array( 'post_type' => array('post', 'page'), 'post_status' => 'publish', 'posts_per_page' => '20', 'post__in' => $post_ids, 'paged' => $paged ); $search_items = new WP_Query( $args );
Je re-précise dans la requête les custom posts type, le status (publish) et je délimite les résultats aux ids de mon tableau.
Il est important de toujours bien préciser ce que l’on souhaite récupérer dans chaque partie du code, cela évite les mauvaises surprises 🙂
Ici je suis certain que si ma requête retourne quelque chose, c’est qu’il s’agit bien d’un post ou d’une page dont l’id se trouve dans le tableau.