Skip Navigation

[Resolved] Query show all children in a relashionship

This support ticket is created 4 years, 1 month 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: Africa/Casablanca (GMT+01:00)

This topic contains 18 replies, has 2 voices.

Last updated by Jamal 4 years, 1 month ago.

Assisted by: Jamal.

Author
Posts
#1779305

Refer to this previous post: https://toolset.com/forums/topic/show-all-posts-that-are-children-of-a-relashionship/
It was not solved. Now a month later I still have no solution...

I am not using Blocks or views. I need my query to work in PHP in functions.php
to recap:
I have parents (oeuvre) linked to cocktail (children) in a one to many relashionship called oeuvre-cocktail.
Now, in my homepage, I want to show the latest cocktails that have been added in this relashionship.
I do not have the ID of parent, since it is in homepage. I want to show cocktail only.
Basically, all cocktails that belong to this relashionship. Or all cocktails that have oeuvre as parent. Or all the children of parents in that relashionship. However you want to look at it, as long as can get the result!

Something like this (obviously not working:)

function my_custom_query10( $query, $widget ) {
$args = array(
'post_type' => 'oeuvre',
'post_status' => 'publish',
'numberposts' => -1,
);

$lescocktailsassocies = toolset_get_related_posts(
$args,
'oeuvre-cocktail ', // relashionship
'parent',
1000000, 0,
array( ),
'post_id',
'child'
);
$query->set( 'post__in', $lescocktailsassocies );
}
add_action( 'elementor/query/maquery10', 'my_custom_query10', 10, 2 );

#1780219

Hello and thank you for contacting the Toolset support.

The following code is not correct:

$args = array(
'post_type' => 'oeuvre',
'post_status' => 'publish',
'numberposts' => -1,
);

$lescocktailsassocies = toolset_get_related_posts(
$args,
'oeuvre-cocktail ', // relashionship
'parent',
1000000, 0,
array( ),
'post_id',
'child'
);

Please check the documentation of toolset_get_related_posts here https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts

The first argument does not accept an associative array such as:

$args = array(
'post_type' => 'oeuvre',
'post_status' => 'publish',
'numberposts' => -1,
);

Even, if you are using the legacy toolset_get_related_posts (legacy) https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts-legacy

Furthermore, you can't use the function if you don't have the list of "Oeuvre" posts. You will have to first query and get the "Oeuvre" posts. Then you can use something like this(assuming your using the latest releases):

// we'll assume we already get the Oeuvre posts in this variable $oeuvres
$lescocktailsassocies = toolset_get_related_posts(
  $oeuvres,
  'oeuvre-cocktail ', 
  array(
    'query_by_role' => 'parent',
    'limit' => 1000000,
    'offset' => 0,
    'role_to_return' => 'child',
    'return' => 'post_id',
  )
);

I hope this helps. Let me know if you have any questions. Can you please paste your Toolset Debug information in the Debug information field? https://toolset.com/faq/provide-debug-information-faster-support/

#1780359

Thank you Jamal, but
// we'll assume we already get the Oeuvre posts in this variable $oeuvres
the point of having array('post_type' => 'oeuvre', etc.
was to query all the oeuvres IDs.
If I cannot get them like this, how do I get them?
I have tried many different scripts and I still cannot get this to work!
I am not legacy, I have latest.

#1780401

You will get the oeuvres posts, or more precisely, their IDs, like this:

$args = array(
  'post_type' => 'oeuvre',
  'post_status' => 'publish',
  'numberposts' => -1,
  'fields' => 'ids'
);
$oeuvres = get_posts($args);

Read more about the get_posts function here https://developer.wordpress.org/reference/functions/get_posts/

Note, that toolset_get_related_posts can also accept a list of posts. You can omit this line "'fields' => 'ids'", but you will have to be aware, that the returned result is an array of WP_Post objects.

I'll remain at your disposal.

#1780407

Plus your code gives me this error:
The query_by_role argument must not be set when passed an array to the $query_by_elements parameter

#1780415

Website crashes when I put this:

$args = array(
'post_type' => 'oeuvre',
'post_status' => 'publish',
'numberposts' => -1,
'fields' => 'ids'
);
$oeuvres = get_posts($args);
$lescocktailsassocies = toolset_get_related_posts(
$oeuvres,
'oeuvre-cocktail',
array(
'query_by_role' => 'parent',
'limit' => 1000000,
'offset' => 0,
'role_to_return' => 'child',
'return' => 'post_id',
)
);
$query->set( 'post__in', $lescocktailsassocies);
}

