[wp-trac] [WordPress Trac] #20904: WP_Query instances getting entangled with $wp_query global
WordPress Trac
wp-trac at lists.automattic.com
Mon Jun 11 11:55:39 UTC 2012
#20904: WP_Query instances getting entangled with $wp_query global
--------------------------+-----------------------------
Reporter: boonebgorges | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Query | Version:
Severity: normal | Keywords: has-patch
--------------------------+-----------------------------
`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'`.
--
Ticket URL: <http://core.trac.wordpress.org/ticket/20904>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software
More information about the wp-trac
mailing list