it-swarm.com.de

Die benutzerdefinierte Suche nach benutzerdefinierten Post-Metas mit pre_get_posts stört WP Suche

Ich führe mit der Funktion pre_get_posts in meiner Divi Child Theme Functions.php-Datei eine benutzerdefinierte Post-Metasuche durch. Das Problem ist, dass die letzte Abfrage nicht nur die Ergebnisse für mein benutzerdefiniertes Post-Feld (mit dem Namen 'autor') sammelt, sondern auch andere Felder wie 'post_title' und 'post_post', die ich nicht angegeben habe.

Das ist die resultierende Abfrage, bei der die problematische Zeile stark hervorgehoben ist:

SELECT SQL_CALC_FOUND_ROWS ebj_posts.ID FROM ebj_posts INNER JOIN ebj_term_relationships ON (ebj_posts.ID = ebj_term_relationships.object_id) INNER JOIN ebj_postmeta ON (ebj_posts.ID = ebj_postid.mta = 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' AND CAST (mt1.meta_value AS CHAR) WIE '% Abulafia%'))) AND ebj_posts.post_type IN ('post', 'page' , 'attachment', 'project', 'ref_bib') AND ((ebj_posts.post_status = 'publish')) GROUP BY ebj_posts.ID ORDER BY ebj_postmeta.meta_value ASC LIMIT 0, 30 "

Wie Sie sehen können, wird das Wort 'Abulafia' in den Feldern post_title und post_content gesucht, was nicht beabsichtigt ist.

Diese fett gedruckte Zeile mit den AND-Argumenten stammt aus der Abfragezeile 2196 von WP> wp-includes>:

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

denn wenn ich diese zeile im wordpress core code kommentiere verschwindet das problem.

Das ist mein Code in 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
}

Vielen Dank!

1
Xavier Caliz

Erstellen Sie einen weiteren Filter, um den Beitragstitel und den Beitragsinhalt zu entfernen. Entfernen Sie Suchbegriffe. Versuchen Sie dies, wenn dies für Sie hilfreich ist

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

Gelöst!

Als Antwort auf @tomjnowell: Yep! Sie haben Recht, ich gebe nicht genug Details und Kontext, tut mir leid. Ich bin es nicht gewohnt, hier Fragen zu stellen, und Englisch ist auch nicht meine Muttersprache, wie Sie sehen können. Also danke, dass du so geduldig bist und mir hilfst.

Was ich wollte

Ich wollte eine Suche nach mehreren Post-Metas und optional nach ALLEN Post-Metas sowie nach dem Post_Titel in einem benutzerdefinierten Post-Typ namens ref_bib durchführen.

Sie können das Geschehen auf dieser Seite über die Familie Borgia sehen (hauptsächlich auf Katalanisch).

Wie Sie sehen werden, gibt es anfangs mehrere Formulare: das erste, das eine allgemeine Suche durchführt (in benutzerdefiniertem Post-Meta und Post_Titel), und vier weitere für die restlichen Optionen (ja, Sie haben Recht: Es kann vereinfacht werden. Ich werde es tun tun).

Eigentlich dank user5200704 habe ich hier und da recherchiert und endlich etwas gefunden, das für mich ganz gut funktioniert (wenn auch nicht in totaler und berauschender Fröhlichkeit, wie ich es wahrscheinlich in einer anderen Frage erklären werde).

Was ich habe

Falls jemand interessiert ist, hier ist der Code.

Das ist das Suchformular (es gibt eines für jedes Post-Meta in der ersten Version des Codes, später verwende ich ein Dropdown-Menü, um es sexier zu machen):

<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>

Und jetzt der Code in "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
}

Durch diesen Filter wird die where-Klausel geändert, um die Suche nach post_title hinzuzufügen, falls der Benutzer eine allgemeine Suche durchführen möchte, die ALLE benutzerdefinierten Metas UND post_title enthält.

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;
 }

Hoffe das kann jemandem weiterhelfen und danke nochmals an @tomjnewell, @Joel und @ user5200704

1
Xavier Caliz

Der Parameter für die Meta-Abfrage lautet meta_key, nicht nur key (gemäß https://codex.wordpress.org/Class_Reference/WP_Query ).

Versuchen Sie 'meta_key' => 'autor' anstelle von 'key' => 'autor'

0
Joel