What is wrong?

#1781353

According to this error The query_by_role argument must not be set when passed an array to the $query_by_elements parameter.
I think, that you should remove this line:

'query_by_role' => 'parent',

I also wonder, from where comes the $query that you are using here:

$query->set( 'post__in', $lescocktailsassocies);
#1781619

Removing the line was the first thing I tried when I saw the error.
Still does not work.

The $query is because this code is being wrapped in a function
As in

function my_custom_query10( $query, $widget ) {
// code here
$query->set( 'post__in', $lescocktailsassocies );
}
add_action( 'elementor/query/maquery10', 'my_custom_query10', 10, 2 );

As a proof of concept, I tried this code:

function my_custom_query9( $query, $widget ) {
$args = array('84','9'); // IDs of cocktails associated to oeuvres
$query->set( 'post__in', $args);
}
add_action( 'elementor/query/maquery9', 'my_custom_query9', 10, 2 );
And this gets the desired result.

Now I have for many more hours to rewrite this code.
This is my last try, which does not work:

function my_custom_allo10($allo_args, $widget) {
$args2 = array( // get the IDs of oeuvre
'post_type' => 'oeuvre',
'post_status' => 'publish',
'numberposts' => -1,
'fields' => 'ids'
);
$lesoeuvresx = get_posts($args2); // get_posts
foreach ( $lesoeuvresx as $uneoeuvre) { // loop to bypass problem with query_by_element
$allo_by_element = $uneoeuvre; // IDs of oeuvres
$relationship = 'oeuvre-cocktail'; // relationship slug
$allo_by_role_name = 'parent'; // $allo_by_element is a parent in this relation
$limit = 999999; // defaults
$offset = 0; // defaults
$args = array();
$return = 'post_id'; // We want Post ID
$role_name_to_return = 'child'; // We want childs as result

$get_results = toolset_get_related_posts(
$allo_by_element,
$relationship,
$allo_by_role_name,
$limit,
$offset,
$args,
$return,
$role_name_to_return
);
foreach ($get_results as $get_result ) { // add all IDs
$allo_args['post__in'][] = $get_result;
}
} //return $allo_args;
}
add_action( 'elementor/query/allo10', 'my_custom_allo10', 10, 2 );

#1781753

This is not a correct code, you are passing 8 arguments to the function. The function expects only 3 arguments:

$get_results = toolset_get_related_posts(
$allo_by_element,
$relationship,
$allo_by_role_name,
$limit,
$offset,
$args,
$return,
$role_name_to_return
);

Check the documentation of the function https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts

And I do not see why are you looping(foreach) through $lesoeuvresx. Test this code:

$args = array(
	'post_type' => 'oeuvre',
	'post_status' => 'publish',
	'numberposts' => -1,
	'fields' => 'ids'
);

$oeuvres = get_posts($args);

$lescocktailsassocies = toolset_get_related_posts(
	$oeuvres,
	'oeuvre-cocktail',
	array(
		'limit' => 1000000,
		'offset' => 0,
		'role_to_return' => 'child',
		'return' => 'post_id',
	)
);
$query->set( 'post__in', $lescocktailsassocies);

Note that the function took 3 arguments, the third one is an array that contains different parameters.

#1781837

Jamal, thank you for trying, but this code you are suggesting
is almost EXACTLY the one I posted in the September 17, 2020 at 5:13 pm message
and I said it did not work...
I just tried this code
So no, it does not work.

The code I tried with all the arguments, I took from your forum, someone who had a similar problem and this was the working result
https://toolset.com/forums/topic/views-select-posts-in-a-relationship-that-are-related-to-any-of-multiple-values/

toolset_get_related_posts does not seem to be able to take more than one ID, which is why I was trying a loop.
Also, this code gave me no results, but at least it did not make the website crash.

Actually, I found a support ticket dating back to June about this problem... It is September now.
I don't see how I can find a solution?

#1782509

I am running some tests to check this, and I am not able to get the cocktails posts from "toolset_get_related_posts", either by passing an array of oeuvre posts or only one oeuvre post.
I also tried with the WP_Query API to no avail. https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/how-to-migrate-your-site-to-new-post-relationships/#public-functions-for-getting-related-posts

Unfortunately, I could not find an easy workaround. Please, let me approach our 2nd Tier about this and get back to you.

#1785581

