[ Index ]

WordPress Cross Reference

title

Body

[close]

/wp-includes/ -> query.php (source)

   1  <?php
   2  /**
   3   * WordPress Query API
   4   *
   5   * The query API attempts to get which part of WordPress the user is on. It
   6   * also provides functionality for getting URL query information.
   7   *
   8   * @link http://codex.wordpress.org/The_Loop More information on The Loop.
   9   *
  10   * @package WordPress
  11   * @subpackage Query
  12   */
  13  
  14  /**
  15   * Retrieve variable in the WP_Query class.
  16   *
  17   * @see WP_Query::get()
  18   * @since 1.5.0
  19   * @uses $wp_query
  20   *
  21   * @param string $var The variable key to retrieve.
  22   * @return mixed
  23   */
  24  function get_query_var($var) {
  25      global $wp_query;
  26  
  27      return $wp_query->get($var);
  28  }
  29  
  30  /**
  31   * Retrieve the currently-queried object. Wrapper for $wp_query->get_queried_object()
  32   *
  33   * @uses WP_Query::get_queried_object
  34   *
  35   * @since 3.1.0
  36   * @access public
  37   *
  38   * @return object
  39   */
  40  function get_queried_object() {
  41      global $wp_query;
  42      return $wp_query->get_queried_object();
  43  }
  44  
  45  /**
  46   * Retrieve ID of the current queried object. Wrapper for $wp_query->get_queried_object_id()
  47   *
  48   * @uses WP_Query::get_queried_object_id()
  49   *
  50   * @since 3.1.0
  51   * @access public
  52   *
  53   * @return int
  54   */
  55  function get_queried_object_id() {
  56      global $wp_query;
  57      return $wp_query->get_queried_object_id();
  58  }
  59  
  60  /**
  61   * Set query variable.
  62   *
  63   * @see WP_Query::set()
  64   * @since 2.2.0
  65   * @uses $wp_query
  66   *
  67   * @param string $var Query variable key.
  68   * @param mixed $value
  69   * @return null
  70   */
  71  function set_query_var($var, $value) {
  72      global $wp_query;
  73  
  74      return $wp_query->set($var, $value);
  75  }
  76  
  77  /**
  78   * Set up The Loop with query parameters.
  79   *
  80   * This will override the current WordPress Loop and shouldn't be used more than
  81   * once. This must not be used within the WordPress Loop.
  82   *
  83   * @since 1.5.0
  84   * @uses $wp_query
  85   *
  86   * @param string $query
  87   * @return array List of posts
  88   */
  89  function query_posts($query) {
  90      $GLOBALS['wp_query'] = new WP_Query();
  91      return $GLOBALS['wp_query']->query($query);
  92  }
  93  
  94  /**
  95   * Destroy the previous query and set up a new query.
  96   *
  97   * This should be used after {@link query_posts()} and before another {@link
  98   * query_posts()}. This will remove obscure bugs that occur when the previous
  99   * wp_query object is not destroyed properly before another is set up.
 100   *
 101   * @since 2.3.0
 102   * @uses $wp_query
 103   */
 104  function wp_reset_query() {
 105      $GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
 106      wp_reset_postdata();
 107  }
 108  
 109  /**
 110   * After looping through a separate query, this function restores
 111   * the $post global to the current post in the main query.
 112   *
 113   * @since 3.0.0
 114   * @uses $wp_query
 115   */
 116  function wp_reset_postdata() {
 117      global $wp_query;
 118  
 119      if ( isset( $wp_query ) ) {
 120          $wp_query->reset_postdata();
 121      }
 122  }
 123  
 124  /*
 125   * Query type checks.
 126   */
 127  
 128  /**
 129   * Is the query for an existing archive page?
 130   *
 131   * Month, Year, Category, Author, Post Type archive...
 132   *
 133   * @see WP_Query::is_archive()
 134   * @since 1.5.0
 135   * @uses $wp_query
 136   *
 137   * @return bool
 138   */
 139  function is_archive() {
 140      global $wp_query;
 141  
 142      if ( ! isset( $wp_query ) ) {
 143          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 144          return false;
 145      }
 146  
 147      return $wp_query->is_archive();
 148  }
 149  
 150  /**
 151   * Is the query for an existing post type archive page?
 152   *
 153   * @see WP_Query::is_post_type_archive()
 154   * @since 3.1.0
 155   * @uses $wp_query
 156   *
 157   * @param mixed $post_types Optional. Post type or array of posts types to check against.
 158   * @return bool
 159   */
 160  function is_post_type_archive( $post_types = '' ) {
 161      global $wp_query;
 162  
 163      if ( ! isset( $wp_query ) ) {
 164          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 165          return false;
 166      }
 167  
 168      return $wp_query->is_post_type_archive( $post_types );
 169  }
 170  
 171  /**
 172   * Is the query for an existing attachment page?
 173   *
 174   * @see WP_Query::is_attachment()
 175   * @since 2.0.0
 176   * @uses $wp_query
 177   *
 178   * @return bool
 179   */
 180  function is_attachment() {
 181      global $wp_query;
 182  
 183      if ( ! isset( $wp_query ) ) {
 184          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 185          return false;
 186      }
 187  
 188      return $wp_query->is_attachment();
 189  }
 190  
 191  /**
 192   * Is the query for an existing author archive page?
 193   *
 194   * If the $author parameter is specified, this function will additionally
 195   * check if the query is for one of the authors specified.
 196   *
 197   * @see WP_Query::is_author()
 198   * @since 1.5.0
 199   * @uses $wp_query
 200   *
 201   * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames
 202   * @return bool
 203   */
 204  function is_author( $author = '' ) {
 205      global $wp_query;
 206  
 207      if ( ! isset( $wp_query ) ) {
 208          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 209          return false;
 210      }
 211  
 212      return $wp_query->is_author( $author );
 213  }
 214  
 215  /**
 216   * Is the query for an existing category archive page?
 217   *
 218   * If the $category parameter is specified, this function will additionally
 219   * check if the query is for one of the categories specified.
 220   *
 221   * @see WP_Query::is_category()
 222   * @since 1.5.0
 223   * @uses $wp_query
 224   *
 225   * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs.
 226   * @return bool
 227   */
 228  function is_category( $category = '' ) {
 229      global $wp_query;
 230  
 231      if ( ! isset( $wp_query ) ) {
 232          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 233          return false;
 234      }
 235  
 236      return $wp_query->is_category( $category );
 237  }
 238  
 239  /**
 240   * Is the query for an existing tag archive page?
 241   *
 242   * If the $tag parameter is specified, this function will additionally
 243   * check if the query is for one of the tags specified.
 244   *
 245   * @see WP_Query::is_tag()
 246   * @since 2.3.0
 247   * @uses $wp_query
 248   *
 249   * @param mixed $tag Optional. Tag ID, name, slug, or array of Tag IDs, names, and slugs.
 250   * @return bool
 251   */
 252  function is_tag( $tag = '' ) {
 253      global $wp_query;
 254  
 255      if ( ! isset( $wp_query ) ) {
 256          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 257          return false;
 258      }
 259  
 260      return $wp_query->is_tag( $tag );
 261  }
 262  
 263  /**
 264   * Is the query for an existing taxonomy archive page?
 265   *
 266   * If the $taxonomy parameter is specified, this function will additionally
 267   * check if the query is for that specific $taxonomy.
 268   *
 269   * If the $term parameter is specified in addition to the $taxonomy parameter,
 270   * this function will additionally check if the query is for one of the terms
 271   * specified.
 272   *
 273   * @see WP_Query::is_tax()
 274   * @since 2.5.0
 275   * @uses $wp_query
 276   *
 277   * @param mixed $taxonomy Optional. Taxonomy slug or slugs.
 278   * @param mixed $term Optional. Term ID, name, slug or array of Term IDs, names, and slugs.
 279   * @return bool
 280   */
 281  function is_tax( $taxonomy = '', $term = '' ) {
 282      global $wp_query;
 283  
 284      if ( ! isset( $wp_query ) ) {
 285          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 286          return false;
 287      }
 288  
 289      return $wp_query->is_tax( $taxonomy, $term );
 290  }
 291  
 292  /**
 293   * Whether the current URL is within the comments popup window.
 294   *
 295   * @see WP_Query::is_comments_popup()
 296   * @since 1.5.0
 297   * @uses $wp_query
 298   *
 299   * @return bool
 300   */
 301  function is_comments_popup() {
 302      global $wp_query;
 303  
 304      if ( ! isset( $wp_query ) ) {
 305          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 306          return false;
 307      }
 308  
 309      return $wp_query->is_comments_popup();
 310  }
 311  
 312  /**
 313   * Is the query for an existing date archive?
 314   *
 315   * @see WP_Query::is_date()
 316   * @since 1.5.0
 317   * @uses $wp_query
 318   *
 319   * @return bool
 320   */
 321  function is_date() {
 322      global $wp_query;
 323  
 324      if ( ! isset( $wp_query ) ) {
 325          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 326          return false;
 327      }
 328  
 329      return $wp_query->is_date();
 330  }
 331  
 332  /**
 333   * Is the query for an existing day archive?
 334   *
 335   * @see WP_Query::is_day()
 336   * @since 1.5.0
 337   * @uses $wp_query
 338   *
 339   * @return bool
 340   */
 341  function is_day() {
 342      global $wp_query;
 343  
 344      if ( ! isset( $wp_query ) ) {
 345          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 346          return false;
 347      }
 348  
 349      return $wp_query->is_day();
 350  }
 351  
 352  /**
 353   * Is the query for a feed?
 354   *
 355   * @see WP_Query::is_feed()
 356   * @since 1.5.0
 357   * @uses $wp_query
 358   *
 359   * @param string|array $feeds Optional feed types to check.
 360   * @return bool
 361   */
 362  function is_feed( $feeds = '' ) {
 363      global $wp_query;
 364  
 365      if ( ! isset( $wp_query ) ) {
 366          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 367          return false;
 368      }
 369  
 370      return $wp_query->is_feed( $feeds );
 371  }
 372  
 373  /**
 374   * Is the query for a comments feed?
 375   *
 376   * @see WP_Query::is_comments_feed()
 377   * @since 3.0.0
 378   * @uses $wp_query
 379   *
 380   * @return bool
 381   */
 382  function is_comment_feed() {
 383      global $wp_query;
 384  
 385      if ( ! isset( $wp_query ) ) {
 386          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 387          return false;
 388      }
 389  
 390      return $wp_query->is_comment_feed();
 391  }
 392  
 393  /**
 394   * Is the query for the front page of the site?
 395   *
 396   * This is for what is displayed at your site's main URL.
 397   *
 398   * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_on_front'.
 399   *
 400   * If you set a static page for the front page of your site, this function will return
 401   * true when viewing that page.
 402   *
 403   * Otherwise the same as @see is_home()
 404   *
 405   * @see WP_Query::is_front_page()
 406   * @since 2.5.0
 407   * @uses is_home()
 408   * @uses get_option()
 409   *
 410   * @return bool True, if front of site.
 411   */
 412  function is_front_page() {
 413      global $wp_query;
 414  
 415      if ( ! isset( $wp_query ) ) {
 416          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 417          return false;
 418      }
 419  
 420      return $wp_query->is_front_page();
 421  }
 422  
 423  /**
 424   * Is the query for the blog homepage?
 425   *
 426   * This is the page which shows the time based blog content of your site.
 427   *
 428   * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_for_posts'.
 429   *
 430   * If you set a static page for the front page of your site, this function will return
 431   * true only on the page you set as the "Posts page".
 432   *
 433   * @see is_front_page()
 434   *
 435   * @see WP_Query::is_home()
 436   * @since 1.5.0
 437   * @uses $wp_query
 438   *
 439   * @return bool True if blog view homepage.
 440   */
 441  function is_home() {
 442      global $wp_query;
 443  
 444      if ( ! isset( $wp_query ) ) {
 445          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 446          return false;
 447      }
 448  
 449      return $wp_query->is_home();
 450  }
 451  
 452  /**
 453   * Is the query for an existing month archive?
 454   *
 455   * @see WP_Query::is_month()
 456   * @since 1.5.0
 457   * @uses $wp_query
 458   *
 459   * @return bool
 460   */
 461  function is_month() {
 462      global $wp_query;
 463  
 464      if ( ! isset( $wp_query ) ) {
 465          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 466          return false;
 467      }
 468  
 469      return $wp_query->is_month();
 470  }
 471  
 472  /**
 473   * Is the query for an existing single page?
 474   *
 475   * If the $page parameter is specified, this function will additionally
 476   * check if the query is for one of the pages specified.
 477   *
 478   * @see is_single()
 479   * @see is_singular()
 480   *
 481   * @see WP_Query::is_page()
 482   * @since 1.5.0
 483   * @uses $wp_query
 484   *
 485   * @param mixed $page Page ID, title, slug, or array of such.
 486   * @return bool
 487   */
 488  function is_page( $page = '' ) {
 489      global $wp_query;
 490  
 491      if ( ! isset( $wp_query ) ) {
 492          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 493          return false;
 494      }
 495  
 496      return $wp_query->is_page( $page );
 497  }
 498  
 499  /**
 500   * Is the query for paged result and not for the first page?
 501   *
 502   * @see WP_Query::is_paged()
 503   * @since 1.5.0
 504   * @uses $wp_query
 505   *
 506   * @return bool
 507   */
 508  function is_paged() {
 509      global $wp_query;
 510  
 511      if ( ! isset( $wp_query ) ) {
 512          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 513          return false;
 514      }
 515  
 516      return $wp_query->is_paged();
 517  }
 518  
 519  /**
 520   * Is the query for a post or page preview?
 521   *
 522   * @see WP_Query::is_preview()
 523   * @since 2.0.0
 524   * @uses $wp_query
 525   *
 526   * @return bool
 527   */
 528  function is_preview() {
 529      global $wp_query;
 530  
 531      if ( ! isset( $wp_query ) ) {
 532          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 533          return false;
 534      }
 535  
 536      return $wp_query->is_preview();
 537  }
 538  
 539  /**
 540   * Is the query for the robots file?
 541   *
 542   * @see WP_Query::is_robots()
 543   * @since 2.1.0
 544   * @uses $wp_query
 545   *
 546   * @return bool
 547   */
 548  function is_robots() {
 549      global $wp_query;
 550  
 551      if ( ! isset( $wp_query ) ) {
 552          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 553          return false;
 554      }
 555  
 556      return $wp_query->is_robots();
 557  }
 558  
 559  /**
 560   * Is the query for a search?
 561   *
 562   * @see WP_Query::is_search()
 563   * @since 1.5.0
 564   * @uses $wp_query
 565   *
 566   * @return bool
 567   */
 568  function is_search() {
 569      global $wp_query;
 570  
 571      if ( ! isset( $wp_query ) ) {
 572          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 573          return false;
 574      }
 575  
 576      return $wp_query->is_search();
 577  }
 578  
 579  /**
 580   * Is the query for an existing single post?
 581   *
 582   * Works for any post type, except attachments and pages
 583   *
 584   * If the $post parameter is specified, this function will additionally
 585   * check if the query is for one of the Posts specified.
 586   *
 587   * @see is_page()
 588   * @see is_singular()
 589   *
 590   * @see WP_Query::is_single()
 591   * @since 1.5.0
 592   * @uses $wp_query
 593   *
 594   * @param mixed $post Post ID, title, slug, or array of such.
 595   * @return bool
 596   */
 597  function is_single( $post = '' ) {
 598      global $wp_query;
 599  
 600      if ( ! isset( $wp_query ) ) {
 601          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 602          return false;
 603      }
 604  
 605      return $wp_query->is_single( $post );
 606  }
 607  
 608  /**
 609   * Is the query for an existing single post of any post type (post, attachment, page, ... )?
 610   *
 611   * If the $post_types parameter is specified, this function will additionally
 612   * check if the query is for one of the Posts Types specified.
 613   *
 614   * @see is_page()
 615   * @see is_single()
 616   *
 617   * @see WP_Query::is_singular()
 618   * @since 1.5.0
 619   * @uses $wp_query
 620   *
 621   * @param mixed $post_types Optional. Post Type or array of Post Types
 622   * @return bool
 623   */
 624  function is_singular( $post_types = '' ) {
 625      global $wp_query;
 626  
 627      if ( ! isset( $wp_query ) ) {
 628          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 629          return false;
 630      }
 631  
 632      return $wp_query->is_singular( $post_types );
 633  }
 634  
 635  /**
 636   * Is the query for a specific time?
 637   *
 638   * @see WP_Query::is_time()
 639   * @since 1.5.0
 640   * @uses $wp_query
 641   *
 642   * @return bool
 643   */
 644  function is_time() {
 645      global $wp_query;
 646  
 647      if ( ! isset( $wp_query ) ) {
 648          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 649          return false;
 650      }
 651  
 652      return $wp_query->is_time();
 653  }
 654  
 655  /**
 656   * Is the query for a trackback endpoint call?
 657   *
 658   * @see WP_Query::is_trackback()
 659   * @since 1.5.0
 660   * @uses $wp_query
 661   *
 662   * @return bool
 663   */
 664  function is_trackback() {
 665      global $wp_query;
 666  
 667      if ( ! isset( $wp_query ) ) {
 668          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 669          return false;
 670      }
 671  
 672      return $wp_query->is_trackback();
 673  }
 674  
 675  /**
 676   * Is the query for an existing year archive?
 677   *
 678   * @see WP_Query::is_year()
 679   * @since 1.5.0
 680   * @uses $wp_query
 681   *
 682   * @return bool
 683   */
 684  function is_year() {
 685      global $wp_query;
 686  
 687      if ( ! isset( $wp_query ) ) {
 688          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 689          return false;
 690      }
 691  
 692      return $wp_query->is_year();
 693  }
 694  
 695  /**
 696   * Is the query a 404 (returns no results)?
 697   *
 698   * @see WP_Query::is_404()
 699   * @since 1.5.0
 700   * @uses $wp_query
 701   *
 702   * @return bool
 703   */
 704  function is_404() {
 705      global $wp_query;
 706  
 707      if ( ! isset( $wp_query ) ) {
 708          _doing_it_wrong( __FUNCTION__, __( 'Conditional query tags do not work before the query is run. Before then, they always return false.' ), '3.1' );
 709          return false;
 710      }
 711  
 712      return $wp_query->is_404();
 713  }
 714  
 715  /**
 716   * Is the query the main query?
 717   *
 718   * @since 3.3.0
 719   *
 720   * @return bool
 721   */
 722  function is_main_query() {
 723      if ( 'pre_get_posts' === current_filter() ) {
 724          $message = sprintf( __( 'In <code>%1$s</code>, use the <code>%2$s</code> method, not the <code>%3$s</code> function. See %4$s.' ),
 725              'pre_get_posts', 'WP_Query::is_main_query()', 'is_main_query()', __( 'http://codex.wordpress.org/Function_Reference/is_main_query' ) );
 726          _doing_it_wrong( __FUNCTION__, $message, '3.7' );
 727      }
 728  
 729      global $wp_query;
 730      return $wp_query->is_main_query();
 731  }
 732  
 733  /*
 734   * The Loop. Post loop control.
 735   */
 736  
 737  /**
 738   * Whether current WordPress query has results to loop over.
 739   *
 740   * @see WP_Query::have_posts()
 741   * @since 1.5.0
 742   * @uses $wp_query
 743   *
 744   * @return bool
 745   */
 746  function have_posts() {
 747      global $wp_query;
 748  
 749      return $wp_query->have_posts();
 750  }
 751  
 752  /**
 753   * Whether the caller is in the Loop.
 754   *
 755   * @since 2.0.0
 756   * @uses $wp_query
 757   *
 758   * @return bool True if caller is within loop, false if loop hasn't started or ended.
 759   */
 760  function in_the_loop() {
 761      global $wp_query;
 762  
 763      return $wp_query->in_the_loop;
 764  }
 765  
 766  /**
 767   * Rewind the loop posts.
 768   *
 769   * @see WP_Query::rewind_posts()
 770   * @since 1.5.0
 771   * @uses $wp_query
 772   *
 773   * @return null
 774   */
 775  function rewind_posts() {
 776      global $wp_query;
 777  
 778      return $wp_query->rewind_posts();
 779  }
 780  
 781  /**
 782   * Iterate the post index in the loop.
 783   *
 784   * @see WP_Query::the_post()
 785   * @since 1.5.0
 786   * @uses $wp_query
 787   */
 788  function the_post() {
 789      global $wp_query;
 790  
 791      $wp_query->the_post();
 792  }
 793  
 794  /*
 795   * Comments loop.
 796   */
 797  
 798  /**
 799   * Whether there are comments to loop over.
 800   *
 801   * @see WP_Query::have_comments()
 802   * @since 2.2.0
 803   * @uses $wp_query
 804   *
 805   * @return bool
 806   */
 807  function have_comments() {
 808      global $wp_query;
 809      return $wp_query->have_comments();
 810  }
 811  
 812  /**
 813   * Iterate comment index in the comment loop.
 814   *
 815   * @see WP_Query::the_comment()
 816   * @since 2.2.0
 817   * @uses $wp_query
 818   *
 819   * @return object
 820   */
 821  function the_comment() {
 822      global $wp_query;
 823      return $wp_query->the_comment();
 824  }
 825  
 826  /*
 827   * WP_Query
 828   */
 829  
 830  /**
 831   * The WordPress Query class.
 832   *
 833   * @link http://codex.wordpress.org/Function_Reference/WP_Query Codex page.
 834   *
 835   * @since 1.5.0
 836   */
 837  class WP_Query {
 838  
 839      /**
 840       * Query vars set by the user
 841       *
 842       * @since 1.5.0
 843       * @access public
 844       * @var array
 845       */
 846      var $query;
 847  
 848      /**
 849       * Query vars, after parsing
 850       *
 851       * @since 1.5.0
 852       * @access public
 853       * @var array
 854       */
 855      var $query_vars = array();
 856  
 857      /**
 858       * Taxonomy query, as passed to get_tax_sql()
 859       *
 860       * @since 3.1.0
 861       * @access public
 862       * @var object WP_Tax_Query
 863       */
 864      var $tax_query;
 865  
 866      /**
 867       * Metadata query container
 868       *
 869       * @since 3.2.0
 870       * @access public
 871       * @var object WP_Meta_Query
 872       */
 873      var $meta_query = false;
 874  
 875      /**
 876       * Date query container
 877       *
 878       * @since 3.7.0
 879       * @access public
 880       * @var object WP_Date_Query
 881       */
 882      var $date_query = false;
 883  
 884      /**
 885       * Holds the data for a single object that is queried.
 886       *
 887       * Holds the contents of a post, page, category, attachment.
 888       *
 889       * @since 1.5.0
 890       * @access public
 891       * @var object|array
 892       */
 893      var $queried_object;
 894  
 895      /**
 896       * The ID of the queried object.
 897       *
 898       * @since 1.5.0
 899       * @access public
 900       * @var int
 901       */
 902      var $queried_object_id;
 903  
 904      /**
 905       * Get post database query.
 906       *
 907       * @since 2.0.1
 908       * @access public
 909       * @var string
 910       */
 911      var $request;
 912  
 913      /**
 914       * List of posts.
 915       *
 916       * @since 1.5.0
 917       * @access public
 918       * @var array
 919       */
 920      var $posts;
 921  
 922      /**
 923       * The amount of posts for the current query.
 924       *
 925       * @since 1.5.0
 926       * @access public
 927       * @var int
 928       */
 929      var $post_count = 0;
 930  
 931      /**
 932       * Index of the current item in the loop.
 933       *
 934       * @since 1.5.0
 935       * @access public
 936       * @var int
 937       */
 938      var $current_post = -1;
 939  
 940      /**
 941       * Whether the loop has started and the caller is in the loop.
 942       *
 943       * @since 2.0.0
 944       * @access public
 945       * @var bool
 946       */
 947      var $in_the_loop = false;
 948  
 949      /**
 950       * The current post.
 951       *
 952       * @since 1.5.0
 953       * @access public
 954       * @var WP_Post
 955       */
 956      var $post;
 957  
 958      /**
 959       * The list of comments for current post.
 960       *
 961       * @since 2.2.0
 962       * @access public
 963       * @var array
 964       */
 965      var $comments;
 966  
 967      /**
 968       * The amount of comments for the posts.
 969       *
 970       * @since 2.2.0
 971       * @access public
 972       * @var int
 973       */
 974      var $comment_count = 0;
 975  
 976      /**
 977       * The index of the comment in the comment loop.
 978       *
 979       * @since 2.2.0
 980       * @access public
 981       * @var int
 982       */
 983      var $current_comment = -1;
 984  
 985      /**
 986       * Current comment ID.
 987       *
 988       * @since 2.2.0
 989       * @access public
 990       * @var int
 991       */
 992      var $comment;
 993  
 994      /**
 995       * The amount of found posts for the current query.
 996       *
 997       * If limit clause was not used, equals $post_count.
 998       *
 999       * @since 2.1.0
1000       * @access public
1001       * @var int
1002       */
1003      var $found_posts = 0;
1004  
1005      /**
1006       * The amount of pages.
1007       *
1008       * @since 2.1.0
1009       * @access public
1010       * @var int
1011       */
1012      var $max_num_pages = 0;
1013  
1014      /**
1015       * The amount of comment pages.
1016       *
1017       * @since 2.7.0
1018       * @access public
1019       * @var int
1020       */
1021      var $max_num_comment_pages = 0;
1022  
1023      /**
1024       * Set if query is single post.
1025       *
1026       * @since 1.5.0
1027       * @access public
1028       * @var bool
1029       */
1030      var $is_single = false;
1031  
1032      /**
1033       * Set if query is preview of blog.
1034       *
1035       * @since 2.0.0
1036       * @access public
1037       * @var bool
1038       */
1039      var $is_preview = false;
1040  
1041      /**
1042       * Set if query returns a page.
1043       *
1044       * @since 1.5.0
1045       * @access public
1046       * @var bool
1047       */
1048      var $is_page = false;
1049  
1050      /**
1051       * Set if query is an archive list.
1052       *
1053       * @since 1.5.0
1054       * @access public
1055       * @var bool
1056       */
1057      var $is_archive = false;
1058  
1059      /**
1060       * Set if query is part of a date.
1061       *
1062       * @since 1.5.0
1063       * @access public
1064       * @var bool
1065       */
1066      var $is_date = false;
1067  
1068      /**
1069       * Set if query contains a year.
1070       *
1071       * @since 1.5.0
1072       * @access public
1073       * @var bool
1074       */
1075      var $is_year = false;
1076  
1077      /**
1078       * Set if query contains a month.
1079       *
1080       * @since 1.5.0
1081       * @access public
1082       * @var bool
1083       */
1084      var $is_month = false;
1085  
1086      /**
1087       * Set if query contains a day.
1088       *
1089       * @since 1.5.0
1090       * @access public
1091       * @var bool
1092       */
1093      var $is_day = false;
1094  
1095      /**
1096       * Set if query contains time.
1097       *
1098       * @since 1.5.0
1099       * @access public
1100       * @var bool
1101       */
1102      var $is_time = false;
1103  
1104      /**
1105       * Set if query contains an author.
1106       *
1107       * @since 1.5.0
1108       * @access public
1109       * @var bool
1110       */
1111      var $is_author = false;
1112  
1113      /**
1114       * Set if query contains category.
1115       *
1116       * @since 1.5.0
1117       * @access public
1118       * @var bool
1119       */
1120      var $is_category = false;
1121  
1122      /**
1123       * Set if query contains tag.
1124       *
1125       * @since 2.3.0
1126       * @access public
1127       * @var bool
1128       */
1129      var $is_tag = false;
1130  
1131      /**
1132       * Set if query contains taxonomy.
1133       *
1134       * @since 2.5.0
1135       * @access public
1136       * @var bool
1137       */
1138      var $is_tax = false;
1139  
1140      /**
1141       * Set if query was part of a search result.
1142       *
1143       * @since 1.5.0
1144       * @access public
1145       * @var bool
1146       */
1147      var $is_search = false;
1148  
1149      /**
1150       * Set if query is feed display.
1151       *
1152       * @since 1.5.0
1153       * @access public
1154       * @var bool
1155       */
1156      var $is_feed = false;
1157  
1158      /**
1159       * Set if query is comment feed display.
1160       *
1161       * @since 2.2.0
1162       * @access public
1163       * @var bool
1164       */
1165      var $is_comment_feed = false;
1166  
1167      /**
1168       * Set if query is trackback.
1169       *
1170       * @since 1.5.0
1171       * @access public
1172       * @var bool
1173       */
1174      var $is_trackback = false;
1175  
1176      /**
1177       * Set if query is blog homepage.
1178       *
1179       * @since 1.5.0
1180       * @access public
1181       * @var bool
1182       */
1183      var $is_home = false;
1184  
1185      /**
1186       * Set if query couldn't found anything.
1187       *
1188       * @since 1.5.0
1189       * @access public
1190       * @var bool
1191       */
1192      var $is_404 = false;
1193  
1194      /**
1195       * Set if query is within comments popup window.
1196       *
1197       * @since 1.5.0
1198       * @access public
1199       * @var bool
1200       */
1201      var $is_comments_popup = false;
1202  
1203      /**
1204       * Set if query is paged
1205       *
1206       * @since 1.5.0
1207       * @access public
1208       * @var bool
1209       */
1210      var $is_paged = false;
1211  
1212      /**
1213       * Set if query is part of administration page.
1214       *
1215       * @since 1.5.0
1216       * @access public
1217       * @var bool
1218       */
1219      var $is_admin = false;
1220  
1221      /**
1222       * Set if query is an attachment.
1223       *
1224       * @since 2.0.0
1225       * @access public
1226       * @var bool
1227       */
1228      var $is_attachment = false;
1229  
1230      /**
1231       * Set if is single, is a page, or is an attachment.
1232       *
1233       * @since 2.1.0
1234       * @access public
1235       * @var bool
1236       */
1237      var $is_singular = false;
1238  
1239      /**
1240       * Set if query is for robots.
1241       *
1242       * @since 2.1.0
1243       * @access public
1244       * @var bool
1245       */
1246      var $is_robots = false;
1247  
1248      /**
1249       * Set if query contains posts.
1250       *
1251       * Basically, the homepage if the option isn't set for the static homepage.
1252       *
1253       * @since 2.1.0
1254       * @access public
1255       * @var bool
1256       */
1257      var $is_posts_page = false;
1258  
1259      /**
1260       * Set if query is for a post type archive.
1261       *
1262       * @since 3.1.0
1263       * @access public
1264       * @var bool
1265       */
1266      var $is_post_type_archive = false;
1267  
1268      /**
1269       * Stores the ->query_vars state like md5(serialize( $this->query_vars ) ) so we know
1270       * whether we have to re-parse because something has changed
1271       *
1272       * @since 3.1.0
1273       * @access private
1274       */
1275      var $query_vars_hash = false;
1276  
1277      /**
1278       * Whether query vars have changed since the initial parse_query() call. Used to catch modifications to query vars made
1279       * via pre_get_posts hooks.
1280       *
1281       * @since 3.1.1
1282       * @access private
1283       */
1284      var $query_vars_changed = true;
1285  
1286      /**
1287       * Set if post thumbnails are cached
1288       *
1289       * @since 3.2.0
1290       * @access public
1291       * @var bool
1292       */
1293       var $thumbnails_cached = false;
1294  
1295      /**
1296       * Cached list of search stopwords.
1297       *
1298       * @since 3.7.0
1299       * @var array
1300       */
1301      private $stopwords;
1302  
1303      /**
1304       * Resets query flags to false.
1305       *
1306       * The query flags are what page info WordPress was able to figure out.
1307       *
1308       * @since 2.0.0
1309       * @access private
1310       */
1311  	function init_query_flags() {
1312          $this->is_single = false;
1313          $this->is_preview = false;
1314          $this->is_page = false;
1315          $this->is_archive = false;
1316          $this->is_date = false;
1317          $this->is_year = false;
1318          $this->is_month = false;
1319          $this->is_day = false;
1320          $this->is_time = false;
1321          $this->is_author = false;
1322          $this->is_category = false;
1323          $this->is_tag = false;
1324          $this->is_tax = false;
1325          $this->is_search = false;
1326          $this->is_feed = false;
1327          $this->is_comment_feed = false;
1328          $this->is_trackback = false;
1329          $this->is_home = false;
1330          $this->is_404 = false;
1331          $this->is_comments_popup = false;
1332          $this->is_paged = false;
1333          $this->is_admin = false;
1334          $this->is_attachment = false;
1335          $this->is_singular = false;
1336          $this->is_robots = false;
1337          $this->is_posts_page = false;
1338          $this->is_post_type_archive = false;
1339      }
1340  
1341      /**
1342       * Initiates object properties and sets default values.
1343       *
1344       * @since 1.5.0
1345       * @access public
1346       */
1347  	function init() {
1348          unset($this->posts);
1349          unset($this->query);
1350          $this->query_vars = array();
1351          unset($this->queried_object);
1352          unset($this->queried_object_id);
1353          $this->post_count = 0;
1354          $this->current_post = -1;
1355          $this->in_the_loop = false;
1356          unset( $this->request );
1357          unset( $this->post );
1358          unset( $this->comments );
1359          unset( $this->comment );
1360          $this->comment_count = 0;
1361          $this->current_comment = -1;
1362          $this->found_posts = 0;
1363          $this->max_num_pages = 0;
1364          $this->max_num_comment_pages = 0;
1365  
1366          $this->init_query_flags();
1367      }
1368  
1369      /**
1370       * Reparse the query vars.
1371       *
1372       * @since 1.5.0
1373       * @access public
1374       */
1375  	function parse_query_vars() {
1376          $this->parse_query();
1377      }
1378  
1379      /**
1380       * Fills in the query variables, which do not exist within the parameter.
1381       *
1382       * @since 2.1.0
1383       * @access public
1384       *
1385       * @param array $array Defined query variables.
1386       * @return array Complete query variables with undefined ones filled in empty.
1387       */
1388  	function fill_query_vars($array) {
1389          $keys = array(
1390              'error'
1391              , 'm'
1392              , 'p'
1393              , 'post_parent'
1394              , 'subpost'
1395              , 'subpost_id'
1396              , 'attachment'
1397              , 'attachment_id'
1398              , 'name'
1399              , 'static'
1400              , 'pagename'
1401              , 'page_id'
1402              , 'second'
1403              , 'minute'
1404              , 'hour'
1405              , 'day'
1406              , 'monthnum'
1407              , 'year'
1408              , 'w'
1409              , 'category_name'
1410              , 'tag'
1411              , 'cat'
1412              , 'tag_id'
1413              , 'author'
1414              , 'author_name'
1415              , 'feed'
1416              , 'tb'
1417              , 'paged'
1418              , 'comments_popup'
1419              , 'meta_key'
1420              , 'meta_value'
1421              , 'preview'
1422              , 's'
1423              , 'sentence'
1424              , 'fields'
1425              , 'menu_order'
1426          );
1427  
1428          foreach ( $keys as $key ) {
1429              if ( !isset($array[$key]) )
1430                  $array[$key] = '';
1431          }
1432  
1433          $array_keys = array( 'category__in', 'category__not_in', 'category__and', 'post__in', 'post__not_in',
1434              'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and', 'post_parent__in', 'post_parent__not_in',
1435              'author__in', 'author__not_in' );
1436  
1437          foreach ( $array_keys as $key ) {
1438              if ( !isset($array[$key]) )
1439                  $array[$key] = array();
1440          }
1441          return $array;
1442      }
1443  
1444      /**
1445       * Parse a query string and set query type booleans.
1446       *
1447       * @since 1.5.0
1448       * @access public
1449       *
1450       * @param string|array $query Optional query.
1451       */
1452  	function parse_query( $query =  '' ) {
1453          if ( ! empty( $query ) ) {
1454              $this->init();
1455              $this->query = $this->query_vars = wp_parse_args( $query );
1456          } elseif ( ! isset( $this->query ) ) {
1457              $this->query = $this->query_vars;
1458          }
1459  
1460          $this->query_vars = $this->fill_query_vars($this->query_vars);
1461          $qv = &$this->query_vars;
1462          $this->query_vars_changed = true;
1463  
1464          if ( ! empty($qv['robots']) )
1465              $this->is_robots = true;
1466  
1467          $qv['p'] =  absint($qv['p']);
1468          $qv['page_id'] =  absint($qv['page_id']);
1469          $qv['year'] = absint($qv['year']);
1470          $qv['monthnum'] = absint($qv['monthnum']);
1471          $qv['day'] = absint($qv['day']);
1472          $qv['w'] = absint($qv['w']);
1473          $qv['m'] = preg_replace( '|[^0-9]|', '', $qv['m'] );
1474          $qv['paged'] = absint($qv['paged']);
1475          $qv['cat'] = preg_replace( '|[^0-9,-]|', '', $qv['cat'] ); // comma separated list of positive or negative integers
1476          $qv['author'] = preg_replace( '|[^0-9,-]|', '', $qv['author'] ); // comma separated list of positive or negative integers
1477          $qv['pagename'] = trim( $qv['pagename'] );
1478          $qv['name'] = trim( $qv['name'] );
1479          if ( '' !== $qv['hour'] ) $qv['hour'] = absint($qv['hour']);
1480          if ( '' !== $qv['minute'] ) $qv['minute'] = absint($qv['minute']);
1481          if ( '' !== $qv['second'] ) $qv['second'] = absint($qv['second']);
1482          if ( '' !== $qv['menu_order'] ) $qv['menu_order'] = absint($qv['menu_order']);
1483  
1484          // Fairly insane upper bound for search string lengths.
1485          if ( ! empty( $qv['s'] ) && strlen( $qv['s'] ) > 1600 )
1486              $qv['s'] = '';
1487  
1488          // Compat. Map subpost to attachment.
1489          if ( '' != $qv['subpost'] )
1490              $qv['attachment'] = $qv['subpost'];
1491          if ( '' != $qv['subpost_id'] )
1492              $qv['attachment_id'] = $qv['subpost_id'];
1493  
1494          $qv['attachment_id'] = absint($qv['attachment_id']);
1495  
1496          if ( ('' != $qv['attachment']) || !empty($qv['attachment_id']) ) {
1497              $this->is_single = true;
1498              $this->is_attachment = true;
1499          } elseif ( '' != $qv['name'] ) {
1500              $this->is_single = true;
1501          } elseif ( $qv['p'] ) {
1502              $this->is_single = true;
1503          } elseif ( ('' !== $qv['hour']) && ('' !== $qv['minute']) &&('' !== $qv['second']) && ('' != $qv['year']) && ('' != $qv['monthnum']) && ('' != $qv['day']) ) {
1504              // If year, month, day, hour, minute, and second are set, a single
1505              // post is being queried.
1506              $this->is_single = true;
1507          } elseif ( '' != $qv['static'] || '' != $qv['pagename'] || !empty($qv['page_id']) ) {
1508              $this->is_page = true;
1509              $this->is_single = false;
1510          } else {
1511          // Look for archive queries. Dates, categories, authors, search, post type archives.
1512  
1513              if ( !empty($qv['s']) ) {
1514                  $this->is_search = true;
1515              }
1516  
1517              if ( '' !== $qv['second'] ) {
1518                  $this->is_time = true;
1519                  $this->is_date = true;
1520              }
1521  
1522              if ( '' !== $qv['minute'] ) {
1523                  $this->is_time = true;
1524                  $this->is_date = true;
1525              }
1526  
1527              if ( '' !== $qv['hour'] ) {
1528                  $this->is_time = true;
1529                  $this->is_date = true;
1530              }
1531  
1532              if ( $qv['day'] ) {
1533                  if ( ! $this->is_date ) {
1534                      $date = sprintf( '%04d-%02d-%02d', $qv['year'], $qv['monthnum'], $qv['day'] );
1535                      if ( $qv['monthnum'] && $qv['year'] && ! wp_checkdate( $qv['monthnum'], $qv['day'], $qv['year'], $date ) ) {
1536                          $qv['error'] = '404';
1537                      } else {
1538                          $this->is_day = true;
1539                          $this->is_date = true;
1540                      }
1541                  }
1542              }
1543  
1544              if ( $qv['monthnum'] ) {
1545                  if ( ! $this->is_date ) {
1546                      if ( 12 < $qv['monthnum'] ) {
1547                          $qv['error'] = '404';
1548                      } else {
1549                          $this->is_month = true;
1550                          $this->is_date = true;
1551                      }
1552                  }
1553              }
1554  
1555              if ( $qv['year'] ) {
1556                  if ( ! $this->is_date ) {
1557                      $this->is_year = true;
1558                      $this->is_date = true;
1559                  }
1560              }
1561  
1562              if ( $qv['m'] ) {
1563                  $this->is_date = true;
1564                  if ( strlen($qv['m']) > 9 ) {
1565                      $this->is_time = true;
1566                  } else if ( strlen($qv['m']) > 7 ) {
1567                      $this->is_day = true;
1568                  } else if ( strlen($qv['m']) > 5 ) {
1569                      $this->is_month = true;
1570                  } else {
1571                      $this->is_year = true;
1572                  }
1573              }
1574  
1575              if ( '' != $qv['w'] ) {
1576                  $this->is_date = true;
1577              }
1578  
1579              $this->query_vars_hash = false;
1580              $this->parse_tax_query( $qv );
1581  
1582              foreach ( $this->tax_query->queries as $tax_query ) {
1583                  if ( 'NOT IN' != $tax_query['operator'] ) {
1584                      switch ( $tax_query['taxonomy'] ) {
1585                          case 'category':
1586                              $this->is_category = true;
1587                              break;
1588                          case 'post_tag':
1589                              $this->is_tag = true;
1590                              break;
1591                          default:
1592                              $this->is_tax = true;
1593                      }
1594                  }
1595              }
1596              unset( $tax_query );
1597  
1598              if ( empty($qv['author']) || ($qv['author'] == '0') ) {
1599                  $this->is_author = false;
1600              } else {
1601                  $this->is_author = true;
1602              }
1603  
1604              if ( '' != $qv['author_name'] )
1605                  $this->is_author = true;
1606  
1607              if ( !empty( $qv['post_type'] ) && ! is_array( $qv['post_type'] ) ) {
1608                  $post_type_obj = get_post_type_object( $qv['post_type'] );
1609                  if ( ! empty( $post_type_obj->has_archive ) )
1610                      $this->is_post_type_archive = true;
1611              }
1612  
1613              if ( $this->is_post_type_archive || $this->is_date || $this->is_author || $this->is_category || $this->is_tag || $this->is_tax )
1614                  $this->is_archive = true;
1615          }
1616  
1617          if ( '' != $qv['feed'] )
1618              $this->is_feed = true;
1619  
1620          if ( '' != $qv['tb'] )
1621              $this->is_trackback = true;
1622  
1623          if ( '' != $qv['paged'] && ( intval($qv['paged']) > 1 ) )
1624              $this->is_paged = true;
1625  
1626          if ( '' != $qv['comments_popup'] )
1627              $this->is_comments_popup = true;
1628  
1629          // if we're previewing inside the write screen
1630          if ( '' != $qv['preview'] )
1631              $this->is_preview = true;
1632  
1633          if ( is_admin() )
1634              $this->is_admin = true;
1635  
1636          if ( false !== strpos($qv['feed'], 'comments-') ) {
1637              $qv['feed'] = str_replace('comments-', '', $qv['feed']);
1638              $qv['withcomments'] = 1;
1639          }
1640  
1641          $this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
1642  
1643          if ( $this->is_feed && ( !empty($qv['withcomments']) || ( empty($qv['withoutcomments']) && $this->is_singular ) ) )
1644              $this->is_comment_feed = true;
1645  
1646          if ( !( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_comments_popup || $this->is_robots ) )
1647              $this->is_home = true;
1648  
1649          // Correct is_* for page_on_front and page_for_posts
1650          if ( $this->is_home && 'page' == get_option('show_on_front') && get_option('page_on_front') ) {
1651              $_query = wp_parse_args($this->query);
1652              // pagename can be set and empty depending on matched rewrite rules. Ignore an empty pagename.
1653              if ( isset($_query['pagename']) && '' == $_query['pagename'] )
1654                  unset($_query['pagename']);
1655              if ( empty($_query) || !array_diff( array_keys($_query), array('preview', 'page', 'paged', 'cpage') ) ) {
1656                  $this->is_page = true;
1657                  $this->is_home = false;
1658                  $qv['page_id'] = get_option('page_on_front');
1659                  // Correct <!--nextpage--> for page_on_front
1660                  if ( !empty($qv['paged']) ) {
1661                      $qv['page'] = $qv['paged'];
1662                      unset($qv['paged']);
1663                  }
1664              }
1665          }
1666  
1667          if ( '' != $qv['pagename'] ) {
1668              $this->queried_object = get_page_by_path($qv['pagename']);
1669              if ( !empty($this->queried_object) )
1670                  $this->queried_object_id = (int) $this->queried_object->ID;
1671              else
1672                  unset($this->queried_object);
1673  
1674              if  ( 'page' == get_option('show_on_front') && isset($this->queried_object_id) && $this->queried_object_id == get_option('page_for_posts') ) {
1675                  $this->is_page = false;
1676                  $this->is_home = true;
1677                  $this->is_posts_page = true;
1678              }
1679          }
1680  
1681          if ( $qv['page_id'] ) {
1682              if  ( 'page' == get_option('show_on_front') && $qv['page_id'] == get_option('page_for_posts') ) {
1683                  $this->is_page = false;
1684                  $this->is_home = true;
1685                  $this->is_posts_page = true;
1686              }
1687          }
1688  
1689          if ( !empty($qv['post_type']) ) {
1690              if ( is_array($qv['post_type']) )
1691                  $qv['post_type'] = array_map('sanitize_key', $qv['post_type']);
1692              else
1693                  $qv['post_type'] = sanitize_key($qv['post_type']);
1694          }
1695  
1696          if ( ! empty( $qv['post_status'] ) ) {
1697              if ( is_array( $qv['post_status'] ) )
1698                  $qv['post_status'] = array_map('sanitize_key', $qv['post_status']);
1699              else
1700                  $qv['post_status'] = preg_replace('|[^a-z0-9_,-]|', '', $qv['post_status']);
1701          }
1702  
1703          if ( $this->is_posts_page && ( ! isset($qv['withcomments']) || ! $qv['withcomments'] ) )
1704              $this->is_comment_feed = false;
1705  
1706          $this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
1707          // Done correcting is_* for page_on_front and page_for_posts
1708  
1709          if ( '404' == $qv['error'] )
1710              $this->set_404();
1711  
1712          $this->query_vars_hash = md5( serialize( $this->query_vars ) );
1713          $this->query_vars_changed = false;
1714  
1715          do_action_ref_array('parse_query', array(&$this));
1716      }
1717  
1718      /**
1719       * Parses various taxonomy related query vars.
1720       *
1721       * @access protected
1722       * @since 3.1.0
1723       *
1724       * @param array &$q The query variables
1725       */
1726  	function parse_tax_query( &$q ) {
1727          if ( ! empty( $q['tax_query'] ) && is_array( $q['tax_query'] ) ) {
1728              $tax_query = $q['tax_query'];
1729          } else {
1730              $tax_query = array();
1731          }
1732  
1733          if ( !empty($q['taxonomy']) && !empty($q['term']) ) {
1734              $tax_query[] = array(
1735                  'taxonomy' => $q['taxonomy'],
1736                  'terms' => array( $q['term'] ),
1737                  'field' => 'slug',
1738              );
1739          }
1740  
1741          foreach ( get_taxonomies( array() , 'objects' ) as $taxonomy => $t ) {
1742              if ( 'post_tag' == $taxonomy )
1743                  continue;    // Handled further down in the $q['tag'] block
1744  
1745              if ( $t->query_var && !empty( $q[$t->query_var] ) ) {
1746                  $tax_query_defaults = array(
1747                      'taxonomy' => $taxonomy,
1748                      'field' => 'slug',
1749                  );
1750  
1751                   if ( isset( $t->rewrite['hierarchical'] ) && $t->rewrite['hierarchical'] ) {
1752                      $q[$t->query_var] = wp_basename( $q[$t->query_var] );
1753                  }
1754  
1755                  $term = $q[$t->query_var];
1756  
1757                  if ( strpos($term, '+') !== false ) {
1758                      $terms = preg_split( '/[+]+/', $term );
1759                      foreach ( $terms as $term ) {
1760                          $tax_query[] = array_merge( $tax_query_defaults, array(
1761                              'terms' => array( $term )
1762                          ) );
1763                      }
1764                  } else {
1765                      $tax_query[] = array_merge( $tax_query_defaults, array(
1766                          'terms' => preg_split( '/[,]+/', $term )
1767                      ) );
1768                  }
1769              }
1770          }
1771  
1772          // Category stuff
1773          if ( ! empty( $q['cat'] ) && ! $this->is_singular ) {
1774              $cat_in = $cat_not_in = array();
1775  
1776              $cat_array = preg_split( '/[,\s]+/', urldecode( $q['cat'] ) );
1777              $cat_array = array_map( 'intval', $cat_array );
1778              $q['cat'] = implode( ',', $cat_array );
1779  
1780              foreach ( $cat_array as $cat ) {
1781                  if ( $cat > 0 )
1782                      $cat_in[] = $cat;
1783                  elseif ( $cat < 0 )
1784                      $cat_not_in[] = abs( $cat );
1785              }
1786  
1787              if ( ! empty( $cat_in ) ) {
1788                  $tax_query[] = array(
1789                      'taxonomy' => 'category',
1790                      'terms' => $cat_in,
1791                      'field' => 'term_id',
1792                      'include_children' => true
1793                  );
1794              }
1795  
1796              if ( ! empty( $cat_not_in ) ) {
1797                  $tax_query[] = array(
1798                      'taxonomy' => 'category',
1799                      'terms' => $cat_not_in,
1800                      'field' => 'term_id',
1801                      'operator' => 'NOT IN',
1802                      'include_children' => true
1803                  );
1804              }
1805              unset( $cat_array, $cat_in, $cat_not_in );
1806          }
1807  
1808          if ( ! empty( $q['category__and'] ) && 1 === count( (array) $q['category__and'] ) ) {
1809              $q['category__and'] = (array) $q['category__and'];
1810              if ( ! isset( $q['category__in'] ) )
1811                  $q['category__in'] = array();
1812              $q['category__in'][] = absint( reset( $q['category__and'] ) );
1813              unset( $q['category__and'] );
1814          }
1815  
1816          if ( ! empty( $q['category__in'] ) ) {
1817              $q['category__in'] = array_map( 'absint', array_unique( (array) $q['category__in'] ) );
1818              $tax_query[] = array(
1819                  'taxonomy' => 'category',
1820                  'terms' => $q['category__in'],
1821                  'field' => 'term_id',
1822                  'include_children' => false
1823              );
1824          }
1825  
1826          if ( ! empty($q['category__not_in']) ) {
1827              $q['category__not_in'] = array_map( 'absint', array_unique( (array) $q['category__not_in'] ) );
1828              $tax_query[] = array(
1829                  'taxonomy' => 'category',
1830                  'terms' => $q['category__not_in'],
1831                  'operator' => 'NOT IN',
1832                  'include_children' => false
1833              );
1834          }
1835  
1836          if ( ! empty($q['category__and']) ) {
1837              $q['category__and'] = array_map( 'absint', array_unique( (array) $q['category__and'] ) );
1838              $tax_query[] = array(
1839                  'taxonomy' => 'category',
1840                  'terms' => $q['category__and'],
1841                  'field' => 'term_id',
1842                  'operator' => 'AND',
1843                  'include_children' => false
1844              );
1845          }
1846  
1847          // Tag stuff
1848          if ( '' != $q['tag'] && !$this->is_singular && $this->query_vars_changed ) {
1849              if ( strpos($q['tag'], ',') !== false ) {
1850                  $tags = preg_split('/[,\r\n\t ]+/', $q['tag']);
1851                  foreach ( (array) $tags as $tag ) {
1852                      $tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
1853                      $q['tag_slug__in'][] = $tag;
1854                  }
1855              } else if ( preg_match('/[+\r\n\t ]+/', $q['tag']) || !empty($q['cat']) ) {
1856                  $tags = preg_split('/[+\r\n\t ]+/', $q['tag']);
1857                  foreach ( (array) $tags as $tag ) {
1858                      $tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
1859                      $q['tag_slug__and'][] = $tag;
1860                  }
1861              } else {
1862                  $q['tag'] = sanitize_term_field('slug', $q['tag'], 0, 'post_tag', 'db');
1863                  $q['tag_slug__in'][] = $q['tag'];
1864              }
1865          }
1866  
1867          if ( !empty($q['tag_id']) ) {
1868              $q['tag_id'] = absint( $q['tag_id'] );
1869              $tax_query[] = array(
1870                  'taxonomy' => 'post_tag',
1871                  'terms' => $q['tag_id']
1872              );
1873          }
1874  
1875          if ( !empty($q['tag__in']) ) {
1876              $q['tag__in'] = array_map('absint', array_unique( (array) $q['tag__in'] ) );
1877              $tax_query[] = array(
1878                  'taxonomy' => 'post_tag',
1879                  'terms' => $q['tag__in']
1880              );
1881          }
1882  
1883          if ( !empty($q['tag__not_in']) ) {
1884              $q['tag__not_in'] = array_map('absint', array_unique( (array) $q['tag__not_in'] ) );
1885              $tax_query[] = array(
1886                  'taxonomy' => 'post_tag',
1887                  'terms' => $q['tag__not_in'],
1888                  'operator' => 'NOT IN'
1889              );
1890          }
1891  
1892          if ( !empty($q['tag__and']) ) {
1893              $q['tag__and'] = array_map('absint', array_unique( (array) $q['tag__and'] ) );
1894              $tax_query[] = array(
1895                  'taxonomy' => 'post_tag',
1896                  'terms' => $q['tag__and'],
1897                  'operator' => 'AND'
1898              );
1899          }
1900  
1901          if ( !empty($q['tag_slug__in']) ) {
1902              $q['tag_slug__in'] = array_map('sanitize_title_for_query', array_unique( (array) $q['tag_slug__in'] ) );
1903              $tax_query[] = array(
1904                  'taxonomy' => 'post_tag',
1905                  'terms' => $q['tag_slug__in'],
1906                  'field' => 'slug'
1907              );
1908          }
1909  
1910          if ( !empty($q['tag_slug__and']) ) {
1911              $q['tag_slug__and'] = array_map('sanitize_title_for_query', array_unique( (array) $q['tag_slug__and'] ) );
1912              $tax_query[] = array(
1913                  'taxonomy' => 'post_tag',
1914                  'terms' => $q['tag_slug__and'],
1915                  'field' => 'slug',
1916                  'operator' => 'AND'
1917              );
1918          }
1919  
1920          $this->tax_query = new WP_Tax_Query( $tax_query );
1921  
1922          do_action( 'parse_tax_query', $this );
1923      }
1924  
1925      /**
1926       * Generate SQL for the WHERE clause based on passed search terms.
1927       *
1928       * @since 3.7.0
1929       *
1930       * @global wpdb $wpdb
1931       * @param array $q Query variables.
1932       * @return string WHERE clause.
1933       */
1934  	protected function parse_search( &$q ) {
1935          global $wpdb;
1936  
1937          $search = '';
1938  
1939          // added slashes screw with quote grouping when done early, so done later
1940          $q['s'] = stripslashes( $q['s'] );
1941          if ( empty( $_GET['s'] ) && $this->is_main_query() )
1942              $q['s'] = urldecode( $q['s'] );
1943          // there are no line breaks in <input /> fields
1944          $q['s'] = str_replace( array( "\r", "\n" ), '', $q['s'] );
1945          $q['search_terms_count'] = 1;
1946          if ( ! empty( $q['sentence'] ) ) {
1947              $q['search_terms'] = array( $q['s'] );
1948          } else {
1949              if ( preg_match_all( '/".*?("|$)|((?<=[\t ",+])|^)[^\t ",+]+/', $q['s'], $matches ) ) {
1950                  $q['search_terms_count'] = count( $matches[0] );
1951                  $q['search_terms'] = $this->parse_search_terms( $matches[0] );
1952                  // if the search string has only short terms or stopwords, or is 10+ terms long, match it as sentence
1953                  if ( empty( $q['search_terms'] ) || count( $q['search_terms'] ) > 9 )
1954                      $q['search_terms'] = array( $q['s'] );
1955              } else {
1956                  $q['search_terms'] = array( $q['s'] );
1957              }
1958          }
1959  
1960          $n = ! empty( $q['exact'] ) ? '' : '%';
1961          $searchand = '';
1962          $q['search_orderby_title'] = array();
1963          foreach ( $q['search_terms'] as $term ) {
1964              $term = like_escape( esc_sql( $term ) );
1965              if ( $n )
1966                  $q['search_orderby_title'][] = "$wpdb->posts.post_title LIKE '%$term%'";
1967  
1968              $search .= "{$searchand}(($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}'))";
1969              $searchand = ' AND ';
1970          }
1971  
1972          if ( ! empty( $search ) ) {
1973              $search = " AND ({$search}) ";
1974              if ( ! is_user_logged_in() )
1975                  $search .= " AND ($wpdb->posts.post_password = '') ";
1976          }
1977  
1978          return $search;
1979      }
1980  
1981      /**
1982       * Check if the terms are suitable for searching.
1983       *
1984       * Uses an array of stopwords (terms) that are excluded from the separate
1985       * term matching when searching for posts. The list of English stopwords is
1986       * the approximate search engines list, and is translatable.
1987       *
1988       * @since 3.7.0
1989       *
1990       * @param array Terms to check.
1991       * @return array Terms that are not stopwords.
1992       */
1993  	protected function parse_search_terms( $terms ) {
1994          $strtolower = function_exists( 'mb_strtolower' ) ? 'mb_strtolower' : 'strtolower';
1995          $checked = array();
1996  
1997          $stopwords = $this->get_search_stopwords();
1998  
1999          foreach ( $terms as $term ) {
2000              // keep before/after spaces when term is for exact match
2001              if ( preg_match( '/^".+"$/', $term ) )
2002                  $term = trim( $term, "\"'" );
2003              else
2004                  $term = trim( $term, "\"' " );
2005  
2006              // Avoid single A-Z.
2007              if ( ! $term || ( 1 === strlen( $term ) && preg_match( '/^[a-z]$/i', $term ) ) )
2008                  continue;
2009  
2010              if ( in_array( call_user_func( $strtolower, $term ), $stopwords, true ) )
2011                  continue;
2012  
2013              $checked[] = $term;
2014          }
2015  
2016          return $checked;
2017      }
2018  
2019      /**
2020       * Retrieve stopwords used when parsing search terms.
2021       *
2022       * @since 3.7.0
2023       *
2024       * @return array Stopwords.
2025       */
2026  	protected function get_search_stopwords() {
2027          if ( isset( $this->stopwords ) )
2028              return $this->stopwords;
2029  
2030          /* translators: This is a comma-separated list of very common words that should be excluded from a search,
2031           * like a, an, and the. These are usually called "stopwords". You should not simply translate these individual
2032           * words into your language. Instead, look for and provide commonly accepted stopwords in your language.
2033           */
2034          $words = explode( ',', _x( 'about,an,are,as,at,be,by,com,for,from,how,in,is,it,of,on,or,that,the,this,to,was,what,when,where,who,will,with,www',
2035              'Comma-separated list of search stopwords in your language' ) );
2036  
2037          $stopwords = array();
2038          foreach( $words as $word ) {
2039              $word = trim( $word, "\r\n\t " );
2040              if ( $word )
2041                  $stopwords[] = $word;
2042          }
2043  
2044          /**
2045           * Filter stopwords used when parsing search terms.
2046           *
2047           * @since 3.7.0
2048           *
2049           * @param array $stopwords Stopwords.
2050           */
2051          $this->stopwords = apply_filters( 'wp_search_stopwords', $stopwords );
2052          return $this->stopwords;
2053      }
2054  
2055      /**
2056       * Generate SQL for the ORDER BY condition based on passed search terms.
2057       *
2058       * @global wpdb $wpdb
2059       * @param array $q Query variables.
2060       * @return string ORDER BY clause.
2061       */
2062  	protected function parse_search_order( &$q ) {
2063          global $wpdb;
2064  
2065          $search_orderby = '';
2066  
2067          if ( $q['search_terms_count'] > 1 ) {
2068              $num_terms = count( $q['search_orderby_title'] );
2069              $search_orderby_s = like_escape( esc_sql( $q['s'] ) );
2070  
2071              $search_orderby = '(CASE ';
2072              // sentence match in 'post_title'
2073              $search_orderby .= "WHEN $wpdb->posts.post_title LIKE '%{$search_orderby_s}%' THEN 1 ";
2074  
2075              // sanity limit, sort as sentence when more than 6 terms
2076              // (few searches are longer than 6 terms and most titles are not)
2077              if ( $num_terms < 7 ) {
2078                  // all words in title
2079                  $search_orderby .= 'WHEN ' . implode( ' AND ', $q['search_orderby_title'] ) . ' THEN 2 ';
2080                  // any word in title, not needed when $num_terms == 1
2081                  if ( $num_terms > 1 )
2082                      $search_orderby .= 'WHEN ' . implode( ' OR ', $q['search_orderby_title'] ) . ' THEN 3 ';
2083              }
2084  
2085              // sentence match in 'post_content'
2086              $search_orderby .= "WHEN $wpdb->posts.post_content LIKE '%{$search_orderby_s}%' THEN 4 ";
2087              $search_orderby .= 'ELSE 5 END)';
2088          } else {
2089              // single word or sentence search
2090              $search_orderby = reset( $q['search_orderby_title'] ) . ' DESC';
2091          }
2092  
2093          return $search_orderby;
2094      }
2095  
2096      /**
2097       * Sets the 404 property and saves whether query is feed.
2098       *
2099       * @since 2.0.0
2100       * @access public
2101       */
2102  	function set_404() {
2103          $is_feed = $this->is_feed;
2104  
2105          $this->init_query_flags();
2106          $this->is_404 = true;
2107  
2108          $this->is_feed = $is_feed;
2109      }
2110  
2111      /**
2112       * Retrieve query variable.
2113       *
2114       * @since 1.5.0
2115       * @access public
2116       *
2117       * @param string $query_var Query variable key.
2118       * @return mixed
2119       */
2120  	function get($query_var) {
2121          if ( isset($this->query_vars[$query_var]) )
2122              return $this->query_vars[$query_var];
2123  
2124          return '';
2125      }
2126  
2127      /**
2128       * Set query variable.
2129       *
2130       * @since 1.5.0
2131       * @access public
2132       *
2133       * @param string $query_var Query variable key.
2134       * @param mixed $value Query variable value.
2135       */
2136  	function set($query_var, $value) {
2137          $this->query_vars[$query_var] = $value;
2138      }
2139  
2140      /**
2141       * Retrieve the posts based on query variables.
2142       *
2143       * There are a few filters and actions that can be used to modify the post
2144       * database query.
2145       *
2146       * @since 1.5.0
2147       * @access public
2148       * @uses do_action_ref_array() Calls 'pre_get_posts' hook before retrieving posts.
2149       *
2150       * @return array List of posts.
2151       */
2152  	function get_posts() {
2153          global $wpdb;
2154  
2155          $this->parse_query();
2156  
2157          do_action_ref_array('pre_get_posts', array(&$this));
2158  
2159          // Shorthand.
2160          $q = &$this->query_vars;
2161  
2162          // Fill again in case pre_get_posts unset some vars.
2163          $q = $this->fill_query_vars($q);
2164  
2165          // Parse meta query
2166          $this->meta_query = new WP_Meta_Query();
2167          $this->meta_query->parse_query_vars( $q );
2168  
2169          // Set a flag if a pre_get_posts hook changed the query vars.
2170          $hash = md5( serialize( $this->query_vars ) );
2171          if ( $hash != $this->query_vars_hash ) {
2172              $this->query_vars_changed = true;
2173              $this->query_vars_hash = $hash;
2174          }
2175          unset($hash);
2176  
2177          // First let's clear some variables
2178          $distinct = '';
2179          $whichauthor = '';
2180          $whichmimetype = '';
2181          $where = '';
2182          $limits = '';
2183          $join = '';
2184          $search = '';
2185          $groupby = '';
2186          $fields = '';
2187          $post_status_join = false;
2188          $page = 1;
2189  
2190          if ( isset( $q['caller_get_posts'] ) ) {
2191              _deprecated_argument( 'WP_Query', '3.1', __( '"caller_get_posts" is deprecated. Use "ignore_sticky_posts" instead.' ) );
2192              if ( !isset( $q['ignore_sticky_posts'] ) )
2193                  $q['ignore_sticky_posts'] = $q['caller_get_posts'];
2194          }
2195  
2196          if ( !isset( $q['ignore_sticky_posts'] ) )
2197              $q['ignore_sticky_posts'] = false;
2198  
2199          if ( !isset($q['suppress_filters']) )
2200              $q['suppress_filters'] = false;
2201  
2202          if ( !isset($q['cache_results']) ) {
2203              if ( wp_using_ext_object_cache() )
2204                  $q['cache_results'] = false;
2205              else
2206                  $q['cache_results'] = true;
2207          }
2208  
2209          if ( !isset($q['update_post_term_cache']) )
2210              $q['update_post_term_cache'] = true;
2211  
2212          if ( !isset($q['update_post_meta_cache']) )
2213              $q['update_post_meta_cache'] = true;
2214  
2215          if ( !isset($q['post_type']) ) {
2216              if ( $this->is_search )
2217                  $q['post_type'] = 'any';
2218              else
2219                  $q['post_type'] = '';
2220          }
2221          $post_type = $q['post_type'];
2222          if ( !isset($q['posts_per_page']) || $q['posts_per_page'] == 0 )
2223              $q['posts_per_page'] = get_option('posts_per_page');
2224          if ( isset($q['showposts']) && $q['showposts'] ) {
2225              $q['showposts'] = (int) $q['showposts'];
2226              $q['posts_per_page'] = $q['showposts'];
2227          }
2228          if ( (isset($q['posts_per_archive_page']) && $q['posts_per_archive_page'] != 0) && ($this->is_archive || $this->is_search) )
2229              $q['posts_per_page'] = $q['posts_per_archive_page'];
2230          if ( !isset($q['nopaging']) ) {
2231              if ( $q['posts_per_page'] == -1 ) {
2232                  $q['nopaging'] = true;
2233              } else {
2234                  $q['nopaging'] = false;
2235              }
2236          }
2237          if ( $this->is_feed ) {
2238              $q['posts_per_page'] = get_option('posts_per_rss');
2239              $q['nopaging'] = false;
2240          }
2241          $q['posts_per_page'] = (int) $q['posts_per_page'];
2242          if ( $q['posts_per_page'] < -1 )
2243              $q['posts_per_page'] = abs($q['posts_per_page']);
2244          else if ( $q['posts_per_page'] == 0 )
2245              $q['posts_per_page'] = 1;
2246  
2247          if ( !isset($q['comments_per_page']) || $q['comments_per_page'] == 0 )
2248              $q['comments_per_page'] = get_option('comments_per_page');
2249  
2250          if ( $this->is_home && (empty($this->query) || $q['preview'] == 'true') && ( 'page' == get_option('show_on_front') ) && get_option('page_on_front') ) {
2251              $this->is_page = true;
2252              $this->is_home = false;
2253              $q['page_id'] = get_option('page_on_front');
2254          }
2255  
2256          if ( isset($q['page']) ) {
2257              $q['page'] = trim($q['page'], '/');
2258              $q['page'] = absint($q['page']);
2259          }
2260  
2261          // If true, forcibly turns off SQL_CALC_FOUND_ROWS even when limits are present.
2262          if ( isset($q['no_found_rows']) )
2263              $q['no_found_rows'] = (bool) $q['no_found_rows'];
2264          else
2265              $q['no_found_rows'] = false;
2266  
2267          switch ( $q['fields'] ) {
2268              case 'ids':
2269                  $fields = "$wpdb->posts.ID";
2270                  break;
2271              case 'id=>parent':
2272                  $fields = "$wpdb->posts.ID, $wpdb->posts.post_parent";
2273                  break;
2274              default:
2275                  $fields = "$wpdb->posts.*";
2276          }
2277  
2278          if ( '' !== $q['menu_order'] )
2279              $where .= " AND $wpdb->posts.menu_order = " . $q['menu_order'];
2280  
2281          // The "m" parameter is meant for months but accepts datetimes of varying specificity
2282          if ( $q['m'] ) {
2283              $where .= " AND YEAR($wpdb->posts.post_date)=" . substr($q['m'], 0, 4);
2284              if ( strlen($q['m']) > 5 )
2285                  $where .= " AND MONTH($wpdb->posts.post_date)=" . substr($q['m'], 4, 2);
2286              if ( strlen($q['m']) > 7 )
2287                  $where .= " AND DAYOFMONTH($wpdb->posts.post_date)=" . substr($q['m'], 6, 2);
2288              if ( strlen($q['m']) > 9 )
2289                  $where .= " AND HOUR($wpdb->posts.post_date)=" . substr($q['m'], 8, 2);
2290              if ( strlen($q['m']) > 11 )
2291                  $where .= " AND MINUTE($wpdb->posts.post_date)=" . substr($q['m'], 10, 2);
2292              if ( strlen($q['m']) > 13 )
2293                  $where .= " AND SECOND($wpdb->posts.post_date)=" . substr($q['m'], 12, 2);
2294          }
2295  
2296          // Handle the other individual date parameters
2297          $date_parameters = array();
2298  
2299          if ( '' !== $q['hour'] )
2300              $date_parameters['hour'] = $q['hour'];
2301  
2302          if ( '' !== $q['minute'] )
2303              $date_parameters['minute'] = $q['minute'];
2304  
2305          if ( '' !== $q['second'] )
2306              $date_parameters['second'] = $q['second'];
2307  
2308          if ( $q['year'] )
2309              $date_parameters['year'] = $q['year'];
2310  
2311          if ( $q['monthnum'] )
2312              $date_parameters['monthnum'] = $q['monthnum'];
2313  
2314          if ( $q['w'] )
2315              $date_parameters['week'] = $q['w'];
2316  
2317          if ( $q['day'] )
2318              $date_parameters['day'] = $q['day'];
2319  
2320          if ( $date_parameters ) {
2321              $date_query = new WP_Date_Query( array( $date_parameters ) );
2322              $where .= $date_query->get_sql();
2323          }
2324          unset( $date_parameters, $date_query );
2325  
2326          // Handle complex date queries
2327          if ( ! empty( $q['date_query'] ) ) {
2328              $this->date_query = new WP_Date_Query( $q['date_query'] );
2329              $where .= $this->date_query->get_sql();
2330          }
2331  
2332  
2333          // If we've got a post_type AND it's not "any" post_type.
2334          if ( !empty($q['post_type']) && 'any' != $q['post_type'] ) {
2335              foreach ( (array)$q['post_type'] as $_post_type ) {
2336                  $ptype_obj = get_post_type_object($_post_type);
2337                  if ( !$ptype_obj || !$ptype_obj->query_var || empty($q[ $ptype_obj->query_var ]) )
2338                      continue;
2339  
2340                  if ( ! $ptype_obj->hierarchical || strpos($q[ $ptype_obj->query_var ], '/') === false ) {
2341                      // Non-hierarchical post_types & parent-level-hierarchical post_types can directly use 'name'
2342                      $q['name'] = $q[ $ptype_obj->query_var ];
2343                  } else {
2344                      // Hierarchical post_types will operate through the
2345                      $q['pagename'] = $q[ $ptype_obj->query_var ];
2346                      $q['name'] = '';
2347                  }
2348  
2349                  // Only one request for a slug is possible, this is why name & pagename are overwritten above.
2350                  break;
2351              } //end foreach
2352              unset($ptype_obj);
2353          }
2354  
2355          if ( '' != $q['name'] ) {
2356              $q['name'] = sanitize_title_for_query( $q['name'] );
2357              $where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'";
2358          } elseif ( '' != $q['pagename'] ) {
2359              if ( isset($this->queried_object_id) ) {
2360                  $reqpage = $this->queried_object_id;
2361              } else {
2362                  if ( 'page' != $q['post_type'] ) {
2363                      foreach ( (array)$q['post_type'] as $_post_type ) {
2364                          $ptype_obj = get_post_type_object($_post_type);
2365                          if ( !$ptype_obj || !$ptype_obj->hierarchical )
2366                              continue;
2367  
2368                          $reqpage = get_page_by_path($q['pagename'], OBJECT, $_post_type);
2369                          if ( $reqpage )
2370                              break;
2371                      }
2372                      unset($ptype_obj);
2373                  } else {
2374                      $reqpage = get_page_by_path($q['pagename']);
2375                  }
2376                  if ( !empty($reqpage) )
2377                      $reqpage = $reqpage->ID;
2378                  else
2379                      $reqpage = 0;
2380              }
2381  
2382              $page_for_posts = get_option('page_for_posts');
2383              if  ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) {
2384                  $q['pagename'] = sanitize_title_for_query( wp_basename( $q['pagename'] ) );
2385                  $q['name'] = $q['pagename'];
2386                  $where .= " AND ($wpdb->posts.ID = '$reqpage')";
2387                  $reqpage_obj = get_post( $reqpage );
2388                  if ( is_object($reqpage_obj) && 'attachment' == $reqpage_obj->post_type ) {
2389                      $this->is_attachment = true;
2390                      $post_type = $q['post_type'] = 'attachment';
2391                      $this->is_page = true;
2392                      $q['attachment_id'] = $reqpage;
2393                  }
2394              }
2395          } elseif ( '' != $q['attachment'] ) {
2396              $q['attachment'] = sanitize_title_for_query( wp_basename( $q['attachment'] ) );
2397              $q['name'] = $q['attachment'];
2398              $where .= " AND $wpdb->posts.post_name = '" . $q['attachment'] . "'";
2399          }
2400  
2401  
2402          if ( intval($q['comments_popup']) )
2403              $q['p'] = absint($q['comments_popup']);
2404  
2405          // If an attachment is requested by number, let it supersede any post number.
2406          if ( $q['attachment_id'] )
2407              $q['p'] = absint($q['attachment_id']);
2408  
2409          // If a post number is specified, load that post
2410          if ( $q['p'] ) {
2411              $where .= " AND {$wpdb->posts}.ID = " . $q['p'];
2412          } elseif ( $q['post__in'] ) {
2413              $post__in = implode(',', array_map( 'absint', $q['post__in'] ));
2414              $where .= " AND {$wpdb->posts}.ID IN ($post__in)";
2415          } elseif ( $q['post__not_in'] ) {
2416              $post__not_in = implode(',',  array_map( 'absint', $q['post__not_in'] ));
2417              $where .= " AND {$wpdb->posts}.ID NOT IN ($post__not_in)";
2418          }
2419  
2420          if ( is_numeric( $q['post_parent'] ) ) {
2421              $where .= $wpdb->prepare( " AND $wpdb->posts.post_parent = %d ", $q['post_parent'] );
2422          } elseif ( $q['post_parent__in'] ) {
2423              $post_parent__in = implode( ',', array_map( 'absint', $q['post_parent__in'] ) );
2424              $where .= " AND {$wpdb->posts}.post_parent IN ($post_parent__in)";
2425          } elseif ( $q['post_parent__not_in'] ) {
2426              $post_parent__not_in = implode( ',',  array_map( 'absint', $q['post_parent__not_in'] ) );
2427              $where .= " AND {$wpdb->posts}.post_parent NOT IN ($post_parent__not_in)";
2428          }
2429  
2430          if ( $q['page_id'] ) {
2431              if  ( ('page' != get_option('show_on_front') ) || ( $q['page_id'] != get_option('page_for_posts') ) ) {
2432                  $q['p'] = $q['page_id'];
2433                  $where = " AND {$wpdb->posts}.ID = " . $q['page_id'];
2434              }
2435          }
2436  
2437          // If a search pattern is specified, load the posts that match.
2438          if ( ! empty( $q['s'] ) )
2439              $search = $this->parse_search( $q );
2440  
2441          /**
2442           * Filter the search SQL that is used in the WHERE clause of WP_Query.
2443           *
2444           * @since 3.0.0
2445           *
2446           * @param string   $search Search SQL for WHERE clause.
2447           * @param WP_Query $this   The current WP_Query object.
2448           */
2449          $search = apply_filters_ref_array( 'posts_search', array( $search, &$this ) );
2450  
2451          // Taxonomies
2452          if ( !$this->is_singular ) {
2453              $this->parse_tax_query( $q );
2454  
2455              $clauses = $this->tax_query->get_sql( $wpdb->posts, 'ID' );
2456  
2457              $join .= $clauses['join'];
2458              $where .= $clauses['where'];
2459          }
2460  
2461          if ( $this->is_tax ) {
2462              if ( empty($post_type) ) {
2463                  // Do a fully inclusive search for currently registered post types of queried taxonomies
2464                  $post_type = array();
2465                  $taxonomies = wp_list_pluck( $this->tax_query->queries, 'taxonomy' );
2466                  foreach ( get_post_types( array( 'exclude_from_search' => false ) ) as $pt ) {
2467                      $object_taxonomies = $pt === 'attachment' ? get_taxonomies_for_attachments() : get_object_taxonomies( $pt );
2468                      if ( array_intersect( $taxonomies, $object_taxonomies ) )
2469                          $post_type[] = $pt;
2470                  }
2471                  if ( ! $post_type )
2472                      $post_type = 'any';
2473                  elseif ( count( $post_type ) == 1 )
2474                      $post_type = $post_type[0];
2475  
2476                  $post_status_join = true;
2477              } elseif ( in_array('attachment', (array) $post_type) ) {
2478                  $post_status_join = true;
2479              }
2480          }
2481  
2482          // Back-compat
2483          if ( !empty($this->tax_query->queries) ) {
2484              $tax_query_in_and = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'NOT IN' ), 'NOT' );
2485              if ( !empty( $tax_query_in_and ) ) {
2486                  if ( !isset( $q['taxonomy'] ) ) {
2487                      foreach ( $tax_query_in_and as $a_tax_query ) {
2488                          if ( !in_array( $a_tax_query['taxonomy'], array( 'category', 'post_tag' ) ) ) {
2489                              $q['taxonomy'] = $a_tax_query['taxonomy'];
2490                              if ( 'slug' == $a_tax_query['field'] )
2491                                  $q['term'] = $a_tax_query['terms'][0];
2492                              else
2493                                  $q['term_id'] = $a_tax_query['terms'][0];
2494  
2495                              break;
2496                          }
2497                      }
2498                  }
2499  
2500                  $cat_query = wp_list_filter( $tax_query_in_and, array( 'taxonomy' => 'category' ) );
2501                  if ( ! empty( $cat_query ) ) {
2502                      $cat_query = reset( $cat_query );
2503  
2504                      if ( ! empty( $cat_query['terms'][0] ) ) {
2505                          $the_cat = get_term_by( $cat_query['field'], $cat_query['terms'][0], 'category' );
2506                          if ( $the_cat ) {
2507                              $this->set( 'cat', $the_cat->term_id );
2508                              $this->set( 'category_name', $the_cat->slug );
2509                          }
2510                          unset( $the_cat );
2511                      }
2512                  }
2513                  unset( $cat_query );
2514  
2515                  $tag_query = wp_list_filter( $tax_query_in_and, array( 'taxonomy' => 'post_tag' ) );
2516                  if ( ! empty( $tag_query ) ) {
2517                      $tag_query = reset( $tag_query );
2518  
2519                      if ( ! empty( $tag_query['terms'][0] ) ) {
2520                          $the_tag = get_term_by( $tag_query['field'], $tag_query['terms'][0], 'post_tag' );
2521                          if ( $the_tag )
2522                              $this->set( 'tag_id', $the_tag->term_id );
2523                          unset( $the_tag );
2524                      }
2525                  }
2526                  unset( $tag_query );
2527              }
2528          }
2529  
2530          if ( !empty( $this->tax_query->queries ) || !empty( $this->meta_query->queries ) ) {
2531              $groupby = "{$wpdb->posts}.ID";
2532          }
2533  
2534          // Author/user stuff
2535  
2536          if ( ! empty( $q['author'] ) && $q['author'] != '0' ) {
2537              $q['author'] = addslashes_gpc( '' . urldecode( $q['author'] ) );
2538              $authors = array_unique( array_map( 'intval', preg_split( '/[,\s]+/', $q['author'] ) ) );
2539              foreach ( $authors as $author ) {
2540                  $key = $author > 0 ? 'author__in' : 'author__not_in';
2541                  $q[$key][] = abs( $author );
2542              }
2543              $q['author'] = implode( ',', $authors );
2544          }
2545  
2546          if ( ! empty( $q['author__not_in'] ) ) {
2547              $author__not_in = implode( ',', array_map( 'absint', array_unique( (array) $q['author__not_in'] ) ) );
2548              $where .= " AND {$wpdb->posts}.post_author NOT IN ($author__not_in) ";
2549          } elseif ( ! empty( $q['author__in'] ) ) {
2550              $author__in = implode( ',', array_map( 'absint', array_unique( (array) $q['author__in'] ) ) );
2551              $where .= " AND {$wpdb->posts}.post_author IN ($author__in) ";
2552          }
2553  
2554          // Author stuff for nice URLs
2555  
2556          if ( '' != $q['author_name'] ) {
2557              if ( strpos($q['author_name'], '/') !== false ) {
2558                  $q['author_name'] = explode('/', $q['author_name']);
2559                  if ( $q['author_name'][ count($q['author_name'])-1 ] ) {
2560                      $q['author_name'] = $q['author_name'][count($q['author_name'])-1]; // no trailing slash
2561                  } else {
2562                      $q['author_name'] = $q['author_name'][count($q['author_name'])-2]; // there was a trailing slash
2563                  }
2564              }
2565              $q['author_name'] = sanitize_title_for_query( $q['author_name'] );
2566              $q['author'] = get_user_by('slug', $q['author_name']);
2567              if ( $q['author'] )
2568                  $q['author'] = $q['author']->ID;
2569              $whichauthor .= " AND ($wpdb->posts.post_author = " . absint($q['author']) . ')';
2570          }
2571  
2572          // MIME-Type stuff for attachment browsing
2573  
2574          if ( isset( $q['post_mime_type'] ) && '' != $q['post_mime_type'] )
2575              $whichmimetype = wp_post_mime_type_where( $q['post_mime_type'], $wpdb->posts );
2576  
2577          $where .= $search . $whichauthor . $whichmimetype;
2578  
2579          if ( empty($q['order']) || ((strtoupper($q['order']) != 'ASC') && (strtoupper($q['order']) != 'DESC')) )
2580              $q['order'] = 'DESC';
2581  
2582          // Order by
2583          if ( empty($q['orderby']) ) {
2584              $orderby = "$wpdb->posts.post_date " . $q['order'];
2585          } elseif ( 'none' == $q['orderby'] ) {
2586              $orderby = '';
2587          } elseif ( $q['orderby'] == 'post__in' && ! empty( $post__in ) ) {
2588              $orderby = "FIELD( {$wpdb->posts}.ID, $post__in )";
2589          } elseif ( $q['orderby'] == 'post_parent__in' && ! empty( $post_parent__in ) ) {
2590              $orderby = "FIELD( {$wpdb->posts}.post_parent, $post_parent__in )";
2591          } else {
2592              // Used to filter values
2593              $allowed_keys = array('name', 'author', 'date', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand', 'comment_count');
2594              if ( !empty($q['meta_key']) ) {
2595                  $allowed_keys[] = $q['meta_key'];
2596                  $allowed_keys[] = 'meta_value';
2597                  $allowed_keys[] = 'meta_value_num';
2598              }
2599              $q['orderby'] = urldecode($q['orderby']);
2600              $q['orderby'] = addslashes_gpc($q['orderby']);
2601  
2602              $orderby_array = array();
2603              foreach ( explode( ' ', $q['orderby'] ) as $i => $orderby ) {
2604                  // Only allow certain values for safety
2605                  if ( ! in_array($orderby, $allowed_keys) )
2606                      continue;
2607  
2608                  switch ( $orderby ) {
2609                      case 'menu_order':
2610                          $orderby = "$wpdb->posts.menu_order";
2611                          break;
2612                      case 'ID':
2613                          $orderby = "$wpdb->posts.ID";
2614                          break;
2615                      case 'rand':
2616                          $orderby = 'RAND()';
2617                          break;
2618                      case $q['meta_key']:
2619                      case 'meta_value':
2620                          if ( isset( $q['meta_type'] ) ) {
2621                              $meta_type = $this->meta_query->get_cast_for_type( $q['meta_type'] );
2622                              $orderby = "CAST($wpdb->postmeta.meta_value AS {$meta_type})";
2623                          } else {
2624                              $orderby = "$wpdb->postmeta.meta_value";
2625                          }
2626                          break;
2627                      case 'meta_value_num':
2628                          $orderby = "$wpdb->postmeta.meta_value+0";
2629                          break;
2630                      case 'comment_count':
2631                          $orderby = "$wpdb->posts.comment_count";
2632                          break;
2633                      default:
2634                          $orderby = "$wpdb->posts.post_" . $orderby;
2635                  }
2636  
2637                  $orderby_array[] = $orderby;
2638              }
2639              $orderby = implode( ',', $orderby_array );
2640  
2641              if ( empty( $orderby ) )
2642                  $orderby = "$wpdb->posts.post_date ".$q['order'];
2643              else
2644                  $orderby .= " {$q['order']}";
2645          }
2646  
2647          // Order search results by relevance only when another "orderby" is not specified in the query.
2648          if ( ! empty( $q['s'] ) ) {
2649              $search_orderby = '';
2650              if ( ! empty( $q['search_orderby_title'] ) && ( empty( $q['orderby'] ) && ! $this->is_feed ) || ( isset( $q['orderby'] ) && 'relevance' === $q['orderby'] ) )
2651                  $search_orderby = $this->parse_search_order( $q );
2652  
2653              /**
2654               * Filter the ORDER BY used when ordering search results.
2655               *
2656               * @since 3.7.0
2657               *
2658               * @param string   $search_orderby The ORDER BY clause.
2659               * @param WP_Query $this           The current WP_Query instance.
2660               */
2661              $search_orderby = apply_filters( 'posts_search_orderby', $search_orderby, $this );
2662              if ( $search_orderby )
2663                  $orderby = $orderby ? $search_orderby . ', ' . $orderby : $search_orderby;
2664          }
2665  
2666          if ( is_array( $post_type ) && count( $post_type ) > 1 ) {
2667              $post_type_cap = 'multiple_post_type';
2668          } else {
2669              if ( is_array( $post_type ) )
2670                  $post_type = reset( $post_type );
2671              $post_type_object = get_post_type_object( $post_type );
2672              if ( empty( $post_type_object ) )
2673                  $post_type_cap = $post_type;
2674          }
2675  
2676          if ( 'any' == $post_type ) {
2677              $in_search_post_types = get_post_types( array('exclude_from_search' => false) );
2678              if ( empty( $in_search_post_types ) )
2679                  $where .= ' AND 1=0 ';
2680              else
2681                  $where .= " AND $wpdb->posts.post_type IN ('" . join("', '", $in_search_post_types ) . "')";
2682          } elseif ( !empty( $post_type ) && is_array( $post_type ) ) {
2683              $where .= " AND $wpdb->posts.post_type IN ('" . join("', '", $post_type) . "')";
2684          } elseif ( ! empty( $post_type ) ) {
2685              $where .= " AND $wpdb->posts.post_type = '$post_type'";
2686              $post_type_object = get_post_type_object ( $post_type );
2687          } elseif ( $this->is_attachment ) {
2688              $where .= " AND $wpdb->posts.post_type = 'attachment'";
2689              $post_type_object = get_post_type_object ( 'attachment' );
2690          } elseif ( $this->is_page ) {
2691              $where .= " AND $wpdb->posts.post_type = 'page'";
2692              $post_type_object = get_post_type_object ( 'page' );
2693          } else {
2694              $where .= " AND $wpdb->posts.post_type = 'post'";
2695              $post_type_object = get_post_type_object ( 'post' );
2696          }
2697  
2698          $edit_cap = 'edit_post';
2699          $read_cap = 'read_post';
2700  
2701          if ( ! empty( $post_type_object ) ) {
2702              $edit_others_cap = $post_type_object->cap->edit_others_posts;
2703              $read_private_cap = $post_type_object->cap->read_private_posts;
2704          } else {
2705              $edit_others_cap = 'edit_others_' . $post_type_cap . 's';
2706              $read_private_cap = 'read_private_' . $post_type_cap . 's';
2707          }
2708  
2709          $user_id = get_current_user_id();
2710  
2711          if ( ! empty( $q['post_status'] ) ) {
2712              $statuswheres = array();
2713              $q_status = $q['post_status'];
2714              if ( ! is_array( $q_status ) )
2715                  $q_status = explode(',', $q_status);
2716              $r_status = array();
2717              $p_status = array();
2718              $e_status = array();
2719              if ( in_array('any', $q_status) ) {
2720                  foreach ( get_post_stati( array('exclude_from_search' => true) ) as $status )
2721                      $e_status[] = "$wpdb->posts.post_status <> '$status'";
2722              } else {
2723                  foreach ( get_post_stati() as $status ) {
2724                      if ( in_array( $status, $q_status ) ) {
2725                          if ( 'private' == $status )
2726                              $p_status[] = "$wpdb->posts.post_status = '$status'";
2727                          else
2728                              $r_status[] = "$wpdb->posts.post_status = '$status'";
2729                      }
2730                  }
2731              }
2732  
2733              if ( empty($q['perm'] ) || 'readable' != $q['perm'] ) {
2734                  $r_status = array_merge($r_status, $p_status);
2735                  unset($p_status);
2736              }
2737  
2738              if ( !empty($e_status) ) {
2739                  $statuswheres[] = "(" . join( ' AND ', $e_status ) . ")";
2740              }
2741              if ( !empty($r_status) ) {
2742                  if ( !empty($q['perm'] ) && 'editable' == $q['perm'] && !current_user_can($edit_others_cap) )
2743                      $statuswheres[] = "($wpdb->posts.post_author = $user_id " . "AND (" . join( ' OR ', $r_status ) . "))";
2744                  else
2745                      $statuswheres[] = "(" . join( ' OR ', $r_status ) . ")";
2746              }
2747              if ( !empty($p_status) ) {
2748                  if ( !empty($q['perm'] ) && 'readable' == $q['perm'] && !current_user_can($read_private_cap) )
2749                      $statuswheres[] = "($wpdb->posts.post_author = $user_id " . "AND (" . join( ' OR ', $p_status ) . "))";
2750                  else
2751                      $statuswheres[] = "(" . join( ' OR ', $p_status ) . ")";
2752              }
2753              if ( $post_status_join ) {
2754                  $join .= " LEFT JOIN $wpdb->posts AS p2 ON ($wpdb->posts.post_parent = p2.ID) ";
2755                  foreach ( $statuswheres as $index => $statuswhere )
2756                      $statuswheres[$index] = "($statuswhere OR ($wpdb->posts.post_status = 'inherit' AND " . str_replace($wpdb->posts, 'p2', $statuswhere) . "))";
2757              }
2758              foreach ( $statuswheres as $statuswhere )
2759                  $where .= " AND $statuswhere";
2760          } elseif ( !$this->is_singular ) {
2761              $where .= " AND ($wpdb->posts.post_status = 'publish'";
2762  
2763              // Add public states.
2764              $public_states = get_post_stati( array('public' => true) );
2765              foreach ( (array) $public_states as $state ) {
2766                  if ( 'publish' == $state ) // Publish is hard-coded above.
2767                      continue;
2768                  $where .= " OR $wpdb->posts.post_status = '$state'";
2769              }
2770  
2771              if ( $this->is_admin ) {
2772                  // Add protected states that should show in the admin all list.
2773                  $admin_all_states = get_post_stati( array('protected' => true, 'show_in_admin_all_list' => true) );
2774                  foreach ( (array) $admin_all_states as $state )
2775                      $where .= " OR $wpdb->posts.post_status = '$state'";
2776              }
2777  
2778              if ( is_user_logged_in() ) {
2779                  // Add private states that are limited to viewing by the author of a post or someone who has caps to read private states.
2780                  $private_states = get_post_stati( array('private' => true) );
2781                  foreach ( (array) $private_states as $state )
2782                      $where .= current_user_can( $read_private_cap ) ? " OR $wpdb->posts.post_status = '$state'" : " OR $wpdb->posts.post_author = $user_id AND $wpdb->posts.post_status = '$state'";
2783              }
2784  
2785              $where .= ')';
2786          }
2787  
2788          if ( !empty( $this->meta_query->queries ) ) {
2789              $clauses = $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this );
2790              $join .= $clauses['join'];
2791              $where .= $clauses['where'];
2792          }
2793  
2794          // Apply filters on where and join prior to paging so that any
2795          // manipulations to them are reflected in the paging by day queries.
2796          if ( !$q['suppress_filters'] ) {
2797              $where = apply_filters_ref_array('posts_where', array( $where, &$this ) );
2798              $join = apply_filters_ref_array('posts_join', array( $join, &$this ) );
2799          }
2800  
2801          // Paging
2802          if ( empty($q['nopaging']) && !$this->is_singular ) {
2803              $page = absint($q['paged']);
2804              if ( !$page )
2805                  $page = 1;
2806  
2807              if ( empty($q['offset']) ) {
2808                  $pgstrt = ($page - 1) * $q['posts_per_page'] . ', ';
2809              } else { // we're ignoring $page and using 'offset'
2810                  $q['offset'] = absint($q['offset']);
2811                  $pgstrt = $q['offset'] . ', ';
2812              }
2813              $limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
2814          }
2815  
2816          // Comments feeds
2817          if ( $this->is_comment_feed && ( $this->is_archive || $this->is_search || !$this->is_singular ) ) {
2818              if ( $this->is_archive || $this->is_search ) {
2819                  $cjoin = "JOIN $wpdb->posts ON ($wpdb->comments.comment_post_ID = $wpdb->posts.ID) $join ";
2820                  $cwhere = "WHERE comment_approved = '1' $where";
2821                  $cgroupby = "$wpdb->comments.comment_id";
2822              } else { // Other non singular e.g. front
2823                  $cjoin = "JOIN $wpdb->posts ON ( $wpdb->comments.comment_post_ID = $wpdb->posts.ID )";
2824                  $cwhere = "WHERE post_status = 'publish' AND comment_approved = '1'";
2825                  $cgroupby = '';
2826              }
2827  
2828              if ( !$q['suppress_filters'] ) {
2829                  $cjoin = apply_filters_ref_array('comment_feed_join', array( $cjoin, &$this ) );
2830                  $cwhere = apply_filters_ref_array('comment_feed_where', array( $cwhere, &$this ) );
2831                  $cgroupby = apply_filters_ref_array('comment_feed_groupby', array( $cgroupby, &$this ) );
2832                  $corderby = apply_filters_ref_array('comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
2833                  $climits = apply_filters_ref_array('comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) );
2834              }
2835              $cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
2836              $corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
2837  
2838              $this->comments = (array) $wpdb->get_results("SELECT $distinct $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere $cgroupby $corderby $climits");
2839              $this->comment_count = count($this->comments);
2840  
2841              $post_ids = array();
2842  
2843              foreach ( $this->comments as $comment )
2844                  $post_ids[] = (int) $comment->comment_post_ID;
2845  
2846              $post_ids = join(',', $post_ids);
2847              $join = '';
2848              if ( $post_ids )
2849                  $where = "AND $wpdb->posts.ID IN ($post_ids) ";
2850              else
2851                  $where = "AND 0";
2852          }
2853  
2854          $pieces = array( 'where', 'groupby', 'join', 'orderby', 'distinct', 'fields', 'limits' );
2855  
2856          // Apply post-paging filters on where and join. Only plugins that
2857          // manipulate paging queries should use these hooks.
2858          if ( !$q['suppress_filters'] ) {
2859              $where        = apply_filters_ref_array( 'posts_where_paged',    array( $where, &$this ) );
2860              $groupby    = apply_filters_ref_array( 'posts_groupby',        array( $groupby, &$this ) );
2861              $join        = apply_filters_ref_array( 'posts_join_paged',    array( $join, &$this ) );
2862              $orderby    = apply_filters_ref_array( 'posts_orderby',        array( $orderby, &$this ) );
2863              $distinct    = apply_filters_ref_array( 'posts_distinct',    array( $distinct, &$this ) );
2864              $limits        = apply_filters_ref_array( 'post_limits',        array( $limits, &$this ) );
2865              $fields        = apply_filters_ref_array( 'posts_fields',        array( $fields, &$this ) );
2866  
2867              // Filter all clauses at once, for convenience
2868              $clauses = (array) apply_filters_ref_array( 'posts_clauses', array( compact( $pieces ), &$this ) );
2869              foreach ( $pieces as $piece )
2870                  $$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : '';
2871          }
2872  
2873          // Announce current selection parameters. For use by caching plugins.
2874          do_action( 'posts_selection', $where . $groupby . $orderby . $limits . $join );
2875  
2876          // Filter again for the benefit of caching plugins. Regular plugins should use the hooks above.
2877          if ( !$q['suppress_filters'] ) {
2878              $where        = apply_filters_ref_array( 'posts_where_request',        array( $where, &$this ) );
2879              $groupby    = apply_filters_ref_array( 'posts_groupby_request',        array( $groupby, &$this ) );
2880              $join        = apply_filters_ref_array( 'posts_join_request',        array( $join, &$this ) );
2881              $orderby    = apply_filters_ref_array( 'posts_orderby_request',        array( $orderby, &$this ) );
2882              $distinct    = apply_filters_ref_array( 'posts_distinct_request',    array( $distinct, &$this ) );
2883              $fields        = apply_filters_ref_array( 'posts_fields_request',        array( $fields, &$this ) );
2884              $limits        = apply_filters_ref_array( 'post_limits_request',        array( $limits, &$this ) );
2885  
2886              // Filter all clauses at once, for convenience
2887              $clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) );
2888              foreach ( $pieces as $piece )
2889                  $$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : '';
2890          }
2891  
2892          if ( ! empty($groupby) )
2893              $groupby = 'GROUP BY ' . $groupby;
2894          if ( !empty( $orderby ) )
2895              $orderby = 'ORDER BY ' . $orderby;
2896  
2897          $found_rows = '';
2898          if ( !$q['no_found_rows'] && !empty($limits) )
2899              $found_rows = 'SQL_CALC_FOUND_ROWS';
2900  
2901          $this->request = $old_request = "SELECT $found_rows $distinct $fields FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits";
2902  
2903          if ( !$q['suppress_filters'] ) {
2904              $this->request = apply_filters_ref_array( 'posts_request', array( $this->request, &$this ) );
2905          }
2906  
2907          if ( 'ids' == $q['fields'] ) {
2908              $this->posts = $wpdb->get_col( $this->request );
2909              $this->post_count = count( $this->posts );
2910              $this->set_found_posts( $q, $limits );
2911  
2912              return $this->posts;
2913          }
2914  
2915          if ( 'id=>parent' == $q['fields'] ) {
2916              $this->posts = $wpdb->get_results( $this->request );
2917              $this->post_count = count( $this->posts );
2918              $this->set_found_posts( $q, $limits );
2919  
2920              $r = array();
2921              foreach ( $this->posts as $post )
2922                  $r[ $post->ID ] = $post->post_parent;
2923  
2924              return $r;
2925          }
2926  
2927          $split_the_query = ( $old_request == $this->request && "$wpdb->posts.*" == $fields && !empty( $limits ) && $q['posts_per_page'] < 500 );
2928          $split_the_query = apply_filters( 'split_the_query', $split_the_query, $this );
2929  
2930          if ( $split_the_query ) {
2931              // First get the IDs and then fill in the objects
2932  
2933              $this->request = "SELECT $found_rows $distinct $wpdb->posts.ID FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits";
2934  
2935              $this->request = apply_filters( 'posts_request_ids', $this->request, $this );
2936  
2937              $ids = $wpdb->get_col( $this->request );
2938  
2939              if ( $ids ) {
2940                  $this->posts = $ids;
2941                  $this->set_found_posts( $q, $limits );
2942                  _prime_post_caches( $ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
2943              } else {
2944                  $this->posts = array();
2945              }
2946          } else {
2947              $this->posts = $wpdb->get_results( $this->request );
2948              $this->set_found_posts( $q, $limits );
2949          }
2950  
2951          // Convert to WP_Post objects
2952          if ( $this->posts )
2953              $this->posts = array_map( 'get_post', $this->posts );
2954  
2955          // Raw results filter. Prior to status checks.
2956          if ( !$q['suppress_filters'] )
2957              $this->posts = apply_filters_ref_array('posts_results', array( $this->posts, &$this ) );
2958  
2959          if ( !empty($this->posts) && $this->is_comment_feed && $this->is_singular ) {
2960              $cjoin = apply_filters_ref_array('comment_feed_join', array( '', &$this ) );
2961              $cwhere = apply_filters_ref_array('comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'", &$this ) );
2962              $cgroupby = apply_filters_ref_array('comment_feed_groupby', array( '', &$this ) );
2963              $cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
2964              $corderby = apply_filters_ref_array('comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
2965              $corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
2966              $climits = apply_filters_ref_array('comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) );
2967              $comments_request = "SELECT $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere $cgroupby $corderby $climits";
2968              $this->comments = $wpdb->get_results($comments_request);
2969              $this->comment_count = count($this->comments);
2970          }
2971  
2972          // Check post status to determine if post should be displayed.
2973          if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) {
2974              $status = get_post_status($this->posts[0]);
2975              $post_status_obj = get_post_status_object($status);
2976              //$type = get_post_type($this->posts[0]);
2977              if ( !$post_status_obj->public ) {
2978                  if ( ! is_user_logged_in() ) {
2979                      // User must be logged in to view unpublished posts.
2980                      $this->posts = array();
2981                  } else {
2982                      if  ( $post_status_obj->protected ) {
2983                          // User must have edit permissions on the draft to preview.
2984                          if ( ! current_user_can($edit_cap, $this->posts[0]->ID) ) {
2985                              $this->posts = array();
2986                          } else {
2987                              $this->is_preview = true;
2988                              if ( 'future' != $status )
2989                                  $this->posts[0]->post_date = current_time('mysql');
2990                          }
2991                      } elseif ( $post_status_obj->private ) {
2992                          if ( ! current_user_can($read_cap, $this->posts[0]->ID) )
2993                              $this->posts = array();
2994                      } else {
2995                          $this->posts = array();
2996                      }
2997                  }
2998              }
2999  
3000              if ( $this->is_preview && $this->posts && current_user_can( $edit_cap, $this->posts[0]->ID ) )
3001                  $this->posts[0] = get_post( apply_filters_ref_array( 'the_preview', array( $this->posts[0], &$this ) ) );
3002          }
3003  
3004          // Put sticky posts at the top of the posts array
3005          $sticky_posts = get_option('sticky_posts');
3006          if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) {
3007              $num_posts = count($this->posts);
3008              $sticky_offset = 0;
3009              // Loop over posts and relocate stickies to the front.
3010              for ( $i = 0; $i < $num_posts; $i++ ) {
3011                  if ( in_array($this->posts[$i]->ID, $sticky_posts) ) {
3012                      $sticky_post = $this->posts[$i];
3013                      // Remove sticky from current position
3014                      array_splice($this->posts, $i, 1);
3015                      // Move to front, after other stickies
3016                      array_splice($this->posts, $sticky_offset, 0, array($sticky_post));
3017                      // Increment the sticky offset. The next sticky will be placed at this offset.
3018                      $sticky_offset++;
3019                      // Remove post from sticky posts array
3020                      $offset = array_search($sticky_post->ID, $sticky_posts);
3021                      unset( $sticky_posts[$offset] );
3022                  }
3023              }
3024  
3025              // If any posts have been excluded specifically, Ignore those that are sticky.
3026              if ( !empty($sticky_posts) && !empty($q['post__not_in']) )
3027                  $sticky_posts = array_diff($sticky_posts, $q['post__not_in']);
3028  
3029              // Fetch sticky posts that weren't in the query results
3030              if ( !empty($sticky_posts) ) {
3031                  $stickies = get_posts( array(
3032                      'post__in' => $sticky_posts,
3033                      'post_type' => $post_type,
3034                      'post_status' => 'publish',
3035                      'nopaging' => true
3036                  ) );
3037  
3038                  foreach ( $stickies as $sticky_post ) {
3039                      array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) );
3040                      $sticky_offset++;
3041                  }
3042              }
3043          }
3044  
3045          if ( !$q['suppress_filters'] )
3046              $this->posts = apply_filters_ref_array('the_posts', array( $this->posts, &$this ) );
3047  
3048          // Ensure that any posts added/modified via one of the filters above are
3049          // of the type WP_Post and are filtered.
3050          if ( $this->posts ) {
3051              $this->post_count = count( $this->posts );
3052  
3053              $this->posts = array_map( 'get_post', $this->posts );
3054  
3055              if ( $q['cache_results'] )
3056                  update_post_caches($this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache']);
3057  
3058              $this->post = reset( $this->posts );
3059          } else {
3060              $this->post_count = 0;
3061              $this->posts = array();
3062          }
3063  
3064          return $this->posts;
3065      }
3066  
3067      /**
3068       * Set up the amount of found posts and the number of pages (if limit clause was used)
3069       * for the current query.
3070       *
3071       * @since 3.5.0
3072       * @access private
3073       */
3074  	function set_found_posts( $q, $limits ) {
3075          global $wpdb;
3076  
3077          // Bail if posts is an empty array. Continue if posts is an empty string,
3078          // null, or false to accommodate caching plugins that fill posts later.
3079          if ( $q['no_found_rows'] || ( is_array( $this->posts ) && ! $this->posts ) )
3080              return;
3081  
3082          if ( ! empty( $limits ) )
3083              $this->found_posts = $wpdb->get_var( apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ) );
3084          else
3085              $this->found_posts = count( $this->posts );
3086  
3087          $this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
3088  
3089          if ( ! empty( $limits ) )
3090              $this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] );
3091      }
3092  
3093      /**
3094       * Set up the next post and iterate current post index.
3095       *
3096       * @since 1.5.0
3097       * @access public
3098       *
3099       * @return WP_Post Next post.
3100       */
3101  	function next_post() {
3102  
3103          $this->current_post++;
3104  
3105          $this->post = $this->posts[$this->current_post];
3106          return $this->post;
3107      }
3108  
3109      /**
3110       * Sets up the current post.
3111       *
3112       * Retrieves the next post, sets up the post, sets the 'in the loop'
3113       * property to true.
3114       *
3115       * @since 1.5.0
3116       * @access public
3117       * @uses $post
3118       * @uses do_action_ref_array() Calls 'loop_start' if loop has just started
3119       */
3120  	function the_post() {
3121          global $post;
3122          $this->in_the_loop = true;
3123  
3124          if ( $this->current_post == -1 ) // loop has just started
3125              do_action_ref_array('loop_start', array(&$this));
3126  
3127          $post = $this->next_post();
3128          setup_postdata($post);
3129      }
3130  
3131      /**
3132       * Whether there are more posts available in the loop.
3133       *
3134       * Calls action 'loop_end', when the loop is complete.
3135       *
3136       * @since 1.5.0
3137       * @access public
3138       * @uses do_action_ref_array() Calls 'loop_end' if loop is ended
3139       *
3140       * @return bool True if posts are available, false if end of loop.
3141       */
3142  	function have_posts() {
3143          if ( $this->current_post + 1 < $this->post_count ) {
3144              return true;
3145          } elseif ( $this->current_post + 1 == $this->post_count && $this->post_count > 0 ) {
3146              do_action_ref_array('loop_end', array(&$this));
3147              // Do some cleaning up after the loop
3148              $this->rewind_posts();
3149          }
3150  
3151          $this->in_the_loop = false;
3152          return false;
3153      }
3154  
3155      /**
3156       * Rewind the posts and reset post index.
3157       *
3158       * @since 1.5.0
3159       * @access public
3160       */
3161  	function rewind_posts() {
3162          $this->current_post = -1;
3163          if ( $this->post_count > 0 ) {
3164              $this->post = $this->posts[0];
3165          }
3166      }
3167  
3168      /**
3169       * Iterate current comment index and return comment object.
3170       *
3171       * @since 2.2.0
3172       * @access public
3173       *
3174       * @return object Comment object.
3175       */
3176  	function next_comment() {
3177          $this->current_comment++;
3178  
3179          $this->comment = $this->comments[$this->current_comment];
3180          return $this->comment;
3181      }
3182  
3183      /**
3184       * Sets up the current comment.
3185       *
3186       * @since 2.2.0
3187       * @access public
3188       * @global object $comment Current comment.
3189       * @uses do_action() Calls 'comment_loop_start' hook when first comment is processed.
3190       */
3191  	function the_comment() {
3192          global $comment;
3193  
3194          $comment = $this->next_comment();
3195  
3196          if ( $this->current_comment == 0 ) {
3197              do_action('comment_loop_start');
3198          }
3199      }
3200  
3201      /**
3202       * Whether there are more comments available.
3203       *
3204       * Automatically rewinds comments when finished.
3205       *
3206       * @since 2.2.0
3207       * @access public
3208       *
3209       * @return bool True, if more comments. False, if no more posts.
3210       */
3211  	function have_comments() {
3212          if ( $this->current_comment + 1 < $this->comment_count ) {
3213              return true;
3214          } elseif ( $this->current_comment + 1 == $this->comment_count ) {
3215              $this->rewind_comments();
3216          }
3217  
3218          return false;
3219      }
3220  
3221      /**
3222       * Rewind the comments, resets the comment index and comment to first.
3223       *
3224       * @since 2.2.0
3225       * @access public
3226       */
3227  	function rewind_comments() {
3228          $this->current_comment = -1;
3229          if ( $this->comment_count > 0 ) {
3230              $this->comment = $this->comments[0];
3231          }
3232      }
3233  
3234      /**
3235       * Sets up the WordPress query by parsing query string.
3236       *
3237       * @since 1.5.0
3238       * @access public
3239       *
3240       * @param string $query URL query string.
3241       * @return array List of posts.
3242       */
3243  	function query( $query ) {
3244          $this->init();
3245          $this->query = $this->query_vars = wp_parse_args( $query );
3246          return $this->get_posts();
3247      }
3248  
3249      /**
3250       * Retrieve queried object.
3251       *
3252       * If queried object is not set, then the queried object will be set from
3253       * the category, tag, taxonomy, posts page, single post, page, or author
3254       * query variable. After it is set up, it will be returned.
3255       *
3256       * @since 1.5.0
3257       * @access public
3258       *
3259       * @return object
3260       */
3261  	function get_queried_object() {
3262          if ( isset($this->queried_object) )
3263              return $this->queried_object;
3264  
3265          $this->queried_object = null;
3266          $this->queried_object_id = 0;
3267  
3268          if ( $this->is_category || $this->is_tag || $this->is_tax ) {
3269              if ( $this->is_category ) {
3270                  if ( $this->get( 'cat' ) ) {
3271                      $term = get_term( $this->get( 'cat' ), 'category' );
3272                  } elseif ( $this->get( 'category_name' ) ) {
3273                      $term = get_term_by( 'slug', $this->get( 'category_name' ), 'category' );
3274                  }
3275              } elseif ( $this->is_tag ) {
3276                  $term = get_term( $this->get( 'tag_id' ), 'post_tag' );
3277              } else {
3278                  $tax_query_in_and = wp_list_filter( $this->tax_query->queries, array( 'operator' => 'NOT IN' ), 'NOT' );
3279                  $query = reset( $tax_query_in_and );
3280  
3281                  if ( $query['terms'] ) {
3282                      if ( 'term_id' == $query['field'] ) {
3283                          $term = get_term( reset( $query['terms'] ), $query['taxonomy'] );
3284                      } else {
3285                          $term = get_term_by( $query['field'], reset( $query['terms'] ), $query['taxonomy'] );
3286                      }
3287                  }
3288              }
3289  
3290              if ( ! empty( $term ) && ! is_wp_error( $term ) )  {
3291                  $this->queried_object = $term;
3292                  $this->queried_object_id = (int) $term->term_id;
3293  
3294                  if ( $this->is_category && 'category' === $this->queried_object->taxonomy )
3295                      _make_cat_compat( $this->queried_object );
3296              }
3297          } elseif ( $this->is_post_type_archive ) {
3298              $post_type = $this->get( 'post_type' );
3299              if ( is_array( $post_type ) )
3300                  $post_type = reset( $post_type );
3301              $this->queried_object = get_post_type_object( $post_type );
3302          } elseif ( $this->is_posts_page ) {
3303              $page_for_posts = get_option('page_for_posts');
3304              $this->queried_object = get_post( $page_for_posts );
3305              $this->queried_object_id = (int) $this->queried_object->ID;
3306          } elseif ( $this->is_singular && !is_null($this->post) ) {
3307              $this->queried_object = $this->post;
3308              $this->queried_object_id = (int) $this->post->ID;
3309          } elseif ( $this->is_author ) {
3310              $this->queried_object_id = (int) $this->get('author');
3311              $this->queried_object = get_userdata( $this->queried_object_id );
3312          }
3313  
3314          return $this->queried_object;
3315      }
3316  
3317      /**
3318       * Retrieve ID of the current queried object.
3319       *
3320       * @since 1.5.0
3321       * @access public
3322       *
3323       * @return int
3324       */
3325  	function get_queried_object_id() {
3326          $this->get_queried_object();
3327  
3328          if ( isset($this->queried_object_id) ) {
3329              return $this->queried_object_id;
3330          }
3331  
3332          return 0;
3333      }
3334  
3335      /**
3336       * Constructor.
3337       *
3338       * Sets up the WordPress query, if parameter is not empty.
3339       *
3340       * @since 1.5.0
3341       * @access public
3342       *
3343       * @param string $query URL query string.
3344       * @return WP_Query
3345       */
3346  	function __construct($query = '') {
3347          if ( ! empty($query) ) {
3348              $this->query($query);
3349          }
3350      }
3351  
3352      /**
3353        * Is the query for an existing archive page?
3354        *
3355        * Month, Year, Category, Author, Post Type archive...
3356       *
3357        * @since 3.1.0
3358        *
3359        * @return bool
3360        */
3361  	function is_archive() {
3362          return (bool) $this->is_archive;
3363      }
3364  
3365      /**
3366       * Is the query for an existing post type archive page?
3367       *
3368       * @since 3.1.0
3369       *
3370       * @param mixed $post_types Optional. Post type or array of posts types to check against.
3371       * @return bool
3372       */
3373  	function is_post_type_archive( $post_types = '' ) {
3374          if ( empty( $post_types ) || ! $this->is_post_type_archive )
3375              return (bool) $this->is_post_type_archive;
3376  
3377          $post_type = $this->get( 'post_type' );
3378          if ( is_array( $post_type ) )
3379              $post_type = reset( $post_type );
3380          $post_type_object = get_post_type_object( $post_type );
3381  
3382          return in_array( $post_type_object->name, (array) $post_types );
3383      }
3384  
3385      /**
3386       * Is the query for an existing attachment page?
3387       *
3388       * @since 3.1.0
3389       *
3390       * @return bool
3391       */
3392  	function is_attachment() {
3393          return (bool) $this->is_attachment;
3394      }
3395  
3396      /**
3397       * Is the query for an existing author archive page?
3398       *
3399       * If the $author parameter is specified, this function will additionally
3400       * check if the query is for one of the authors specified.
3401       *
3402       * @since 3.1.0
3403       *
3404       * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames
3405       * @return bool
3406       */
3407  	function is_author( $author = '' ) {
3408          if ( !$this->is_author )
3409              return false;
3410  
3411          if ( empty($author) )
3412              return true;
3413  
3414          $author_obj = $this->get_queried_object();
3415  
3416          $author = (array) $author;
3417  
3418          if ( in_array( $author_obj->ID, $author ) )
3419              return true;
3420          elseif ( in_array( $author_obj->nickname, $author ) )
3421              return true;
3422          elseif ( in_array( $author_obj->user_nicename, $author ) )
3423              return true;
3424  
3425          return false;
3426      }
3427  
3428      /**
3429       * Is the query for an existing category archive page?
3430       *
3431       * If the $category parameter is specified, this function will additionally
3432       * check if the query is for one of the categories specified.
3433       *
3434       * @since 3.1.0
3435       *
3436       * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs.
3437       * @return bool
3438       */
3439  	function is_category( $category = '' ) {
3440          if ( !$this->is_category )
3441              return false;
3442  
3443          if ( empty($category) )
3444              return true;
3445  
3446          $cat_obj = $this->get_queried_object();
3447  
3448          $category = (array) $category;
3449  
3450          if ( in_array( $cat_obj->term_id, $category ) )
3451              return true;
3452          elseif ( in_array( $cat_obj->name, $category ) )
3453              return true;
3454          elseif ( in_array( $cat_obj->slug, $category ) )
3455              return true;
3456  
3457          return false;
3458      }
3459  
3460      /**
3461       * Is the query for an existing tag archive page?
3462       *
3463       * If the $tag parameter is specified, this function will additionally
3464       * check if the query is for one of the tags specified.
3465       *
3466       * @since 3.1.0
3467       *
3468       * @param mixed $tag Optional. Tag ID, name, slug, or array of Tag IDs, names, and slugs.
3469       * @return bool
3470       */
3471  	function is_tag( $tag = '' ) {
3472          if ( ! $this->is_tag )
3473              return false;
3474  
3475          if ( empty( $tag ) )
3476              return true;
3477  
3478          $tag_obj = $this->get_queried_object();
3479  
3480          $tag = (array) $tag;
3481  
3482          if ( in_array( $tag_obj->term_id, $tag ) )
3483              return true;
3484          elseif ( in_array( $tag_obj->name, $tag ) )
3485              return true;
3486          elseif ( in_array( $tag_obj->slug, $tag ) )
3487              return true;
3488  
3489          return false;
3490      }
3491  
3492      /**
3493       * Is the query for an existing taxonomy archive page?
3494       *
3495       * If the $taxonomy parameter is specified, this function will additionally
3496       * check if the query is for that specific $taxonomy.
3497       *
3498       * If the $term parameter is specified in addition to the $taxonomy parameter,
3499       * this function will additionally check if the query is for one of the terms
3500       * specified.
3501       *
3502       * @since 3.1.0
3503       *
3504       * @param mixed $taxonomy Optional. Taxonomy slug or slugs.
3505       * @param mixed $term. Optional. Term ID, name, slug or array of Term IDs, names, and slugs.
3506       * @return bool
3507       */
3508  	function is_tax( $taxonomy = '', $term = '' ) {
3509          global $wp_taxonomies;
3510  
3511          if ( !$this->is_tax )
3512              return false;
3513  
3514          if ( empty( $taxonomy ) )
3515              return true;
3516  
3517          $queried_object = $this->get_queried_object();
3518          $tax_array = array_intersect( array_keys( $wp_taxonomies ), (array) $taxonomy );
3519          $term_array = (array) $term;
3520  
3521          // Check that the taxonomy matches.
3522          if ( ! ( isset( $queried_object->taxonomy ) && count( $tax_array ) && in_array( $queried_object->taxonomy, $tax_array ) ) )
3523              return false;
3524  
3525          // Only a Taxonomy provided.
3526          if ( empty( $term ) )
3527              return true;
3528  
3529          return isset( $queried_object->term_id ) &&
3530              count( array_intersect(
3531                  array( $queried_object->term_id, $queried_object->name, $queried_object->slug ),
3532                  $term_array
3533              ) );
3534      }
3535  
3536      /**
3537       * Whether the current URL is within the comments popup window.
3538       *
3539       * @since 3.1.0
3540       *
3541       * @return bool
3542       */
3543  	function is_comments_popup() {
3544          return (bool) $this->is_comments_popup;
3545      }
3546  
3547      /**
3548       * Is the query for an existing date archive?
3549       *
3550       * @since 3.1.0
3551       *
3552       * @return bool
3553       */
3554  	function is_date() {
3555          return (bool) $this->is_date;
3556      }
3557  
3558      /**
3559       * Is the query for an existing day archive?
3560       *
3561       * @since 3.1.0
3562       *
3563       * @return bool
3564       */
3565  	function is_day() {
3566          return (bool) $this->is_day;
3567      }
3568  
3569      /**
3570       * Is the query for a feed?
3571       *
3572       * @since 3.1.0
3573       *
3574       * @param string|array $feeds Optional feed types to check.
3575       * @return bool
3576       */
3577  	function is_feed( $feeds = '' ) {
3578          if ( empty( $feeds ) || ! $this->is_feed )
3579              return (bool) $this->is_feed;
3580          $qv = $this->get( 'feed' );
3581          if ( 'feed' == $qv )
3582              $qv = get_default_feed();
3583          return in_array( $qv, (array) $feeds );
3584      }
3585  
3586      /**
3587       * Is the query for a comments feed?
3588       *
3589       * @since 3.1.0
3590       *
3591       * @return bool
3592       */
3593  	function is_comment_feed() {
3594          return (bool) $this->is_comment_feed;
3595      }
3596  
3597      /**
3598       * Is the query for the front page of the site?
3599       *
3600       * This is for what is displayed at your site's main URL.
3601       *
3602       * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_on_front'.
3603       *
3604       * If you set a static page for the front page of your site, this function will return
3605       * true when viewing that page.
3606       *
3607       * Otherwise the same as @see WP_Query::is_home()
3608       *
3609       * @since 3.1.0
3610       * @uses is_home()
3611       * @uses get_option()
3612       *
3613       * @return bool True, if front of site.
3614       */
3615  	function is_front_page() {
3616          // most likely case
3617          if ( 'posts' == get_option( 'show_on_front') && $this->is_home() )
3618              return true;
3619          elseif ( 'page' == get_option( 'show_on_front') && get_option( 'page_on_front' ) && $this->is_page( get_option( 'page_on_front' ) ) )
3620              return true;
3621          else
3622              return false;
3623      }
3624  
3625      /**
3626       * Is the query for the blog homepage?
3627       *
3628       * This is the page which shows the time based blog content of your site.
3629       *
3630       * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_for_posts'.
3631       *
3632       * If you set a static page for the front page of your site, this function will return
3633       * true only on the page you set as the "Posts page".
3634       *
3635       * @see WP_Query::is_front_page()
3636       *
3637       * @since 3.1.0
3638       *
3639       * @return bool True if blog view homepage.
3640       */
3641  	function is_home() {
3642          return (bool) $this->is_home;
3643      }
3644  
3645      /**
3646       * Is the query for an existing month archive?
3647       *
3648       * @since 3.1.0
3649       *
3650       * @return bool
3651       */
3652  	function is_month() {
3653          return (bool) $this->is_month;
3654      }
3655  
3656      /**
3657       * Is the query for an existing single page?
3658       *
3659       * If the $page parameter is specified, this function will additionally
3660       * check if the query is for one of the pages specified.
3661       *
3662       * @see WP_Query::is_single()
3663       * @see WP_Query::is_singular()
3664       *
3665       * @since 3.1.0
3666       *
3667       * @param mixed $page Page ID, title, slug, or array of such.
3668       * @return bool
3669       */
3670  	function is_page( $page = '' ) {
3671          if ( !$this->is_page )
3672              return false;
3673  
3674          if ( empty( $page ) )
3675              return true;
3676  
3677          $page_obj = $this->get_queried_object();
3678  
3679          $page = (array) $page;
3680  
3681          if ( in_array( $page_obj->ID, $page ) )
3682              return true;
3683          elseif ( in_array( $page_obj->post_title, $page ) )
3684              return true;
3685          else if ( in_array( $page_obj->post_name, $page ) )
3686              return true;
3687  
3688          return false;
3689      }
3690  
3691      /**
3692       * Is the query for paged result and not for the first page?
3693       *
3694       * @since 3.1.0
3695       *
3696       * @return bool
3697       */
3698  	function is_paged() {
3699          return (bool) $this->is_paged;
3700      }
3701  
3702      /**
3703       * Is the query for a post or page preview?
3704       *
3705       * @since 3.1.0
3706       *
3707       * @return bool
3708       */
3709  	function is_preview() {
3710          return (bool) $this->is_preview;
3711      }
3712  
3713      /**
3714       * Is the query for the robots file?
3715       *
3716       * @since 3.1.0
3717       *
3718       * @return bool
3719       */
3720  	function is_robots() {
3721          return (bool) $this->is_robots;
3722      }
3723  
3724      /**
3725       * Is the query for a search?
3726       *
3727       * @since 3.1.0
3728       *
3729       * @return bool
3730       */
3731  	function is_search() {
3732          return (bool) $this->is_search;
3733      }
3734  
3735      /**
3736       * Is the query for an existing single post?
3737       *
3738       * Works for any post type, except attachments and pages
3739       *
3740       * If the $post parameter is specified, this function will additionally
3741       * check if the query is for one of the Posts specified.
3742       *
3743       * @see WP_Query::is_page()
3744       * @see WP_Query::is_singular()
3745       *
3746       * @since 3.1.0
3747       *
3748       * @param mixed $post Post ID, title, slug, or array of such.
3749       * @return bool
3750       */
3751  	function is_single( $post = '' ) {
3752          if ( !$this->is_single )
3753              return false;
3754  
3755          if ( empty($post) )
3756              return true;
3757  
3758          $post_obj = $this->get_queried_object();
3759  
3760          $post = (array) $post;
3761  
3762          if ( in_array( $post_obj->ID, $post ) )
3763              return true;
3764          elseif ( in_array( $post_obj->post_title, $post ) )
3765              return true;
3766          elseif ( in_array( $post_obj->post_name, $post ) )
3767              return true;
3768  
3769          return false;
3770      }
3771  
3772      /**
3773       * Is the query for an existing single post of any post type (post, attachment, page, ... )?
3774       *
3775       * If the $post_types parameter is specified, this function will additionally
3776       * check if the query is for one of the Posts Types specified.
3777       *
3778       * @see WP_Query::is_page()
3779       * @see WP_Query::is_single()
3780       *
3781       * @since 3.1.0
3782       *
3783       * @param mixed $post_types Optional. Post Type or array of Post Types
3784       * @return bool
3785       */
3786  	function is_singular( $post_types = '' ) {
3787          if ( empty( $post_types ) || !$this->is_singular )
3788              return (bool) $this->is_singular;
3789  
3790          $post_obj = $this->get_queried_object();
3791  
3792          return in_array( $post_obj->post_type, (array) $post_types );
3793      }
3794  
3795      /**
3796       * Is the query for a specific time?
3797       *
3798       * @since 3.1.0
3799       *
3800       * @return bool
3801       */
3802  	function is_time() {
3803          return (bool) $this->is_time;
3804      }
3805  
3806      /**
3807       * Is the query for a trackback endpoint call?
3808       *
3809       * @since 3.1.0
3810       *
3811       * @return bool
3812       */
3813  	function is_trackback() {
3814          return (bool) $this->is_trackback;
3815      }
3816  
3817      /**
3818       * Is the query for an existing year archive?
3819       *
3820       * @since 3.1.0
3821       *
3822       * @return bool
3823       */
3824  	function is_year() {
3825          return (bool) $this->is_year;
3826      }
3827  
3828      /**
3829       * Is the query a 404 (returns no results)?
3830       *
3831       * @since 3.1.0
3832       *
3833       * @return bool
3834       */
3835  	function is_404() {
3836          return (bool) $this->is_404;
3837      }
3838  
3839      /**
3840       * Is the query the main query?
3841       *
3842       * @since 3.3.0
3843       *
3844       * @return bool
3845       */
3846  	function is_main_query() {
3847          global $wp_the_query;
3848          return $wp_the_query === $this;
3849      }
3850  
3851      /**
3852       * After looping through a nested query, this function
3853       * restores the $post global to the current post in this query.
3854       *
3855       * @since 3.7.0
3856       *
3857       * @return bool
3858       */
3859  	function reset_postdata() {
3860          if ( ! empty( $this->post ) ) {
3861              $GLOBALS['post'] = $this->post;
3862              setup_postdata( $this->post );
3863          }
3864      }
3865  }
3866  
3867  /**
3868   * Redirect old slugs to the correct permalink.
3869   *
3870   * Attempts to find the current slug from the past slugs.
3871   *
3872   * @since 2.1.0
3873   * @uses $wp_query
3874   * @uses $wpdb
3875   *
3876   * @return null If no link is found, null is returned.
3877   */
3878  function wp_old_slug_redirect() {
3879      global $wp_query;
3880      if ( is_404() && '' != $wp_query->query_vars['name'] ) :
3881          global $wpdb;
3882  
3883          // Guess the current post_type based on the query vars.
3884          if ( get_query_var('post_type') )
3885              $post_type = get_query_var('post_type');
3886          elseif ( !empty($wp_query->query_vars['pagename']) )
3887              $post_type = 'page';
3888          else
3889              $post_type = 'post';
3890  
3891          if ( is_array( $post_type ) ) {
3892              if ( count( $post_type ) > 1 )
3893                  return;
3894              $post_type = array_shift( $post_type );
3895          }
3896  
3897          // Do not attempt redirect for hierarchical post types
3898          if ( is_post_type_hierarchical( $post_type ) )
3899              return;
3900  
3901          $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']);
3902  
3903          // if year, monthnum, or day have been specified, make our query more precise
3904          // just in case there are multiple identical _wp_old_slug values
3905          if ( '' != $wp_query->query_vars['year'] )
3906              $query .= $wpdb->prepare(" AND YEAR(post_date) = %d", $wp_query->query_vars['year']);
3907          if ( '' != $wp_query->query_vars['monthnum'] )
3908              $query .= $wpdb->prepare(" AND MONTH(post_date) = %d", $wp_query->query_vars['monthnum']);
3909          if ( '' != $wp_query->query_vars['day'] )
3910              $query .= $wpdb->prepare(" AND DAYOFMONTH(post_date) = %d", $wp_query->query_vars['day']);
3911  
3912          $id = (int) $wpdb->get_var($query);
3913  
3914          if ( ! $id )
3915              return;
3916  
3917          $link = get_permalink($id);
3918  
3919          if ( !$link )
3920              return;
3921  
3922          wp_redirect( $link, 301 ); // Permanent redirect
3923          exit;
3924      endif;
3925  }
3926  
3927  /**
3928   * Set up global post data.
3929   *
3930   * @since 1.5.0
3931   *
3932   * @param object $post Post data.
3933   * @uses do_action_ref_array() Calls 'the_post'
3934   * @return bool True when finished.
3935   */
3936  function setup_postdata( $post ) {
3937      global $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages;
3938  
3939      $id = (int) $post->ID;
3940  
3941      $authordata = get_userdata($post->post_author);
3942  
3943      $currentday = mysql2date('d.m.y', $post->post_date, false);
3944      $currentmonth = mysql2date('m', $post->post_date, false);
3945      $numpages = 1;
3946      $multipage = 0;
3947      $page = get_query_var('page');
3948      if ( ! $page )
3949          $page = 1;
3950      if ( is_single() || is_page() || is_feed() )
3951          $more = 1;
3952      $content = $post->post_content;
3953      if ( false !== strpos( $content, '<!--nextpage-->' ) ) {
3954          if ( $page > 1 )
3955              $more = 1;
3956          $content = str_replace( "\n<!--nextpage-->\n", '<!--nextpage-->', $content );
3957          $content = str_replace( "\n<!--nextpage-->", '<!--nextpage-->', $content );
3958          $content = str_replace( "<!--nextpage-->\n", '<!--nextpage-->', $content );
3959          // Ignore nextpage at the beginning of the content.
3960          if ( 0 === strpos( $content, '<!--nextpage-->' ) )
3961              $content = substr( $content, 15 );
3962          $pages = explode('<!--nextpage-->', $content);
3963          $numpages = count($pages);
3964          if ( $numpages > 1 )
3965              $multipage = 1;
3966      } else {
3967          $pages = array( $post->post_content );
3968      }
3969  
3970      do_action_ref_array('the_post', array(&$post));
3971  
3972      return true;
3973  }


Generated: Tue Mar 25 01:41:18 2014 WordPress honlapkészítés: online1.hu