Skip Navigation

[Resolved] toolset_get_related_posts "Order" Parameter Does Not Seem to Work

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

Last updated by Dave 2 years, 8 months ago.

Assisted by: Nigel.

Author
Posts
#2307453

Tell us what you are trying to do?

I'm attempting to return the single, most recently created post of a specific type, related to the current post in the loop.

Is there any documentation that you are following?

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

Using this code:

$tokens = toolset_get_related_posts($child_id, 'child-token', 'parent', 1, 0, array(), 'post_id', 'child', 'null', 'DESC');

But the code always returns the oldest first. There are currently two possible posts it can return for testing purposes, 1449 and 1452, and no matter what I do it will always return 1449 first. If I set the Limit to 2 instead of 1 it gives this:

Array ( [0] => 1449 [1] => 1452 )

Further proving that the Order parameter doesn't seem to be doing anything.

Can someone please advise on why this is happening? The documentation makes no mention of it, but does one of the other parameters need to be set a certain way?

Many thanks.

#2307485

Nigel
Supporter

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

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

Hi Dave

It doesn't look like you've set up the arguments in the correct format (it is a fairly complex API function, so understandable).

Only the first two arguments are passed directly, the remainder are passed within an array, so the structure looks like this:

$related = toolset_get_related_posts(
    $post,
    $relationship_slug,
    array(
        'query_by_role'     => 'parent',
        'role_to_return'    => 'child',
        'orderby'           => 'title',
        'order'             => 'DESC',
        'limit'             => 1
    )
);

The orderby setting only accepts null, title, meta_value, meta_value_num, rfg_order, i.e. there isn't an explicit post_date option, but I think that is what would be used if you set null.

#2307505

Hi Nigel,

Thanks for the quick response.

If that layout is what the documentation was trying to portray then I got absolutely none of that from it, it is very confusing in the way it has been written up and the examples don't really do a good job of illustrating that. The layout I've been using has come from other support threads as it was the only way I could get results out of it, but now I'm guessing that it's only been partially working and the rest is operating on default options as it doesn't understand the parameters outside of an array.

However, this still hasn't got me much further really I'm afraid.

I tried it exactly as you suggested:

$token = toolset_get_related_posts(
    $child_id,
    'child_token',
    array(
        'query_by_role'     => 'parent',
        'role_to_return'    => 'child',
        'orderby'           => 'title',
        'order'             => 'DESC',
        'limit'             => 1
    )
);

and it returns nothing. Now I wasn't sure if you'd written up a full example or were just explaining the layout, so I reworked my code to use the formatting you've highlighted (note: I had to include all options sequentially, as leaving out the args caused it to fail) like so:

$token = toolset_get_related_posts(
    $child_id,
    'child-token',
    array( 
      'query_by_role'	=>	'parent',
      'limit'			=>	1,
      'offset'			=>	0,
      'args'			=>	array(),
      'return'			=>	'post_id',
      'role_to_return'	=>	'child',
      'order_by'		=>	'null',
      'order'			=>	'DESC'
      )
  );

and it's exactly the same. Returns them in ascending order regardless.

Just to confuse things further, I've noticed weird behaviour with another of my uses of 'toolset_get_related_posts', where it doesn't even return them in an order that makes any sense whatsoever!

Here's the original code:

$classes = toolset_get_related_posts( $term, 'term-class', 'parent', 999, 0, array(), 'post_id', 'child' );

and the response it provides:

Array (
     [0] => 1201
     [1] => 1192
     [2] => 1193
     [3] => 1194
     [4] => 1195
     [5] => 1196
     [6] => 1197
     [7] => 1198
     [8] => 1199
     [9] => 1200
     [10] => 1265
)

As you can see, for some bizarre reason it's returned 1201 at the start, out of sequence! This is not the order of post title, post date, or anything to do with the meta data!

If I rework the code into the structure you have mentioned:

$classes = toolset_get_related_posts(
    $term,
    'term-class',
    array( 
      'query_by_role'	=>	'parent',
      'limit'			=>	999,
      'offset'			=>	0,
      'args'			=>	array(),
      'return'			=>	'post_id',
      'role_to_return'	=>	'child',
      )
    );

