Erweiterte oder nicht so fortgeschrittene pre_get_posts Abfrage

Ich möchte nur Posts anzeigen , die ” Now and Future” -Kinder mit pre_get_posts Action Hook haben. Hat jemand eine Idee, wie man das erreicht?

function pre_get_posts($query) { if(!is_admin() && $query->is_main_query()) { //check if the query matches this post type if(is_post_type_archive('event')) { $query->set('post_parent', 0); //only show parent posts //should only display posts that have children from now to future } } } 

Alle Ereignisse mit parent_id 0 sollten angezeigt werden, aber es sollten Ereignisse ausgeschlossen werden, mit denen keine untergeordneten Ereignisse verknüpft sind.

Beispiel:

  • Ereignis 1 hat 5 Kinder. (einschließen)
  • Ereignis 2 hat keine Kinder. (ausschließen)
  • Event 3 hat 2 Kinder. (einschließen)
  • Ereignis 4 hat 1 Kind. (einschließen)
  • Ereignis 5 hat keine Kinder. (ausschließen)

Ich habe noch nichts Nützliches gefunden, werde aber weiter nach Lösungen suchen.

Vielen Dank für Ihre Antworten.

Solutions Collecting From Web of "Erweiterte oder nicht so fortgeschrittene pre_get_posts Abfrage"

Bevor wir $query ändern, müssen wir zuerst herausfinden, welche Beiträge ausgeschlossen werden sollen, was zwei Querys erfordert (wenn ich mir einen Weg vorstelle, dies zu tun, werde ich die Antwort aktualisieren).

Der erste wird eine Liste von eindeutigen IDs aller Elternereignisse aufnehmen, zum Beispiel –

 SELECT DISTINCT wp_posts.post_parent FROM wp_posts WHERE wp_posts.post_type = "event" AND wp_posts.post_type = "publish" AND wp_posts.post_parent != 0 

Der nächste wird die ID aller Ereignisse auf höchster Ebene erfassen, die keine Kinder haben (also diejenigen, die nicht in der Liste sind, die wir mit der vorherigen Abfrage erzeugt haben), zum Beispiel –

 SELECT fgw_2_posts.ID FROM wp_posts WHERE wp_posts.post_type = "event" AND wp_posts.post_type = "publish" AND wp_posts.post_parent = 0 AND wp_posts.ID NOT IN (1,2,3) 

Schließlich können wir die $ query wie gewünscht einstellen –

 $query->set('post__not_in', $loners); $query->set('post_parent', 0); 

Hier ist der vollständige Code –

 add_action('pre_get_posts', 'my_exclude_parents_without_children'); function my_exclude_parents_without_children($query){ global $wpdb; if($query->is_main_query() && !is_admin()) : if(is_post_type_archive('event')) : /** First grab the ID's of all post parents */ $my_query = $wpdb->prepare('SELECT DISTINCT %1$s.post_parent FROM %1$s WHERE %1$s.post_type = "event" AND %1$s.post_status = "publish" AND %1$s.post_parent != 0', $wpdb->posts); $parents = $wpdb->get_col($my_query); /** Next grab the ID of all posts who do not have children (we'll call them 'loners') */ $my_query = $wpdb->prepare('SELECT %1$s.ID FROM %1$s WHERE %1$s.post_type = "event" AND %1$s.post_status = "publish" AND %1$s.post_parent = 0', $wpdb->posts, join(',', $parents)); if(!empty($parents)) : // Ensure that there are events with children to exclude from this query $my_query.= $wpdb->prepare(' AND %1$s.ID NOT IN (%2$s)', $wpdb->posts, join(',', $parents)); endif; $loners = $wpdb->get_col($my_query); /** Now exclude the 'loners' */ $query->set('post__not_in', $loners); $query->set('post_parent', 0); endif; endif; }