miguelpeixe / WP_Query_Multisite

A subclass of WP_Query to allow for easy querying of multisite posts

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SQL not generating properly since WordPress 6.0.0

marcinkieruzel opened this issue · comments

After upgrading to WordPress 6.0.0 I get an empty response from query.

with 6.0.0 request in wp_query looks like:

"\n\t\t\tSELECT SQL_CALC_FOUND_ROWS  prx23_posts.*\n\t\t\tFROM prx23_posts \n\t\t\t \n\t\t\t\n\t\t\tORDER BY tables.post_date DESC\n\t\t\tLIMIT 0, 10\n\t\t"

with 5.9.4 like:

"SELECT SQL_CALC_FOUND_ROWS  tables.* FROM (  SELECT prx23_posts.*, '1' as site_ID FROM prx23_posts  WHERE 1=1  AND ((prx23_posts.post_type = 'news' AND (prx23_posts.post_status = 'publish' OR prx23_posts.post_status = 'acf-disabled')))  UNION  SELECT prx23_9_posts.*, '9' as site_ID FROM prx23_9_posts  WHERE 1=1  AND ((prx23_9_posts.post_type = 'news' AND (prx23_9_posts.post_status = 'publish' OR prx23_9_posts.post_status = 'acf-disabled')))  UNION  SELECT prx23_10_posts.*, '10' as site_ID FROM prx23_10_posts  WHERE 1=1  AND ((prx23_10_posts.post_type = 'news' AND (prx23_10_posts.post_status = 'publish' OR prx23_10_posts.post_status = 'acf-disabled')))  UNION  SELECT prx23_11_posts.*, '11' as site_ID FROM prx23_11_posts  WHERE 1=1  AND ... 

It happens to all of this plugin popular forks:
https://github.com/ericandrewlewis/WP_Query_Multisite
https://github.com/miguelpeixe/WP_Query_Multisite
https://github.com/timothyjensen/wp-query-multisite

I haven't found a solution yet, but I found the source of the problem.

It's on (currently line 94):
$sql = str_replace("$wpdb->posts.* FROM $wpdb->posts", 'tables.* FROM ( ' . implode(" UNION ", $this->ms_select) . ' ) tables', $sql);

I'm dumbfounded as to why, AND why I'm struggling to find a fix for it.

It's the first argument of the str_replace function, the 'find string'.
The problem is the space between "$wpdb->posts.*" and "FROM"
The space after that between "FROM" and "$wpdb->posts" is fine.
Only that first space after the asterisk * is a problem.

I've tried different variations of single quotes '' and double quotes "" for that string, preg_replace generic whitespace with a actual space character, various escape secquences, and so far - no luck.

Something about how the $sql var is formatted/escaped/passed to the posts_request hook changed in WP, and now str_replace isn't able to find the string, purely because of a single space.

Got it working with preg_replace and it was actually pretty easy. Not sure why I kept hitting dead ends before.

I'm going to fork this and submit a pull request. Hopefully it gets updated soon.

In the meantime, you can fix it by adding this line at the very top of the post_request method (like around line 85, just below "function posts_request($sql, $query) {")

	function posts_request($sql, $query) {
            
                $sql = preg_replace('/\s+/', " ", $sql); // <- add this line here: fix for WP using tabs instead of spaces 
                
		if($query->get('multisite')) {