I actually found a workaround using the legacy views, using two views, that return the cocktails posts IDs.
Both views use the wpv-item shortcode to add a comma for the returned posts except the latest one. And both views disable the wrapping DIV around the View.
The first view queries the "Oeuvres" post type and includes the second view inside of its loop. The second view queries the "Cocktails" post types that are related to the current post in the loop.
You can then use the view programmatically with the do_shortcode function, and explode the result with the comma separator:

$posts_ids_as_string = do_shortcode("[wpv-view name='get-all-oeuvres-ids-separated-by-comma']");
$cocktails_ids = explode(',', $posts_ids_as_string);

Then you can use the $cocktails array in your Elementor query.

I hope this is a viable workaround for you and will let you continue working on your website. And I'll get back to you as soon as we found the cause for the "toolset_get_related_posts".

#1785597

You can check my workaround in this test site hidden link

Check the views in Toolset->Views. You can see the results on the 3rd container block in the page /test-page/
And if you need to enable this menu on your website, go to Toolset->Settings and enable both editors(blocks and legacy) for your website.

#1786219

As stated in my first message:
"I am not using Blocks or views. I need my query to work in PHP in functions.php"
The entire page is made in Elementor, I do not use the wordpress page editor, nor the block editor.

But I reproduced your views, exactly, of my demo website.
I created a test page.
I put a View of get-all-oeuvres-ids-separated-by-comma
I get 9, 84 (on my demo) which are IDs of cocktails in the relashionship NOT oeuvre. But it is what we want to show in the end.
I put a View of get-all-linked-cocktails-ids-separated-by-comma
I get a list of ALL cocktails in database

If I put your shortcode in Elementor, it does not work, it does not convert to result it just shows the shortcode as text
Like [get-only-related-cocktails-with-wp_query]

So I tried creating a view that gives me just the IDS of oeuvres
get-all-oeuvres-ids-period
and then use it in toolset_get_related_posts

function my_custom_query10( $query, $widget ) {
$posts_ids_as_string = do_shortcode("[wpv-view name='get-all-oeuvres-ids-period']");
$cocktail_id10 = toolset_get_related_posts(
$posts_ids_as_string, // ids of oeuvres
'oeuvre-cocktail', // slug of the post relationship
'parent',
1000000, 0,
array( ),
'post_id',
'child'
);
$query->set( 'post__in', $cocktail_id10);
}
add_action( 'elementor/query/maquery10', 'my_custom_query10', 10, 2 );

It gives 0 results

I tried this:

function my_custom_query11( $query, $widget ) {
$oeuvres_ids2 = array('159','187');
$cocktail_id11 = toolset_get_related_posts(
$oeuvres_ids2, // ids of oeuvres
'oeuvre-cocktail', // slug of the post relationship
'parent',
1000000, 0,
array( ),
'post_id',
'child'
);
$query->set( 'post__in', $cocktail_id11);
}
add_action( 'elementor/query/maquery11', 'my_custom_query11', 10, 2 );

It gives no results

I tried this:

function my_custom_query10( $query, $widget ) {
$posts_ids_as_string = do_shortcode("[wpv-view name='get-all-oeuvres-ids-separated-by-comma']");
$cocktails_ids = explode(',', $posts_ids_as_string);

$query->set( 'post__in', $cocktails_ids);
}
add_action( 'elementor/query/maquery10', 'my_custom_query10', 10, 2 );

Does not work

The only thing that works is if I enter it by hand
$args = array('84','9');
$query->set( 'post__in', $args);
-> This gives desired result

#1787625

Our 2nd Tier has helped figure out the issue with the code I provided. I was putting "$oeuvre" as the first argument, and this will make the "toolset_get_related_posts" return the posts that are connected to ALL the $oeuvres instead of those connected to ANY of the $oeuvres.

If we use the following code, we will be able to get the IDs of the cocktails that are linked to any Oeuvre:

$oeuvres = get_posts( array(
        'post_type' => 'oeuvre',
        'numberposts'   => -1,
        'post_status'   => 'publish',
        'fields'    => 'ids'
    ) );

    $cocktails = toolset_get_related_posts( 
        array( 'parent' => $oeuvres ),
        'oeuvre-cocktail',
        array(
            'return' => 'post_object',
            'role_to_return' => 'child'
        )
    );

    $ids = wp_list_pluck( $cocktails, 'ID' );

Then you can put the $ids in the elementor query argument object:

$query->set( 'post__in', $ids);

Please test it on your website and let us know if it helped.