Advertisement
SergeyBiryukov

Sergey Biryukov

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