0

I'm fetching all posts of a specific custom post type like below.

print_r(ANCR_POST_TYPE);

$announcements = array();
$announcement_posts = get_posts(array(
    'post_type' => ANCR_POST_TYPE, // Post type is set to "announcer"
    'posts_per_page' => 2,
    'orderby' => 'menu_order',
    'order' => 'asc',
    'post_status' => 'publish'
));

print_r($announcement_posts);

But the get_posts() function returns posts which are not of type ANCR_POST_TYPE

announcer
Array
    (
        [0] => WP_Post Object
            (
                [ID] => 104
                [post_author] => 1
                [post_date] => 2023-07-07 18:15:23
                [post_date_gmt] => 2023-07-07 18:15:23
                [post_content] => This is an event
                [post_title] => Event
                [post_excerpt] => 
                [post_status] => publish
                [comment_status] => open
                [ping_status] => closed
                [post_password] => 
                [post_name] => event
                [to_ping] => 
                [pinged] => 
                [post_modified] => 2023-07-07 18:15:23
                [post_modified_gmt] => 2023-07-07 18:15:23
                [post_content_filtered] => 
                [post_parent] => 0
                [guid] => https://example.com/?post_type=tribe_events&p=104
                [menu_order] => 0
                [post_type] => tribe_events  <----- posts of type "tribe_events" is retreived instead of type "announcer"
                [post_mime_type] => 
                [comment_count] => 0
                [filter] => raw
            )
    
    )

This is seen only on the tags archive page of "tribe_events" post type.

Any idea on when this could happen?

3
  • 1
    are you using a pre_get_posts filter in your sites code? Functions on that filter can modify parameters that are fed into WP_Query and its wrapper functions such as get_posts
    – Tom J Nowell
    Commented Jul 8, 2023 at 0:06
  • Hi @TomJNowell, no, this was reported by one my plugin's user. This is observed in "the events calendar" plugin's post type page. As you said it is possible that the plugin has a filter to tweak the post type. I'll look into it's source and update. Commented Jul 8, 2023 at 8:09
  • it's very possible, pre_get_posts filters sometimes do this if they don't have enough conditions/checks to prevent leakage. You could use the suppress filters option but then that means it's impossible to filter/extend that query and you break compatibility with caching plugins and other things, e.g. no more elastic search support. My suspicion is that the filter the user has doesn't check if it's the main query or not
    – Tom J Nowell
    Commented Jul 8, 2023 at 12:12

1 Answer 1

0

This could be caused by a pre_get_posts action that doesn't have the proper conditions/checks.

For example:

add_action( 'pre_get_posts', function( $query ) : void {
    if ( is_post_type_archive( 'tribe_events' ) ) {
        $query->set( 'post_type', 'tribe_events' );
    }
} );

Likewise if this was a page template and not a post archive they might have this in their theme template to force it to show only posts of that type:

add_action( 'pre_get_posts', function( $query ) : void {
    $query->set( 'post_type', 'tribe_events' );
} );

Both of these would cause the problem you described. Fixing them will be specific to that specific callback though.Checking $query->is_main_query() may help.

How to Fix It?

Fundamentally this isn't a problem with your plugin, it's something in the users site code, and they will need to find and identify this. The usual process of elimination of disabling things and checking will help, as will a search and code review of any pre_get_posts callbacks.

6
  • I agree that the issue in question happened likely due to failure in targeting the right query. However, it should be noted that get_posts() by default sets suppress_filters to true, i.e. it suppresses all (pre-query) filters like posts_search and posts_where. Secondly, pre_get_posts is an action hook and not a filter, hence it still runs even when using get_posts().
    – Sally CJ
    Commented Jul 8, 2023 at 13:04
  • that's not true in newer versions of WordPress, suppress filters default value was changed to false on `get_posts, so that only applies for much older versions. I've removed that paragraph though to avoid confusion
    – Tom J Nowell
    Commented Jul 8, 2023 at 17:06
  • What newer versions are they 🤔, because to my knowledge, get_posts() has always been suppressing filters by default - it's like that a decade ago (example) and still like that in version 6.2.2, and even the trunk version as of writing.
    – Sally CJ
    Commented Jul 8, 2023 at 23:40
  • it seems in WP 6.1 core will still cache results even when suppress_filters is set to true make.wordpress.org/core/2022/10/07/…
    – Tom J Nowell
    Commented Jul 9, 2023 at 0:41
  • Yes, it doesn't suppress caching.. and not all filters are suppressed, either - e.g. posts_pre_query (filters the posts array before the query takes place) is not suppressed, but posts_results (this runs after querying the database) is suppressed.
    – Sally CJ
    Commented Jul 11, 2023 at 18:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.