Skip Navigation

[Resolved] wpv_filter_query Filter by post relationship

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

Last updated by davidS-53 5 years, 10 months ago.

Assisted by: Nigel.

Author
Posts
#1196430

I have post types Boat and Drill. I've got a one-many relationship set for them. I have a view set up to list out all drills. I want to filter the list of drills to only be the drills related to a specific boatid.

Here's my current code- how can I add the boat-drill relationship filter to the query?

add_filter( 'wpv_filter_query', 'func_related_drills', 10, 3 );
function func_related_drills( $query_args, $view_settings, $view_id ) {

$boatid = 1234;

if($view_settings['view_id'] == 2781){

$query_args['meta_query'][] = array(
// How do I add the boat-drill relationship filter here?
);

}

return $query_args;

}

And yes, I know I could do it by creating a filter but having a shortcode parameter (eg. [wpv-view name="view-name" wpvrelatedto="123"]) breaks the view in this case. (I'm using it to populate a generic select field- hence the complexity.)

Thanks in advance!

#1196506

Nigel
Supporter

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

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

Screenshot 2019-02-06 at 07.44.10.png

Hi David

Before going down the code route, from your description it sounds like you want the View to return posts which are related to a known, specific post ($boatid = 1234), rather than, say, the boat where the View is displayed.

You can do that in the View settings.

See in my screenshot where I'm adding a Query Filter for a relationship, and I am specifying a specific post that is the starting point for find related posts. (In my example the relationship is between left and right posts, and I'm finding right posts related to the single post "left hand".)

#1197059

Hi Nigel,

That isn't going to work sorry- in this case I need to filter it via the query args.

The $boatid is actually dynamic- I've just used 1234 as an example.

Cheers.

#1197193

Nigel
Supporter

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

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

OK, you must be getting that $boatid from somewhere and I would have thought you could then pass it as a shortcode attribute for example and still handle it within Views without recourse to the API, but you know your scenario better than I.

Views queries are built on top of standard WP Queries.

The way relationship filters work is to run a separate relationship query to get all of the related posts according to the filter settings and then add the resulting array of post ID's as a post__in argument to the main query, so you would need to do the same.

Edit your View and delete any relationship Query Filter you added in the GUI.

Here is a very generic example of the kind of thing you will need to implement:

function tssupp_filter_query( $view_args, $view_settings, $view_id )  {
  
  if ( in_array( $view_id, array( 99 ) ) ) {
    
	$children = toolset_get_related_posts(
		$parent_id,
		$relationship_slug,
		array(
			'query_by_role' => 'parent',
			'limit'			=> 999,
			'return'		=> 'post_id',
			'role_to_return'	=> 'child'
		)
	);

	$view_args['post__in'] = $children;
	$view_args['post__not_in'] = null;

  }
  
  return $view_args;
}
add_filter( 'wpv_filter_query', 'tssupp_filter_query', 101, 3 );

Let me know if you have trouble understanding that or implementing it.

#1198052

Thanks Nigel, works a treat.

#1367337

If anyone comes across this in future, here's an example of how to intersect two post relationships:

function sf_filter_training_items( $view_args, $view_settings, $view_id )  {
	 
	if ( in_array( $view_id, array( 11971 ) ) ) {
		
		global $post;

		// Query Boat
		$boat_parent_id = $_COOKIE['boatidcookie'];
		$boat_relationship_slug = 'boat-training-item';

		$posts_boat = toolset_get_related_posts(
				$boat_parent_id,
				$boat_relationship_slug,
				array(
						'query_by_role' => 'parent',
						'limit'         => 999,
						'return'        => 'post_id',
						'role_to_return'    => 'child'
				)
		);

		// Query Crew
		$crew_parent_id = $post->ID;
		$crew_relationship_slug = 'crew-member-training-item';

		$posts_crew = toolset_get_related_posts(
				$crew_parent_id,
				$crew_relationship_slug,
				array(
						'query_by_role' => 'parent',
						'limit'         => 999,
						'return'        => 'post_id',
						'role_to_return'    => 'child'
				)
		);

		// Intersect arrays
		$training_item_ids = array_intersect( $posts_boat, $posts_crew );

		if (empty($training_item_ids)) {
			$view_args['post__in'] = array('0');
		} else {
			$view_args['post__in'] = $training_item_ids;
		}

		$view_args['post__not_in'] = null;
 
	}
	 
	return $view_args;

}
add_filter( 'wpv_filter_query', 'sf_filter_training_items', 101, 3 );