Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a sniff for suppress_filters in get_posts #1416

Closed
tomjn opened this issue Jul 8, 2018 · 11 comments
Closed

Add a sniff for suppress_filters in get_posts #1416

tomjn opened this issue Jul 8, 2018 · 11 comments

Comments

@tomjn
Copy link
Contributor

tomjn commented Jul 8, 2018

Consider these 2 queries snippets:

$args = [
    'post_type' => 'page'
];

$results = get_posts( $args ); // 1
$q = new WP_Query( $args ); // 2

2 is faster, despite 1 using 2 internally. The reason for this is a difference in default arguments, specifically suppress_filters. In WP_Query it is false by default, but in get_posts it is true.

In this example, the performance difference is resolved:

$args = [
    'post_type' => 'page',
    'suppress_filters' => false
];

$results = get_posts( $args ); // 1
$q = new WP_Query( $args ); // 2

With suppress_filters set to true, any caching mechanisms are unable to do their job. Setting it to false fixes this. It's particularly noticeable on sites with any kind of object cache or effective caching plugins.

We flag this at VIP, and as a result a PR for a new VIP sniff was submitted in #1041 (comment) but this is not VIP specific, and falls into the cached vs uncached core APIs bucket

@jrfnl
Copy link
Member

jrfnl commented Jul 8, 2018

So a sniff for this should flag any equivalent of suppress_filters = true whether it is passed to WP_Query or to get_posts() and also get_posts() when called without suppress_filters set.

However, if a plugin very deliberately sets suppress_filters = true when calling either, I believe this should be considered a conscious choice of the developer and should probably not be flagged.

So that just leaves sniffing for get_posts() when called without suppress_filters set.

This can be done when the $args are set within the same scope (function) as the call to get_posts(), but as soon as the $args are passed as a function parameter or taken from a class property, sniffing for this will be highly inaccurate.

This would mean that if its "undetermined", the sniff should not flag the code.

function plugin_get_posts( $args ) {
    return get_posts( $args ); // OK.
}

class plugin_class {
    private $args = array(); // Set via constructor or other method.

    public function get_posts() {
        return get_posts( $this->args ); // OK.
    }
}

And what about code like this:

function plugin_get_posts() {
    $args = [
        'post_type' => 'page',
        'suppress_filters' => false
    ];
    $args = apply_filter( 'plugin_filter_hook', $args );

    return get_posts( $args ); // ???
}

Or along those same lines:

function plugin_get_posts() {
    $args = [
        'post_type' => 'page',
    ];
    $args = apply_filter( 'plugin_filter_hook', $args );

    return get_posts( $args ); // ???
}

It's particularly noticeable on sites with any kind of object cache or effective caching plugins.

In other words, this is only valid in a limited number of all cases as by far not all sites are running with caching (plugins or otherwise).

When there is no caching plugin active, calling WP_Query/get_posts() with suppress_filters = true should be faster, though the results may be different.

All in all, for this to be added to WPCS, I would like to see some more discussion about this.

@jrfnl
Copy link
Member

jrfnl commented Jul 8, 2018

P.S.: @tomjn Thanks for opening the issue 😉

@dingo-d
Copy link
Member

dingo-d commented Nov 11, 2022

The problem with sniffing this, as I see it, is that arguments can be passed to the get_posts() function in various ways that can be nearly impossible to sniff correctly (in addition to what Juliette mentioned already).

  1. Passing it as a static method from a class (missing context to know what the argument contains, similar to what the apply_filter call would do)
  2. Passing a global argument array (please never do this 😅)

We could detect only if we have some array in the file where the get_posts function is, containing the 'suppress_filters' => true item. And even that could get complex if we take class context into it.

Just flagging every get_posts as a warning could cause a bit of noise.

@jrfnl
Copy link
Member

jrfnl commented Nov 11, 2022

Good points from @dingo-d

I'm also just now wondering if the recent changes to WP_Query in WP 6.1 have any impact on this and if so, whether this issue is still relevant.

As I haven't done a deep dive into the WP 6.1 changes, I'm pinging @spacedmonkey and @felixarntz for an opinion.

@spacedmonkey
Copy link
Member

WP_Query is now cached by default. So this sniff is much less important now.

@dingo-d
Copy link
Member

dingo-d commented Nov 11, 2022

@spacedmonkey Does this mean that the supress_filters in the get_posts function is no longer relevant?

@spacedmonkey
Copy link
Member

@spacedmonkey Does this mean that the supress_filters in the get_posts function is no longer relevant?

Not sure what you mean by relevant. There is no longer a need to pass supress_filters => false, to ensure that caching plugins remain working. Core does this out of the box now. The sniff should be for cache_results => false.

@tomjn
Copy link
Contributor Author

tomjn commented Nov 11, 2022

@spacedmonkey is cache_results set to false by default for get_posts or is it only if the user decides to use it?

@spacedmonkey
Copy link
Member

@spacedmonkey is cache_results set to false by default for get_posts or is it only if the user decides to use it?

Set to true by default.

@jrfnl
Copy link
Member

jrfnl commented Dec 9, 2022

Given the above, I get the impression a sniff for this is no longer relevant. Is that correct ? If so, I suggest we close the issue.

If a sniff would still be relevant, it needs to be hashed out in detail what the conditions should be for the sniff to flag something and I would like to see that input in this issue.

@tomjn
Copy link
Contributor Author

tomjn commented Dec 9, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants