Skip Navigation

[Resolved] How to get a single deduplicated list from nested view

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.

Tagged: 

This topic contains 9 replies, has 2 voices.

Last updated by Brad 4 years, 10 months ago.

Assigned support staff: Luo Yang.

Author
Posts
#348480

Hi Luo,

Referring to https://toolset.com/forums/topic/sort-loop-output-of-children-of-the-post-set-by-parent-view/#post-348126 I added the additional unit and officers. See the Little Italy page. Debug output shows that sort_query_func is being called twice. (Once per unit I presume.)

The result was that each of the two units appears to be independently displaying a sorted list of officers.

My objective was to produce a single deduplicated list of officers, not one list per unit. Can I accomplish this with the nested view structure that I am using or will that only be able to produce one list per unit? If the nested view structure isn't the best way to go, is there a query that I could pass to the inner view directly rather than using the outer view?

Thanks.

#348740

Luo Yang
Supporter

Languages: English (English ) Chinese (Simplified) (简体中文 )

Timezone: Asia/Hong_Kong (GMT+08:00)

Dear Brad,

You are right, sort_query_func is being called twice in the Little Italy page, since there are two unit posts connect with this area post: "Test" and "unit 3", each unit post is connect different officer post, we run "sort_query_func ", when display officer post, so the function sort_query_func is being called twice.

In your case, I think it would be better to query the officer posts directly without nested views. you can try manually add filters with Views filter hook wpv_filter_query:
https://toolset.com/documentation/user-guides/views-filters/

Please let me know if you need assistance for it. thanks

#348878

Hi Luo,

Thanks for the pointer. I may also find a use for the nested views but for my current purpose, I'll need something different. It would be nice if in some future version of Views I could set up the hierarchy of queries that I need to make. For now, it looks like PHP time. So yes, please, I could use your help with that.

Below is what I have in mind so far. Please fill in the holes and adjust my thinking as needed. This is in my plugin that you helped me with earlier.

/*
Primary custom post types: Officers, Units, Areas (These are Parent CPTs.)
Intermediary object custom post types: Assignments, Deployments (These are Child CPTs.)

Assignments are children of Officers and Units.
Deployments are children of Units and Areas.

Conceptually, Officers are assigned to Units are deployed to Areas.

I want to create a View (or Views) that will display a deduplicated list of all Officers who are assigned to all Units that are deployed to the Area that is the current post. (If an Officer is assigned to more than one Unit that is deployed to the Area, I want to display the Officer only once, not once per Unit.) In more general terms, this would be how to display a deduplicated list of parents of children of parents of children of the current post.
*/

// make a query to select for the specified area(s)
// deployments that are children of the area
// units that are parents of those areas
// assignments that are children of those units
// officers that are parents of those assignments
// see http://codex.wordpress.org/Class_Reference/WP_Query
// see https://toolset.com/documentation/user-guides/views-filters/wpv_filter_query_post_process/
add_filter( 'wpv_filter_query_post_process', 'cbgetofficers', 10, 3 );
function cbgetofficers( $query, $view_settings, $view_id ) {
	if ($view_id == 5304) { // 5304 is the ID for OfficerListView6 on the dev site
// deployments that are children of the area(s)
		$areas = array("???"); // how to get the id(s) of the current area(s)?
		$args = array(
			'post_type'		=> 'deployment',
			'meta_key'		=> 'area',
			'meta_value'	=> $areas,
			'meta_compare'	=> '=',
		);
		$query1 = new WP_Query( $args ); // these are the child deployments
		
// units that are parents of those areas
		$deployments = array("???"); // how to get the id(s) of the child deployment(s) from $query1?
		$args = array(
			'post_type'		=> 'unit',
			'meta_key'		=> 'deployment',
			'meta_value'	=> $deployments,
			'meta_compare'	=> '=',
		);
		$query2 = new WP_Query( $args ); // these are the parent units
		
// assignments that are children of those units
		$units = array("???"); // how to get the id(s) of the parent units from $query2?
		$args = array(
			'post_type'		=> 'assignment',
			'meta_key'		=> 'unit',
			'meta_value'	=> $units,
			'meta_compare'	=> '=',
		);
		$query3 = new WP_Query( $args ); // these are the child assignments
		
// officers that are parents of those assignments
		$assignments = array("???"); // how to get the id(s) of the child assignment(s) from $query3?
		$args = array(
			'post_type'		=> 'deployment',
			'meta_key'		=> 'area',
			'meta_value'	=> $area,
			'meta_compare'	=> '=',
			'orderby'		=> 'wpcf-numeric_rank',
		);
		$query4 = new WP_Query( $args ); // these are the parent officers
// Do we need to deduplicate the list of officers in $query4?
// if so $query->posts = cbdedupe($query4);
// if not $query->posts = $query4;
		$query->posts = cbdedupe($query4);
	}
	return $query;
}
#348930

