Opened 12 months ago

Last modified 10 days ago

#20904 new defect (bug)

WP_Query instances getting entangled with $wp_query global

Reported by: boonebgorges Owned by:
Priority: normal Milestone: Future Release
Component: Query Version:
Severity: normal Keywords: has-patch 3.5-early
Cc:

Description

WP_Query::the_post() fires setup_postdata(), which then uses get_query_var(). get_query_var(), in turn, calls the get() method on the $wp_query global object. In this way, WP_Query instances are not truly insulated from each other - they all are tied up with $wp_query in a way that seems unnecessary, and causes fatal errors in some cases.

In normal use, you would never really notice the issue, because after the 'init' action, the following offending line in setup_postdata() will return the 'page' query var from $wp_query:

$page = get_query_var('page');

And, since secondary WP_Query instances don't paginate in the same way as the primary query, the 'page' property on those instances doesn't matter much. So, while the value of $page is not strictly speaking correct in these cases (it comes from the wrong object), it generally fails silently.

However, if you instantiate a WP_Query object before 'init', you get a fatal error, because $wp_query->get() is an undefined method. Here's a simple mu-plugin that will demonstrate the problem:

function bbg_create_early_wp_query_object() {
	$q = new WP_Query( array(
		'post_type' => 'post'
	) );

	if ( $q->have_posts() ) {
		while ( $q->have_posts() ) {
			$q->the_post();
		}
	}
}
add_action( 'plugins_loaded', 'bbg_create_early_wp_query_object' );

My suggested solution is to move the setup_postdata() logic into a method of the WP_Query class, and then use $this->get( 'page' ) rather than get_query_var( 'page' ), to ensure that you're referring to the query vars of the correct query object. The old function setup_postdata() then becomes a wrapper for $wp_query->setup_postdata().

In addition, I modified the way that the $more global is set, so that it references the current object as well. This prevents _doing_it_wrong() errors when firing up a WP_Query instance before 'init'.

Attachments (1)

20904.patch (3.0 KB) - added by boonebgorges 12 months ago.

Download all attachments as: .zip

Change History (4)

  • Keywords 3.5-early added
  • Milestone changed from Awaiting Review to Future Release

We're still tied to all those globals, but this is definitely an improvement.

  • Milestone changed from Future Release to 3.6

comment:3   ryan10 days ago

  • Milestone changed from 3.6 to Future Release
Note: See TracTickets for help on using tickets.