WordPress.org

Make WordPress Core

Opened 2 months ago

Last modified 10 days ago

#49028 new enhancement

Provide functionality to suppress $wpdb query filter

Reported by: aurovrata Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: trunk
Component: Database Keywords: reporter-feedback
Focuses: Cc:
PR Number:

Description

The custom query class wpdb methods (get_col, get_car, update, delete...) all use the underlying query method which (since WP 2.1) has a filter hook 'query' which allows modification of the sql query.

Some queries are specific to the internals of a plugin's functionality and are not meant to be exposed to other plugins/functionality, however, currently, there is no mechanism to suppress this filter.

Would it make sense to add a boolean flag on the $wpdb instance which would allow developers to suppress any query modification?

Something like $wpdb->suppress_filters which would be set to false by default.

Attachments (1)

wp-db.php (101.6 KB) - added by aurovrata 10 days ago.
modified wp-insludes/wp-db.php

Download all attachments as: .zip

Change History (7)

#1 @aurovrata
2 months ago

Something like $wpdb->suppress_filters which would be set to false by default.

or possible true by default to make it consistent with the get_posts suppress_filters parameter.

#2 @johnbillion
2 months ago

  • Keywords reporter-feedback added

Thanks for the report @aurovrata .

What's the underlying problem here? If you're running a plugin that's filtering a query and having unintended side effects, that's best addressed by contacting the plugin author and asking them to filter the query less liberally.

Removing the ability to filter the query altogether just reduces the extensibility of WordPress.

#3 @aurovrata
2 months ago

Good eve @johnbillion, thank you for looking into this.

What's the underlying problem here?

I maintain a plugin which uses $wpdb to retrieve values from the DB and some users are facing issues with the values retrieved being construed by a filter in one of thee plugins/theme they use which alters the query.

Removing the ability to filter the query altogether just reduces the extensibility of WordPress.

no that's not what I am suggesting, if you read my initial ticket I am suggesting a similar functionality as the 'suppress_filters' parameter that is passed to the get_posts function.

This would allow me to fire a $wpdb query and suppress the 'query' filter, just for that specific query.

So here is a scenario I am suggesting,

$wpdb->suppress_filters = true;
$wpdb->get_col($wpdb->prep(<sql query>));

in the wp-includes/wp-db.php file where the $wpdb class resides,

if(!$this->suppress_filters){
  $query = apply_filters( 'query', $query );
}


#4 @aurovrata
10 days ago

@johnbillion anyone reviewed this?

I have built the following hack in order to overcome this shortcoming,

<?php
global $wpdb;
//I select postmetas that are specific to my plugin only (but some poorly coded plugin still filters the query causing spurious results to be returned).
$query =$wpdb->prepare("SELECT rpwc_pm.meta_id, rpwc_pm.post_id FROM {$wpdb->postmeta} as rpwc_pm WHERE rpwc_pm.meta_key ='_rpwc2' AND rpwc_pm.meta_value=%d", $term_id);
$match = "SELECT rpwc_pm.meta_id, rpwc_pm.post_id";
//so before I execute the query I register a filter with an anonymous fn and put it last in the filter queue...
add_filter('query', function($q) use ($query, $match) {
  if(strpos($q, $match)!==false) $q = $query;
  return $q;
},PHP_INT_MAX);

$ranked_rows = $wpdb->get_results($query);

this is the only way to ensure I get the right results.

It would be so much simpler with a suppress_filter flag. Implementing a flag is a very simple (few lines of code) fix in wp-includes/wp-db.php. Can I make this change and submit it for review?

#5 @aurovrata
10 days ago

Here is what I propose in the $wpdb class (wp-incudes/wp-db.php),

<?php
//declare a new variable property for the class
/**
 * Whether to suppress filters 'query' filter prior to execution..
 *
 * @since 5.4.0
 * @var bool
 */
var $suppress_filters = false;

//on line 1902 in the query() method

if(!$this->suppress_filters)    $query = apply_filters( 'query', $query );

so by default no change whatsoever to the current working of the class.

i have attached my modified wp-db.php file to this ticket.

@aurovrata
10 days ago

modified wp-insludes/wp-db.php

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


10 days ago

Note: See TracTickets for help on using tickets.