Skip Navigation

[Resolved] Filtering View Based on Relationship with Two Parents

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

Problem: I would like to filter a View using two one-to-many relationships, but I am only able to add one relationship filter using the GUI. I would like to be able to pass both parent post filter values into the View using shortcode attributes.

Solution: Use the wpv_filter_query API to apply multiple toolset relationships filters, and use any arbitrary shortcode attributes to pass values into the View.

add_filter( 'wpv_filter_query', 'query_two_rels_by_shortcode_atts',99,3 );
function query_two_rels_by_shortcode_atts( $query_args, $views_settings, $view_id) {
  global $WP_Views;
  $view_ids = array( 498 );
  
  if (in_array($view_id, $view_ids)){
    $shortcode_atts = array('childid'=>0, 'courseid'=>0);
    $viewSlug = get_post_field('post_name', $view_id);
    foreach($WP_Views->view_shortcode_attributes as $atts) {
      if($atts['name'] == $viewSlug) {
        $shortcode_atts = $atts;
        break;
      }
    }
    $child_id = $shortcode_atts['childid'];
    $course_id = $shortcode_atts['courseid'];
    $query_args['toolset_relationships'] = array(
      array(
        'role' => 'child',
        'related_to' => $child_id,
        'relationship' => 'household-child_household-enrollment',
      ),
      array(
        'role' => 'child',
        'related_to' => $course_id,
        'relationship' => 'household-course_household-enrollment',
      ),
    );
  }
  return $query_args;
}

Relevant Documentation:
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/how-to-migrate-your-site-to-new-post-relationships/
https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query

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
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 15 replies, has 3 voices.

Last updated by Beda 6 years, 2 months ago.

Assisted by: Christian Cox.

Author
Posts
#914250

I need to filter a view to show any posts that have two parents - in this specific example it is one enrollment (the child) for every course and term combination (the parents). I thought this functionality was being added to the latest release of Views but it still seems to only allow filtering based on a single relationship. Can you tell me how to do this using the current release of Views? The link below was all I could find and it was for the previous release:

https://toolset.com/forums/topic/view-list-of-children-based-on-two-or-more-parents/

Thanks.

- Aaron

#914468

Hi, this functionality wasn't built into the GUI yet, but depending on the filter type you may be able to use the new Post Relationships API together with wpv_filter_query or wpv_filter_query_post_process. The toolset_get_related_post API can be used to determine if any post has a parent in a specific relationship:
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_post

You can combine that API with the Views filter wpv_filter_query_post_process to loop over the View results and drop any results without both parents.
https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query_post_process

Can you explain the filter a bit more? Are you testing if the Enrollment post has specific parents, or only if the Enrollment has parents in both post types? Is this a custom search View where the User can choose those filters, or are the filters predefined based on something else?

#914721

Hi Christian,

The view is nested inside another view, not that that matters, and I'd like it to have two filters on it:

1) in the household-child_household-enrollment relationship as related item of the post ID set by the shortcode attribute "childid"
2) in the household-course_household-enrollment relationship as related item of the post ID set by the shortcode attribute "courseid"

Right now I can only have one of the two. Does that help clarify? Thanks.

- Aaron

#914908

Okay yes, it's possible. Here's how I would set this up:
- Remove any post relationship Query Filters you may have applied to the View.
- Add the following code to functions.php:

add_filter( 'wpv_filter_query', 'query_two_rels_by_shortcode_atts',99,3 );
function query_two_rels_by_shortcode_atts( $query_args, $views_settings, $view_id) {
  global $WP_Views;
  $view_ids = array( 12345 );

  if (in_array($view_id, $view_ids)){
    $shortcode_atts = $WP_Views->view_shortcode_attributes[0];
    $child_id = $shortcode_atts['childid'];
    $course_id = $shortcode_atts['courseid'];
    $query_args['toolset_relationships'] = array(
      array(
        'role' => 'child',
        'related_to' => $child_id,
        'relationship' => 'household-child_household-enrollment',
      ),
      array(
        'role' => 'child',
        'related_to' => $course_id,
        'relationship' => 'household-course_household-enrollment',
      ),
    );
  }
  return $query_args;
}

Replace 12345 with the numeric ID of this View.

#917089

Sorry, I have not yet had a chance to try this out since I was at an event all week launching the site. I'll take a look in the morning. Thanks.

- Aaron

#917423

Thanks for that. When running that code it throws the following two error messages:

PHP Notice: Undefined index: courseid in /home/aaronmckeon/public_html/wp-content/plugins/code-snippets/php/snippet-ops.php(352) : eval()'d code on line 13

Line 13: $course_id = $shortcode_atts['courseid'];

PHP Fatal error: Uncaught InvalidArgumentException: Invalid relationship query argument. in /home/aaronmckeon/public_html/wp-content/plugins/wp-views/vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/m2m.php:269

However, I can see here below that the courseid is indeed being passed to the view:

[wpv-layout-start]
	[wpv-items-found]
	<!-- wpv-loop-start -->
		<wpv-loop>
          	[wpv-view name="view-household-transcript-03-enrollments" courseid="[wpv-post-id]" childid="[wpv-attribute name="childid"]"]
		</wpv-loop>
	<!-- wpv-loop-end -->
	[/wpv-items-found]
	[wpv-no-items-found]<tr><td colspan="4">The student was not enrolled in any courses during this term.</td></tr>[/wpv-no-items-found]
[wpv-layout-end]
#917501

Okay let's confirm that the childid and courseid are what you expect in this context, and replace the nested double quotes with single quotes like this:

Child ID: [wpv-attribute name='childid']<br />
Course ID: [wpv-post-id]<br />
[wpv-view name="view-household-transcript-03-enrollments" courseid="[wpv-post-id]" childid="[wpv-attribute name='childid']"]
#917509

Thanks. Oddly enough, it was passing the courseid correctly but not the childid. I fixed that (now both attributes are passing correctly) and I get the following messages:

PHP Notice: Undefined index: courseid in /home/aaronmckeon/public_html/wp-content/plugins/code-snippets/php/snippet-ops.php(352) : eval()'d code on line 13

PHP Fatal error: Uncaught InvalidArgumentException: Invalid relationship query argument. in /home/aaronmckeon/public_html/wp-content/plugins/wp-views/vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/m2m.php:269

#917511
temp.jpg

Attaching screenshot - took the debug info down since the site is live now.

#917616

I'm still seeing nested double quotes around the childid attribute of the wpv-attribute shortcode here:
/wp-admin/admin.php?page=views-editor&view_id=497

[wpv-view name="view-household-transcript-03-enrollments" courseid="[wpv-post-id]" childid="[wpv-attribute name="childid"]"]

If you were testing with nested double quotes, please test with nested single quotes instead like this:

[wpv-view name="view-household-transcript-03-enrollments" courseid="[wpv-post-id]" childid="[wpv-attribute name='childid']"]

If this still does not work, please tell me how the View "view-household-transcript-01-terms" is added to the page, and where I would go to see it on the site. Perhaps there is a nested View configuration issue I am misunderstanding.

#918454

Still getting the same errors (pasted at bottom of message). To answer your question on how the nesting works, along with passing of attributes:

1) "view-household-transcript-01-terms" is added to the page via "layout-household-transcripts" using the following code:

<p>[wpv-view name="view-household-transcript-01-terms" householdid="[be_get_parent_id postid='[wpv-post-id item="@household-child_household-transcript.parent"]' parent='household']" childid="[wpv-post-id item="@household-child_household-transcript.parent"]" startdate="[types field='household-transcript-start-date' output='raw'][/types]" enddate="[types field='household-transcript-end-date' output='raw'][/types]"]</p>

For reference, [be_get_parent_id] functions as follows:

function be_get_parent_id($atts){
  
  	//Get current post object and ID
    global $post;
    $post_id_current = $post->ID;
  
  	$a = shortcode_atts( array(
	  	'postid' => $post_id_current,
        'parent' => '',
    ), $atts );

	//get post type
	$post_id_current = $a['postid'];
  	$post_type_current = get_post_type($post_id_current);
  
  	//The Post relationship slug to check - NOTE THE NEW SYNTAX WITH - HERE
    $relationship_to_query = $a['parent']."-".$post_type_current;
   
    //Set the role the other post type has:
    $role = "parent";
   
	//Get related posts with new API, if none, it'll return 0, if any, the ID (hence not 0)
    // try legacy method
    $related_post = toolset_get_related_post( $post_id_current, array($a['parent'], $post_type_current), $role);
    if (! $related_post ){
        $related_post = toolset_get_related_post( $post_id_current, $relationship_to_query, $role);
    }
    return $related_post;
 
}

