WordPress.org

Make WordPress Core

Opened 14 months ago

Last modified 6 months ago

#38034 new defect (bug)

post__in orderby not working when passed in an array to orderby

Reported by: kelvink Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 4.6
Component: Query Keywords: needs-patch
Focuses: Cc:

Description

Currently order by post__in only works if you pass it as a string. If you pass it inside an array, it won't orderby post__in at all.

To reproduce:

<?php
$query = new WP_Query( array( 
    'post__in' => array( 1,2,3,4,5,6,7,8 ), 
    'orderby' => array( 'post__in' => 'desc', 'title' => 'asc' ) 
));

Attachments (2)

class-wp-query.diff (1.5 KB) - added by kelvink 14 months ago.
38034.diff (2.4 KB) - added by boonebgorges 8 months ago.

Download all attachments as: .zip

Change History (14)

This ticket was mentioned in Slack in #core by helen. View the logs.


11 months ago

#3 follow-up: @helen
11 months ago

  • Keywords reporter-feedback added
  • Version changed from trunk to 4.6

Hi @kelvink - thanks for your report. Could you also provide the query set up that does work for you?

Not new to trunk, so moving back to 4.6, though it would be something that's existed longer than that I imagine.

#4 in reply to: ↑ 3 @kelvink
11 months ago

Replying to helen:

Hi @kelvink - thanks for your report. Could you also provide the query set up that does work for you?

Not new to trunk, so moving back to 4.6, though it would be something that's existed longer than that I imagine.

Works:

<?php
$query = new WP_Query( array( 
    'post__in' => array( 19, 21, 27, 16 ), 
    'orderby' => 'post__in'
));

Does NOT work:

<?php
$query = new WP_Query( array( 
    'post__in' => array( 19, 21, 27, 16 ), 
    'orderby' => array( 'post__in' )
));

My fix makes post__in orderby work if you pass it in an array. So you can use the post__in orderby in conjunction with other ordering parameters.

I can submit a patch for version 4.6 as well, if needed.

Last edited 11 months ago by kelvink (previous) (diff)

#5 @maccast
9 months ago

Not sure if this has gotten worse or if I'm experiencing a different issue, but I have a site where the post__in sort order is not working anymore when it was in the past. For me it's doesn't work even if i use a string or an array. It was working in the past and I only noticed the issue after upgrading to Wordpress 4.7.2.

Here is my code for reference:

$query_images_args = array( 'post__in' => explode(',',$include), 'post_parent' => $thePost->ID, 'post_type' => 'attachment', 'post_mime_type' =>'image', 'post_status' => 'inherit', 'orderby' => 'post__in' );

$featuredPosts = new WP_Query( $query_images_args );

Another possible difference is I'm getting the gallery attachments associated with the post, but my $include contains the a comma seperatedstring of the gallery image_ids in the order I want them sorted in.

#6 @AllysonSouza
8 months ago

I'm also having this problem, ordeby post__in not work even in string. That's my code:

<?php
    $membros = array( 156, 159, 153 );
    $args = array(
        'post_type'      => 'time',
        'posts_per_page' => -1,
        'post__in'       => $membros, 
        'orderby'        => 'post__in',
    );
?>

The posts are displayed in the default admin list order, ignoring the post__in.

#7 @boonebgorges
8 months ago

In 40278:

Tests: Use assertSame() for WP_Query 'orderby' tests.

assertEqualSets() ignores order, so isn't much good for testing 'orderby'.

See #38034.

#8 follow-up: @boonebgorges
8 months ago

  • Keywords needs-patch added; reporter-feedback removed
  • Milestone changed from Awaiting Review to Future Release

I'm unable to reproduce the problems described by @AllysonSouza and @maccast. It's possible that they indicate some other issue.

What @kelvink describes is, indeed, a problem, and the approach in the patch looks correct. I'm about to attach a patch that also contains a test demonstrating the issue.

However, the patch causes some other orderby tests to fail. The reason is this. Once you start treating post__in as a "regular" orderby value instead of a special case, it means that you automatically start inheriting the order parameter too. And since the default order param is DESC, WP_Query( array( 'orderby' => 'post__in' ) ) starts returning results in reverse. This is too big a backward compatibility break. So we need to add some logic somewhere that indicates that when you pass orderby=post__in but don't specify order, you intend the order to be ASC.

@boonebgorges
8 months ago

#9 in reply to: ↑ 8 @maccast
7 months ago

Thanks of checking this out. Is there possibly some additional information or details I could provide to help determine why @AllysonSouza and I are seeing a different but similar issue to the one being described here?

Replying to boonebgorges:

I'm unable to reproduce the problems described by @AllysonSouza and @maccast. It's possible that they indicate some other issue.

What @kelvink describes is, indeed, a problem, and the approach in the patch looks correct. I'm about to attach a patch that also contains a test demonstrating the issue.

However, the patch causes some other orderby tests to fail. The reason is this. Once you start treating post__in as a "regular" orderby value instead of a special case, it means that you automatically start inheriting the order parameter too. And since the default order param is DESC, WP_Query( array( 'orderby' => 'post__in' ) ) starts returning results in reverse. This is too big a backward compatibility break. So we need to add some logic somewhere that indicates that when you pass orderby=post__in but don't specify order, you intend the order to be ASC.

#10 @boonebgorges
7 months ago

@maccast The first thing I'd check is the SQL that's being generated in your case by WP_Query ($this->request).

#11 @thefraj
6 months ago

Hi All,

I came across this thread when I realised that the posts-in operator actually doesn't seem to work at all in the latest versions of Wordpress.

Below is the sort of code I was using, it will not produce any results under any conditions that I can see (even if pages by this Id exist). I also tried casing using foreach ($posts as $p) : ... ... blah blah but have not been able to get any results back

<?php

$args = array(
'post__in' => array(25199, 27, 1448, 6509)
);
$query = new WP_Query( $args );
?>
<?php if ( $query->have_posts() ) : ?>
    <?php while ( $query->have_posts() ) : $query->the_post(); ?>
        <h2><?php the_title(); ?></h2>
        <?php echo the_content(); ?>
 
    <?php endwhile; ?>
<?php endif; ?>
<?php wp_reset_postdata(); ?>

#12 @boonebgorges
6 months ago

@thefraj post__in is definitely working more generally. See, for instance, the post__in tests in tests/phpunit/tests/query/results.php. In your case, you're probably not passing the proper post_type or post_status to WP_Query. If you have done further debugging and determined that it's definitely a core bug, please post your full analysis, including post type definition and the SQL generated by your WP_Query instance (and, ideally, automated tests demonstrating the failure).

Note: See TracTickets for help on using tickets.