Skip Navigation

[Resolved] How to programmaticaly get legacy many to many relationship posts

This support ticket is created 6 years 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
- 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 -
- 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 -

Supporter timezone: Asia/Hong_Kong (GMT+08:00)

This topic contains 5 replies, has 2 voices.

Last updated by Luo Yang 6 years ago.

Assisted by: Luo Yang.

Author
Posts
#1168744

Hello,

I have old relationship system (legacy).
Here are the 3 post types :

member, production and production-member (I have X members and Y productions, each members can have many productions, and each productions can have many members).

(I have other same kind of relationships like : member, program and program-member and member, event, event-member)

First of all, I try to use this code :

$posts = toolset_get_related_posts(
	$post,
	['member', 'production-member'],
	'parent'
);

Instead of returning only 'production-member' posts linked to member, the function returns a list of 'production-member', 'program-member' and 'event-member'... strange

Anyway, I filter the results by post_type in a loop and then I try to get the production of the production-member :

// $posts is an array like : [0 => 3096, 1 => 3122, ...]

foreach ($posts as $row)
{
	$tmp_post = get_post($row);

	if ($tmp_post->post_type == 'production-member')
	{
		$productions_posts = toolset_get_related_posts(
			$tmp_post,
			['production-member', 'production'],
			'parent' // tried with child too
		);
	}
}

When I dump $productions_posts, always have an empty array.

Any help much appreciated.
Thanks

WordPress 4.9.8
All Toolset plugins are up to date

#1169390

Hello,

For the legacy post type relationships, you will need to query the intermediary posts first, then use intermediary post's ID to query related posts.

For example:
in a single member post, you can query the related intermediary "production-member" posts, like this:

$production_member_posts = toolset_get_related_posts(
    get_the_ID(),
    ['member', 'production-member'],
    'child' // "production-member" is child post type of member
);

You will be able to get the intermediary "production-member" posts in var "$production_member_posts", and use them to get related "production" posts, like this:

$productions_posts = array();
foreach ($production_member_posts as $production_member_post)
{
        $productions_posts[] = toolset_get_related_posts(
            $production_member_post->ID,
            ['production-member', 'production'],
            'parent' // tried with child too
        );
}

var_dump($productions_posts);

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

#1169644
Screenshot_2018-12-19 Edit Post Type ‹ Elico, équipe de recherche de Lyon en sciences de l'information et de la communicati[...].png

Hello,

I tried your solution/improvement. Unfortunately, it does not work.
A dump of $production_member_posts give me an empty array.
I tried with my other intermediary relations, and the results are the same.

I joined a screenshot of the relations of my member post type page :
/wp-admin/admin.php?page=wpcf-edit-type&wpcf-post-type=membres
(I am french, so I translated membre to member and so on in my first post for comprehension - event->manifestation, program->programme).

For information, I have no problem to query the relation 'member -> production-member -> production' in a Toolset View. For one member, I list the productions of the member easily, his programs and his events...
But I must sort this results by a custom fields, and by a field. I didn't manage to do it.
So I thought it will be easier programmatically.

Thanks

PS: I am in a single member post

#1170250

Please elaborate the new question with more details:
But I must sort this results by a custom fields, and by a field.
How and where do you setup the custom fields? are they in post type "member" or "production-member" or "production"?
If they are in the post type "production", then it is not possible.

Since you are querying "production-member" intermediary posts , but the custom fields are in another post type "production", toolset_get_related_posts() function is using wordpress PHP class WP_Query to query posts, see wordpress document
https://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters
meta_value' - Note that a 'meta_key=keyname' must also be present in the query.
Since there isn't those specific custom fields in "production-member" intermediary posts, you will get the result:
Empty reault

#1170621

Hello,

The post type is in production, so it is not possible to do. That's why I tried to do this programmatically.
After a lot of time passed on this featured, I manage to find a way to get the data I needed (I read the toolset_get_related_posts code in legacy_relationships.php).
But in your first answer, the use of toolset_get_related_posts was not accurate. Perhaps I have problems in my WordPress post types. I can be wrong, but for me, this function is either bugged or lack of functionalities.
Here is the code (commented) :

function get_member_productions()
{
	$post = get_post();

	$field = wpcf_admin_fields_get_field('types-de-productions'); // the custom field I want to order by in first
	$options = $field['data']['options'];

	$types = [];
	$arr = [];

	foreach ($options as $option)
	{
		if (is_array($option))
		{
			$types[] = $option['value'];
			$types[$option['value']] = $option;
		}
	}

	$types_flip = array_flip($types);

	// 1 - If I replace production-membre by another post type slug, the results are the same : all the intermediary post types are returned.
	$myposts = toolset_get_related_posts(
		$post,
		['membres', 'production-membre'],
//		['membres', 'membre-manifestation'],
//		['membres', 'membre-programme'],
		'parent',
		1000,
		0,
		[],
		'post_object',
		'child'
	);

	foreach ($myposts as $tmp_post)
	{
		// 2 - so I must test the post type of the object
		if ($tmp_post->post_type == 'production-membre')
		{
			// 3 - The only solution I found is to query like this the production I want
			$productions_posts = toolset_get_related_posts(
				$tmp_post,
				['production', 'production-membre'],
				'child',
				1,
				0,
				[],
				'post_object',
				'parent'
			);

			$post_production = $productions_posts[0];

			$type_prod = get_post_meta($post_production->ID, 'wpcf-types-de-productions', true);
			$date_pub = get_post_meta($post_production->ID, 'wpcf-date-de-publication', true);
			$entree_bibliographique = get_post_meta($post_production->ID, 'wpcf-entree-bibliographique-complete', true);

			$post_production->date_pub = $date_pub;
			$post_production->type_prod = $type_prod;
			$post_production->entree_bibliographique = $entree_bibliographique;

			$type_prod_num = $types_flip[$type_prod];

			if (!isset($arr[$type_prod_num]))
			{
				$arr[$type_prod_num] = [];
			}

			$arr[$type_prod_num][] = $post_production;
		}
	}

	if (!count($arr))
	{
		return '';
	}

	ksort($arr);

	foreach ($arr as $k => $v)
	{
		if (count($v) == 1)
		{
			continue;
		}

		$date_pub = array_column($v, 'date_pub');

		array_multisort($date_pub, SORT_DESC, $v);

		$arr[$k] = $v;
	}

	$str = '<div><h2>Production(s) scientifique(s)</h2>';

	foreach ($arr as $type_prod => $post_productions)
	{

		$str .= '
			<div class="production-items">
				<div class="production-type">' . $post_production->type_prod . '</div>';

		foreach ($post_productions as $i => $post_production)
		{
			$str .= '
				<div class="production-item">
					<div class="production-entree-biblio">' . $post_production->entree_bibliographique . '</div>
				</div>';
		}
		$str .= '</div>';

	}

	$str .= '</div>';

	return $str;
}

Do you think the new relationship in Toolset can solve my problem ? Do I have to run the migration process ?

Thanks for your answers.

#1170819

Yes, in the new post type relationship of Types plugin, you can query "Product" posts, filter by the "many-to-many" relationships, and order the result by fields of "Product" post.

See our document:
https://toolset.com/documentation/post-relationships/how-to-display-related-posts-with-toolset/#displaying-many-related-items

I think you can do the migration, and you need to backup your website first.

If there is any new problem, new ticket please. thanks