Make WordPress Core


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/query.php

    r15470 r17455  
    2626
    2727    return $wp_query->get($var);
     28}
     29
     30
     31/**
     32 * Retrieve the currently-queried object.  Wrapper for $wp_query->get_queried_object()
     33 *
     34 * @uses WP_Query::get_queried_object
     35 *
     36 * @since 3.1.0
     37 * @access public
     38 *
     39 * @return object
     40 */
     41function get_queried_object() {
     42    global $wp_query;
     43    return $wp_query->get_queried_object();
     44}
     45
     46/**
     47 * Retrieve ID of the current queried object. Wrapper for $wp_query->get_queried_object_id()
     48 *
     49 * @uses WP_Query::get_queried_object_id()
     50 *
     51 * @since 3.1.0
     52 * @access public
     53 *
     54 * @return int
     55 */
     56function get_queried_object_id() {
     57    global $wp_query;
     58    return $wp_query->get_queried_object_id();
    2859}
    2960
     
    99130
    100131/**
    101  * Is query requesting an archive page.
    102  *
     132 * Is the query for an archive page?
     133 *
     134 * Month, Year, Category, Author, Post Type archive...
     135 *
     136 * @see WP_Query::is_archive()
    103137 * @since 1.5.0
    104138 * @uses $wp_query
    105139 *
    106  * @return bool True if page is archive.
     140 * @return bool
    107141 */
    108142function is_archive() {
    109143    global $wp_query;
    110144
    111     return $wp_query->is_archive;
    112 }
    113 
    114 /**
    115  * Is query requesting an attachment page.
    116  *
     145    if ( ! isset( $wp_query ) ) {
     146        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     147        return false;
     148    }
     149
     150    return $wp_query->is_archive();
     151}
     152
     153/**
     154 * Is the query for a post type archive page?
     155 *
     156 * @see WP_Query::is_post_type_archive()
     157 * @since 3.1.0
     158 * @uses $wp_query
     159 *
     160 * @param mixed $post_types Optional. Post type or array of posts types to check against.
     161 * @return bool
     162 */
     163function is_post_type_archive( $post_types = '' ) {
     164    global $wp_query;
     165
     166    if ( ! isset( $wp_query ) ) {
     167        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     168        return false;
     169    }
     170
     171    return $wp_query->is_post_type_archive( $post_types );
     172}
     173
     174/**
     175 * Is the query for an attachment page?
     176 *
     177 * @see WP_Query::is_attachment()
    117178 * @since 2.0.0
    118179 * @uses $wp_query
    119180 *
    120  * @return bool True if page is attachment.
     181 * @return bool
    121182 */
    122183function is_attachment() {
    123184    global $wp_query;
    124185
    125     return $wp_query->is_attachment;
    126 }
    127 
    128 /**
    129  * Is query requesting an author page.
    130  *
    131  * If the $author parameter is specified then the check will be expanded to
    132  * include whether the queried author matches the one given in the parameter.
    133  * You can match against integers and against strings.
    134  *
    135  * If matching against an integer, the ID should be used of the author for the
    136  * test. If the $author is an ID and matches the author page user ID, then
    137  * 'true' will be returned.
    138  *
    139  * If matching against strings, then the test will be matched against both the
    140  * nickname and user nicename and will return true on success.
    141  *
     186    if ( ! isset( $wp_query ) ) {
     187        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     188        return false;
     189    }
     190
     191    return $wp_query->is_attachment();
     192}
     193
     194/**
     195 * Is the query for an author archive page?
     196 *
     197 * If the $author parameter is specified, this function will additionally
     198 * check if the query is for one of the authors specified.
     199 *
     200 * @see WP_Query::is_author()
    142201 * @since 1.5.0
    143202 * @uses $wp_query
    144203 *
    145  * @param string|int $author Optional. Is current page this author.
    146  * @return bool True if page is author or $author (if set).
    147  */
    148 function is_author($author = '') {
    149     global $wp_query;
    150 
    151     if ( !$wp_query->is_author )
     204 * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames
     205 * @return bool
     206 */
     207function is_author( $author = '' ) {
     208    global $wp_query;
     209
     210    if ( ! isset( $wp_query ) ) {
     211        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
    152212        return false;
    153 
    154     if ( empty($author) )
    155         return true;
    156 
    157     $author_obj = $wp_query->get_queried_object();
    158 
    159     $author = (array) $author;
    160 
    161     if ( in_array( $author_obj->ID, $author ) )
    162         return true;
    163     elseif ( in_array( $author_obj->nickname, $author ) )
    164         return true;
    165     elseif ( in_array( $author_obj->user_nicename, $author ) )
    166         return true;
    167 
    168     return false;
    169 }
    170 
    171 /**
    172  * Whether current page query contains a category name or given category name.
    173  *
    174  * The category list can contain category IDs, names, or category slugs. If any
    175  * of them are part of the query, then it will return true.
    176  *
     213    }
     214
     215    return $wp_query->is_author( $author );
     216}
     217
     218/**
     219 * Is the query for a category archive page?
     220 *
     221 * If the $category parameter is specified, this function will additionally
     222 * check if the query is for one of the categories specified.
     223 *
     224 * @see WP_Query::is_category()
    177225 * @since 1.5.0
    178226 * @uses $wp_query
    179227 *
    180  * @param string|array $category Optional.
     228 * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs.
    181229 * @return bool
    182230 */
    183 function is_category($category = '') {
    184     global $wp_query;
    185 
    186     if ( !$wp_query->is_category )
     231function is_category( $category = '' ) {
     232    global $wp_query;
     233
     234    if ( ! isset( $wp_query ) ) {
     235        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
    187236        return false;
    188 
    189     if ( empty($category) )
    190         return true;
    191 
    192     $cat_obj = $wp_query->get_queried_object();
    193 
    194     $category = (array) $category;
    195 
    196     if ( in_array( $cat_obj->term_id, $category ) )
    197         return true;
    198     elseif ( in_array( $cat_obj->name, $category ) )
    199         return true;
    200     elseif ( in_array( $cat_obj->slug, $category ) )
    201         return true;
    202 
    203     return false;
    204 }
    205 
    206 /**
    207  * Whether the current page query has the given tag slug or contains tag.
    208  *
     237    }
     238
     239    return $wp_query->is_category( $category );
     240}
     241
     242/**
     243 * Is the query for a tag archive page?
     244 *
     245 * If the $tag parameter is specified, this function will additionally
     246 * check if the query is for one of the tags specified.
     247 *
     248 * @see WP_Query::is_tag()
    209249 * @since 2.3.0
    210250 * @uses $wp_query
    211251 *
    212  * @param string|array $slug Optional. Single tag or list of tags to check for.
     252 * @param mixed $slug Optional. Tag slug or array of slugs.
    213253 * @return bool
    214254 */
     
    216256    global $wp_query;
    217257
    218     if ( !$wp_query->is_tag )
     258    if ( ! isset( $wp_query ) ) {
     259        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
    219260        return false;
    220 
    221     if ( empty( $slug ) )
    222         return true;
    223 
    224     $tag_obj = $wp_query->get_queried_object();
    225 
    226     $slug = (array) $slug;
    227 
    228     if ( in_array( $tag_obj->slug, $slug ) )
    229         return true;
    230 
    231     return false;
    232 }
    233 
    234 /**
    235  * Whether the current query is for the given taxonomy and/or term.
    236  *
    237  * If no taxonomy argument is set, returns true if any taxonomy is queried.
    238  * If the taxonomy argument is passed but no term argument, returns true
    239  *    if the taxonomy or taxonomies in the argument are being queried.
    240  * If both taxonomy and term arguments are passed, returns true
    241  *    if the current query is for a term contained in the terms argument
    242  *    which has a taxonomy contained in the taxonomy argument.
    243  *
     261    }
     262
     263    return $wp_query->is_tag( $slug );
     264}
     265
     266/**
     267 * Is the query for a taxonomy archive page?
     268 *
     269 * If the $taxonomy parameter is specified, this function will additionally
     270 * check if the query is for that specific $taxonomy.
     271 *
     272 * If the $term parameter is specified in addition to the $taxonomy parameter,
     273 * this function will additionally check if the query is for one of the terms
     274 * specified.
     275 *
     276 * @see WP_Query::is_tax()
    244277 * @since 2.5.0
    245278 * @uses $wp_query
    246279 *
    247  * @param string|array $taxonomy Optional. Taxonomy slug or slugs to check in current query.
    248  * @param int|array|string $term. Optional. A single or array of, The term's ID, Name or Slug
     280 * @param mixed $taxonomy Optional. Taxonomy slug or slugs.
     281 * @param mixed $term Optional. Term ID, name, slug or array of Term IDs, names, and slugs.
    249282 * @return bool
    250283 */
    251284function is_tax( $taxonomy = '', $term = '' ) {
    252     global $wp_query, $wp_taxonomies;
    253 
    254     $queried_object = $wp_query->get_queried_object();
    255     $tax_array = array_intersect(array_keys($wp_taxonomies), (array) $taxonomy);
    256     $term_array = (array) $term;
    257 
    258     if ( !$wp_query->is_tax )
     285    global $wp_query;
     286
     287    if ( ! isset( $wp_query ) ) {
     288        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
    259289        return false;
    260 
    261     if ( empty( $taxonomy ) )
    262         return true;
    263 
    264     if ( empty( $term ) ) // Only a Taxonomy provided
    265         return isset($queried_object->taxonomy) && count( $tax_array ) && in_array($queried_object->taxonomy, $tax_array);
    266 
    267     return isset($queried_object->term_id) &&
    268             count(array_intersect(
    269                 array($queried_object->term_id, $queried_object->name, $queried_object->slug),
    270                 $term_array
    271             ));
     290    }
     291
     292    return $wp_query->is_tax( $taxonomy, $term );
    272293}
    273294
     
    275296 * Whether the current URL is within the comments popup window.
    276297 *
     298 * @see WP_Query::is_comments_popup()
    277299 * @since 1.5.0
    278300 * @uses $wp_query
     
    283305    global $wp_query;
    284306
    285     return $wp_query->is_comments_popup;
    286 }
    287 
    288 /**
    289  * Whether current URL is based on a date.
    290  *
     307    if ( ! isset( $wp_query ) ) {
     308        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     309        return false;
     310    }
     311
     312    return $wp_query->is_comments_popup();
     313}
     314
     315/**
     316 * Is the query for a date archive?
     317 *
     318 * @see WP_Query::is_date()
    291319 * @since 1.5.0
    292320 * @uses $wp_query
     
    297325    global $wp_query;
    298326
    299     return $wp_query->is_date;
    300 }
    301 
    302 /**
    303  * Whether current blog URL contains a day.
    304  *
     327    if ( ! isset( $wp_query ) ) {
     328        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     329        return false;
     330    }
     331
     332    return $wp_query->is_date();
     333}
     334
     335/**
     336 * Is the query for a day archive?
     337 *
     338 * @see WP_Query::is_day()
    305339 * @since 1.5.0
    306340 * @uses $wp_query
     
    311345    global $wp_query;
    312346
    313     return $wp_query->is_day;
    314 }
    315 
    316 /**
    317  * Whether current page query is feed URL.
    318  *
     347    if ( ! isset( $wp_query ) ) {
     348        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     349        return false;
     350    }
     351
     352    return $wp_query->is_day();
     353}
     354
     355/**
     356 * Is the query for a feed?
     357 *
     358 * @see WP_Query::is_feed()
    319359 * @since 1.5.0
    320360 * @uses $wp_query
    321361 *
     362 * @param string|array $feeds Optional feed types to check.
    322363 * @return bool
    323364 */
    324 function is_feed() {
    325     global $wp_query;
    326 
    327     return $wp_query->is_feed;
    328 }
    329 
    330 /**
    331  * Whether current page query is comment feed URL.
    332  *
     365function is_feed( $feeds = '' ) {
     366    global $wp_query;
     367
     368    if ( ! isset( $wp_query ) ) {
     369        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     370        return false;
     371    }
     372
     373    return $wp_query->is_feed( $feeds );
     374}
     375
     376/**
     377 * Is the query for a comments feed?
     378 *
     379 * @see WP_Query::is_comments_feed()
    333380 * @since 3.0.0
    334381 * @uses $wp_query
     
    339386    global $wp_query;
    340387
    341     return $wp_query->is_comment_feed;
    342 }
    343 
    344 /**
    345  * Whether current page query is the front of the site.
    346  *
     388    if ( ! isset( $wp_query ) ) {
     389        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     390        return false;
     391    }
     392
     393    return $wp_query->is_comment_feed();
     394}
     395
     396/**
     397 * Is the query for the front page of the site?
     398 *
     399 * This is for what is displayed at your site's main URL.
     400 *
     401 * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_on_front'.
     402 *
     403 * If you set a static page for the front page of your site, this function will return
     404 * true when viewing that page.
     405 *
     406 * Otherwise the same as @see is_home()
     407 *
     408 * @see WP_Query::is_front_page()
    347409 * @since 2.5.0
    348410 * @uses is_home()
     
    352414 */
    353415function is_front_page() {
    354     // most likely case
    355     if ( 'posts' == get_option('show_on_front') && is_home() )
    356         return true;
    357     elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') && is_page(get_option('page_on_front')) )
    358         return true;
    359     else
     416    global $wp_query;
     417
     418    if ( ! isset( $wp_query ) ) {
     419        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
    360420        return false;
    361 }
    362 
    363 /**
    364  * Whether current page view is the blog homepage.
    365  *
    366  * This is the page which is showing the time based blog content of your site
    367  * so if you set a static page for the front page of your site then this will
    368  * only be true on the page which you set as the "Posts page" in Reading Settings.
    369  *
     421    }
     422
     423    return $wp_query->is_front_page();
     424}
     425
     426/**
     427 * Is the query for the blog homepage?
     428 *
     429 * This is the page which shows the time based blog content of your site.
     430 *
     431 * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_for_posts'.
     432 *
     433 * If you set a static page for the front page of your site, this function will return
     434 * true only on the page you set as the "Posts page".
     435 *
     436 * @see is_front_page()
     437 *
     438 * @see WP_Query::is_home()
    370439 * @since 1.5.0
    371440 * @uses $wp_query
     
    376445    global $wp_query;
    377446
    378     return $wp_query->is_home;
    379 }
    380 
    381 /**
    382  * Whether current page query contains a month.
    383  *
     447    if ( ! isset( $wp_query ) ) {
     448        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     449        return false;
     450    }
     451
     452    return $wp_query->is_home();
     453}
     454
     455/**
     456 * Is the query for a month archive?
     457 *
     458 * @see WP_Query::is_month()
    384459 * @since 1.5.0
    385460 * @uses $wp_query
     
    390465    global $wp_query;
    391466
    392     return $wp_query->is_month;
    393 }
    394 
    395 /**
    396  * Whether query is page or contains given page(s).
    397  *
    398  * Calls the function without any parameters will only test whether the current
    399  * query is of the page type. Either a list or a single item can be tested
    400  * against for whether the query is a page and also is the value or one of the
    401  * values in the page parameter.
    402  *
    403  * The parameter can contain the page ID, page title, or page name. The
    404  * parameter can also be an array of those three values.
    405  *
     467    if ( ! isset( $wp_query ) ) {
     468        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     469        return false;
     470    }
     471
     472    return $wp_query->is_month();
     473}
     474
     475/**
     476 * Is the query for a single page?
     477 *
     478 * If the $page parameter is specified, this function will additionally
     479 * check if the query is for one of the pages specified.
     480 *
     481 * @see is_single()
     482 * @see is_singular()
     483 *
     484 * @see WP_Query::is_page()
    406485 * @since 1.5.0
    407486 * @uses $wp_query
    408487 *
    409  * @param mixed $page Either page or list of pages to test against.
     488 * @param mixed $page Page ID, title, slug, or array of such.
    410489 * @return bool
    411490 */
    412 function is_page($page = '') {
    413     global $wp_query;
    414 
    415     if ( !$wp_query->is_page )
     491function is_page( $page = '' ) {
     492    global $wp_query;
     493
     494    if ( ! isset( $wp_query ) ) {
     495        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
    416496        return false;
    417 
    418     if ( empty($page) )
    419         return true;
    420 
    421     $page_obj = $wp_query->get_queried_object();
    422 
    423     $page = (array) $page;
    424 
    425     if ( in_array( $page_obj->ID, $page ) )
    426         return true;
    427     elseif ( in_array( $page_obj->post_title, $page ) )
    428         return true;
    429     else if ( in_array( $page_obj->post_name, $page ) )
    430         return true;
    431 
    432     return false;
    433 }
    434 
    435 /**
    436  * Whether query contains multiple pages for the results.
    437  *
     497    }
     498
     499    return $wp_query->is_page( $page );
     500}
     501
     502/**
     503 * Is the query for paged result and not for the first page?
     504 *
     505 * @see WP_Query::is_paged()
    438506 * @since 1.5.0
    439507 * @uses $wp_query
     
    444512    global $wp_query;
    445513
    446     return $wp_query->is_paged;
    447 }
    448 
    449 /**
    450  * Whether the current page was created by a plugin.
    451  *
    452  * The plugin can set this by using the global $plugin_page and setting it to
    453  * true.
    454  *
     514    if ( ! isset( $wp_query ) ) {
     515        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     516        return false;
     517    }
     518
     519    return $wp_query->is_paged();
     520}
     521
     522/**
     523 * Is the query for a post or page preview?
     524 *
     525 * @see WP_Query::is_preview()
     526 * @since 2.0.0
     527 * @uses $wp_query
     528 *
     529 * @return bool
     530 */
     531function is_preview() {
     532    global $wp_query;
     533
     534    if ( ! isset( $wp_query ) ) {
     535        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     536        return false;
     537    }
     538
     539    return $wp_query->is_preview();
     540}
     541
     542/**
     543 * Is the query for the robots file?
     544 *
     545 * @see WP_Query::is_robots()
     546 * @since 2.1.0
     547 * @uses $wp_query
     548 *
     549 * @return bool
     550 */
     551function is_robots() {
     552    global $wp_query;
     553
     554    if ( ! isset( $wp_query ) ) {
     555        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     556        return false;
     557    }
     558
     559    return $wp_query->is_robots();
     560}
     561
     562/**
     563 * Is the query for a search?
     564 *
     565 * @see WP_Query::is_search()
    455566 * @since 1.5.0
    456  * @global bool $plugin_page Used by plugins to tell the query that current is a plugin page.
     567 * @uses $wp_query
    457568 *
    458569 * @return bool
    459570 */
    460 function is_plugin_page() {
    461     global $plugin_page;
    462 
    463     if ( isset($plugin_page) )
    464         return true;
    465 
    466     return false;
    467 }
    468 
    469 /**
    470  * Whether the current query is preview of post or page.
    471  *
    472  * @since 2.0.0
    473  * @uses $wp_query
    474  *
     571function is_search() {
     572    global $wp_query;
     573
     574    if ( ! isset( $wp_query ) ) {
     575        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     576        return false;
     577    }
     578
     579    return $wp_query->is_search();
     580}
     581
     582/**
     583 * Is the query for a single post?
     584 *
     585 * Works for any post type, except attachments and pages
     586 *
     587 * If the $post parameter is specified, this function will additionally
     588 * check if the query is for one of the Posts specified.
     589 *
     590 * @see is_page()
     591 * @see is_singular()
     592 *
     593 * @see WP_Query::is_single()
     594 * @since 1.5.0
     595 * @uses $wp_query
     596 *
     597 * @param mixed $post Post ID, title, slug, or array of such.
    475598 * @return bool
    476599 */
    477 function is_preview() {
    478     global $wp_query;
    479 
    480     return $wp_query->is_preview;
    481 }
    482 
    483 /**
    484  * Whether the current query post is robots.
    485  *
    486  * @since 2.1.0
    487  * @uses $wp_query
    488  *
     600function is_single( $post = '' ) {
     601    global $wp_query;
     602
     603    if ( ! isset( $wp_query ) ) {
     604        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     605        return false;
     606    }
     607
     608    return $wp_query->is_single( $post );
     609}
     610
     611/**
     612 * Is the query for a single post of any post type (post, attachment, page, ... )?
     613 *
     614 * If the $post_types parameter is specified, this function will additionally
     615 * check if the query is for one of the Posts Types specified.
     616 *
     617 * @see is_page()
     618 * @see is_single()
     619 *
     620 * @see WP_Query::is_singular()
     621 * @since 1.5.0
     622 * @uses $wp_query
     623 *
     624 * @param mixed $post_types Optional. Post Type or array of Post Types
    489625 * @return bool
    490626 */
    491 function is_robots() {
    492     global $wp_query;
    493 
    494     return $wp_query->is_robots;
    495 }
    496 
    497 /**
    498  * Whether current query is the result of a user search.
    499  *
     627function is_singular( $post_types = '' ) {
     628    global $wp_query;
     629
     630    if ( ! isset( $wp_query ) ) {
     631        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     632        return false;
     633    }
     634
     635    return $wp_query->is_singular( $post_types );
     636}
     637
     638/**
     639 * Is the query for a specific time?
     640 *
     641 * @see WP_Query::is_time()
    500642 * @since 1.5.0
    501643 * @uses $wp_query
     
    503645 * @return bool
    504646 */
    505 function is_search() {
    506     global $wp_query;
    507 
    508     return $wp_query->is_search;
    509 }
    510 
    511 /**
    512  * Whether the current page query is single page.
    513  *
    514  * The parameter can contain the post ID, post title, or post name. The
    515  * parameter can also be an array of those three values.
    516  *
    517  * This applies to other post types, attachments, pages, posts. Just means that
    518  * the current query has only a single object.
    519  *
     647function is_time() {
     648    global $wp_query;
     649
     650    if ( ! isset( $wp_query ) ) {
     651        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     652        return false;
     653    }
     654
     655    return $wp_query->is_time();
     656}
     657
     658/**
     659 * Is the query for a trackback endpoint call?
     660 *
     661 * @see WP_Query::is_trackback()
    520662 * @since 1.5.0
    521663 * @uses $wp_query
    522664 *
    523  * @param mixed $post Either post or list of posts to test against.
    524665 * @return bool
    525666 */
    526 function is_single($post = '') {
    527     global $wp_query;
    528 
    529     if ( !$wp_query->is_single )
     667function is_trackback() {
     668    global $wp_query;
     669
     670    if ( ! isset( $wp_query ) ) {
     671        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
    530672        return false;
    531 
    532     if ( empty($post) )
    533         return true;
    534 
    535     $post_obj = $wp_query->get_queried_object();
    536 
    537     $post = (array) $post;
    538 
    539     if ( in_array( $post_obj->ID, $post ) )
    540         return true;
    541     elseif ( in_array( $post_obj->post_title, $post ) )
    542         return true;
    543     elseif ( in_array( $post_obj->post_name, $post ) )
    544         return true;
    545 
    546     return false;
    547 }
    548 
    549 /**
    550  * Whether is single post, is a page, or is an attachment.
    551  *
     673    }
     674
     675    return $wp_query->is_trackback();
     676}
     677
     678/**
     679 * Is the query for a specific year?
     680 *
     681 * @see WP_Query::is_year()
    552682 * @since 1.5.0
    553683 * @uses $wp_query
    554684 *
    555  * @param string|array $post_types Optional. Post type or types to check in current query.
    556685 * @return bool
    557686 */
    558 function is_singular($post_types = '') {
    559     global $wp_query;
    560 
    561     if ( empty($post_types) || !$wp_query->is_singular )
    562         return $wp_query->is_singular;
    563 
    564     $post_obj = $wp_query->get_queried_object();
    565 
    566     return in_array($post_obj->post_type, (array) $post_types);
    567 }
    568 
    569 /**
    570  * Whether the query contains a time.
    571  *
     687function is_year() {
     688    global $wp_query;
     689
     690    if ( ! isset( $wp_query ) ) {
     691        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     692        return false;
     693    }
     694
     695    return $wp_query->is_year();
     696}
     697
     698/**
     699 * Is the query a 404 (returns no results)?
     700 *
     701 * @see WP_Query::is_404()
    572702 * @since 1.5.0
    573703 * @uses $wp_query
     
    575705 * @return bool
    576706 */
    577 function is_time() {
    578     global $wp_query;
    579 
    580     return $wp_query->is_time;
    581 }
    582 
    583 /**
    584  * Whether the query is a trackback.
    585  *
    586  * @since 1.5.0
    587  * @uses $wp_query
    588  *
    589  * @return bool
    590  */
    591 function is_trackback() {
    592     global $wp_query;
    593 
    594     return $wp_query->is_trackback;
    595 }
    596 
    597 /**
    598  * Whether the query contains a year.
    599  *
    600  * @since 1.5.0
    601  * @uses $wp_query
    602  *
    603  * @return bool
    604  */
    605 function is_year() {
    606     global $wp_query;
    607 
    608     return $wp_query->is_year;
    609 }
    610 
    611 /**
    612  * Whether current page query is a 404 and no results for WordPress query.
    613  *
    614  * @since 1.5.0
    615  * @uses $wp_query
    616  *
    617  * @return bool True, if nothing is found matching WordPress Query.
    618  */
    619707function is_404() {
    620708    global $wp_query;
    621709
    622     return $wp_query->is_404;
     710    if ( ! isset( $wp_query ) ) {
     711        _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
     712        return false;
     713    }
     714
     715    return $wp_query->is_404();
    623716}
    624717
     
    730823
    731824    /**
    732      * Query string
    733      *
    734      * @since 1.5.0
     825     * Query vars set by the user
     826     *
     827     * @since 1.5.0
     828     * @access public
     829     * @var array
     830     */
     831    var $query;
     832
     833    /**
     834     * Query vars, after parsing
     835     *
     836     * @since 1.5.0
     837     * @access public
     838     * @var array
     839     */
     840    var $query_vars = array();
     841
     842    /**
     843     * Taxonomy query, as passed to get_tax_sql()
     844     *
     845     * @since 3.1.0
     846     * @access public
     847     * @var object WP_Tax_Query
     848     */
     849    var $tax_query;
     850
     851    /**
     852     * Holds the data for a single object that is queried.
     853     *
     854     * Holds the contents of a post, page, category, attachment.
     855     *
     856     * @since 1.5.0
     857     * @access public
     858     * @var object|array
     859     */
     860    var $queried_object;
     861
     862    /**
     863     * The ID of the queried object.
     864     *
     865     * @since 1.5.0
     866     * @access public
     867     * @var int
     868     */
     869    var $queried_object_id;
     870
     871    /**
     872     * Get post database query.
     873     *
     874     * @since 2.0.1
    735875     * @access public
    736876     * @var string
    737877     */
    738     var $query;
    739 
    740     /**
    741      * Query search variables set by the user.
     878    var $request;
     879
     880    /**
     881     * List of posts.
    742882     *
    743883     * @since 1.5.0
     
    745885     * @var array
    746886     */
    747     var $query_vars = array();
    748 
    749     /**
    750      * Holds the data for a single object that is queried.
    751      *
    752      * Holds the contents of a post, page, category, attachment.
    753      *
    754      * @since 1.5.0
    755      * @access public
    756      * @var object|array
    757      */
    758     var $queried_object;
    759 
    760     /**
    761      * The ID of the queried object.
     887    var $posts;
     888
     889    /**
     890     * The amount of posts for the current query.
    762891     *
    763892     * @since 1.5.0
     
    765894     * @var int
    766895     */
    767     var $queried_object_id;
    768 
    769     /**
    770      * Get post database query.
    771      *
    772      * @since 2.0.1
    773      * @access public
    774      * @var string
    775      */
    776     var $request;
    777 
    778     /**
    779      * List of posts.
    780      *
    781      * @since 1.5.0
     896    var $post_count = 0;
     897
     898    /**
     899     * Index of the current item in the loop.
     900     *
     901     * @since 1.5.0
     902     * @access public
     903     * @var int
     904     */
     905    var $current_post = -1;
     906
     907    /**
     908     * Whether the loop has started and the caller is in the loop.
     909     *
     910     * @since 2.0.0
     911     * @access public
     912     * @var bool
     913     */
     914    var $in_the_loop = false;
     915
     916    /**
     917     * The current post ID.
     918     *
     919     * @since 1.5.0
     920     * @access public
     921     * @var object
     922     */
     923    var $post;
     924
     925    /**
     926     * The list of comments for current post.
     927     *
     928     * @since 2.2.0
    782929     * @access public
    783930     * @var array
    784931     */
    785     var $posts;
    786 
    787     /**
    788      * The amount of posts for the current query.
    789      *
    790      * @since 1.5.0
     932    var $comments;
     933
     934    /**
     935     * The amount of comments for the posts.
     936     *
     937     * @since 2.2.0
    791938     * @access public
    792939     * @var int
    793940     */
    794     var $post_count = 0;
    795 
    796     /**
    797      * Index of the current item in the loop.
    798      *
    799      * @since 1.5.0
     941    var $comment_count = 0;
     942
     943    /**
     944     * The index of the comment in the comment loop.
     945     *
     946     * @since 2.2.0
    800947     * @access public
    801948     * @var int
    802949     */
    803     var $current_post = -1;
    804 
    805     /**
    806      * Whether the loop has started and the caller is in the loop.
     950    var $current_comment = -1;
     951
     952    /**
     953     * Current comment ID.
     954     *
     955     * @since 2.2.0
     956     * @access public
     957     * @var int
     958     */
     959    var $comment;
     960
     961    /**
     962     * Amount of posts if limit clause was not used.
     963     *
     964     * @since 2.1.0
     965     * @access public
     966     * @var int
     967     */
     968    var $found_posts = 0;
     969
     970    /**
     971     * The amount of pages.
     972     *
     973     * @since 2.1.0
     974     * @access public
     975     * @var int
     976     */
     977    var $max_num_pages = 0;
     978
     979    /**
     980     * The amount of comment pages.
     981     *
     982     * @since 2.7.0
     983     * @access public
     984     * @var int
     985     */
     986    var $max_num_comment_pages = 0;
     987
     988    /**
     989     * Set if query is single post.
     990     *
     991     * @since 1.5.0
     992     * @access public
     993     * @var bool
     994     */
     995    var $is_single = false;
     996
     997    /**
     998     * Set if query is preview of blog.
    807999     *
    8081000     * @since 2.0.0
     
    8101002     * @var bool
    8111003     */
    812     var $in_the_loop = false;
    813 
    814     /**
    815      * The current post ID.
    816      *
    817      * @since 1.5.0
    818      * @access public
    819      * @var int
    820      */
    821     var $post;
    822 
    823     /**
    824      * The list of comments for current post.
     1004    var $is_preview = false;
     1005
     1006    /**
     1007     * Set if query returns a page.
     1008     *
     1009     * @since 1.5.0
     1010     * @access public
     1011     * @var bool
     1012     */
     1013    var $is_page = false;
     1014
     1015    /**
     1016     * Set if query is an archive list.
     1017     *
     1018     * @since 1.5.0
     1019     * @access public
     1020     * @var bool
     1021     */
     1022    var $is_archive = false;
     1023
     1024    /**
     1025     * Set if query is part of a date.
     1026     *
     1027     * @since 1.5.0
     1028     * @access public
     1029     * @var bool
     1030     */
     1031    var $is_date = false;
     1032
     1033    /**
     1034     * Set if query contains a year.
     1035     *
     1036     * @since 1.5.0
     1037     * @access public
     1038     * @var bool
     1039     */
     1040    var $is_year = false;
     1041
     1042    /**
     1043     * Set if query contains a month.
     1044     *
     1045     * @since 1.5.0
     1046     * @access public
     1047     * @var bool
     1048     */
     1049    var $is_month = false;
     1050
     1051    /**
     1052     * Set if query contains a day.
     1053     *
     1054     * @since 1.5.0
     1055     * @access public
     1056     * @var bool
     1057     */
     1058    var $is_day = false;
     1059
     1060    /**
     1061     * Set if query contains time.
     1062     *
     1063     * @since 1.5.0
     1064     * @access public
     1065     * @var bool
     1066     */
     1067    var $is_time = false;
     1068
     1069    /**
     1070     * Set if query contains an author.
     1071     *
     1072     * @since 1.5.0
     1073     * @access public
     1074     * @var bool
     1075     */
     1076    var $is_author = false;
     1077
     1078    /**
     1079     * Set if query contains category.
     1080     *
     1081     * @since 1.5.0
     1082     * @access public
     1083     * @var bool
     1084     */
     1085    var $is_category = false;
     1086
     1087    /**
     1088     * Set if query contains tag.
     1089     *
     1090     * @since 2.3.0
     1091     * @access public
     1092     * @var bool
     1093     */
     1094    var $is_tag = false;
     1095
     1096    /**
     1097     * Set if query contains taxonomy.
     1098     *
     1099     * @since 2.5.0
     1100     * @access public
     1101     * @var bool
     1102     */
     1103    var $is_tax = false;
     1104
     1105    /**
     1106     * Set if query was part of a search result.
     1107     *
     1108     * @since 1.5.0
     1109     * @access public
     1110     * @var bool
     1111     */
     1112    var $is_search = false;
     1113
     1114    /**
     1115     * Set if query is feed display.
     1116     *
     1117     * @since 1.5.0
     1118     * @access public
     1119     * @var bool
     1120     */
     1121    var $is_feed = false;
     1122
     1123    /**
     1124     * Set if query is comment feed display.
    8251125     *
    8261126     * @since 2.2.0
    8271127     * @access public
    828      * @var array
    829      */
    830     var $comments;
    831 
    832     /**
    833      * The amount of comments for the posts.
    834      *
    835      * @since 2.2.0
    836      * @access public
    837      * @var int
    838      */
    839     var $comment_count = 0;
    840 
    841     /**
    842      * The index of the comment in the comment loop.
    843      *
    844      * @since 2.2.0
    845      * @access public
    846      * @var int
    847      */
    848     var $current_comment = -1;
    849 
    850     /**
    851      * Current comment ID.
    852      *
    853      * @since 2.2.0
    854      * @access public
    855      * @var int
    856      */
    857     var $comment;
    858 
    859     /**
    860      * Amount of posts if limit clause was not used.
     1128     * @var bool
     1129     */
     1130    var $is_comment_feed = false;
     1131
     1132    /**
     1133     * Set if query is trackback.
     1134     *
     1135     * @since 1.5.0
     1136     * @access public
     1137     * @var bool
     1138     */
     1139    var $is_trackback = false;
     1140
     1141    /**
     1142     * Set if query is blog homepage.
     1143     *
     1144     * @since 1.5.0
     1145     * @access public
     1146     * @var bool
     1147     */
     1148    var $is_home = false;
     1149
     1150    /**
     1151     * Set if query couldn't found anything.
     1152     *
     1153     * @since 1.5.0
     1154     * @access public
     1155     * @var bool
     1156     */
     1157    var $is_404 = false;
     1158
     1159    /**
     1160     * Set if query is within comments popup window.
     1161     *
     1162     * @since 1.5.0
     1163     * @access public
     1164     * @var bool
     1165     */
     1166    var $is_comments_popup = false;
     1167
     1168    /**
     1169     * Set if query is paged
     1170     *
     1171     * @since 1.5.0
     1172     * @access public
     1173     * @var bool
     1174     */
     1175    var $is_paged = false;
     1176
     1177    /**
     1178     * Set if query is part of administration page.
     1179     *
     1180     * @since 1.5.0
     1181     * @access public
     1182     * @var bool
     1183     */
     1184    var $is_admin = false;
     1185
     1186    /**
     1187     * Set if query is an attachment.
     1188     *
     1189     * @since 2.0.0
     1190     * @access public
     1191     * @var bool
     1192     */
     1193    var $is_attachment = false;
     1194
     1195    /**
     1196     * Set if is single, is a page, or is an attachment.
    8611197     *
    8621198     * @since 2.1.0
    8631199     * @access public
    864      * @var int
    865      */
    866     var $found_posts = 0;
    867 
    868     /**
    869      * The amount of pages.
     1200     * @var bool
     1201     */
     1202    var $is_singular = false;
     1203
     1204    /**
     1205     * Set if query is for robots.
    8701206     *
    8711207     * @since 2.1.0
    8721208     * @access public
    873      * @var int
    874      */
    875     var $max_num_pages = 0;
    876 
    877     /**
    878      * The amount of comment pages.
    879      *
    880      * @since 2.7.0
    881      * @access public
    882      * @var int
    883      */
    884     var $max_num_comment_pages = 0;
    885 
    886     /**
    887      * Set if query is single post.
    888      *
    889      * @since 1.5.0
    890      * @access public
    8911209     * @var bool
    8921210     */
    893     var $is_single = false;
    894 
    895     /**
    896      * Set if query is preview of blog.
    897      *
    898      * @since 2.0.0
     1211    var $is_robots = false;
     1212
     1213    /**
     1214     * Set if query contains posts.
     1215     *
     1216     * Basically, the homepage if the option isn't set for the static homepage.
     1217     *
     1218     * @since 2.1.0
    8991219     * @access public
    9001220     * @var bool
    9011221     */
    902     var $is_preview = false;
    903 
    904     /**
    905      * Set if query returns a page.
    906      *
    907      * @since 1.5.0
     1222    var $is_posts_page = false;
     1223
     1224    /**
     1225     * Set if query is for a post type archive.
     1226     *
     1227     * @since 3.1.0
    9081228     * @access public
    9091229     * @var bool
    9101230     */
    911     var $is_page = false;
    912 
    913     /**
    914      * Set if query is an archive list.
    915      *
    916      * @since 1.5.0
    917      * @access public
     1231    var $is_post_type_archive = false;
     1232
     1233    /**
     1234     * Whether the tax query has been parsed once.
     1235     *
     1236     * @since 3.1.0
     1237     * @access private
    9181238     * @var bool
    9191239     */
    920     var $is_archive = false;
    921 
    922     /**
    923      * Set if query is part of a date.
    924      *
    925      * @since 1.5.0
    926      * @access public
    927      * @var bool
    928      */
    929     var $is_date = false;
    930 
    931     /**
    932      * Set if query contains a year.
    933      *
    934      * @since 1.5.0
    935      * @access public
    936      * @var bool
    937      */
    938     var $is_year = false;
    939 
    940     /**
    941      * Set if query contains a month.
    942      *
    943      * @since 1.5.0
    944      * @access public
    945      * @var bool
    946      */
    947     var $is_month = false;
    948 
    949     /**
    950      * Set if query contains a day.
    951      *
    952      * @since 1.5.0
    953      * @access public
    954      * @var bool
    955      */
    956     var $is_day = false;
    957 
    958     /**
    959      * Set if query contains time.
    960      *
    961      * @since 1.5.0
    962      * @access public
    963      * @var bool
    964      */
    965     var $is_time = false;
    966 
    967     /**
    968      * Set if query contains an author.
    969      *
    970      * @since 1.5.0
    971      * @access public
    972      * @var bool
    973      */
    974     var $is_author = false;
    975 
    976     /**
    977      * Set if query contains category.
    978      *
    979      * @since 1.5.0
    980      * @access public
    981      * @var bool
    982      */
    983     var $is_category = false;
    984 
    985     /**
    986      * Set if query contains tag.
    987      *
    988      * @since 2.3.0
    989      * @access public
    990      * @var bool
    991      */
    992     var $is_tag = false;
    993 
    994     /**
    995      * Set if query contains taxonomy.
    996      *
    997      * @since 2.5.0
    998      * @access public
    999      * @var bool
    1000      */
    1001     var $is_tax = false;
    1002 
    1003     /**
    1004      * Set if query was part of a search result.
    1005      *
    1006      * @since 1.5.0
    1007      * @access public
    1008      * @var bool
    1009      */
    1010     var $is_search = false;
    1011 
    1012     /**
    1013      * Set if query is feed display.
    1014      *
    1015      * @since 1.5.0
    1016      * @access public
    1017      * @var bool
    1018      */
    1019     var $is_feed = false;
    1020 
    1021     /**
    1022      * Set if query is comment feed display.
    1023      *
    1024      * @since 2.2.0
    1025      * @access public
    1026      * @var bool
    1027      */
    1028     var $is_comment_feed = false;
    1029 
    1030     /**
    1031      * Set if query is trackback.
    1032      *
    1033      * @since 1.5.0
    1034      * @access public
    1035      * @var bool
    1036      */
    1037     var $is_trackback = false;
    1038 
    1039     /**
    1040      * Set if query is blog homepage.
    1041      *
    1042      * @since 1.5.0
    1043      * @access public
    1044      * @var bool
    1045      */
    1046     var $is_home = false;
    1047 
    1048     /**
    1049      * Set if query couldn't found anything.
    1050      *
    1051      * @since 1.5.0
    1052      * @access public
    1053      * @var bool
    1054      */
    1055     var $is_404 = false;
    1056 
    1057     /**
    1058      * Set if query is within comments popup window.
    1059      *
    1060      * @since 1.5.0
    1061      * @access public
    1062      * @var bool
    1063      */
    1064     var $is_comments_popup = false;
    1065 
    1066     /**
    1067      * Set if query is part of administration page.
    1068      *
    1069      * @since 1.5.0
    1070      * @access public
    1071      * @var bool
    1072      */
    1073     var $is_admin = false;
    1074 
    1075     /**
    1076      * Set if query is an attachment.
    1077      *
    1078      * @since 2.0.0
    1079      * @access public
    1080      * @var bool
    1081      */
    1082     var $is_attachment = false;
    1083 
    1084     /**
    1085      * Set if is single, is a page, or is an attachment.
    1086      *
    1087      * @since 2.1.0
    1088      * @access public
    1089      * @var bool
    1090      */
    1091     var $is_singular = false;
    1092 
    1093     /**
    1094      * Set if query is for robots.
    1095      *
    1096      * @since 2.1.0
    1097      * @access public
    1098      * @var bool
    1099      */
    1100     var $is_robots = false;
    1101 
    1102     /**
    1103      * Set if query contains posts.
    1104      *
    1105      * Basically, the homepage if the option isn't set for the static homepage.
    1106      *
    1107      * @since 2.1.0
    1108      * @access public
    1109      * @var bool
    1110      */
    1111     var $is_posts_page = false;
     1240    var $parsed_tax_query = false;
    11121241
    11131242    /**
     
    11211250    function init_query_flags() {
    11221251        $this->is_single = false;
     1252        $this->is_preview = false;
    11231253        $this->is_page = false;
    11241254        $this->is_archive = false;
     
    11381268        $this->is_home = false;
    11391269        $this->is_404 = false;
     1270        $this->is_comments_popup = false;
    11401271        $this->is_paged = false;
    11411272        $this->is_admin = false;
     
    11441275        $this->is_robots = false;
    11451276        $this->is_posts_page = false;
     1277        $this->is_post_type_archive = false;
    11461278    }
    11471279
     
    11611293        $this->current_post = -1;
    11621294        $this->in_the_loop = false;
     1295        unset( $this->request );
     1296        unset( $this->post );
     1297        unset( $this->comments );
     1298        unset( $this->comment );
     1299        $this->comment_count = 0;
     1300        $this->current_comment = -1;
     1301        $this->found_posts = 0;
     1302        $this->max_num_pages = 0;
     1303        $this->max_num_comment_pages = 0;
    11631304
    11641305        $this->init_query_flags();
     
    11721313     */
    11731314    function parse_query_vars() {
    1174         $this->parse_query('');
     1315        $this->parse_query();
    11751316    }
    11761317
     
    12191360            , 's'
    12201361            , 'sentence'
     1362            , 'fields'
    12211363        );
    12221364
    12231365        foreach ( $keys as $key ) {
    1224             if ( !isset($array[$key]))
     1366            if ( !isset($array[$key]) )
    12251367                $array[$key] = '';
    12261368        }
     
    12301372
    12311373        foreach ( $array_keys as $key ) {
    1232             if ( !isset($array[$key]))
     1374            if ( !isset($array[$key]) )
    12331375                $array[$key] = array();
    12341376        }
     
    12421384     * @access public
    12431385     *
    1244      * @param string|array $query
    1245      */
    1246     function parse_query($query) {
    1247         if ( !empty($query) || !isset($this->query) ) {
     1386     * @param string|array $query Optional query.
     1387     */
     1388    function parse_query( $query =  '' ) {
     1389        if ( ! empty( $query ) ) {
    12481390            $this->init();
    1249             if ( is_array($query) )
    1250                 $this->query_vars = $query;
    1251             else
    1252                 parse_str($query, $this->query_vars);
    1253             $this->query = $query;
     1391            $this->query = $this->query_vars = wp_parse_args( $query );
     1392        } elseif ( ! isset( $this->query ) ) {
     1393            $this->query = $this->query_vars;
    12541394        }
    12551395
     
    12971437            $this->is_page = true;
    12981438            $this->is_single = false;
    1299         } elseif ( !empty($qv['s']) ) {
    1300             $this->is_search = true;
    13011439        } else {
    1302         // Look for archive queries.  Dates, categories, authors.
     1440        // Look for archive queries.  Dates, categories, authors, search, post type archives.
     1441
     1442            if ( !empty($qv['s']) ) {
     1443                $this->is_search = true;
     1444            }
    13031445
    13041446            if ( '' !== $qv['second'] ) {
     
    13551497            }
    13561498
    1357             if ( empty($qv['cat']) || ($qv['cat'] == '0') ) {
    1358                 $this->is_category = false;
    1359             } else {
    1360                 if ( strpos($qv['cat'], '-') !== false ) {
    1361                     $this->is_category = false;
    1362                 } else {
    1363                     $this->is_category = true;
    1364                 }
    1365             }
    1366 
    1367             if ( '' != $qv['category_name'] ) {
    1368                 $this->is_category = true;
    1369             }
    1370 
    1371             if ( !is_array($qv['category__in']) || empty($qv['category__in']) ) {
    1372                 $qv['category__in'] = array();
    1373             } else {
    1374                 $qv['category__in'] = array_map('absint', $qv['category__in']);
    1375                 $this->is_category = true;
    1376             }
    1377 
    1378             if ( !is_array($qv['category__not_in']) || empty($qv['category__not_in']) ) {
    1379                 $qv['category__not_in'] = array();
    1380             } else {
    1381                 $qv['category__not_in'] = array_map('absint', $qv['category__not_in']);
    1382             }
    1383 
    1384             if ( !is_array($qv['category__and']) || empty($qv['category__and']) ) {
    1385                 $qv['category__and'] = array();
    1386             } else {
    1387                 $qv['category__and'] = array_map('absint', $qv['category__and']);
    1388                 $this->is_category = true;
    1389             }
    1390 
    1391             if (  '' != $qv['tag'] )
    1392                 $this->is_tag = true;
    1393 
    1394             $qv['tag_id'] = absint($qv['tag_id']);
    1395             if (  !empty($qv['tag_id']) )
    1396                 $this->is_tag = true;
    1397 
    1398             if ( !is_array($qv['tag__in']) || empty($qv['tag__in']) ) {
    1399                 $qv['tag__in'] = array();
    1400             } else {
    1401                 $qv['tag__in'] = array_map('absint', $qv['tag__in']);
    1402                 $this->is_tag = true;
    1403             }
    1404 
    1405             if ( !is_array($qv['tag__not_in']) || empty($qv['tag__not_in']) ) {
    1406                 $qv['tag__not_in'] = array();
    1407             } else {
    1408                 $qv['tag__not_in'] = array_map('absint', $qv['tag__not_in']);
    1409             }
    1410 
    1411             if ( !is_array($qv['tag__and']) || empty($qv['tag__and']) ) {
    1412                 $qv['tag__and'] = array();
    1413             } else {
    1414                 $qv['tag__and'] = array_map('absint', $qv['tag__and']);
    1415                 $this->is_category = true;
    1416             }
    1417 
    1418             if ( !is_array($qv['tag_slug__in']) || empty($qv['tag_slug__in']) ) {
    1419                 $qv['tag_slug__in'] = array();
    1420             } else {
    1421                 $qv['tag_slug__in'] = array_map('sanitize_title', $qv['tag_slug__in']);
    1422                 $this->is_tag = true;
    1423             }
    1424 
    1425             if ( !is_array($qv['tag_slug__and']) || empty($qv['tag_slug__and']) ) {
    1426                 $qv['tag_slug__and'] = array();
    1427             } else {
    1428                 $qv['tag_slug__and'] = array_map('sanitize_title', $qv['tag_slug__and']);
    1429                 $this->is_tag = true;
    1430             }
    1431 
    1432             if ( empty($qv['taxonomy']) || empty($qv['term']) ) {
    1433                 $this->is_tax = false;
    1434                 foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t ) {
    1435                     if ( $t->query_var && isset($qv[$t->query_var]) && '' != $qv[$t->query_var] ) {
    1436                         $qv['taxonomy'] = $taxonomy;
    1437                         $qv['term'] = $qv[$t->query_var];
    1438                         $this->is_tax = true;
    1439                         break;
     1499            $this->parsed_tax_query = false;
     1500            $this->parse_tax_query( $qv );
     1501
     1502            foreach ( $this->tax_query->queries as $tax_query ) {
     1503                if ( 'IN' == $tax_query['operator'] ) {
     1504                    switch ( $tax_query['taxonomy'] ) {
     1505                        case 'category':
     1506                            $this->is_category = true;
     1507                            break;
     1508                        case 'post_tag':
     1509                            $this->is_tag = true;
     1510                            break;
     1511                        default:
     1512                            $this->is_tax = true;
    14401513                    }
    14411514                }
    1442             } else {
    1443                 $this->is_tax = true;
    1444             }
     1515            }
     1516            unset( $tax_query );
     1517
     1518            _parse_meta_query( $qv );
    14451519
    14461520            if ( empty($qv['author']) || ($qv['author'] == '0') ) {
     
    14501524            }
    14511525
    1452             if ( '' != $qv['author_name'] ) {
     1526            if ( '' != $qv['author_name'] )
    14531527                $this->is_author = true;
    1454             }
    1455 
    1456             if ( ($this->is_date || $this->is_author || $this->is_category || $this->is_tag || $this->is_tax) )
     1528
     1529            if ( !empty( $qv['post_type'] ) && ! is_array( $qv['post_type'] ) ) {
     1530                $post_type_obj = get_post_type_object( $qv['post_type'] );
     1531                if ( ! empty( $post_type_obj->has_archive ) )
     1532                    $this->is_post_type_archive = true;
     1533            }
     1534
     1535            if ( $this->is_post_type_archive || $this->is_date || $this->is_author || $this->is_category || $this->is_tag || $this->is_tax )
    14571536                $this->is_archive = true;
    14581537        }
     
    14921571        // Correct is_* for page_on_front and page_for_posts
    14931572        if ( $this->is_home && 'page' == get_option('show_on_front') && get_option('page_on_front') ) {
    1494             $_query = wp_parse_args($query);
     1573            $_query = wp_parse_args($this->query);
     1574            // pagename can be set and empty depending on matched rewrite rules. Ignore an empty pagename.
     1575            if ( isset($_query['pagename']) && '' == $_query['pagename'] )
     1576                unset($_query['pagename']);
    14951577            if ( empty($_query) || !array_diff( array_keys($_query), array('preview', 'page', 'paged', 'cpage') ) ) {
    14961578                $this->is_page = true;
     
    15291611        if ( !empty($qv['post_type']) ) {
    15301612            if ( is_array($qv['post_type']) )
    1531                 $qv['post_type'] = array_map('sanitize_user', $qv['post_type'], array(true));
     1613                $qv['post_type'] = array_map('sanitize_key', $qv['post_type']);
    15321614            else
    1533                 $qv['post_type'] = sanitize_user($qv['post_type'], true);
     1615                $qv['post_type'] = sanitize_key($qv['post_type']);
    15341616        }
    15351617
     
    15461628            $this->set_404();
    15471629
    1548         if ( !empty($query) )
    1549             do_action_ref_array('parse_query', array(&$this));
    1550     }
    1551 
    1552     /**
    1553      * Sets the 404 property and saves whether query is feed.
    1554      *
    1555      * @since 2.0.0
    1556      * @access public
    1557      */
    1558     function set_404() {
    1559         $is_feed = $this->is_feed;
    1560 
    1561         $this->init_query_flags();
    1562         $this->is_404 = true;
    1563 
    1564         $this->is_feed = $is_feed;
    1565     }
    1566 
    1567     /**
    1568      * Retrieve query variable.
    1569      *
    1570      * @since 1.5.0
    1571      * @access public
    1572      *
    1573      * @param string $query_var Query variable key.
    1574      * @return mixed
    1575      */
    1576     function get($query_var) {
    1577         if ( isset($this->query_vars[$query_var]) )
    1578             return $this->query_vars[$query_var];
    1579 
    1580         return '';
    1581     }
    1582 
    1583     /**
    1584      * Set query variable.
    1585      *
    1586      * @since 1.5.0
    1587      * @access public
    1588      *
    1589      * @param string $query_var Query variable key.
    1590      * @param mixed $value Query variable value.
    1591      */
    1592     function set($query_var, $value) {
    1593         $this->query_vars[$query_var] = $value;
    1594     }
    1595 
    1596     /**
    1597      * Retrieve the posts based on query variables.
    1598      *
    1599      * There are a few filters and actions that can be used to modify the post
    1600      * database query.
    1601      *
    1602      * @since 1.5.0
    1603      * @access public
    1604      * @uses do_action_ref_array() Calls 'pre_get_posts' hook before retrieving posts.
    1605      *
    1606      * @return array List of posts.
    1607      */
    1608     function &get_posts() {
    1609         global $wpdb, $user_ID, $_wp_using_ext_object_cache;
    1610 
    1611         do_action_ref_array('pre_get_posts', array(&$this));
    1612 
    1613         // Shorthand.
    1614         $q = &$this->query_vars;
    1615 
    1616         $q = $this->fill_query_vars($q);
    1617 
    1618         // First let's clear some variables
    1619         $distinct = '';
    1620         $whichcat = '';
    1621         $whichauthor = '';
    1622         $whichmimetype = '';
    1623         $where = '';
    1624         $limits = '';
    1625         $join = '';
    1626         $search = '';
    1627         $groupby = '';
    1628         $fields = "$wpdb->posts.*";
    1629         $post_status_join = false;
    1630         $page = 1;
    1631 
    1632         if ( !isset($q['caller_get_posts']) )
    1633             $q['caller_get_posts'] = false;
    1634 
    1635         if ( !isset($q['suppress_filters']) )
    1636             $q['suppress_filters'] = false;
    1637 
    1638         if ( !isset($q['cache_results']) ) {
    1639             if ( $_wp_using_ext_object_cache )
    1640                 $q['cache_results'] = false;
    1641             else
    1642                 $q['cache_results'] = true;
    1643         }
    1644 
    1645         if ( !isset($q['update_post_term_cache']) )
    1646             $q['update_post_term_cache'] = true;
    1647 
    1648         if ( !isset($q['update_post_meta_cache']) )
    1649             $q['update_post_meta_cache'] = true;
    1650 
    1651         if ( !isset($q['post_type']) ) {
    1652             if ( $this->is_search )
    1653                 $q['post_type'] = 'any';
    1654             else
    1655                 $q['post_type'] = '';
    1656         }
    1657         $post_type = $q['post_type'];
    1658         if ( !isset($q['posts_per_page']) || $q['posts_per_page'] == 0 )
    1659             $q['posts_per_page'] = get_option('posts_per_page');
    1660         if ( isset($q['showposts']) && $q['showposts'] ) {
    1661             $q['showposts'] = (int) $q['showposts'];
    1662             $q['posts_per_page'] = $q['showposts'];
    1663         }
    1664         if ( (isset($q['posts_per_archive_page']) && $q['posts_per_archive_page'] != 0) && ($this->is_archive || $this->is_search) )
    1665             $q['posts_per_page'] = $q['posts_per_archive_page'];
    1666         if ( !isset($q['nopaging']) ) {
    1667             if ( $q['posts_per_page'] == -1 ) {
    1668                 $q['nopaging'] = true;
    1669             } else {
    1670                 $q['nopaging'] = false;
    1671             }
    1672         }
    1673         if ( $this->is_feed ) {
    1674             $q['posts_per_page'] = get_option('posts_per_rss');
    1675             $q['nopaging'] = false;
    1676         }
    1677         $q['posts_per_page'] = (int) $q['posts_per_page'];
    1678         if ( $q['posts_per_page'] < -1 )
    1679             $q['posts_per_page'] = abs($q['posts_per_page']);
    1680         else if ( $q['posts_per_page'] == 0 )
    1681             $q['posts_per_page'] = 1;
    1682 
    1683         if ( !isset($q['comments_per_page']) || $q['comments_per_page'] == 0 )
    1684             $q['comments_per_page'] = get_option('comments_per_page');
    1685 
    1686         if ( $this->is_home && (empty($this->query) || $q['preview'] == 'true') && ( 'page' == get_option('show_on_front') ) && get_option('page_on_front') ) {
    1687             $this->is_page = true;
    1688             $this->is_home = false;
    1689             $q['page_id'] = get_option('page_on_front');
    1690         }
    1691 
    1692         if ( isset($q['page']) ) {
    1693             $q['page'] = trim($q['page'], '/');
    1694             $q['page'] = absint($q['page']);
    1695         }
    1696 
    1697         // If true, forcibly turns off SQL_CALC_FOUND_ROWS even when limits are present.
    1698         if ( isset($q['no_found_rows']) )
    1699             $q['no_found_rows'] = (bool) $q['no_found_rows'];
    1700         else
    1701             $q['no_found_rows'] = false;
    1702 
    1703         // If a month is specified in the querystring, load that month
    1704         if ( $q['m'] ) {
    1705             $q['m'] = '' . preg_replace('|[^0-9]|', '', $q['m']);
    1706             $where .= " AND YEAR($wpdb->posts.post_date)=" . substr($q['m'], 0, 4);
    1707             if ( strlen($q['m']) > 5 )
    1708                 $where .= " AND MONTH($wpdb->posts.post_date)=" . substr($q['m'], 4, 2);
    1709             if ( strlen($q['m']) > 7 )
    1710                 $where .= " AND DAYOFMONTH($wpdb->posts.post_date)=" . substr($q['m'], 6, 2);
    1711             if ( strlen($q['m']) > 9 )
    1712                 $where .= " AND HOUR($wpdb->posts.post_date)=" . substr($q['m'], 8, 2);
    1713             if ( strlen($q['m']) > 11 )
    1714                 $where .= " AND MINUTE($wpdb->posts.post_date)=" . substr($q['m'], 10, 2);
    1715             if ( strlen($q['m']) > 13 )
    1716                 $where .= " AND SECOND($wpdb->posts.post_date)=" . substr($q['m'], 12, 2);
    1717         }
    1718 
    1719         if ( '' !== $q['hour'] )
    1720             $where .= " AND HOUR($wpdb->posts.post_date)='" . $q['hour'] . "'";
    1721 
    1722         if ( '' !== $q['minute'] )
    1723             $where .= " AND MINUTE($wpdb->posts.post_date)='" . $q['minute'] . "'";
    1724 
    1725         if ( '' !== $q['second'] )
    1726             $where .= " AND SECOND($wpdb->posts.post_date)='" . $q['second'] . "'";
    1727 
    1728         if ( $q['year'] )
    1729             $where .= " AND YEAR($wpdb->posts.post_date)='" . $q['year'] . "'";
    1730 
    1731         if ( $q['monthnum'] )
    1732             $where .= " AND MONTH($wpdb->posts.post_date)='" . $q['monthnum'] . "'";
    1733 
    1734         if ( $q['day'] )
    1735             $where .= " AND DAYOFMONTH($wpdb->posts.post_date)='" . $q['day'] . "'";
    1736 
    1737         // If we've got a post_type AND its not "any" post_type.
    1738         if ( !empty($q['post_type']) && 'any' != $q['post_type'] ) {
    1739             foreach ( (array)$q['post_type'] as $_post_type ) {
    1740                 $ptype_obj = get_post_type_object($_post_type);
    1741                 if ( !$ptype_obj || !$ptype_obj->query_var || empty($q[ $ptype_obj->query_var ]) )
    1742                     continue;
    1743 
    1744                 if ( ! $ptype_obj->hierarchical || strpos($q[ $ptype_obj->query_var ], '/') === false ) {
    1745                     // Non-hierarchical post_types & parent-level-hierarchical post_types can directly use 'name'
    1746                     $q['name'] = $q[ $ptype_obj->query_var ];
     1630        do_action_ref_array('parse_query', array(&$this));
     1631    }
     1632
     1633    /*
     1634     * Parses various taxonomy related query vars.
     1635     *
     1636     * @access protected
     1637     * @since 3.1.0
     1638     *
     1639     * @param array &$q The query variables
     1640     */
     1641    function parse_tax_query( &$q ) {
     1642        if ( ! empty( $q['tax_query'] ) && is_array( $q['tax_query'] ) ) {
     1643            $tax_query = $q['tax_query'];
     1644        } else {
     1645            $tax_query = array();
     1646        }
     1647
     1648        if ( !empty($q['taxonomy']) && !empty($q['term']) ) {
     1649            $tax_query[] = array(
     1650                'taxonomy' => $q['taxonomy'],
     1651                'terms' => array( $q['term'] ),
     1652                'field' => 'slug',
     1653            );
     1654        }
     1655
     1656        foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t ) {
     1657            if ( $t->query_var && !empty( $q[$t->query_var] ) ) {
     1658                $tax_query_defaults = array(
     1659                    'taxonomy' => $taxonomy,
     1660                    'field' => 'slug',
     1661                );
     1662
     1663                if ( isset( $t->rewrite['hierarchical'] ) && $t->rewrite['hierarchical'] ) {
     1664                    $q[$t->query_var] = wp_basename( $q[$t->query_var] );
     1665                }
     1666
     1667                $term = $q[$t->query_var];
     1668
     1669                if ( strpos($term, '+') !== false ) {
     1670                    $terms = preg_split( '/[+]+/', $term );
     1671                    foreach ( $terms as $term ) {
     1672                        $tax_query[] = array_merge( $tax_query_defaults, array(
     1673                            'terms' => array( $term )
     1674                        ) );
     1675                    }
    17471676                } else {
    1748                     // Hierarchical post_types will operate through the
    1749                     $q['pagename'] = $q[ $ptype_obj->query_var ];
    1750                     $q['name'] = '';
     1677                    $tax_query[] = array_merge( $tax_query_defaults, array(
     1678                        'terms' => preg_split( '/[,]+/', $term )
     1679                    ) );
    17511680                }
    1752 
    1753                 // Only one request for a slug is possible, this is why name & pagename are overwritten above.
    1754                 break;
    1755             } //end foreach
    1756             unset($ptype_obj);
    1757         }
    1758 
    1759         if ( '' != $q['name'] ) {
    1760             $q['name'] = sanitize_title($q['name']);
    1761             $where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'";
    1762         } elseif ( '' != $q['pagename'] ) {
    1763             if ( isset($this->queried_object_id) ) {
    1764                 $reqpage = $this->queried_object_id;
    1765             } else {
    1766                 if ( 'page' != $q['post_type'] ) {
    1767                     foreach ( (array)$q['post_type'] as $_post_type ) {
    1768                         $ptype_obj = get_post_type_object($_post_type);
    1769                         if ( !$ptype_obj || !$ptype_obj->hierarchical )
    1770                             continue;
    1771 
    1772                         $reqpage = get_page_by_path($q['pagename'], OBJECT, $_post_type);
    1773                         if ( $reqpage )
    1774                             break;
    1775                     }
    1776                     unset($ptype_obj);
    1777                 } else {
    1778                     $reqpage = get_page_by_path($q['pagename']);
    1779                 }
    1780                 if ( !empty($reqpage) )
    1781                     $reqpage = $reqpage->ID;
    1782                 else
    1783                     $reqpage = 0;
    1784             }
    1785 
    1786             $page_for_posts = get_option('page_for_posts');
    1787             if  ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) {
    1788                 $q['pagename'] = str_replace('%2F', '/', urlencode(urldecode($q['pagename'])));
    1789                 $page_paths = '/' . trim($q['pagename'], '/');
    1790                 $q['pagename'] = sanitize_title(basename($page_paths));
    1791                 $q['name'] = $q['pagename'];
    1792                 $where .= " AND ($wpdb->posts.ID = '$reqpage')";
    1793                 $reqpage_obj = get_page($reqpage);
    1794                 if ( is_object($reqpage_obj) && 'attachment' == $reqpage_obj->post_type ) {
    1795                     $this->is_attachment = true;
    1796                     $post_type = $q['post_type'] = 'attachment';
    1797                     $this->is_page = true;
    1798                     $q['attachment_id'] = $reqpage;
    1799                 }
    1800             }
    1801         } elseif ( '' != $q['attachment'] ) {
    1802             $q['attachment'] = str_replace('%2F', '/', urlencode(urldecode($q['attachment'])));
    1803             $attach_paths = '/' . trim($q['attachment'], '/');
    1804             $q['attachment'] = sanitize_title(basename($attach_paths));
    1805             $q['name'] = $q['attachment'];
    1806             $where .= " AND $wpdb->posts.post_name = '" . $q['attachment'] . "'";
    1807         }
    1808 
    1809         if ( $q['w'] )
    1810             $where .= ' AND ' . _wp_mysql_week( "`$wpdb->posts`.`post_date`" ) . " = '" . $q['w'] . "'";
    1811 
    1812         if ( intval($q['comments_popup']) )
    1813             $q['p'] = absint($q['comments_popup']);
    1814 
    1815         // If an attachment is requested by number, let it supercede any post number.
    1816         if ( $q['attachment_id'] )
    1817             $q['p'] = absint($q['attachment_id']);
    1818 
    1819         // If a post number is specified, load that post
    1820         if ( $q['p'] ) {
    1821             $where .= " AND {$wpdb->posts}.ID = " . $q['p'];
    1822         } elseif ( $q['post__in'] ) {
    1823             $post__in = implode(',', array_map( 'absint', $q['post__in'] ));
    1824             $where .= " AND {$wpdb->posts}.ID IN ($post__in)";
    1825         } elseif ( $q['post__not_in'] ) {
    1826             $post__not_in = implode(',',  array_map( 'absint', $q['post__not_in'] ));
    1827             $where .= " AND {$wpdb->posts}.ID NOT IN ($post__not_in)";
    1828         }
    1829 
    1830         if ( is_numeric($q['post_parent']) )
    1831             $where .= $wpdb->prepare( " AND $wpdb->posts.post_parent = %d ", $q['post_parent'] );
    1832 
    1833         if ( $q['page_id'] ) {
    1834             if  ( ('page' != get_option('show_on_front') ) || ( $q['page_id'] != get_option('page_for_posts') ) ) {
    1835                 $q['p'] = $q['page_id'];
    1836                 $where = " AND {$wpdb->posts}.ID = " . $q['page_id'];
    1837             }
    1838         }
    1839 
    1840         // If a search pattern is specified, load the posts that match
    1841         if ( !empty($q['s']) ) {
    1842             // added slashes screw with quote grouping when done early, so done later
    1843             $q['s'] = stripslashes($q['s']);
    1844             if ( !empty($q['sentence']) ) {
    1845                 $q['search_terms'] = array($q['s']);
    1846             } else {
    1847                 preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $q['s'], $matches);
    1848                 $q['search_terms'] = array_map('_search_terms_tidy', $matches[0]);
    1849             }
    1850             $n = !empty($q['exact']) ? '' : '%';
    1851             $searchand = '';
    1852             foreach( (array) $q['search_terms'] as $term ) {
    1853                 $term = addslashes_gpc($term);
    1854                 $search .= "{$searchand}(($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}'))";
    1855                 $searchand = ' AND ';
    1856             }
    1857             $term = esc_sql($q['s']);
    1858             if ( empty($q['sentence']) && count($q['search_terms']) > 1 && $q['search_terms'][0] != $q['s'] )
    1859                 $search .= " OR ($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}')";
    1860 
    1861             if ( !empty($search) ) {
    1862                 $search = " AND ({$search}) ";
    1863                 if ( !is_user_logged_in() )
    1864                     $search .= " AND ($wpdb->posts.post_password = '') ";
    1865             }
    1866         }
    1867 
    1868         // Allow plugins to contextually add/remove/modify the search section of the database query
    1869         $search = apply_filters_ref_array('posts_search', array( $search, &$this ) );
     1681            }
     1682        }
    18701683
    18711684        // Category stuff
    1872 
    1873         if ( empty($q['cat']) || ($q['cat'] == '0') ||
    1874                 // Bypass cat checks if fetching specific posts
    1875                 $this->is_singular ) {
    1876             $whichcat = '';
    1877         } else {
     1685        if ( !empty($q['cat']) && '0' != $q['cat'] && !$this->is_singular && !$this->parsed_tax_query ) {
    18781686            $q['cat'] = ''.urldecode($q['cat']).'';
    18791687            $q['cat'] = addslashes_gpc($q['cat']);
     
    18881696                if ( $in ) {
    18891697                    $q['category__in'][] = $cat;
    1890                     $q['category__in'] = array_merge($q['category__in'], get_term_children($cat, 'category'));
     1698                    $q['category__in'] = array_merge( $q['category__in'], get_term_children($cat, 'category') );
    18911699                } else {
    18921700                    $q['category__not_in'][] = $cat;
    1893                     $q['category__not_in'] = array_merge($q['category__not_in'], get_term_children($cat, 'category'));
     1701                    $q['category__not_in'] = array_merge( $q['category__not_in'], get_term_children($cat, 'category') );
    18941702                }
    18951703            }
     
    18981706
    18991707        if ( !empty($q['category__in']) ) {
    1900             $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) ";
    1901             $whichcat .= " AND $wpdb->term_taxonomy.taxonomy = 'category' ";
    1902             $include_cats = "'" . implode("', '", $q['category__in']) . "'";
    1903             $whichcat .= " AND $wpdb->term_taxonomy.term_id IN ($include_cats) ";
     1708            $q['category__in'] = array_map('absint', array_unique( (array) $q['category__in'] ) );
     1709            $tax_query[] = array(
     1710                'taxonomy' => 'category',
     1711                'terms' => $q['category__in'],
     1712                'field' => 'term_id',
     1713                'include_children' => false
     1714            );
    19041715        }
    19051716
    19061717        if ( !empty($q['category__not_in']) ) {
    1907             $cat_string = "'" . implode("', '", $q['category__not_in']) . "'";
    1908             $whichcat .= " AND $wpdb->posts.ID NOT IN ( SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy = 'category' AND tt.term_id IN ($cat_string) )";
    1909         }
    1910 
    1911         // Category stuff for nice URLs
    1912         if ( '' != $q['category_name'] && !$this->is_singular ) {
    1913             $q['category_name'] = implode('/', array_map('sanitize_title', explode('/', $q['category_name'])));
    1914             $reqcat = get_category_by_path($q['category_name']);
    1915             $q['category_name'] = str_replace('%2F', '/', urlencode(urldecode($q['category_name'])));
    1916             $cat_paths = '/' . trim($q['category_name'], '/');
    1917             $q['category_name'] = sanitize_title(basename($cat_paths));
    1918 
    1919             $cat_paths = '/' . trim(urldecode($q['category_name']), '/');
    1920             $q['category_name'] = sanitize_title(basename($cat_paths));
    1921             $cat_paths = explode('/', $cat_paths);
    1922             $cat_path = '';
    1923             foreach ( (array) $cat_paths as $pathdir )
    1924                 $cat_path .= ( $pathdir != '' ? '/' : '' ) . sanitize_title($pathdir);
    1925 
    1926             //if we don't match the entire hierarchy fallback on just matching the nicename
    1927             if ( empty($reqcat) )
    1928                 $reqcat = get_category_by_path($q['category_name'], false);
    1929 
    1930             if ( !empty($reqcat) )
    1931                 $reqcat = $reqcat->term_id;
    1932             else
    1933                 $reqcat = 0;
    1934 
    1935             $q['cat'] = $reqcat;
    1936 
    1937             $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) ";
    1938             $whichcat = " AND $wpdb->term_taxonomy.taxonomy = 'category' ";
    1939             $in_cats = array($q['cat']);
    1940             $in_cats = array_merge($in_cats, get_term_children($q['cat'], 'category'));
    1941             $in_cats = "'" . implode("', '", $in_cats) . "'";
    1942             $whichcat .= "AND $wpdb->term_taxonomy.term_id IN ($in_cats)";
    1943             $groupby = "{$wpdb->posts}.ID";
    1944         }
    1945 
    1946         // Tags
    1947         if ( '' != $q['tag'] ) {
     1718            $q['category__not_in'] = array_map('absint', array_unique( (array) $q['category__not_in'] ) );
     1719            $tax_query[] = array(
     1720                'taxonomy' => 'category',
     1721                'terms' => $q['category__not_in'],
     1722                'operator' => 'NOT IN',
     1723                'include_children' => false
     1724            );
     1725        }
     1726
     1727        if ( !empty($q['category__and']) ) {
     1728            $q['category__and'] = array_map('absint', array_unique( (array) $q['category__and'] ) );
     1729            $tax_query[] = array(
     1730                'taxonomy' => 'category',
     1731                'terms' => $q['category__and'],
     1732                'field' => 'term_id',
     1733                'operator' => 'AND',
     1734                'include_children' => false
     1735            );
     1736        }
     1737
     1738        // Tag stuff
     1739        if ( '' != $q['tag'] && !$this->is_singular && !$this->parsed_tax_query ) {
    19481740            if ( strpos($q['tag'], ',') !== false ) {
    19491741                $tags = preg_split('/[,\s]+/', $q['tag']);
     
    19641756        }
    19651757
    1966         if ( !empty($q['category__in']) || !empty($q['meta_key']) || !empty($q['tag__in']) || !empty($q['tag_slug__in']) ) {
    1967             $groupby = "{$wpdb->posts}.ID";
    1968         }
    1969 
    1970         if ( !empty($q['tag__in']) && empty($q['cat']) ) {
    1971             $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) ";
    1972             $whichcat .= " AND $wpdb->term_taxonomy.taxonomy = 'post_tag' ";
    1973             $include_tags = "'" . implode("', '", $q['tag__in']) . "'";
    1974             $whichcat .= " AND $wpdb->term_taxonomy.term_id IN ($include_tags) ";
    1975             $reqtag = term_exists( $q['tag__in'][0], 'post_tag' );
    1976             if ( !empty($reqtag) )
    1977                 $q['tag_id'] = $reqtag['term_id'];
    1978         }
    1979 
    1980         if ( !empty($q['tag_slug__in']) && empty($q['cat']) ) {
    1981             $join = " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) INNER JOIN $wpdb->terms ON ($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id) ";
    1982             $whichcat .= " AND $wpdb->term_taxonomy.taxonomy = 'post_tag' ";
    1983             $include_tags = "'" . implode("', '", $q['tag_slug__in']) . "'";
    1984             $whichcat .= " AND $wpdb->terms.slug IN ($include_tags) ";
    1985             $reqtag = get_term_by( 'slug', $q['tag_slug__in'][0], 'post_tag' );
    1986             if ( !empty($reqtag) )
    1987                 $q['tag_id'] = $reqtag->term_id;
     1758        if ( !empty($q['tag_id']) ) {
     1759            $q['tag_id'] = absint( $q['tag_id'] );
     1760            $tax_query[] = array(
     1761                'taxonomy' => 'post_tag',
     1762                'terms' => $q['tag_id']
     1763            );
     1764        }
     1765
     1766        if ( !empty($q['tag__in']) ) {
     1767            $q['tag__in'] = array_map('absint', array_unique( (array) $q['tag__in'] ) );
     1768            $tax_query[] = array(
     1769                'taxonomy' => 'post_tag',
     1770                'terms' => $q['tag__in']
     1771            );
    19881772        }
    19891773
    19901774        if ( !empty($q['tag__not_in']) ) {
    1991             $tag_string = "'" . implode("', '", $q['tag__not_in']) . "'";
    1992             $whichcat .= " AND $wpdb->posts.ID NOT IN ( SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy = 'post_tag' AND tt.term_id IN ($tag_string) )";
    1993         }
    1994 
    1995         // Tag and slug intersections.
    1996         $intersections = array('category__and' => 'category', 'tag__and' => 'post_tag', 'tag_slug__and' => 'post_tag', 'tag__in' => 'post_tag', 'tag_slug__in' => 'post_tag');
    1997         $tagin = array('tag__in', 'tag_slug__in'); // These are used to make some exceptions below
    1998         foreach ( $intersections as $item => $taxonomy ) {
    1999             if ( empty($q[$item]) ) continue;
    2000             if ( in_array($item, $tagin) && empty($q['cat']) ) continue; // We should already have what we need if categories aren't being used
    2001 
    2002             if ( $item != 'category__and' ) {
    2003                 $reqtag = term_exists( $q[$item][0], 'post_tag' );
    2004                 if ( !empty($reqtag) )
    2005                     $q['tag_id'] = $reqtag['term_id'];
    2006             }
    2007 
    2008             if ( in_array( $item, array('tag_slug__and', 'tag_slug__in' ) ) )
    2009                 $taxonomy_field = 'slug';
     1775            $q['tag__not_in'] = array_map('absint', array_unique( (array) $q['tag__not_in'] ) );
     1776            $tax_query[] = array(
     1777                'taxonomy' => 'post_tag',
     1778                'terms' => $q['tag__not_in'],
     1779                'operator' => 'NOT IN'
     1780            );
     1781        }
     1782
     1783        if ( !empty($q['tag__and']) ) {
     1784            $q['tag__and'] = array_map('absint', array_unique( (array) $q['tag__and'] ) );
     1785            $tax_query[] = array(
     1786                'taxonomy' => 'post_tag',
     1787                'terms' => $q['tag__and'],
     1788                'operator' => 'AND'
     1789            );
     1790        }
     1791
     1792        if ( !empty($q['tag_slug__in']) ) {
     1793            $q['tag_slug__in'] = array_map('sanitize_title', (array) $q['tag_slug__in']);
     1794            $tax_query[] = array(
     1795                'taxonomy' => 'post_tag',
     1796                'terms' => $q['tag_slug__in'],
     1797                'field' => 'slug'
     1798            );
     1799        }
     1800
     1801        if ( !empty($q['tag_slug__and']) ) {
     1802            $q['tag_slug__and'] = array_map('sanitize_title', (array) $q['tag_slug__and']);
     1803            $tax_query[] = array(
     1804                'taxonomy' => 'post_tag',
     1805                'terms' => $q['tag_slug__and'],
     1806                'field' => 'slug',
     1807                'operator' => 'AND'
     1808            );
     1809        }
     1810
     1811        $this->parsed_tax_query = true;
     1812
     1813        $this->tax_query = new WP_Tax_Query( $tax_query );
     1814    }
     1815
     1816    /**
     1817     * Sets the 404 property and saves whether query is feed.
     1818     *
     1819     * @since 2.0.0
     1820     * @access public
     1821     */
     1822    function set_404() {
     1823        $is_feed = $this->is_feed;
     1824
     1825        $this->init_query_flags();
     1826        $this->is_404 = true;
     1827
     1828        $this->is_feed = $is_feed;
     1829    }
     1830
     1831    /**
     1832     * Retrieve query variable.
     1833     *
     1834     * @since 1.5.0
     1835     * @access public
     1836     *
     1837     * @param string $query_var Query variable key.
     1838     * @return mixed
     1839     */
     1840    function get($query_var) {
     1841        if ( isset($this->query_vars[$query_var]) )
     1842            return $this->query_vars[$query_var];
     1843
     1844        return '';
     1845    }
     1846
     1847    /**
     1848     * Set query variable.
     1849     *
     1850     * @since 1.5.0
     1851     * @access public
     1852     *
     1853     * @param string $query_var Query variable key.
     1854     * @param mixed $value Query variable value.
     1855     */
     1856    function set($query_var, $value) {
     1857        $this->query_vars[$query_var] = $value;
     1858    }
     1859
     1860    /**
     1861     * Retrieve the posts based on query variables.
     1862     *
     1863     * There are a few filters and actions that can be used to modify the post
     1864     * database query.
     1865     *
     1866     * @since 1.5.0
     1867     * @access public
     1868     * @uses do_action_ref_array() Calls 'pre_get_posts' hook before retrieving posts.
     1869     *
     1870     * @return array List of posts.
     1871     */
     1872    function &get_posts() {
     1873        global $wpdb, $user_ID, $_wp_using_ext_object_cache;
     1874
     1875        $this->parse_query();
     1876
     1877        do_action_ref_array('pre_get_posts', array(&$this));
     1878
     1879        // Shorthand.
     1880        $q = &$this->query_vars;
     1881
     1882        $q = $this->fill_query_vars($q);
     1883
     1884        // First let's clear some variables
     1885        $distinct = '';
     1886        $whichauthor = '';
     1887        $whichmimetype = '';
     1888        $where = '';
     1889        $limits = '';
     1890        $join = '';
     1891        $search = '';
     1892        $groupby = '';
     1893        $fields = '';
     1894        $post_status_join = false;
     1895        $page = 1;
     1896
     1897        if ( isset( $q['caller_get_posts'] ) ) {
     1898            _deprecated_argument( 'WP_Query', '3.1', __( '"caller_get_posts" is deprecated. Use "ignore_sticky_posts" instead.' ) );
     1899            if ( !isset( $q['ignore_sticky_posts'] ) )
     1900                $q['ignore_sticky_posts'] = $q['caller_get_posts'];
     1901        }
     1902
     1903        if ( !isset( $q['ignore_sticky_posts'] ) )
     1904            $q['ignore_sticky_posts'] = false;
     1905
     1906        if ( !isset($q['suppress_filters']) )
     1907            $q['suppress_filters'] = false;
     1908
     1909        if ( !isset($q['cache_results']) ) {
     1910            if ( $_wp_using_ext_object_cache )
     1911                $q['cache_results'] = false;
    20101912            else
    2011                 $taxonomy_field = 'term_id';
    2012 
    2013             $q[$item] = array_unique($q[$item]);
    2014             $tsql = "SELECT p.ID FROM $wpdb->posts p INNER JOIN $wpdb->term_relationships tr ON (p.ID = tr.object_id) INNER JOIN $wpdb->term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id) INNER JOIN $wpdb->terms t ON (tt.term_id = t.term_id)";
    2015             $tsql .= " WHERE tt.taxonomy = '$taxonomy' AND t.$taxonomy_field IN ('" . implode("', '", $q[$item]) . "')";
    2016             if ( !in_array($item, $tagin) ) { // This next line is only helpful if we are doing an and relationship
    2017                 $tsql .= " GROUP BY p.ID HAVING count(p.ID) = " . count($q[$item]);
    2018             }
    2019             $post_ids = $wpdb->get_col($tsql);
    2020 
    2021             if ( count($post_ids) )
    2022                 $whichcat .= " AND $wpdb->posts.ID IN (" . implode(', ', $post_ids) . ") ";
    2023             else {
    2024                 $whichcat = " AND 0 = 1";
     1913                $q['cache_results'] = true;
     1914        }
     1915
     1916        if ( !isset($q['update_post_term_cache']) )
     1917            $q['update_post_term_cache'] = true;
     1918
     1919        if ( !isset($q['update_post_meta_cache']) )
     1920            $q['update_post_meta_cache'] = true;
     1921
     1922        if ( !isset($q['post_type']) ) {
     1923            if ( $this->is_search )
     1924                $q['post_type'] = 'any';
     1925            else
     1926                $q['post_type'] = '';
     1927        }
     1928        $post_type = $q['post_type'];
     1929        if ( !isset($q['posts_per_page']) || $q['posts_per_page'] == 0 )
     1930            $q['posts_per_page'] = get_option('posts_per_page');
     1931        if ( isset($q['showposts']) && $q['showposts'] ) {
     1932            $q['showposts'] = (int) $q['showposts'];
     1933            $q['posts_per_page'] = $q['showposts'];
     1934        }
     1935        if ( (isset($q['posts_per_archive_page']) && $q['posts_per_archive_page'] != 0) && ($this->is_archive || $this->is_search) )
     1936            $q['posts_per_page'] = $q['posts_per_archive_page'];
     1937        if ( !isset($q['nopaging']) ) {
     1938            if ( $q['posts_per_page'] == -1 ) {
     1939                $q['nopaging'] = true;
     1940            } else {
     1941                $q['nopaging'] = false;
     1942            }
     1943        }
     1944        if ( $this->is_feed ) {
     1945            $q['posts_per_page'] = get_option('posts_per_rss');
     1946            $q['nopaging'] = false;
     1947        }
     1948        $q['posts_per_page'] = (int) $q['posts_per_page'];
     1949        if ( $q['posts_per_page'] < -1 )
     1950            $q['posts_per_page'] = abs($q['posts_per_page']);
     1951        else if ( $q['posts_per_page'] == 0 )
     1952            $q['posts_per_page'] = 1;
     1953
     1954        if ( !isset($q['comments_per_page']) || $q['comments_per_page'] == 0 )
     1955            $q['comments_per_page'] = get_option('comments_per_page');
     1956
     1957        if ( $this->is_home && (empty($this->query) || $q['preview'] == 'true') && ( 'page' == get_option('show_on_front') ) && get_option('page_on_front') ) {
     1958            $this->is_page = true;
     1959            $this->is_home = false;
     1960            $q['page_id'] = get_option('page_on_front');
     1961        }
     1962
     1963        if ( isset($q['page']) ) {
     1964            $q['page'] = trim($q['page'], '/');
     1965            $q['page'] = absint($q['page']);
     1966        }
     1967
     1968        // If true, forcibly turns off SQL_CALC_FOUND_ROWS even when limits are present.
     1969        if ( isset($q['no_found_rows']) )
     1970            $q['no_found_rows'] = (bool) $q['no_found_rows'];
     1971        else
     1972            $q['no_found_rows'] = false;
     1973
     1974        switch ( $q['fields'] ) {
     1975            case 'ids':
     1976                $fields = "$wpdb->posts.ID";
    20251977                break;
    2026             }
    2027         }
     1978            case 'id=>parent':
     1979                $fields = "$wpdb->posts.ID, $wpdb->posts.post_parent";
     1980                break;
     1981            default:
     1982                $fields = "$wpdb->posts.*";
     1983        }
     1984
     1985        // If a month is specified in the querystring, load that month
     1986        if ( $q['m'] ) {
     1987            $q['m'] = '' . preg_replace('|[^0-9]|', '', $q['m']);
     1988            $where .= " AND YEAR($wpdb->posts.post_date)=" . substr($q['m'], 0, 4);
     1989            if ( strlen($q['m']) > 5 )
     1990                $where .= " AND MONTH($wpdb->posts.post_date)=" . substr($q['m'], 4, 2);
     1991            if ( strlen($q['m']) > 7 )
     1992                $where .= " AND DAYOFMONTH($wpdb->posts.post_date)=" . substr($q['m'], 6, 2);
     1993            if ( strlen($q['m']) > 9 )
     1994                $where .= " AND HOUR($wpdb->posts.post_date)=" . substr($q['m'], 8, 2);
     1995            if ( strlen($q['m']) > 11 )
     1996                $where .= " AND MINUTE($wpdb->posts.post_date)=" . substr($q['m'], 10, 2);
     1997            if ( strlen($q['m']) > 13 )
     1998                $where .= " AND SECOND($wpdb->posts.post_date)=" . substr($q['m'], 12, 2);
     1999        }
     2000
     2001        if ( '' !== $q['hour'] )
     2002            $where .= " AND HOUR($wpdb->posts.post_date)='" . $q['hour'] . "'";
     2003
     2004        if ( '' !== $q['minute'] )
     2005            $where .= " AND MINUTE($wpdb->posts.post_date)='" . $q['minute'] . "'";
     2006
     2007        if ( '' !== $q['second'] )
     2008            $where .= " AND SECOND($wpdb->posts.post_date)='" . $q['second'] . "'";
     2009
     2010        if ( $q['year'] )
     2011            $where .= " AND YEAR($wpdb->posts.post_date)='" . $q['year'] . "'";
     2012
     2013        if ( $q['monthnum'] )
     2014            $where .= " AND MONTH($wpdb->posts.post_date)='" . $q['monthnum'] . "'";
     2015
     2016        if ( $q['day'] )
     2017            $where .= " AND DAYOFMONTH($wpdb->posts.post_date)='" . $q['day'] . "'";
     2018
     2019        // If we've got a post_type AND its not "any" post_type.
     2020        if ( !empty($q['post_type']) && 'any' != $q['post_type'] ) {
     2021            foreach ( (array)$q['post_type'] as $_post_type ) {
     2022                $ptype_obj = get_post_type_object($_post_type);
     2023                if ( !$ptype_obj || !$ptype_obj->query_var || empty($q[ $ptype_obj->query_var ]) )
     2024                    continue;
     2025
     2026                if ( ! $ptype_obj->hierarchical || strpos($q[ $ptype_obj->query_var ], '/') === false ) {
     2027                    // Non-hierarchical post_types & parent-level-hierarchical post_types can directly use 'name'
     2028                    $q['name'] = $q[ $ptype_obj->query_var ];
     2029                } else {
     2030                    // Hierarchical post_types will operate through the
     2031                    $q['pagename'] = $q[ $ptype_obj->query_var ];
     2032                    $q['name'] = '';
     2033                }
     2034
     2035                // Only one request for a slug is possible, this is why name & pagename are overwritten above.
     2036                break;
     2037            } //end foreach
     2038            unset($ptype_obj);
     2039        }
     2040
     2041        if ( '' != $q['name'] ) {
     2042            $q['name'] = sanitize_title_for_query( $q['name'] );
     2043            $where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'";
     2044        } elseif ( '' != $q['pagename'] ) {
     2045            if ( isset($this->queried_object_id) ) {
     2046                $reqpage = $this->queried_object_id;
     2047            } else {
     2048                if ( 'page' != $q['post_type'] ) {
     2049                    foreach ( (array)$q['post_type'] as $_post_type ) {
     2050                        $ptype_obj = get_post_type_object($_post_type);
     2051                        if ( !$ptype_obj || !$ptype_obj->hierarchical )
     2052                            continue;
     2053
     2054                        $reqpage = get_page_by_path($q['pagename'], OBJECT, $_post_type);
     2055                        if ( $reqpage )
     2056                            break;
     2057                    }
     2058                    unset($ptype_obj);
     2059                } else {
     2060                    $reqpage = get_page_by_path($q['pagename']);
     2061                }
     2062                if ( !empty($reqpage) )
     2063                    $reqpage = $reqpage->ID;
     2064                else
     2065                    $reqpage = 0;
     2066            }
     2067
     2068            $page_for_posts = get_option('page_for_posts');
     2069            if  ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) {
     2070                $q['pagename'] = sanitize_title_for_query( wp_basename( $q['pagename'] ) );
     2071                $q['name'] = $q['pagename'];
     2072                $where .= " AND ($wpdb->posts.ID = '$reqpage')";
     2073                $reqpage_obj = get_page($reqpage);
     2074                if ( is_object($reqpage_obj) && 'attachment' == $reqpage_obj->post_type ) {
     2075                    $this->is_attachment = true;
     2076                    $post_type = $q['post_type'] = 'attachment';
     2077                    $this->is_page = true;
     2078                    $q['attachment_id'] = $reqpage;
     2079                }
     2080            }
     2081        } elseif ( '' != $q['attachment'] ) {
     2082            $q['attachment'] = sanitize_title_for_query( wp_basename( $q['attachment'] ) );
     2083            $q['name'] = $q['attachment'];
     2084            $where .= " AND $wpdb->posts.post_name = '" . $q['attachment'] . "'";
     2085        }
     2086
     2087        if ( $q['w'] )
     2088            $where .= ' AND ' . _wp_mysql_week( "`$wpdb->posts`.`post_date`" ) . " = '" . $q['w'] . "'";
     2089
     2090        if ( intval($q['comments_popup']) )
     2091            $q['p'] = absint($q['comments_popup']);
     2092
     2093        // If an attachment is requested by number, let it supercede any post number.
     2094        if ( $q['attachment_id'] )
     2095            $q['p'] = absint($q['attachment_id']);
     2096
     2097        // If a post number is specified, load that post
     2098        if ( $q['p'] ) {
     2099            $where .= " AND {$wpdb->posts}.ID = " . $q['p'];
     2100        } elseif ( $q['post__in'] ) {
     2101            $post__in = implode(',', array_map( 'absint', $q['post__in'] ));
     2102            $where .= " AND {$wpdb->posts}.ID IN ($post__in)";
     2103        } elseif ( $q['post__not_in'] ) {
     2104            $post__not_in = implode(',',  array_map( 'absint', $q['post__not_in'] ));
     2105            $where .= " AND {$wpdb->posts}.ID NOT IN ($post__not_in)";
     2106        }
     2107
     2108        if ( is_numeric($q['post_parent']) )
     2109            $where .= $wpdb->prepare( " AND $wpdb->posts.post_parent = %d ", $q['post_parent'] );
     2110
     2111        if ( $q['page_id'] ) {
     2112            if  ( ('page' != get_option('show_on_front') ) || ( $q['page_id'] != get_option('page_for_posts') ) ) {
     2113                $q['p'] = $q['page_id'];
     2114                $where = " AND {$wpdb->posts}.ID = " . $q['page_id'];
     2115            }
     2116        }
     2117
     2118        // If a search pattern is specified, load the posts that match
     2119        if ( !empty($q['s']) ) {
     2120            // added slashes screw with quote grouping when done early, so done later
     2121            $q['s'] = stripslashes($q['s']);
     2122            if ( !empty($q['sentence']) ) {
     2123                $q['search_terms'] = array($q['s']);
     2124            } else {
     2125                preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $q['s'], $matches);
     2126                $q['search_terms'] = array_map('_search_terms_tidy', $matches[0]);
     2127            }
     2128            $n = !empty($q['exact']) ? '' : '%';
     2129            $searchand = '';
     2130            foreach( (array) $q['search_terms'] as $term ) {
     2131                $term = esc_sql( like_escape( $term ) );
     2132                $search .= "{$searchand}(($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}'))";
     2133                $searchand = ' AND ';
     2134            }
     2135            $term = esc_sql( like_escape( $q['s'] ) );
     2136            if ( empty($q['sentence']) && count($q['search_terms']) > 1 && $q['search_terms'][0] != $q['s'] )
     2137                $search .= " OR ($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}')";
     2138
     2139            if ( !empty($search) ) {
     2140                $search = " AND ({$search}) ";
     2141                if ( !is_user_logged_in() )
     2142                    $search .= " AND ($wpdb->posts.post_password = '') ";
     2143            }
     2144        }
     2145
     2146        // Allow plugins to contextually add/remove/modify the search section of the database query
     2147        $search = apply_filters_ref_array('posts_search', array( $search, &$this ) );
    20282148
    20292149        // Taxonomies
     2150        $this->parse_tax_query( $q );
     2151
     2152        $clauses = $this->tax_query->get_sql( $wpdb->posts, 'ID' );
     2153
     2154        $join .= $clauses['join'];
     2155        $where .= $clauses['where'];
     2156
    20302157        if ( $this->is_tax ) {
    2031             if ( '' != $q['taxonomy'] ) {
    2032                 $taxonomy = $q['taxonomy'];
    2033                 $tt[$taxonomy] = $q['term'];
    2034             } else {
    2035                 foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t ) {
    2036                     if ( $t->query_var && '' != $q[$t->query_var] ) {
    2037                         $tt[$taxonomy] = $q[$t->query_var];
    2038                         break;
     2158            if ( empty($post_type) ) {
     2159                $post_type = 'any';
     2160                $post_status_join = true;
     2161            } elseif ( in_array('attachment', (array) $post_type) ) {
     2162                $post_status_join = true;
     2163            }
     2164        }
     2165
     2166        // Back-compat
     2167        if ( !empty($this->tax_query->queries) ) {
     2168            $tax_query_in_and = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'NOT IN' ), 'NOT' );
     2169            if ( !empty( $tax_query_in_and ) ) {
     2170                if ( !isset( $q['taxonomy'] ) ) {
     2171                    foreach ( $tax_query_in_and as $a_tax_query ) {
     2172                        if ( !in_array( $a_tax_query['taxonomy'], array( 'category', 'post_tag' ) ) ) {
     2173                            $q['taxonomy'] = $a_tax_query['taxonomy'];
     2174                            if ( 'slug' == $a_tax_query['field'] )
     2175                                $q['term'] = $a_tax_query['terms'][0];
     2176                            else
     2177                                $q['term_id'] = $a_tax_query['terms'][0];
     2178
     2179                            break;
     2180                        }
    20392181                    }
    20402182                }
    2041             }
    2042 
    2043             $terms = get_terms($taxonomy, array('slug' => $tt[$taxonomy], 'hide_empty' => !is_taxonomy_hierarchical($taxonomy)));
    2044 
    2045             if ( is_wp_error($terms) || empty($terms) ) {
    2046                 $whichcat = " AND 0 ";
    2047             } else {
    2048                 foreach ( $terms as $term ) {
    2049                     $term_ids[] = $term->term_id;
    2050                     if ( is_taxonomy_hierarchical($taxonomy) ) {
    2051                         $children = get_term_children($term->term_id, $taxonomy);
    2052                         $term_ids = array_merge($term_ids, $children);
     2183
     2184                $cat_query = wp_list_filter( $tax_query_in_and, array( 'taxonomy' => 'category' ) );
     2185                if ( !empty( $cat_query ) ) {
     2186                    $cat_query = reset( $cat_query );
     2187                    $the_cat = get_term_by( $cat_query['field'], $cat_query['terms'][0], 'category' );
     2188                    if ( $the_cat ) {
     2189                        $this->set( 'cat', $the_cat->term_id );
     2190                        $this->set( 'category_name', $the_cat->slug );
    20532191                    }
     2192                    unset( $the_cat );
    20542193                }
    2055                 $post_ids = get_objects_in_term($term_ids, $taxonomy);
    2056                 if ( !is_wp_error($post_ids) && !empty($post_ids) ) {
    2057                     $whichcat .= " AND $wpdb->posts.ID IN (" . implode(', ', $post_ids) . ") ";
    2058                     if ( empty($post_type) ) {
    2059                         $post_type = 'any';
    2060                         $post_status_join = true;
    2061                     } elseif ( in_array('attachment', (array)$post_type) ) {
    2062                         $post_status_join = true;
     2194                unset( $cat_query );
     2195
     2196                $tag_query = wp_list_filter( $tax_query_in_and, array( 'taxonomy' => 'post_tag' ) );
     2197                if ( !empty( $tag_query ) ) {
     2198                    $tag_query = reset( $tag_query );
     2199                    $the_tag = get_term_by( $tag_query['field'], $tag_query['terms'][0], 'post_tag' );
     2200                    if ( $the_tag ) {
     2201                        $this->set( 'tag_id', $the_tag->term_id );
    20632202                    }
    2064                 } else {
    2065                     $whichcat = " AND 0 ";
     2203                    unset( $the_tag );
    20662204                }
    2067             }
     2205                unset( $tag_query );
     2206            }
     2207        }
     2208
     2209        if ( !empty( $this->tax_query->queries ) || !empty( $q['meta_key'] ) ) {
     2210            $groupby = "{$wpdb->posts}.ID";
    20682211        }
    20692212
     
    21032246                }
    21042247            }
    2105             $q['author_name'] = sanitize_title($q['author_name']);
     2248            $q['author_name'] = sanitize_title_for_query( $q['author_name'] );
    21062249            $q['author'] = get_user_by('slug', $q['author_name']);
    21072250            if ( $q['author'] )
     
    21172260        }
    21182261
    2119         $where .= $search . $whichcat . $whichauthor . $whichmimetype;
     2262        $where .= $search . $whichauthor . $whichmimetype;
    21202263
    21212264        if ( empty($q['order']) || ((strtoupper($q['order']) != 'ASC') && (strtoupper($q['order']) != 'DESC')) )
     
    21792322        }
    21802323
    2181         if ( is_array($post_type) ) {
     2324        if ( is_array( $post_type ) ) {
    21822325            $post_type_cap = 'multiple_post_type';
    21832326        } else {
    2184             $post_type_object = get_post_type_object ( $post_type );
    2185             if ( !empty($post_type_object) )
    2186                 $post_type_cap = $post_type_object->capability_type;
    2187             else
     2327            $post_type_object = get_post_type_object( $post_type );
     2328            if ( empty( $post_type_object ) )
    21882329                $post_type_cap = $post_type;
    21892330        }
     
    22122353        }
    22132354
    2214         if ( !empty($post_type_object) ) {
    2215             $post_type_cap = $post_type_object->capability_type;
     2355        if ( ! empty( $post_type_object ) ) {
    22162356            $edit_cap = $post_type_object->cap->edit_post;
    22172357            $read_cap = $post_type_object->cap->read_post;
     
    23002440        }
    23012441
    2302         // postmeta queries
    2303         if ( ! empty($q['meta_key']) || ! empty($q['meta_value']) )
    2304             $join .= " JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id) ";
    2305         if ( ! empty($q['meta_key']) )
    2306             $where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_key = %s ", $q['meta_key']);
    2307         if ( ! empty($q['meta_value']) ) {
    2308             if ( empty($q['meta_compare']) || ! in_array($q['meta_compare'], array('=', '!=', '>', '>=', '<', '<=')) )
    2309                 $q['meta_compare'] = '=';
    2310 
    2311             $where .= $wpdb->prepare("AND $wpdb->postmeta.meta_value {$q['meta_compare']} %s ", $q['meta_value']);
     2442        if ( !empty( $q['meta_query'] ) ) {
     2443            $clauses = call_user_func_array( '_get_meta_sql', array( $q['meta_query'], 'post', $wpdb->posts, 'ID', &$this) );
     2444            $join .= $clauses['join'];
     2445            $where .= $clauses['where'];
    23122446        }
    23132447
     
    23762510        $orderby = $q['orderby'];
    23772511
     2512        $pieces = array( 'where', 'groupby', 'join', 'orderby', 'distinct', 'fields', 'limits' );
     2513
    23782514        // Apply post-paging filters on where and join.  Only plugins that
    23792515        // manipulate paging queries should use these hooks.
     
    23862522            $limits     = apply_filters_ref_array( 'post_limits',       array( $limits, &$this ) );
    23872523            $fields     = apply_filters_ref_array( 'posts_fields',      array( $fields, &$this ) );
     2524
     2525            // Filter all clauses at once, for convenience
     2526            $clauses = (array) apply_filters_ref_array( 'posts_clauses', array( compact( $pieces ), &$this ) );
     2527            foreach ( $pieces as $piece )
     2528                $$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : '';
    23882529        }
    23892530
     
    23932534        // Filter again for the benefit of caching plugins.  Regular plugins should use the hooks above.
    23942535        if ( !$q['suppress_filters'] ) {
    2395             $where      = apply_filters_ref_array( 'posts_where_request',   array( $where, &$this ) );
     2536            $where      = apply_filters_ref_array( 'posts_where_request',       array( $where, &$this ) );
    23962537            $groupby    = apply_filters_ref_array( 'posts_groupby_request',     array( $groupby, &$this ) );
    2397             $join       = apply_filters_ref_array( 'posts_join_request',    array( $join, &$this ) );
     2538            $join       = apply_filters_ref_array( 'posts_join_request',        array( $join, &$this ) );
    23982539            $orderby    = apply_filters_ref_array( 'posts_orderby_request',     array( $orderby, &$this ) );
    23992540            $distinct   = apply_filters_ref_array( 'posts_distinct_request',    array( $distinct, &$this ) );
    24002541            $fields     = apply_filters_ref_array( 'posts_fields_request',      array( $fields, &$this ) );
    24012542            $limits     = apply_filters_ref_array( 'post_limits_request',       array( $limits, &$this ) );
     2543
     2544            // Filter all clauses at once, for convenience
     2545            $clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) );
     2546            foreach ( $pieces as $piece )
     2547                $$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : '';
    24022548        }
    24032549
     
    24062552        if ( !empty( $orderby ) )
    24072553            $orderby = 'ORDER BY ' . $orderby;
     2554
    24082555        $found_rows = '';
    24092556        if ( !$q['no_found_rows'] && !empty($limits) )
     
    24142561            $this->request = apply_filters_ref_array('posts_request', array( $this->request, &$this ) );
    24152562
     2563        if ( 'ids' == $q['fields'] ) {
     2564            $this->posts = $wpdb->get_col($this->request);
     2565
     2566            return $this->posts;
     2567        }
     2568
     2569        if ( 'id=>parent' == $q['fields'] ) {
     2570            $this->posts = $wpdb->get_results($this->request);
     2571
     2572            $r = array();
     2573            foreach ( $this->posts as $post )
     2574                $r[ $post->ID ] = $post->post_parent;
     2575
     2576            return $r;
     2577        }
     2578
    24162579        $this->posts = $wpdb->get_results($this->request);
     2580
    24172581        // Raw results filter.  Prior to status checks.
    24182582        if ( !$q['suppress_filters'] )
     
    24732637        // Put sticky posts at the top of the posts array
    24742638        $sticky_posts = get_option('sticky_posts');
    2475         if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['caller_get_posts'] ) {
     2639        if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) {
    24762640            $num_posts = count($this->posts);
    24772641            $sticky_offset = 0;
     
    26912855     * @return array List of posts.
    26922856     */
    2693     function &query($query) {
    2694         $this->parse_query($query);
     2857    function &query( $query ) {
     2858        $this->init();
     2859        $this->query = $this->query_vars = wp_parse_args( $query );
    26952860        return $this->get_posts();
    26962861    }
     
    27152880        $this->queried_object_id = 0;
    27162881
    2717         if ( $this->is_category ) {
    2718             $cat = $this->get('cat');
    2719             $category = &get_category($cat);
    2720             if ( is_wp_error( $category ) )
    2721                 return NULL;
    2722             $this->queried_object = &$category;
    2723             $this->queried_object_id = (int) $cat;
    2724         } elseif ( $this->is_tag ) {
    2725             $tag_id = $this->get('tag_id');
    2726             $tag = &get_term($tag_id, 'post_tag');
    2727             if ( is_wp_error( $tag ) )
    2728                 return NULL;
    2729             $this->queried_object = &$tag;
    2730             $this->queried_object_id = (int) $tag_id;
    2731         } elseif ( $this->is_tax ) {
    2732             $tax = $this->get('taxonomy');
    2733             $slug = $this->get('term');
    2734             $term = &get_terms($tax, array( 'slug' => $slug, 'hide_empty' => false ) );
    2735             if ( is_wp_error($term) || empty($term) )
    2736                 return NULL;
    2737             $term = $term[0];
    2738             $this->queried_object = $term;
    2739             $this->queried_object_id = $term->term_id;
     2882        if ( $this->is_category || $this->is_tag || $this->is_tax ) {
     2883            $tax_query_in_and = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'NOT IN' ), 'NOT' );
     2884
     2885            $query = reset( $tax_query_in_and );
     2886
     2887            if ( 'term_id' == $query['field'] )
     2888                $term = get_term( reset( $query['terms'] ), $query['taxonomy'] );
     2889            else
     2890                $term = get_term_by( $query['field'], reset( $query['terms'] ), $query['taxonomy'] );
     2891
     2892            if ( $term && ! is_wp_error($term) )  {
     2893                $this->queried_object = $term;
     2894                $this->queried_object_id = (int) $term->term_id;
     2895            }
     2896        } elseif ( $this->is_post_type_archive ) {
     2897            $this->queried_object = get_post_type_object( $this->get('post_type') );
    27402898        } elseif ( $this->is_posts_page ) {
    27412899            $page_for_posts = get_option('page_for_posts');
    27422900            $this->queried_object = & get_page( $page_for_posts );
    27432901            $this->queried_object_id = (int) $this->queried_object->ID;
    2744         } elseif ( $this->is_single && !is_null($this->post) ) {
    2745             $this->queried_object = $this->post;
    2746             $this->queried_object_id = (int) $this->post->ID;
    2747         } elseif ( $this->is_page && !is_null($this->post) ) {
     2902        } elseif ( $this->is_singular && !is_null($this->post) ) {
    27482903            $this->queried_object = $this->post;
    27492904            $this->queried_object_id = (int) $this->post->ID;
    27502905        } elseif ( $this->is_author ) {
    2751             $author_id = (int) $this->get('author');
    2752             $author = get_userdata($author_id);
    2753             $this->queried_object = $author;
    2754             $this->queried_object_id = $author_id;
     2906            $this->queried_object_id = (int) $this->get('author');
     2907            $this->queried_object = get_userdata( $this->queried_object_id );
    27552908        }
    27562909
     
    27922945        }
    27932946    }
     2947
     2948    /**
     2949     * Is the query for an archive page?
     2950     *
     2951     * Month, Year, Category, Author, Post Type archive...
     2952     *
     2953     * @since 3.1.0
     2954     *
     2955     * @return bool
     2956     */
     2957    function is_archive() {
     2958        return (bool) $this->is_archive;
     2959    }
     2960
     2961    /**
     2962     * Is the query for a post type archive page?
     2963     *
     2964     * @since 3.1.0
     2965     *
     2966     * @param mixed $post_types Optional. Post type or array of posts types to check against.
     2967     * @return bool
     2968     */
     2969    function is_post_type_archive( $post_types = '' ) {
     2970        if ( empty( $post_types ) || !$this->is_post_type_archive )
     2971            return (bool) $this->is_post_type_archive;
     2972
     2973        $post_type_object = $this->get_queried_object();
     2974
     2975        return in_array( $post_type_object->name, (array) $post_types );
     2976    }
     2977
     2978    /**
     2979     * Is the query for an attachment page?
     2980     *
     2981     * @since 3.1.0
     2982     *
     2983     * @return bool
     2984     */
     2985    function is_attachment() {
     2986        return (bool) $this->is_attachment;
     2987    }
     2988
     2989    /**
     2990     * Is the query for an author archive page?
     2991     *
     2992     * If the $author parameter is specified, this function will additionally
     2993     * check if the query is for one of the authors specified.
     2994     *
     2995     * @since 3.1.0
     2996     *
     2997     * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames
     2998     * @return bool
     2999     */
     3000    function is_author( $author = '' ) {
     3001        if ( !$this->is_author )
     3002            return false;
     3003
     3004        if ( empty($author) )
     3005            return true;
     3006
     3007        $author_obj = $this->get_queried_object();
     3008
     3009        $author = (array) $author;
     3010
     3011        if ( in_array( $author_obj->ID, $author ) )
     3012            return true;
     3013        elseif ( in_array( $author_obj->nickname, $author ) )
     3014            return true;
     3015        elseif ( in_array( $author_obj->user_nicename, $author ) )
     3016            return true;
     3017
     3018        return false;
     3019    }
     3020
     3021    /**
     3022     * Is the query for a category archive page?
     3023     *
     3024     * If the $category parameter is specified, this function will additionally
     3025     * check if the query is for one of the categories specified.
     3026     *
     3027     * @since 3.1.0
     3028     *
     3029     * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs.
     3030     * @return bool
     3031     */
     3032    function is_category( $category = '' ) {
     3033        if ( !$this->is_category )
     3034            return false;
     3035
     3036        if ( empty($category) )
     3037            return true;
     3038
     3039        $cat_obj = $this->get_queried_object();
     3040
     3041        $category = (array) $category;
     3042
     3043        if ( in_array( $cat_obj->term_id, $category ) )
     3044            return true;
     3045        elseif ( in_array( $cat_obj->name, $category ) )
     3046            return true;
     3047        elseif ( in_array( $cat_obj->slug, $category ) )
     3048            return true;
     3049
     3050        return false;
     3051    }
     3052
     3053    /**
     3054     * Is the query for a tag archive page?
     3055     *
     3056     * If the $tag parameter is specified, this function will additionally
     3057     * check if the query is for one of the tags specified.
     3058     *
     3059     * @since 3.1.0
     3060     *
     3061     * @param mixed $slug Optional. Tag slug or array of slugs.
     3062     * @return bool
     3063     */
     3064    function is_tag( $slug = '' ) {
     3065        if ( !$this->is_tag )
     3066            return false;
     3067
     3068        if ( empty( $slug ) )
     3069            return true;
     3070
     3071        $tag_obj = $this->get_queried_object();
     3072
     3073        $slug = (array) $slug;
     3074
     3075        if ( in_array( $tag_obj->slug, $slug ) )
     3076            return true;
     3077
     3078        return false;
     3079    }
     3080
     3081    /**
     3082     * Is the query for a taxonomy archive page?
     3083     *
     3084     * If the $taxonomy parameter is specified, this function will additionally
     3085     * check if the query is for that specific $taxonomy.
     3086     *
     3087     * If the $term parameter is specified in addition to the $taxonomy parameter,
     3088     * this function will additionally check if the query is for one of the terms
     3089     * specified.
     3090     *
     3091     * @since 3.1.0
     3092     *
     3093     * @param mixed $taxonomy Optional. Taxonomy slug or slugs.
     3094     * @param mixed $term. Optional. Term ID, name, slug or array of Term IDs, names, and slugs.
     3095     * @return bool
     3096     */
     3097    function is_tax( $taxonomy = '', $term = '' ) {
     3098        global $wp_taxonomies;
     3099
     3100        if ( !$this->is_tax )
     3101            return false;
     3102
     3103        if ( empty( $taxonomy ) )
     3104            return true;
     3105
     3106        $queried_object = $this->get_queried_object();
     3107        $tax_array = array_intersect( array_keys( $wp_taxonomies ), (array) $taxonomy );
     3108        $term_array = (array) $term;
     3109
     3110        if ( empty( $term ) ) // Only a Taxonomy provided
     3111            return isset( $queried_object->taxonomy ) && count( $tax_array ) && in_array( $queried_object->taxonomy, $tax_array );
     3112
     3113        return isset( $queried_object->term_id ) &&
     3114            count( array_intersect(
     3115                array( $queried_object->term_id, $queried_object->name, $queried_object->slug ),
     3116                $term_array
     3117            ) );
     3118    }
     3119
     3120    /**
     3121     * Whether the current URL is within the comments popup window.
     3122     *
     3123     * @since 3.1.0
     3124     *
     3125     * @return bool
     3126     */
     3127    function is_comments_popup() {
     3128        return (bool) $this->is_comments_popup;
     3129    }
     3130
     3131    /**
     3132     * Is the query for a date archive?
     3133     *
     3134     * @since 3.1.0
     3135     *
     3136     * @return bool
     3137     */
     3138    function is_date() {
     3139        return (bool) $this->is_date;
     3140    }
     3141
     3142
     3143    /**
     3144     * Is the query for a day archive?
     3145     *
     3146     * @since 3.1.0
     3147     *
     3148     * @return bool
     3149     */
     3150    function is_day() {
     3151        return (bool) $this->is_day;
     3152    }
     3153
     3154    /**
     3155     * Is the query for a feed?
     3156     *
     3157     * @since 3.1.0
     3158     *
     3159     * @param string|array $feeds Optional feed types to check.
     3160     * @return bool
     3161     */
     3162    function is_feed( $feeds = '' ) {
     3163        if ( empty( $feeds ) || ! $this->is_feed )
     3164            return (bool) $this->is_feed;
     3165        $qv = $this->get( 'feed' );
     3166        if ( 'feed' == $qv )
     3167            $qv = get_default_feed();
     3168        return in_array( $qv, (array) $feeds );
     3169    }
     3170
     3171    /**
     3172     * Is the query for a comments feed?
     3173     *
     3174     * @since 3.1.0
     3175     *
     3176     * @return bool
     3177     */
     3178    function is_comment_feed() {
     3179        return (bool) $this->is_comment_feed;
     3180    }
     3181
     3182    /**
     3183     * Is the query for the front page of the site?
     3184     *
     3185     * This is for what is displayed at your site's main URL.
     3186     *
     3187     * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_on_front'.
     3188     *
     3189     * If you set a static page for the front page of your site, this function will return
     3190     * true when viewing that page.
     3191     *
     3192     * Otherwise the same as @see WP_Query::is_home()
     3193     *
     3194     * @since 3.1.0
     3195     * @uses is_home()
     3196     * @uses get_option()
     3197     *
     3198     * @return bool True, if front of site.
     3199     */
     3200    function is_front_page() {
     3201        // most likely case
     3202        if ( 'posts' == get_option( 'show_on_front') && $this->is_home() )
     3203            return true;
     3204        elseif ( 'page' == get_option( 'show_on_front') && get_option( 'page_on_front' ) && $this->is_page( get_option( 'page_on_front' ) ) )
     3205            return true;
     3206        else
     3207            return false;
     3208    }
     3209
     3210    /**
     3211     * Is the query for the blog homepage?
     3212     *
     3213     * This is the page which shows the time based blog content of your site.
     3214     *
     3215     * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_for_posts'.
     3216     *
     3217     * If you set a static page for the front page of your site, this function will return
     3218     * true only on the page you set as the "Posts page".
     3219     *
     3220     * @see WP_Query::is_front_page()
     3221     *
     3222     * @since 3.1.0
     3223     *
     3224     * @return bool True if blog view homepage.
     3225     */
     3226    function is_home() {
     3227        return (bool) $this->is_home;
     3228    }
     3229
     3230    /**
     3231     * Is the query for a month archive?
     3232     *
     3233     * @since 3.1.0
     3234     *
     3235     * @return bool
     3236     */
     3237    function is_month() {
     3238        return (bool) $this->is_month;
     3239    }
     3240
     3241    /**
     3242     * Is the query for a single page?
     3243     *
     3244     * If the $page parameter is specified, this function will additionally
     3245     * check if the query is for one of the pages specified.
     3246     *
     3247     * @see WP_Query::is_single()
     3248     * @see WP_Query::is_singular()
     3249     *
     3250     * @since 3.1.0
     3251     *
     3252     * @param mixed $page Page ID, title, slug, or array of such.
     3253     * @return bool
     3254     */
     3255    function is_page( $page = '' ) {
     3256        if ( !$this->is_page )
     3257            return false;
     3258
     3259        if ( empty( $page ) )
     3260            return true;
     3261
     3262        $page_obj = $this->get_queried_object();
     3263
     3264        $page = (array) $page;
     3265
     3266        if ( in_array( $page_obj->ID, $page ) )
     3267            return true;
     3268        elseif ( in_array( $page_obj->post_title, $page ) )
     3269            return true;
     3270        else if ( in_array( $page_obj->post_name, $page ) )
     3271            return true;
     3272
     3273        return false;
     3274    }
     3275
     3276    /**
     3277     * Is the query for paged result and not for the first page?
     3278     *
     3279     * @since 3.1.0
     3280     *
     3281     * @return bool
     3282     */
     3283    function is_paged() {
     3284        return (bool) $this->is_paged;
     3285    }
     3286
     3287    /**
     3288     * Is the query for a post or page preview?
     3289     *
     3290     * @since 3.1.0
     3291     *
     3292     * @return bool
     3293     */
     3294    function is_preview() {
     3295        return (bool) $this->is_preview;
     3296    }
     3297
     3298    /**
     3299     * Is the query for the robots file?
     3300     *
     3301     * @since 3.1.0
     3302     *
     3303     * @return bool
     3304     */
     3305    function is_robots() {
     3306        return (bool) $this->is_robots;
     3307    }
     3308
     3309    /**
     3310     * Is the query for a search?
     3311     *
     3312     * @since 3.1.0
     3313     *
     3314     * @return bool
     3315     */
     3316    function is_search() {
     3317        return (bool) $this->is_search;
     3318    }
     3319
     3320    /**
     3321     * Is the query for a single post?
     3322     *
     3323     * Works for any post type, except attachments and pages
     3324     *
     3325     * If the $post parameter is specified, this function will additionally
     3326     * check if the query is for one of the Posts specified.
     3327     *
     3328     * @see WP_Query::is_page()
     3329     * @see WP_Query::is_singular()
     3330     *
     3331     * @since 3.1.0
     3332     *
     3333     * @param mixed $post Post ID, title, slug, or array of such.
     3334     * @return bool
     3335     */
     3336    function is_single( $post = '' ) {
     3337        if ( !$this->is_single )
     3338            return false;
     3339
     3340        if ( empty($post) )
     3341            return true;
     3342
     3343        $post_obj = $this->get_queried_object();
     3344
     3345        $post = (array) $post;
     3346
     3347        if ( in_array( $post_obj->ID, $post ) )
     3348            return true;
     3349        elseif ( in_array( $post_obj->post_title, $post ) )
     3350            return true;
     3351        elseif ( in_array( $post_obj->post_name, $post ) )
     3352            return true;
     3353
     3354        return false;
     3355    }
     3356
     3357    /**
     3358     * Is the query for a single post of any post type (post, attachment, page, ... )?
     3359     *
     3360     * If the $post_types parameter is specified, this function will additionally
     3361     * check if the query is for one of the Posts Types specified.
     3362     *
     3363     * @see WP_Query::is_page()
     3364     * @see WP_Query::is_single()
     3365     *
     3366     * @since 3.1.0
     3367     *
     3368     * @param mixed $post_types Optional. Post Type or array of Post Types
     3369     * @return bool
     3370     */
     3371    function is_singular( $post_types = '' ) {
     3372        if ( empty( $post_types ) || !$this->is_singular )
     3373            return (bool) $this->is_singular;
     3374
     3375        $post_obj = $this->get_queried_object();
     3376
     3377        return in_array( $post_obj->post_type, (array) $post_types );
     3378    }
     3379
     3380    /**
     3381     * Is the query for a specific time?
     3382     *
     3383     * @since 3.1.0
     3384     *
     3385     * @return bool
     3386     */
     3387    function is_time() {
     3388        return (bool) $this->is_time;
     3389    }
     3390
     3391    /**
     3392     * Is the query for a trackback endpoint call?
     3393     *
     3394     * @since 3.1.0
     3395     *
     3396     * @return bool
     3397     */
     3398    function is_trackback() {
     3399        return (bool) $this->is_trackback;
     3400    }
     3401
     3402    /**
     3403     * Is the query for a specific year?
     3404     *
     3405     * @since 3.1.0
     3406     *
     3407     * @return bool
     3408     */
     3409    function is_year() {
     3410        return (bool) $this->is_year;
     3411    }
     3412
     3413    /**
     3414     * Is the query a 404 (returns no results)?
     3415     *
     3416     * @since 3.1.0
     3417     *
     3418     * @return bool
     3419     */
     3420    function is_404() {
     3421        return (bool) $this->is_404;
     3422    }
    27943423}
    27953424
     
    28103439        global $wpdb;
    28113440
    2812         $query = "SELECT post_id FROM $wpdb->postmeta, $wpdb->posts WHERE ID = post_id AND meta_key = '_wp_old_slug' AND meta_value='" . $wp_query->query_vars['name'] . "'";
     3441        // Guess the current post_type based on the query vars.
     3442        if ( get_query_var('post_type') )
     3443            $post_type = get_query_var('post_type');
     3444        elseif ( !empty($wp_query->query_vars['pagename']) )
     3445            $post_type = 'page';
     3446        else
     3447            $post_type = 'post';
     3448
     3449        // Do not attempt redirect for hierarchical post types
     3450        if ( is_post_type_hierarchical( $post_type ) )
     3451            return;
     3452
     3453        $query = $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta, $wpdb->posts WHERE ID = post_id AND post_type = %s AND meta_key = '_wp_old_slug' AND meta_value = %s", $post_type, $wp_query->query_vars['name']);
    28133454
    28143455        // if year, monthnum, or day have been specified, make our query more precise
    28153456        // just in case there are multiple identical _wp_old_slug values
    28163457        if ( '' != $wp_query->query_vars['year'] )
    2817             $query .= " AND YEAR(post_date) = '{$wp_query->query_vars['year']}'";
     3458            $query .= $wpdb->prepare(" AND YEAR(post_date) = %d", $wp_query->query_vars['year']);
    28183459        if ( '' != $wp_query->query_vars['monthnum'] )
    2819             $query .= " AND MONTH(post_date) = '{$wp_query->query_vars['monthnum']}'";
     3460            $query .= $wpdb->prepare(" AND MONTH(post_date) = %d", $wp_query->query_vars['monthnum']);
    28203461        if ( '' != $wp_query->query_vars['day'] )
    2821             $query .= " AND DAYOFMONTH(post_date) = '{$wp_query->query_vars['day']}'";
     3462            $query .= $wpdb->prepare(" AND DAYOFMONTH(post_date) = %d", $wp_query->query_vars['day']);
    28223463
    28233464        $id = (int) $wpdb->get_var($query);
    28243465
    2825         if ( !$id )
     3466        if ( ! $id )
    28263467            return;
    28273468
     
    28463487 */
    28473488function setup_postdata($post) {
    2848     global $id, $authordata, $day, $currentmonth, $page, $pages, $multipage, $more, $numpages;
     3489    global $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages;
    28493490
    28503491    $id = (int) $post->ID;
     
    28523493    $authordata = get_userdata($post->post_author);
    28533494
    2854     $day = mysql2date('d.m.y', $post->post_date, false);
     3495    $currentday = mysql2date('d.m.y', $post->post_date, false);
    28553496    $currentmonth = mysql2date('m', $post->post_date, false);
    28563497    $numpages = 1;
Note: See TracChangeset for help on using the changeset viewer.