web-dev-qa-db-fra.com

Extension de la recherche sur le site pour inclure un seul champ personnalisé

J'ai le code suivant dans mon fichier functions.php

function __adapted_search_function($search, $query) {
  if(is_admin() || !$query->is_main_query() || !$query->is_search)
    return; //determine if we are modifying the right query

  global $wpdb;
  $search_term = $query->get('s');
  $search = ' AND (';

  //point 1
  $search .= "($wpdb->posts.post_title LIKE '%$search_term%')";

  //need to add an OR between search conditions
  $search .= " OR ";

  //point 2
  $search .= "($wpdb->posts.post_excerpt LIKE '%$search_term%')";

  //need to add an OR between search conditions
  $search .= " OR ";

  //point 3
  $search .= "($wpdb->postmeta.meta_key = 'mcb-product' AND $wpdb->postmeta.meta_value LIKE '%$search_term%')";

  //add the filter to join, sql will error out without joining the tables to the query
  add_filter('posts_join', '__custom_join_tables');   


  return $search . ') ';
}

function __custom_join_tables($joins) {
  global $wpdb;
  $joins = "JOIN $wpdb->postmeta ON ($wpdb->postmeta.post_ID = $wpdb->posts.ID)";
  return $joins;
}

J'espérais que seul le titre, l'extrait et un seul champ personnalisé seraient recherchés.

Cela fonctionne si je supprime la jointure mais que je dois vraiment garder cela inclus. Est-ce que quelqu'un peut voir où je me suis trompé?

1
Brob

J'ai réussi à résoudre en étendant la requête

function extend_search( $search, &$wp_query ) {
    global $wpdb;

    if ( empty( $search ))
        return $search;

    $terms = $wp_query->query_vars[ 's' ];
    $exploded = explode( ' ', $terms );
    if( $exploded === FALSE || count( $exploded ) == 0 )
        $exploded = array( 0 => $terms );

    $search = '';
    foreach( $exploded as $tag ) {
        $search .= " AND (
            ($wpdb->posts.post_title LIKE '%$tag%')
            OR ($wpdb->posts.post_excerpt LIKE '%$tag%')
            OR EXISTS
            (
                SELECT * FROM $wpdb->postmeta
                WHERE post_ID = pl_posts.ID
                    AND meta_key = '--KEY--'
                    AND meta_value LIKE '%$tag%'
            )

        )";
    }

    return $search;
}
2
Brob

pre_get_posts ne prend qu'un paramètre, mais vous semblez l'utiliser comme s'il s'agissait de posts_where. Ce n'est pas vraiment que pre_get_posts fonctionne. Vous devez modifier l'objet $query qui y est passé, non pas construire et renvoyer une clause SQL.

Ce n’est pas possible pour moi de le tester facilement, mais je pense que le hook que vous voulez utiliser est soit le filtre posts_where, soit le filtre posts_search qui a le plus de sens.

add_action('posts_where', '__adapted_search_function',1,2);

Ou

add_action('posts_search', '__adapted_search_function',1,2);

Vous devrez peut-être modifier le code, mais il est essentiel de changer le crochet que vous utilisez.

0
s_ha_dum