It again makes zero difference, with or without the order_by and order parameters.

So I can't even tell for sure having the extra parameters in an array is even making a difference at present as this works to return posts with a blank meta_value:

$single_classes = toolset_get_related_posts(
    $term,
    'term-class',
    'parent',
    999,
    0, 
    array(
    	'meta_key'   => 'wpcf-recurring-class-name',
        'meta_value' => '',
        'meta_compare' => '=',
    ),
    'post_id',
    'child'
  );

And as you can see, the parameters are not in an array.

So I'm thoroughly confused as to this behaviour. Any thoughts?

#2307541

Just to clarify, all I'm trying to achieve is having the post ID's in order, newest or highest number first, which surely should be the default behaviour here.

#2307639

Nigel
Supporter

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

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

First, to clarify, you should really use the format I describe. For backwards-compatibility reasons a format without specifying many of the arguments within an array is supported, but it is a brittle implementation that requires all arguments to be provided in exactly the right order. The current implementation is more flexible, in that only the necessary arguments need be passed, and aside from the first $post and $relationship_slug arguments, the rest can be passed in whatever order.

As for the output, I checked on my own site and it seems that null offers de facto sorting by ID or post date, but because it is not specified (it is not null) the order cannot be specified (i.e. ASC or DESC). The results are always in ascending order.

Which means instead of the first result you want the last one, which you can find like so:

$latest_token = end($tokens);

To avoid any possible problems (arising if the results are not actually in correct ascending order) you could instead sort the results, like so:

$rtokens = rsort($tokens);
$latest_token = $rtokens[0];
#2307713

Message 100% received on the formatting of the toolset_get_related_posts queries, so thank you for informing me of this. But you can surely see my point in so much as I'm getting zero difference so it doesn't appear necessary to "over complicate" it and add a lot of additional information to the layout. But I will take this on board moving forward as I dare say the flexibility might be deprecated one day and this will be necessary.

In regards to the output, I knew I could work around the results to manipulate them to what I needed, but this seems like a ridiculous oversight not to allow basic sorting by post ID.

For this work around to be effective, I'm going to have to return EVERY post as I need the one at what is always going to be the bottom of the pile, which in this example may only be two, but could easily grow into thousands, when it should just be returning one to me. This is not only grossly inefficient, it's frankly nonsensical that this is the intended way it should work!

Is there truly no way of making it simply return the most recent / highest post ID that meets it's criteria?

Also, whilst rsort will of course help rearrange the results into a proper order, this doesn't address why on earth it would do this in the first place. You say that null will result in "offers de facto sorting by ID or post date," but this misordering is neither. Yes, this could well be a one off, but it worries me over the integrity of the data handling in the long run as this has not been explained. It seems like the "null" option is being described very vaguely so it is really unclear what this is actually doing. But again, why is post ID not the default option?!

#2308287

Nigel
Supporter

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

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

It's not clear that ordering by post_id is an obvious omission as that can be somewhat arbitrary, but ordering by post_date does seem like something that should be possible.

I've read through the plugin source code and confirm the only available options are to order by title or post meta. Null means that no ordering will be specified at all and the results will be returned in whatever sequence the MySQL query produces.

There aren't any filters available to modify the generated SQL query, so it is not possible to change this. You are welcome to submit a feature request to add more options to the API, at https://toolset.com/home/contact-us/suggest-a-new-feature-for-toolset/

You could query the database directly yourself to get the result you need.

I'd suggest using the Query Monitor plugin with which you'll be able to see the actual SQL query generated by the current API call to toolset_get_related_posts, from which you can construct your own query that includes the required ordering.

Use the core $wpdb class to apply the query: https://developer.wordpress.org/reference/classes/wpdb/

I'm sorry that there isn't a way for you to achieve what you need using the existing API.

#2308443

We're going to have to agree to differ on that point I'm afraid. I'd say that ID's are the most basic requirement for any queries, just think about it in database terms, they are essentially the primary key for anything generated by WordPress. Just look at the WP_Query documentation, its order defaults to post_date and the first option listed after that is post_id, and seeing as they both present unique data, I'd certainly call this a glaring omission and I will log a feature request for it.

Thanks for the suggestions on a workaround, one way or another I will come up with a way round it.