Also FYI, I am using the 'Union Park Gardens' Area for testing. I'm getting the Deployments from the initial View, but I'm not seeing where to find the Units that are parents of those Deployments.

I tried echo '<pre>'.print_r($deployments,TRUE).'</pre>' but didn't see anyhting that looked like a Unit ID. Maybe a get_post_meta is needed here?

I'll wait to hear from you before I dig myself in any deeper.

Thanks.

#349130

Luo Yang
Supporter

Languages: English (English ) Chinese (Simplified) (简体中文 )

Timezone: Asia/Hong_Kong (GMT+08:00)

Thanks for the details, since I have the login access of your website in your previous threads, I am trying to log into your website, will feedback if there is any found.

#349302

Thanks, Luo. Your login credentials are unchanged.

I will wait to hear from you before I attempt any further changes.

#349419

Luo Yang
Supporter

Languages: English (English ) Chinese (Simplified) (简体中文 )

Timezone: Asia/Hong_Kong (GMT+08:00)

Thanks for the details, I have add a view "officers of current area" in your test site:
1) hidden link

select officer posts, without any other filters, we use custom PHP codes to filter this view.
order by the "numeric rank" field

2) add below codes in your crimeboard.php:

// https://toolset.com/forums/topic/how-to-get-a-single-deduplicated-list-from-nested-view/
add_filter( 'wpv_filter_query', 'officers_ara_func', 99, 3 );
function officers_ara_func($query_args, $view_settings, $view_id){
	
	if($view_id == 5309){
		$area_ids_arr = array(get_the_ID());
		$unit_ids_arr = get_related_ids($area_ids_arr, $from='area', $to='units', $intermediat = 'deployment');
		$officers_ids_arr = get_related_ids($unit_ids_arr, $from='units', $to='officers', $intermediat = 'assignment');
		$query_args['post__in'] = $officers_ids_arr;
	}
	return $query_args;
}

function get_related_ids($ids=array(), $from='', $to='', $intermediat = ''){
	$to_slug = '_wpcf_belongs_' . $to . '_id';
	$res = array();
	foreach($ids as $v){
		$child_posts = types_child_posts($intermediat, array('post_id' => $v));
		foreach ($child_posts as $child_post) {
		  $res[] = get_post_meta($child_post->ID, $to_slug, true);
		}
	}
	return $res;
}

3) modify the content template for single area post:
hidden link
replace the views shortcode with above view:
[wpv-view name="officers of current area" cached="off"]

Please test again, check if it is what you needed

#349443

Thank you, Luo, that is some nice elegant code. I see how it is supposed to work, but I'm puzzled that the resulting output is not what I expect.

For testing, these are the conditions I used:
Display the Area "Union Park Gardens" using content template "AreaTemplate5" (the one that now includes [wpv-view name="officers of current area" cached="off"]).
Area "Union Park Gardens" has two Units deployed: "Sector 3" and "Test"
Unit "Sector 3" has four Officers assigned: "Nolan, S.", "Oliver, T.", "Vignola, D.", and "Browne, W."
Unit "Test" has two officers assigned: "Browne, W." and "Akil, F."

Ideally, the resulting output of the view "officers of current area" for Union Park Gardens would show five officers (including "Akil, F." but not duplicating "Browne, W."). However, when I display the Union Park Gardens area, I see only four officers. "Akil, F." is missing, so it appears that the "Test" unit was not included.

Could this be some cache issue? See hidden link.

#349452

Luo Yang
Supporter

Languages: English (English ) Chinese (Simplified) (简体中文 )

Timezone: Asia/Hong_Kong (GMT+08:00)

Since the view "officers of current area" is order by the "numeric rank" field, according to wordpress document:
http://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters
Also note that a 'meta_key=keyname' must also be present in the query.

So each of the officer post should set a value in custom field "numeric rank", please try edit the "Akil, F." post, set a value in field "numeric rank", and test again.

#349517

Thank you, Luo, that was exactly the issue. I must have missed setting a value in the "numeric rank" field for officer "Akil, F."

I am grateful for the help that you have provided. I hope that our correspondence on this issue is helpful to others who encounter a similar issue.

My next step will be to explore how I can use CRED to move the data entry to the front end and make sure that any required fields such as "numeric rank" are properly populated. I haven't used CRED yet but this seems like a fitting opportunity to give it a try.

Once again, my sincere thanks for all your help. You have fully resolved this issue.