Consulta pre_get_posts avançada ou não tão avançada

Gostaria apenas de mostrar posts que tenham filhos “agora e futuros” usando o gancho de ação pre_get_posts . Alguém tem uma idéia de como conseguir isso?

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

Todos os events com parent_id 0 devem mostrar, mas devem excluir events que não tenham events infantis relacionados a ele.

Exemplo:

  • Evento 1 tem 5 filhos. (include)
  • O evento 2 não tem filhos. (excluir)
  • O evento 3 tem 2 filhos. (include)
  • O evento 4 tem 1 filho. (include)
  • Evento 5 não tem filhos. (excluir)

Ainda não encontrei nada útil, mas continuarei buscando soluções.

Obrigado por todas as respostas.

Solutions Collecting From Web of "Consulta pre_get_posts avançada ou não tão avançada"

Antes de alterar a $query primeiro, temos que descobrir quais postagens para excluir, que requer duas consultas (se eu posso pensar em uma maneira de fazê-lo em uma, eu atualizarei a resposta).

O primeiro irá pegar uma lista de identificação distinta de todos os events pai, por exemplo –

 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 

O próximo irá pegar o ID de todos os events de nível superior que não têm filhos (para aqueles que não estão na lista que geramos com a consulta anterior), por exemplo –

 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) 

Finalmente, podemos configurar a consulta $ conforme necessário –

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

Aqui está o código completo –

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