Make WordPress Core

Opened 7 years ago

Last modified 3 years ago

#43238 reopened defect (bug)

`suppress_filters` not set in `pre_get_posts` hook

Reported by: adampatterson's profile adampatterson Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.9.4
Component: Query Keywords: dev-feedback
Focuses: Cc:

Description

After updating to 4.9.4 my media library is empty locally and on my server. I confirmed this on a handful of sites that I have updated.

I cleared the cache and also checked the console.

I don't see any errors or any ajax requests being made.

The /wp-json/wp/v2/media does however contain a response with media.

Locally I am running latest OSX, my server is Ubuntu 16.04 both with PHP ~7.0

Change History (10)

#1 @desrosj
7 years ago

  • Keywords reporter-feedback added

Hey @adampatterson,

Thanks for the ticket, and welcome to Trac! Sorry that you are experiencing this. Let's figure out what happened.

I was just working with @mikeschroder to reproduce this issue and we were both unable to do so. I click updated to 4.9.4 in my dashboard, and @mikeschroder had a site that auto-updated to 4.9.4 and neither of us experienced the issue described.

Can you think of anything else in common between the sites you are experiencing this on? Are there any sites that are not experiencing this issue? It could be a theme or plugin has an incompatibility with 4.9.4 causing the failure. If you are able to, can you disable plugins one at a time and try to see if that is the cause? Also, try switching to a core theme.

If those steps don't show any positive results, can you try clicking the "Re-install Now" button on the update page on one of the sites to see if that fixes the issue?

#2 @adampatterson
7 years ago

Thanks for the speedy reply.

I have disabled all plugins and still had the same issue.

I have however reverted my theme to Twenty Seventeen did fix the problem, So I will do some digging and see what might be the cause.

Other than a few custom media sizes I don't do anything with the gallery or media manager.

#3 follow-up: @adampatterson
7 years ago

OK, I found the error, and I'm a little confused. Would suppress_filters not be availbile at all times?

The error found in the log was:

[06-Feb-2018 22:17:03 UTC] PHP Notice:  Undefined index: suppress_filters in /PATH/wp-content/themes/adam/functions.php on line 22
[06-Feb-2018 22:17:03 UTC] PHP Stack trace:
[06-Feb-2018 22:17:03 UTC] PHP   1. {main}() /PATH/wp-admin/admin-ajax.php:0
[06-Feb-2018 22:17:03 UTC] PHP   2. do_action() /PATH/wp-admin/admin-ajax.php:97
[06-Feb-2018 22:17:03 UTC] PHP   3. WP_Hook->do_action() /PATH/wp-includes/plugin.php:453
[06-Feb-2018 22:17:03 UTC] PHP   4. WP_Hook->apply_filters() /PATH/wp-includes/class-wp-hook.php:310
[06-Feb-2018 22:17:03 UTC] PHP   5. wp_ajax_query_attachments() /PATH/wp-includes/class-wp-hook.php:286
[06-Feb-2018 22:17:03 UTC] PHP   6. WP_Query->__construct() /PATH/wp-admin/includes/ajax-actions.php:2482
[06-Feb-2018 22:17:03 UTC] PHP   7. WP_Query->query() /PATH/wp-includes/class-wp-query.php:3336
[06-Feb-2018 22:17:03 UTC] PHP   8. WP_Query->get_posts() /PATH/wp-includes/class-wp-query.php:3230
[06-Feb-2018 22:17:03 UTC] PHP   9. do_action_ref_array() /PATH/wp-includes/class-wp-query.php:1634
[06-Feb-2018 22:17:03 UTC] PHP  10. WP_Hook->do_action() /PATH/wp-includes/plugin.php:515
[06-Feb-2018 22:17:03 UTC] PHP  11. WP_Hook->apply_filters() /PATH/wp-includes/class-wp-hook.php:310
[06-Feb-2018 22:17:03 UTC] PHP  12. show_draft_posts() /PATH/wp-includes/class-wp-hook.php:286

Caused by

function show_draft_posts( $query ) {
    if ( user_can( wp_get_current_user(), 'administrator' ) ) {
        if ( $query->query_vars['suppress_filters'] ) {
            return $query;
        }

        $query->set( 'post_status', [ 'publish', 'draft' ] );

        return $query;
    }

    if ( is_admin() ) {
        return $query;
    }
}

