Skip Navigation

[Resolved] Filter out child posts of related posts in custom view

This support ticket is created 6 years, 6 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 4 replies, has 2 voices.

Last updated by Nigel 6 years, 6 months ago.

Assisted by: Nigel.

Author
Posts
#953258

I have a custom view that is currently displaying two post types correctly.

However, I need to be able to filter out the "child" posts if a relationship exists between any of the post types.

I have setup a one-to-many relationship between Pages (one) to Products (many).

This means that I may have multiple products connected to 1 page.

I would like to create a view where if any page has a connected product, then that product should NOT be displayed in the results. If no relationship is present for that product, then it should appear in the results.

Is this easy to do?

#953473

I have made progress, but cannot get the following code to work, so I still need help.

I tried writing a custom query, but the code below does not seem to have any effect. I'm not sure what I am doing wrong.

		$query_args = array(
			'meta_query' => array(
				array(
					'key'     => '_wpcf_belongs_auction-page_id',
					'compare' => 'NOT EXISTS',
				)
			),
		);

I tested this query with other parameters and they all take effect (so I know it's working), except the part above.

"auction-page" is the slug of the "parent" that each "product" is connected to.

So if there is a woocommerce product connected to any "auction-page" then I don't want to display the "product" in the results.

Thanks.

#953486

Nigel
Supporter

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

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

Hi Alex

If you have created this relationship with Types 3 (rather than Types 2) then the relationship is stored in a custom database table and is no longer stored as post meta (with the _wpcf_belongs_parent-slud_id key), in which case your meta query outlined above would be ineffective.

We have a new relationships API (https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/), but you are trying to modify the results of a View using wpv_filter_query, is that right?

I can try and help with that, but I need to clarify what you are aiming to do, I wasn't completely sure from your question.

You have a one-2-many relationship between pages and products.

The View in question is listing *both* pages and products, is that right? And you want to exclude products which are connected to a page (any page)?

#953491

Yes, I am using Types 3.

Here is the code I am currently using, which works as intended, but it's simply missing the aforementioned query to filter out the child pages.

add_filter( 'wpv_filter_query', 'hide_closed_auctions' );
function hide_closed_auctions( $query_args ) {
	
	$query_args = array(
		'post_status' => 'publish',
		'posts_per_page' => '100',
		'has_password' => FALSE,
		'orderby' => 'date',
		'post_type'   => array('product','auction-page'),
		'meta_query' => array(
			array(
				'key' => '_auction_closed',
				'compare' => 'NOT EXISTS'
			),
		),
		'tax_query' => array(
			array(
				'taxonomy' => 'product_visibility',
				'field'    => 'name',
				'terms'    => 'exclude-from-catalog',
				'operator' => 'NOT IN',
			),
		),
	);
	
    return $query_args;
}

The results show woocommerce products and a new custom post type called "auction-pages" (created by types).

It is a One to Many relationship between Auction Pages (one) to Products (many).

For example:

Product 1 -> Auction Page A
Product 2 -> Auction Page A

In this example I would like the query to only display Auction Page A, but not show Product 1 or Product 2 in the results since they are connected. If however a product is NOT connected to any Auction Page, then it should appear in the results.

I appreciate your support!

#954492

Nigel
Supporter

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

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

Hi Alex

Because the relationships are stored in custom database tables you cannot simply modify the arguments of an existing View (which is based on WP_Query) to additionally exclude/include related posts.

You must use the Toolset relationships API to establish which posts you want, in this case, to exclude.

(You want to exclude all product posts which have a related auction page.)

You can either expand the code you have above which runs with wpv_filter_query *before* the query occurs.

In that case you would perform another query (a simple get_posts call will suffice) which gets all of the product posts. You then loop over these and use toolset_get_related_post (https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_post) to try and get its parent auction-page. In this way you build a list of post ids to exclude (i.e. products which *do* have a parent).

You can then use that list of ids as a post__not_in argument in the main query (see search section of https://codex.wordpress.org/Class_Reference/WP_Query).

Then the View will only return the required posts.

The alternative would be to use the wpv_filter_query_post_process (https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query_post_process) filter to modify the query results after the query has been run but before they are output by Views.

In that case you have the query results available and you loop over all of the results and, for products, you again use toolset_get_related_post to try and get the parent auction-page. If there is one then you would remove the post from the results (and would also need to decrement found_posts and post_count each time).

The issue is different, but you can see an example of doing something similar—discarding unwanted results from a View—in this thread: https://toolset.com/forums/topic/displays-only-posts-with-less-than-3-children/#post-452734

Maybe take a look at that, and if you try to implement something and get stuck, let me know.