web-dev-qa-db-fra.com

Une recherche personnalisée de méta de publication personnalisée avec pre_get_posts interfère avec WP chercher

Je fais une méta-recherche personnalisée avec la fonction pre_get_posts dans mon fichier functions.php du thème enfant Divi. Le problème est que la requête finale rassemble non seulement les résultats de mon champ de publication personnalisé (nommé "auteur"), mais également d'autres champs tels que "post_title" et "post_post" que je n'ai pas inclus.

C'est la requête résultante avec la ligne gênante mise en évidence en fort:

Faites la même chose que vous ne le voulez = 1 AND (ebj_term_relationships.term_taxonomy_id IN (456)) AND ((ebj_posts.post_title LIKE '% Abulafia%') OR (ebj_posts.post_content LIKE '% Abulafia%')) AND ebj_postmeta.meta_key = 'autor' AND ((mt1.meta_key = 'autor' ET CAST (mt1.meta_value AS CHAR) LIKE '% Abulafia%'))) ET ebj_posts.post_type IN ('post', 'page', ' pièce jointe ',' projet ',' ref_bib ') ET ((ebj_posts.post_status =' publish ')) GROUP BY ebj_posts.ID ORDER BY ebj_postmeta.meta_value ASC LIMIT 0, 30 "

Comme vous pouvez le voir, le mot 'Abulafia' est recherché dans les champs post_title et post_content , ce qui n'est pas prévu.

Cette ligne en gras avec les arguments AND provient de WP> wp-includes>, ligne de requête 2196:

$search .= $wpdb->prepare( "{$searchand}(($wpdb->posts.post_title $like_op %s) $andor_op ($wpdb->posts.post_content $like_op %s))", $like, $like );

parce que lorsque je commente ces lignes dans le code de base wordpress, le problème disparaît.

C'est mon code dans functions.php:

function filtra_inici( $query ){
global $wp;
if ( ( is_archive() ) && $query->is_main_query() && !is_admin() ) {
  if ($query->is_search && isset($_GET['search-type']) && $_GET['search-type'] == 'autor') {
    $query->set( 'post_type', 'ref_bib');
    $query->set( 'post_status', 'publish');
    $query->set( 'orderby', 'meta_value');
    $query->set( 'meta_key', 'autor' );
    $query->set( 'order', 'ASC' );
    $meta_query = array('relation' => 'AND');
     array_Push( $meta_query, array(
      'key' => 'autor',
      'value' => $query->query_vars['s'],
      'compare' => 'LIKE'
     ));
    $query->set( 'meta_query', $meta_query);
  } 
}// end is_archive
}

Merci!

1
Xavier Caliz

Créez un autre filtre pour supprimer le titre de l'article et le contenu de l'article pour supprimer les termes de recherche essayez ceci si cela vous est utile

add_filter( 'posts_search', 'custom_post_search_author_do', 10, 2 );

function custom_post_search_author_do($search, $query ){
  if(  ! empty($search) 
       && $query->is_main_query() 
       && !is_admin() 
       && isset($_GET['search-type'])
       && $_GET['search-type'] == 'autor'
  )
  $search = '';
  return $search;
}
1
user5200704

Résolu!

En réponse à @tomjnowell: Yep! vous avez raison, je ne donne pas assez de détails ni de contexte, désolé. Je n'ai pas l'habitude de poser de questions ici, et l'anglais n'est pas ma langue maternelle, comme vous pouvez le constater. Alors merci d'être si patient pour m'aider.

Ce que je voulais

Ce que je voulais, c’est faire une recherche par plusieurs posts meta ET, éventuellement, TOUT le post meta PLUS le post_title dans un type de post personnalisé appelé ref_bib.

Vous pouvez voir la chose en action dans ce site à propos de la famille Borgia (principalement en catalan).

Comme vous le remarquerez, il existe initialement plusieurs formulaires: le premier qui permet d'effectuer une recherche générale (dans les messages custom meta et post_title) et quatre autres pour le reste des options (oui, vous avez raison: cela peut être simplifié. faire).

En fait, grâce à user5200704, j'ai fait des recherches ici et là et j'ai enfin trouvé quelque chose qui fonctionne assez bien pour moi (mais pas dans un bonheur total et grisant, comme je l'expliquerai probablement dans une autre question).

Ce que j'ai

Au cas où quelqu'un serait intéressé, voici le code.

C'est le formulaire de recherche (il y en a un pour chaque méta de publication dans la première version du code, plus tard, je vais utiliser un menu déroulant pour le rendre plus sexy):

<form method="get" id="searchform"  class="searchform" action="http://www.elsborja.cat/cat_bib/general/">
<div class="cercadiv">
<input type="text" value="" name="s" id="s" />
<input type="hidden" name="search-type" value="autor" />
<input id="cercabib" class="eb_submit" name="submit" type="submit" value="Cerca" />
</div>
</form>

Et maintenant le code dans "functions.php":

add_filter('pre_get_posts', 'filtra_inici', 10, 2);

function filtra_inici( $query )
{

  global $wp;
  if ( ( is_archive() ) && $query->is_main_query() && !is_admin() ) {

if ( strpos(  $wp->query_vars['category_name'], 'revista-borja' ) !== false ) {
  $query->set( 'orderby', 'date');
  $query->set( 'order', 'ASC' );
}

if (
  $query->is_search
  && isset($_GET['search-type'])
  && $_GET['search-type'] == 'bibliografia'
) {
  $query->set( 'post_status', 'publish');
  $query->set( 'post_type', 'ref_bib');
}

if (
  $query->is_search
  && isset($_GET['search-type'])
  && 'bibliografia' !== $_GET['search-type']
) {

  $camp = $_GET['search-type'];

  if ($camp == 'general') {
    $custom_fields = array('autor', 'publicacio', 'edito', 'observacions');
  }else {
    $custom_fields = array( $camp);
  }

  $searchterm = $query->query_vars['s'];
  // we have to remove the "s" parameter from the query, because it will prevent the posts from being found
  $query->query_vars['s'] = "";
  if ($searchterm != "") {
    $meta_query = array('relation' => 'OR');
    foreach ($custom_fields as $cf) {
      array_Push($meta_query, array(
          'key' => $cf,
          'value' => $searchterm,
          'compare' => 'LIKE'
        ));
    }
    $query->set("meta_query", $meta_query);
    $query->set( 'post_type', 'ref_bib');
    $query->set( 'post_status', 'publish');
  };
}
}// end is_archive
}

Ce filtre modifie la clause where pour ajouter la recherche du post_title au cas où l'utilisateur souhaite effectuer une recherche générale incluant TOUT la méta personnalisée ET le post_title.

add_filter( 'posts_where', 'titol_posts_where', 11, 2 );
function titol_posts_where( $where, &$wp_query )
{
  global $wpdb;
 global $wp;
  if ($_GET['search-type'] == 'general') {
    $where .= ' OR ' . $wpdb->posts . '.post_title LIKE \'' . esc_sql(   $wpdb->esc_like( $_GET['s'] ) ) . '%\'';
 str_replace("LIKE", "", $where);
  }
  return $where;
 }

J'espère que cela pourra être utile à quelqu'un et merci encore à @tomjnewell, @Joel et @ user5200704

1
Xavier Caliz

Le paramètre pour la méta requête est meta_key, pas seulement key (selon https://codex.wordpress.org/Class_Reference/WP_Query )

Essayez 'meta_key' => 'autor' au lieu de 'key' => 'autor'

0
Joel