Skip Navigation

[Resolved] View only query posts that have children

This thread is resolved. Here is a description of the problem and solution.

Problem: I am using a View of child posts nested inside a View of parent posts to display parent and child post information. I would like to filter out parents that do not have any children.

Solution: There is no built-in way to filter out childless parent posts, so the solution requires custom code. Another ticket in the forum discusses this approach:
https://toolset.com/forums/topic/table-with-child-posts

add_filter('wpv_filter_query', 'jobs_with_bewerbungs_func', 101, 3);
function jobs_with_bewerbungs_func($query, $view_settings, $view_id) {
  $views = array( 84 );
  $relationship_slug = 'job-bewerbung-multis';
  $parent_type_slug = 'job';
  // you should not edit anything below this line
  if ( in_array( $view_id, $views ) ) {
    $ids = array();
    $parents_args = array(
      'post_type' => $parent_type_slug,
      'numberposts' => -1,
    );
    $parents = get_posts( $parents_args );
    foreach($parents as $parent) {
      $children = toolset_get_related_posts(
        $parent->ID,
        $relationship_slug,
        'parent',
        1000000,
        0,
        array(),
        'post_id',
        'child'
      );
      if( !is_array($children) || count($children) < 1 ) {
        array_push( $ids, $parent->ID );
      }
    }
    $query['post__not_in'] = isset($query['post__not_in']) ? $query['post__not_in'] : array();
    $query['post__not_in'] = array_merge($query['post__not_in'], $ids );
  }
  return $query;
}

Relevant Documentation:
https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts

This support ticket is created 5 years, 12 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 2 replies, has 2 voices.

Last updated by bobA-2 5 years, 12 months ago.

Assisted by: Christian Cox.

Author
Posts
#1174504

Say I have a Post type called Movies and Post type called Showings with a One To Many relationship.

I make a view and in the loop section I call a nested view which has showing information for relationship current post in the loop.

But what if I some movies does not have showings data yet and I want to see only Movies that have. So basically I only want to query Movie posts that actually have children posts (Showings). How do I do that? I found old post about this I think with the code below. But I guess that is for old Views relationship and will not work with the new right?

add_filter('wpv_filter_query', 'parent_has_childs_func', 101, 3);
 
function parent_has_childs_func($query, $view_settings, $view_id) {
if ( $view_id == 'ID OF THE VIEW' ) {
  global $wpdb;
  $ids = $wpdb->get_results( "SELECT meta_value FROM wp_postmeta WHERE meta_key = '_wpcf_belongs_city_id'" );
  $query['post__in'] = array($ids);
}
return $query;
}
#1174840

Hi, you are correct that this code should be used with legacy post relationships only. For migrated or new relationships, you should use the new post relationships API to determine which parent posts have no children, and exclude those parent posts from the query with post__not_in. I helped on another ticket that does something similar:
https://toolset.com/forums/topic/table-with-child-posts

You'll edit the View ID to be the ID of the View that shows parent posts, you'll edit the relationship slug, and you'll change the parent post type slug to match your site's content. You can also change the function name (in both places) if you'd like. Then add this code to your child theme's functions.php file, or to a new custom code snippet in Toolset > Settings > Custom code:

add_filter('wpv_filter_query', 'jobs_with_bewerbungs_func', 101, 3);
function jobs_with_bewerbungs_func($query, $view_settings, $view_id) {
  $views = array( 84 );
  $relationship_slug = 'job-bewerbung-multis';
  $parent_type_slug = 'job';
  // you should not edit anything below this line
  if ( in_array( $view_id, $views ) ) {
    $ids = array();
    $parents_args = array(
      'post_type' => $parent_type_slug,
      'numberposts' => -1,
    );
    $parents = get_posts( $parents_args );
    foreach($parents as $parent) {
      $children = toolset_get_related_posts(
        $parent->ID,
        $relationship_slug,
        'parent',
        1000000,
        0,
        array(),
        'post_id',
        'child'
      );
      if( !is_array($children) || count($children) < 1 ) {
        array_push( $ids, $parent->ID );
      }
    }
    $query['post__not_in'] = isset($query['post__not_in']) ? $query['post__not_in'] : array();
    $query['post__not_in'] = array_merge($query['post__not_in'], $ids );
  }
  return $query;
}
#1175818

My issue is resolved now. Thank you!