Skip Navigation

[Resolved] create a view that only displays CPT who have a child

This support ticket is created 6 years, 3 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
- 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 -
- 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 -

Supporter timezone: Europe/London (GMT+00:00)

This topic contains 6 replies, has 2 voices.

Last updated by olivierF 6 years, 3 months ago.

Assisted by: Nigel.

Author
Posts
#1116480
capture.jpg

Hi,

I have two CPT, album (parent) and product (child), I want to create a view that only displays albums who have a child (product). I do not find how to do the query filter in my view ? Can you enlighten me on this point?

Thank you in advance for your help.

Olivier

#1116975

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+00:00)

Hi Olivier

There is no way using a standard View (built upon WP_Query) to filter parent posts by how many child posts they have.

You would need to use a combination of the Toolset APIs to achieve this.

You have a View which queries the parent post type (which may include various filters, such as a taxonomy filter, unrelated to this particular issue).

This will return parent posts whether or not they have child posts.

You would then modify the query results before they are output by the View using the wpv_filter_query_post_process filter.

(hidden link)

You would loop over the query results and for each parent post use the toolset_get_related_posts function to get the child posts. If there were none, you would remove the parent post from the results.

(https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts)

I answered a very similar question about this before and provided some sample code: https://toolset.com/forums/topic/displays-only-posts-with-less-than-3-children/#post-452734

The difference is that this was before Types 3 and was based on Types 2 relationships. So you would need to change the "//get the child posts of the parent" section to use toolset_get_related_posts instead of get_posts.

If you want to try that let me know how you get on, and if you get stuck I'll help (the support queue is very busy at the moment so it may be a while before I can provide such code).

#1117101

Hi Nigel,

I do not quite understand what I have to do.
My problem is similar to this one (https://toolset.com/forums/topic/displays-only-posts-with-less-than -3-children / # post-452734) but in reverse (only shows if there are children) At the moment I have a view that shows all the albums and I would like it to display only albums that has at least child.
The following code seems to be the right track but I do not know how to use it to do the opposite ?
The function would then become "min-post" in place of "max-post"

 
function max_children( $query, $view_settings, $view_id ){
 
    // Edit these
    $my_view_id = 205;
    $my_child_post_type = 'child-post';
    $max_children = 3;
 
    if ( $view_id == $my_view_id && !empty( $query->posts ) ){
 
        foreach ($query->posts as $key => $parent_post) {
 
            // get the child posts of the parent post
            $child_posts_args = array(
                'post_type'     =>   $my_child_post_type,
                'numberofposts' =>   -1,
                'meta_query'    =>   array(
                    array(
                        'key'       =>   '_wpcf_belongs_' . $parent_post->post_type . '_id',
                        'value'     =>   $parent_post->ID
                    )
                )
            );
            $child_posts = get_posts( $child_posts_args );
 
            $number_of_children = count( $child_posts );
 
            if ( $number_of_children >= $max_children ) {
 
                unset( $query->posts[$key] );
                $query->found_posts = $query->found_posts - 1;
                $query->post_count = $query->post_count - 1;
            }
 
        }
 
        $query->posts = array_values( $query->posts );
    }
 
    return $query;
}
add_filter( 'wpv_filter_query_post_process', 'max_children', 1001, 3 );

Thank you for your precious help Nigel

#1117147

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+00:00)

Hi Olivier

I think this is what you need.

<?php
function tssupp_have_children( $query, $view_settings, $view_id ){

    $relationship = 'album-product'; // Edit for relationship slug
    
    if ( in_array( $view_id, array( 99, 123 ) ) && !empty( $query->posts ) ){
  
        foreach ($query->posts as $key => $parent) {
  
            // get the child posts of the parent post
            $children = toolset_get_related_posts(
                $parent->ID,
                $relationship,
                array(
                    'query_by_role'     =>  'parent',
                    'role_to_return'    =>  'child'
                )
            );
  
            $number_of_children = count( $children );
  
            if ( $number_of_children > 0 ) {
  
                unset( $query->posts[$key] );
                $query->found_posts = $query->found_posts - 1;
                $query->post_count = $query->post_count - 1;
            }
  
        }
  
        $query->posts = array_values( $query->posts );
    }
  
    return $query;
}
add_filter( 'wpv_filter_query_post_process', 'tssupp_have_children', 1001, 3 );

I haven't tested it, so please let me know that it works okay.

You should only need to edit the IDs of the Views where this should apply, and the slug of the relationship.

#1118946
capture.jpg

Thank you Nigel,

I need some clarification :
where do I have to encode the ID of the view ?
And I dont know where I can get the slug of the relationship. It seems that I dont use it because I still work on the old toolset plugin method.
I have a page that asks me if I want to do the migration? (see screenshot) Will it not damage my site?
Thanks a lot

Olivier

#1119051

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+00:00)

OK, sorry, if your site is not using Types 3 relationships it is not necessary to migrate, but the code I offered in the last reply needs changing back to use the old method.

So, it would look like:

function tssupp_have_children( $query, $view_settings, $view_id ){

    // Edit these
    $my_view_id = 205;
    $my_child_post_type = 'child-post';
 
    if ( $view_id == $my_view_id && !empty( $query->posts ) ){
   
        foreach ($query->posts as $key => $parent) {
   
            // get the child posts of the parent post
            $child_posts_args = array(
                'post_type'     =>   $my_child_post_type,
                'numberofposts' =>   -1,
                'meta_query'    =>   array(
                    array(
                        'key'       =>   '_wpcf_belongs_' . $parent->post_type . '_id',
                        'value'     =>   $parent->ID
                    )
                )
            );
            $child_posts = get_posts( $child_posts_args );
      
            if ( count( $child_posts ) == 0 ) {
   
                unset( $query->posts[$key] );
                $query->found_posts = $query->found_posts - 1;
                $query->post_count = $query->post_count - 1;
            }
   
        }
   
        $query->posts = array_values( $query->posts );
    }
   
    return $query;
}
add_filter( 'wpv_filter_query_post_process', 'tssupp_have_children', 1001, 3 );

Edit the first couple of lines for the View ID and the child post type slug.

#1122591

My issue is resolved now. Thank you!