add_filter( 'pre_get_posts', 'show_draft_posts' );
Last edited 7 years ago by SergeyBiryukov (previous) (diff)

#4 @desrosj
7 years ago

  • Component changed from Media to Query
  • Focuses javascript administration removed
  • Keywords reporter-feedback removed
  • Summary changed from Media Library is empty on multiple sites to `suppress_filters` not set in `pre_get_posts` hook

I'm moving this over to a different component and renaming it to reflect our findings. Your code looks right at first glance, but have not been able to dive in and verify.

#5 @adampatterson
7 years ago

  • Component changed from Query to Media
  • Focuses javascript administration added
  • Keywords reporter-feedback added
  • Summary changed from `suppress_filters` not set in `pre_get_posts` hook to Media Library is empty on multiple sites

I don't know enough about suppress_filters, but it works fine. I was attempting to display draft posts to logged in admin users. It seems that suppress_filters is not always defined.

https://codex.wordpress.org/Template_Tags/get_posts

#6 @adampatterson
7 years ago

  • Component changed from Media to Query
  • Focuses javascript administration removed
  • Summary changed from Media Library is empty on multiple sites to `suppress_filters` not set in `pre_get_posts` hook

Sorry, I updated the ticket while you save it.

#7 @adampatterson
7 years ago

I fixed my original issue, but I still think that supress_filters is supposed to be present.

<?php
function show_draft_posts( $query ) {
    if ( is_admin() ) {
        return $query;
    }

    if ( user_can( wp_get_current_user(), 'administrator' ) ) {
        if ( array_key_exists( 'suppress_filters', $query->query_vars ) and $query->query_vars['suppress_filters'] ) {
            return $query;
        }

        $query->set( 'post_status', [ 'publish', 'draft' ] );

        return $query;
    }
}

add_filter( 'pre_get_posts', 'show_draft_posts' );

#8 in reply to: ↑ 3 @SergeyBiryukov
7 years ago

  • Keywords reporter-feedback removed
  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from new to closed

Replying to adampatterson:

Would suppress_filters not be available at all times?

Yes, pre_get_posts runs after the request is parsed and query vars are set in WP::parse_request(), but before any additional WP_Query arguments are processed, including suppress_filters, ignore_sticky_posts, etc.

If you need to check the value of those arguments that may or may not be passed, I'd suggest using isset(), empty(), $query->get(), or array_key_exists(), as you did.

As far as I can tell, there were no changes in behavior here in 4.9.3 or 4.9.4. Thanks for the ticket though!

#9 @Giorgio25b
5 years ago

  • Keywords dev-feedback added
  • Resolution invalid deleted
  • Status changed from closed to reopened

Even though this ticket highlights a solution, it does not address the problem at its source.
The reporter did experience and describe the correct scenario, but I found some other instances where the problem does not occur and it might be a problem with the /wp-json/wp/v2/media endpoint itself.
The fully working function passes validation and control that the user can actually see drafts:

<?php
function show_draft_posts( $query ) {
    if ( is_admin() ) {
        return $query;
    }

    if ( user_can( wp_get_current_user(), 'administrator' ) ) {
        if ( array_key_exists( 'suppress_filters', $query->query_vars ) and $query->query_vars['suppress_filters'] ) {
            return $query;
        }

        $query->set( 'post_status', [ 'publish', 'draft' ] );

        return $query;
    }
}

add_filter( 'pre_get_posts', 'show_draft_posts' );

Though when we pass the same function without the user validation, such as:

<?php
function show_draft_posts( $query ) {
    if (is_admin()) {
        return $query;
    }

    if (array_key_exists('suppress_filters', $query->query_vars) && $query->query_vars['suppress_filters']) {
        return $query;
    }

    $query->set('post_status', ['publish', 'draft']);
    return $query;
}

add_filter( 'pre_get_posts', 'show_draft_posts' );

We only trigger an error in the /wp-json/wp/v2/media endpoint, which will return an empty array [ ]. The same issue should occur with /wp-json/wp/v2/users and /wp-json/wp/v2/posts for example but it does not, therefore I think that the media endpoint is either treated differently or there is something wrong somewhere that I can not pin down.

I really hope this helps, thank you!

#10 @SergeyBiryukov
3 years ago

  • Milestone set to Awaiting Review
Note: See TracTickets for help on using tickets.