2) "View-Household-Transcript-02-Courses" is added as follows:

[wpv-view name="view-household-transcript-02-courses" termid="[wpv-post-id]" childid="[wpv-attribute name="childid"]"]

3) "view-household-transcript-03-enrollments" is added as follows:

[wpv-view name="view-household-transcript-03-enrollments" courseid="[wpv-post-id]" childid="[wpv-attribute name='childid']"]

PHP Notice: Undefined index: courseid in .../public_html/wp-content/plugins/code-snippets/php/snippet-ops.php(352) : eval()'d code on line 13

PHP Fatal error: Uncaught InvalidArgumentException: Invalid relationship query argument. in .../public_html/wp-content/plugins/wp-views/vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/m2m.php:269

Stack trace:
#0 /home/aaronmckeon/public_html/wp-content/plugins/wp-views/vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/m2m.php(131): Toolset_Wp_Query_Adjustments_M2m->get_post(Array)
#1 /home/aaronmckeon/public_html/wp-content/plugins/wp-views/vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/m2m.php(116): Toolset_Wp_Query_Adjustments_M2m->add_single_relationship_query_where_clause(Array, Object(WP_Query))
#2 /home/aaronmckeon/public_html/wp-content/plugins/wp-views/vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/m2m.php(81): Toolset_Wp_Query_Adjustments_M2m->add_relationship_query_where(' AND wpsv_posts...', Array, Object(WP_Query))
#3 /home/aaronmckeon/public_html/wp-includes/class-wp-hook.php(286): Toolset_Wp_Query_Adjustments_M2m->posts_where(' in /home/aaronmckeon/public_html/wp-content/plugins/wp-views/vendor/toolset/toolset-common/inc/autoloaded/wp_query_adjustments/m2m.php on line 269

#918455

PS - Just updated the quotes around childid in view 02 to single quotes with no effect.

#918820

Okay yes, there some nesting I wasn't fully grasping. Here is an update that will fix the missing courseid error:

add_filter( 'wpv_filter_query', 'query_two_rels_by_shortcode_atts',99,3 );
function query_two_rels_by_shortcode_atts( $query_args, $views_settings, $view_id) {
  global $WP_Views;
  $view_ids = array( 498 );
 
  if (in_array($view_id, $view_ids)){
	$shortcode_atts = array('childid'=>0, 'courseid'=>0);
	$viewSlug = get_post_field('post_name', $view_id);
	foreach($WP_Views->view_shortcode_attributes as $atts) {
	  if($atts['name'] == $viewSlug) {
		$shortcode_atts = $atts;
		break;
	  }
	}
    $child_id = $shortcode_atts['childid'];
    $course_id = $shortcode_atts['courseid'];
    $query_args['toolset_relationships'] = array(
      array(
        'role' => 'child',
        'related_to' => $child_id,
        'relationship' => 'household-child_household-enrollment',
      ),
      array(
        'role' => 'child',
        'related_to' => $course_id,
        'relationship' => 'household-course_household-enrollment',
      ),
    );
  }
  return $query_args;
}

However, I'm running into a bug now, where hard-coded database prefixes are causing failures in some relationship queries:
https://toolset.com/forums/topic/new-wp_query-toolset_relationships-argument-is-not-returning-results/#post-914586

Our developers have a hotfix planned for this in Types 3.0.2, tentatively planned for tomorrow, so I'm marking this ticket as "fixed in next release."

#922257

Hi, please find Types 3.0.2 available for download or automatic update. Install the latest version and apply the code I mentioned in the last reply, then let me know if the problem is not fully resolved.

#922603

Hi Christian,

I checked to make sure I have the most recent version and I re-ran the view with that code activated and no more error message is being thrown. Thanks for the help.

- Aaron