web/wp-includes/query.php
changeset 204 09a1c134465b
parent 194 32102edaa81b
equal deleted inserted replaced
203:f507feede89a 204:09a1c134465b
    84  * @uses $wp_query
    84  * @uses $wp_query
    85  *
    85  *
    86  * @param string $query
    86  * @param string $query
    87  * @return array List of posts
    87  * @return array List of posts
    88  */
    88  */
    89 function &query_posts($query) {
    89 function query_posts($query) {
    90 	unset($GLOBALS['wp_query']);
       
    91 	$GLOBALS['wp_query'] = new WP_Query();
    90 	$GLOBALS['wp_query'] = new WP_Query();
    92 	return $GLOBALS['wp_query']->query($query);
    91 	return $GLOBALS['wp_query']->query($query);
    93 }
    92 }
    94 
    93 
    95 /**
    94 /**
   101  *
   100  *
   102  * @since 2.3.0
   101  * @since 2.3.0
   103  * @uses $wp_query
   102  * @uses $wp_query
   104  */
   103  */
   105 function wp_reset_query() {
   104 function wp_reset_query() {
   106 	unset($GLOBALS['wp_query']);
       
   107 	$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
   105 	$GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
   108 	wp_reset_postdata();
   106 	wp_reset_postdata();
   109 }
   107 }
   110 
   108 
   111 /**
   109 /**
   126 /*
   124 /*
   127  * Query type checks.
   125  * Query type checks.
   128  */
   126  */
   129 
   127 
   130 /**
   128 /**
   131  * Is the query for an archive page?
   129  * Is the query for an existing archive page?
   132  *
   130  *
   133  * Month, Year, Category, Author, Post Type archive...
   131  * Month, Year, Category, Author, Post Type archive...
   134  *
   132  *
   135  * @see WP_Query::is_archive()
   133  * @see WP_Query::is_archive()
   136  * @since 1.5.0
   134  * @since 1.5.0
   148 
   146 
   149 	return $wp_query->is_archive();
   147 	return $wp_query->is_archive();
   150 }
   148 }
   151 
   149 
   152 /**
   150 /**
   153  * Is the query for a post type archive page?
   151  * Is the query for an existing post type archive page?
   154  *
   152  *
   155  * @see WP_Query::is_post_type_archive()
   153  * @see WP_Query::is_post_type_archive()
   156  * @since 3.1.0
   154  * @since 3.1.0
   157  * @uses $wp_query
   155  * @uses $wp_query
   158  *
   156  *
   169 
   167 
   170 	return $wp_query->is_post_type_archive( $post_types );
   168 	return $wp_query->is_post_type_archive( $post_types );
   171 }
   169 }
   172 
   170 
   173 /**
   171 /**
   174  * Is the query for an attachment page?
   172  * Is the query for an existing attachment page?
   175  *
   173  *
   176  * @see WP_Query::is_attachment()
   174  * @see WP_Query::is_attachment()
   177  * @since 2.0.0
   175  * @since 2.0.0
   178  * @uses $wp_query
   176  * @uses $wp_query
   179  *
   177  *
   189 
   187 
   190 	return $wp_query->is_attachment();
   188 	return $wp_query->is_attachment();
   191 }
   189 }
   192 
   190 
   193 /**
   191 /**
   194  * Is the query for an author archive page?
   192  * Is the query for an existing author archive page?
   195  *
   193  *
   196  * If the $author parameter is specified, this function will additionally
   194  * If the $author parameter is specified, this function will additionally
   197  * check if the query is for one of the authors specified.
   195  * check if the query is for one of the authors specified.
   198  *
   196  *
   199  * @see WP_Query::is_author()
   197  * @see WP_Query::is_author()
   213 
   211 
   214 	return $wp_query->is_author( $author );
   212 	return $wp_query->is_author( $author );
   215 }
   213 }
   216 
   214 
   217 /**
   215 /**
   218  * Is the query for a category archive page?
   216  * Is the query for an existing category archive page?
   219  *
   217  *
   220  * If the $category parameter is specified, this function will additionally
   218  * If the $category parameter is specified, this function will additionally
   221  * check if the query is for one of the categories specified.
   219  * check if the query is for one of the categories specified.
   222  *
   220  *
   223  * @see WP_Query::is_category()
   221  * @see WP_Query::is_category()
   237 
   235 
   238 	return $wp_query->is_category( $category );
   236 	return $wp_query->is_category( $category );
   239 }
   237 }
   240 
   238 
   241 /**
   239 /**
   242  * Is the query for a tag archive page?
   240  * Is the query for an existing tag archive page?
   243  *
   241  *
   244  * If the $tag parameter is specified, this function will additionally
   242  * If the $tag parameter is specified, this function will additionally
   245  * check if the query is for one of the tags specified.
   243  * check if the query is for one of the tags specified.
   246  *
   244  *
   247  * @see WP_Query::is_tag()
   245  * @see WP_Query::is_tag()
   261 
   259 
   262 	return $wp_query->is_tag( $slug );
   260 	return $wp_query->is_tag( $slug );
   263 }
   261 }
   264 
   262 
   265 /**
   263 /**
   266  * Is the query for a taxonomy archive page?
   264  * Is the query for an existing taxonomy archive page?
   267  *
   265  *
   268  * If the $taxonomy parameter is specified, this function will additionally
   266  * If the $taxonomy parameter is specified, this function will additionally
   269  * check if the query is for that specific $taxonomy.
   267  * check if the query is for that specific $taxonomy.
   270  *
   268  *
   271  * If the $term parameter is specified in addition to the $taxonomy parameter,
   269  * If the $term parameter is specified in addition to the $taxonomy parameter,
   310 
   308 
   311 	return $wp_query->is_comments_popup();
   309 	return $wp_query->is_comments_popup();
   312 }
   310 }
   313 
   311 
   314 /**
   312 /**
   315  * Is the query for a date archive?
   313  * Is the query for an existing date archive?
   316  *
   314  *
   317  * @see WP_Query::is_date()
   315  * @see WP_Query::is_date()
   318  * @since 1.5.0
   316  * @since 1.5.0
   319  * @uses $wp_query
   317  * @uses $wp_query
   320  *
   318  *
   330 
   328 
   331 	return $wp_query->is_date();
   329 	return $wp_query->is_date();
   332 }
   330 }
   333 
   331 
   334 /**
   332 /**
   335  * Is the query for a day archive?
   333  * Is the query for an existing day archive?
   336  *
   334  *
   337  * @see WP_Query::is_day()
   335  * @see WP_Query::is_day()
   338  * @since 1.5.0
   336  * @since 1.5.0
   339  * @uses $wp_query
   337  * @uses $wp_query
   340  *
   338  *
   450 
   448 
   451 	return $wp_query->is_home();
   449 	return $wp_query->is_home();
   452 }
   450 }
   453 
   451 
   454 /**
   452 /**
   455  * Is the query for a month archive?
   453  * Is the query for an existing month archive?
   456  *
   454  *
   457  * @see WP_Query::is_month()
   455  * @see WP_Query::is_month()
   458  * @since 1.5.0
   456  * @since 1.5.0
   459  * @uses $wp_query
   457  * @uses $wp_query
   460  *
   458  *
   470 
   468 
   471 	return $wp_query->is_month();
   469 	return $wp_query->is_month();
   472 }
   470 }
   473 
   471 
   474 /**
   472 /**
   475  * Is the query for a single page?
   473  * Is the query for an existing single page?
   476  *
   474  *
   477  * If the $page parameter is specified, this function will additionally
   475  * If the $page parameter is specified, this function will additionally
   478  * check if the query is for one of the pages specified.
   476  * check if the query is for one of the pages specified.
   479  *
   477  *
   480  * @see is_single()
   478  * @see is_single()
   577 
   575 
   578 	return $wp_query->is_search();
   576 	return $wp_query->is_search();
   579 }
   577 }
   580 
   578 
   581 /**
   579 /**
   582  * Is the query for a single post?
   580  * Is the query for an existing single post?
   583  *
   581  *
   584  * Works for any post type, except attachments and pages
   582  * Works for any post type, except attachments and pages
   585  *
   583  *
   586  * If the $post parameter is specified, this function will additionally
   584  * If the $post parameter is specified, this function will additionally
   587  * check if the query is for one of the Posts specified.
   585  * check if the query is for one of the Posts specified.
   606 
   604 
   607 	return $wp_query->is_single( $post );
   605 	return $wp_query->is_single( $post );
   608 }
   606 }
   609 
   607 
   610 /**
   608 /**
   611  * Is the query for a single post of any post type (post, attachment, page, ... )?
   609  * Is the query for an existing single post of any post type (post, attachment, page, ... )?
   612  *
   610  *
   613  * If the $post_types parameter is specified, this function will additionally
   611  * If the $post_types parameter is specified, this function will additionally
   614  * check if the query is for one of the Posts Types specified.
   612  * check if the query is for one of the Posts Types specified.
   615  *
   613  *
   616  * @see is_page()
   614  * @see is_page()
   673 
   671 
   674 	return $wp_query->is_trackback();
   672 	return $wp_query->is_trackback();
   675 }
   673 }
   676 
   674 
   677 /**
   675 /**
   678  * Is the query for a specific year?
   676  * Is the query for an existing year archive?
   679  *
   677  *
   680  * @see WP_Query::is_year()
   678  * @see WP_Query::is_year()
   681  * @since 1.5.0
   679  * @since 1.5.0
   682  * @uses $wp_query
   680  * @uses $wp_query
   683  *
   681  *
   977 	 * @var int
   975 	 * @var int
   978 	 */
   976 	 */
   979 	var $comment;
   977 	var $comment;
   980 
   978 
   981 	/**
   979 	/**
   982 	 * Amount of posts if limit clause was not used.
   980 	 * The amount of found posts for the current query.
       
   981 	 *
       
   982 	 * If limit clause was not used, equals $post_count.
   983 	 *
   983 	 *
   984 	 * @since 2.1.0
   984 	 * @since 2.1.0
   985 	 * @access public
   985 	 * @access public
   986 	 * @var int
   986 	 * @var int
   987 	 */
   987 	 */
  1396 			, 'meta_value'
  1396 			, 'meta_value'
  1397 			, 'preview'
  1397 			, 'preview'
  1398 			, 's'
  1398 			, 's'
  1399 			, 'sentence'
  1399 			, 'sentence'
  1400 			, 'fields'
  1400 			, 'fields'
       
  1401 			, 'menu_order'
  1401 		);
  1402 		);
  1402 
  1403 
  1403 		foreach ( $keys as $key ) {
  1404 		foreach ( $keys as $key ) {
  1404 			if ( !isset($array[$key]) )
  1405 			if ( !isset($array[$key]) )
  1405 				$array[$key] = '';
  1406 				$array[$key] = '';
  1450 		$qv['pagename'] = trim( $qv['pagename'] );
  1451 		$qv['pagename'] = trim( $qv['pagename'] );
  1451 		$qv['name'] = trim( $qv['name'] );
  1452 		$qv['name'] = trim( $qv['name'] );
  1452 		if ( '' !== $qv['hour'] ) $qv['hour'] = absint($qv['hour']);
  1453 		if ( '' !== $qv['hour'] ) $qv['hour'] = absint($qv['hour']);
  1453 		if ( '' !== $qv['minute'] ) $qv['minute'] = absint($qv['minute']);
  1454 		if ( '' !== $qv['minute'] ) $qv['minute'] = absint($qv['minute']);
  1454 		if ( '' !== $qv['second'] ) $qv['second'] = absint($qv['second']);
  1455 		if ( '' !== $qv['second'] ) $qv['second'] = absint($qv['second']);
       
  1456 		if ( '' !== $qv['menu_order'] ) $qv['menu_order'] = absint($qv['menu_order']);
  1455 
  1457 
  1456 		// Compat. Map subpost to attachment.
  1458 		// Compat. Map subpost to attachment.
  1457 		if ( '' != $qv['subpost'] )
  1459 		if ( '' != $qv['subpost'] )
  1458 			$qv['attachment'] = $qv['subpost'];
  1460 			$qv['attachment'] = $qv['subpost'];
  1459 		if ( '' != $qv['subpost_id'] )
  1461 		if ( '' != $qv['subpost_id'] )
  1783 		}
  1785 		}
  1784 
  1786 
  1785 		// Tag stuff
  1787 		// Tag stuff
  1786 		if ( '' != $q['tag'] && !$this->is_singular && $this->query_vars_changed ) {
  1788 		if ( '' != $q['tag'] && !$this->is_singular && $this->query_vars_changed ) {
  1787 			if ( strpos($q['tag'], ',') !== false ) {
  1789 			if ( strpos($q['tag'], ',') !== false ) {
  1788 				$tags = preg_split('/[,\s]+/', $q['tag']);
  1790 				$tags = preg_split('/[,\r\n\t ]+/', $q['tag']);
  1789 				foreach ( (array) $tags as $tag ) {
  1791 				foreach ( (array) $tags as $tag ) {
  1790 					$tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
  1792 					$tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
  1791 					$q['tag_slug__in'][] = $tag;
  1793 					$q['tag_slug__in'][] = $tag;
  1792 				}
  1794 				}
  1793 			} else if ( preg_match('/[+\s]+/', $q['tag']) || !empty($q['cat']) ) {
  1795 			} else if ( preg_match('/[+\r\n\t ]+/', $q['tag']) || !empty($q['cat']) ) {
  1794 				$tags = preg_split('/[+\s]+/', $q['tag']);
  1796 				$tags = preg_split('/[+\r\n\t ]+/', $q['tag']);
  1795 				foreach ( (array) $tags as $tag ) {
  1797 				foreach ( (array) $tags as $tag ) {
  1796 					$tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
  1798 					$tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
  1797 					$q['tag_slug__and'][] = $tag;
  1799 					$q['tag_slug__and'][] = $tag;
  1798 				}
  1800 				}
  1799 			} else {
  1801 			} else {
  1912 	 * @access public
  1914 	 * @access public
  1913 	 * @uses do_action_ref_array() Calls 'pre_get_posts' hook before retrieving posts.
  1915 	 * @uses do_action_ref_array() Calls 'pre_get_posts' hook before retrieving posts.
  1914 	 *
  1916 	 *
  1915 	 * @return array List of posts.
  1917 	 * @return array List of posts.
  1916 	 */
  1918 	 */
  1917 	function &get_posts() {
  1919 	function get_posts() {
  1918 		global $wpdb, $user_ID, $_wp_using_ext_object_cache;
  1920 		global $wpdb, $user_ID, $_wp_using_ext_object_cache;
  1919 
  1921 
  1920 		$this->parse_query();
  1922 		$this->parse_query();
  1921 
  1923 
  1922 		do_action_ref_array('pre_get_posts', array(&$this));
  1924 		do_action_ref_array('pre_get_posts', array(&$this));
  2037 				$fields = "$wpdb->posts.ID, $wpdb->posts.post_parent";
  2039 				$fields = "$wpdb->posts.ID, $wpdb->posts.post_parent";
  2038 				break;
  2040 				break;
  2039 			default:
  2041 			default:
  2040 				$fields = "$wpdb->posts.*";
  2042 				$fields = "$wpdb->posts.*";
  2041 		}
  2043 		}
       
  2044 
       
  2045 		if ( '' !== $q['menu_order'] )
       
  2046 			$where .= " AND $wpdb->posts.menu_order = " . $q['menu_order'];
  2042 
  2047 
  2043 		// If a month is specified in the querystring, load that month
  2048 		// If a month is specified in the querystring, load that month
  2044 		if ( $q['m'] ) {
  2049 		if ( $q['m'] ) {
  2045 			$q['m'] = '' . preg_replace('|[^0-9]|', '', $q['m']);
  2050 			$q['m'] = '' . preg_replace('|[^0-9]|', '', $q['m']);
  2046 			$where .= " AND YEAR($wpdb->posts.post_date)=" . substr($q['m'], 0, 4);
  2051 			$where .= " AND YEAR($wpdb->posts.post_date)=" . substr($q['m'], 0, 4);
  2126 			$page_for_posts = get_option('page_for_posts');
  2131 			$page_for_posts = get_option('page_for_posts');
  2127 			if  ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) {
  2132 			if  ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) {
  2128 				$q['pagename'] = sanitize_title_for_query( wp_basename( $q['pagename'] ) );
  2133 				$q['pagename'] = sanitize_title_for_query( wp_basename( $q['pagename'] ) );
  2129 				$q['name'] = $q['pagename'];
  2134 				$q['name'] = $q['pagename'];
  2130 				$where .= " AND ($wpdb->posts.ID = '$reqpage')";
  2135 				$where .= " AND ($wpdb->posts.ID = '$reqpage')";
  2131 				$reqpage_obj = get_page($reqpage);
  2136 				$reqpage_obj = get_post( $reqpage );
  2132 				if ( is_object($reqpage_obj) && 'attachment' == $reqpage_obj->post_type ) {
  2137 				if ( is_object($reqpage_obj) && 'attachment' == $reqpage_obj->post_type ) {
  2133 					$this->is_attachment = true;
  2138 					$this->is_attachment = true;
  2134 					$post_type = $q['post_type'] = 'attachment';
  2139 					$post_type = $q['post_type'] = 'attachment';
  2135 					$this->is_page = true;
  2140 					$this->is_page = true;
  2136 					$q['attachment_id'] = $reqpage;
  2141 					$q['attachment_id'] = $reqpage;
  2175 
  2180 
  2176 		// If a search pattern is specified, load the posts that match
  2181 		// If a search pattern is specified, load the posts that match
  2177 		if ( !empty($q['s']) ) {
  2182 		if ( !empty($q['s']) ) {
  2178 			// added slashes screw with quote grouping when done early, so done later
  2183 			// added slashes screw with quote grouping when done early, so done later
  2179 			$q['s'] = stripslashes($q['s']);
  2184 			$q['s'] = stripslashes($q['s']);
       
  2185 			if ( empty( $_GET['s'] ) && $this->is_main_query() )
       
  2186 				$q['s'] = urldecode($q['s']);
  2180 			if ( !empty($q['sentence']) ) {
  2187 			if ( !empty($q['sentence']) ) {
  2181 				$q['search_terms'] = array($q['s']);
  2188 				$q['search_terms'] = array($q['s']);
  2182 			} else {
  2189 			} else {
  2183 				preg_match_all('/".*?("|$)|((?<=[\r\n\t ",+])|^)[^\r\n\t ",+]+/', $q['s'], $matches);
  2190 				preg_match_all('/".*?("|$)|((?<=[\r\n\t ",+])|^)[^\r\n\t ",+]+/', $q['s'], $matches);
  2184 				$q['search_terms'] = array_map('_search_terms_tidy', $matches[0]);
  2191 				$q['search_terms'] = array_map('_search_terms_tidy', $matches[0]);
  2211 			$where .= $clauses['where'];
  2218 			$where .= $clauses['where'];
  2212 		}
  2219 		}
  2213 
  2220 
  2214 		if ( $this->is_tax ) {
  2221 		if ( $this->is_tax ) {
  2215 			if ( empty($post_type) ) {
  2222 			if ( empty($post_type) ) {
  2216 				$post_type = 'any';
  2223 				// Do a fully inclusive search for currently registered post types of queried taxonomies
       
  2224 				$post_type = array();
       
  2225 				$taxonomies = wp_list_pluck( $this->tax_query->queries, 'taxonomy' );
       
  2226 				foreach ( get_post_types( array( 'exclude_from_search' => false ) ) as $pt ) {
       
  2227 					$object_taxonomies = $pt === 'attachment' ? get_taxonomies_for_attachments() : get_object_taxonomies( $pt );
       
  2228 					if ( array_intersect( $taxonomies, $object_taxonomies ) )
       
  2229 						$post_type[] = $pt;
       
  2230 				}
       
  2231 				if ( ! $post_type )
       
  2232 					$post_type = 'any';
       
  2233 
  2217 				$post_status_join = true;
  2234 				$post_status_join = true;
  2218 			} elseif ( in_array('attachment', (array) $post_type) ) {
  2235 			} elseif ( in_array('attachment', (array) $post_type) ) {
  2219 				$post_status_join = true;
  2236 				$post_status_join = true;
  2220 			}
  2237 			}
  2221 		}
  2238 		}
  2322 		// Order by
  2339 		// Order by
  2323 		if ( empty($q['orderby']) ) {
  2340 		if ( empty($q['orderby']) ) {
  2324 			$orderby = "$wpdb->posts.post_date " . $q['order'];
  2341 			$orderby = "$wpdb->posts.post_date " . $q['order'];
  2325 		} elseif ( 'none' == $q['orderby'] ) {
  2342 		} elseif ( 'none' == $q['orderby'] ) {
  2326 			$orderby = '';
  2343 			$orderby = '';
       
  2344 		} elseif ( $q['orderby'] == 'post__in' && ! empty( $post__in ) ) {
       
  2345 			$orderby = "FIELD( {$wpdb->posts}.ID, $post__in )";
  2327 		} else {
  2346 		} else {
  2328 			// Used to filter values
  2347 			// Used to filter values
  2329 			$allowed_keys = array('name', 'author', 'date', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand', 'comment_count');
  2348 			$allowed_keys = array('name', 'author', 'date', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand', 'comment_count');
  2330 			if ( !empty($q['meta_key']) ) {
  2349 			if ( !empty($q['meta_key']) ) {
  2331 				$allowed_keys[] = $q['meta_key'];
  2350 				$allowed_keys[] = $q['meta_key'];
  2384 		}
  2403 		}
  2385 
  2404 
  2386 		if ( 'any' == $post_type ) {
  2405 		if ( 'any' == $post_type ) {
  2387 			$in_search_post_types = get_post_types( array('exclude_from_search' => false) );
  2406 			$in_search_post_types = get_post_types( array('exclude_from_search' => false) );
  2388 			if ( ! empty( $in_search_post_types ) )
  2407 			if ( ! empty( $in_search_post_types ) )
  2389 				$where .= $wpdb->prepare(" AND $wpdb->posts.post_type IN ('" . join("', '", $in_search_post_types ) . "')");
  2408 				$where .= " AND $wpdb->posts.post_type IN ('" . join("', '", $in_search_post_types ) . "')";
  2390 		} elseif ( !empty( $post_type ) && is_array( $post_type ) ) {
  2409 		} elseif ( !empty( $post_type ) && is_array( $post_type ) ) {
  2391 			$where .= " AND $wpdb->posts.post_type IN ('" . join("', '", $post_type) . "')";
  2410 			$where .= " AND $wpdb->posts.post_type IN ('" . join("', '", $post_type) . "')";
  2392 		} elseif ( ! empty( $post_type ) ) {
  2411 		} elseif ( ! empty( $post_type ) ) {
  2393 			$where .= " AND $wpdb->posts.post_type = '$post_type'";
  2412 			$where .= " AND $wpdb->posts.post_type = '$post_type'";
  2394 			$post_type_object = get_post_type_object ( $post_type );
  2413 			$post_type_object = get_post_type_object ( $post_type );
  2610 		if ( !$q['suppress_filters'] ) {
  2629 		if ( !$q['suppress_filters'] ) {
  2611 			$this->request = apply_filters_ref_array( 'posts_request', array( $this->request, &$this ) );
  2630 			$this->request = apply_filters_ref_array( 'posts_request', array( $this->request, &$this ) );
  2612 		}
  2631 		}
  2613 
  2632 
  2614 		if ( 'ids' == $q['fields'] ) {
  2633 		if ( 'ids' == $q['fields'] ) {
  2615 			$this->posts = $wpdb->get_col($this->request);
  2634 			$this->posts = $wpdb->get_col( $this->request );
       
  2635 			$this->post_count = count( $this->posts );
       
  2636 			$this->set_found_posts( $q, $limits );
  2616 
  2637 
  2617 			return $this->posts;
  2638 			return $this->posts;
  2618 		}
  2639 		}
  2619 
  2640 
  2620 		if ( 'id=>parent' == $q['fields'] ) {
  2641 		if ( 'id=>parent' == $q['fields'] ) {
  2621 			$this->posts = $wpdb->get_results($this->request);
  2642 			$this->posts = $wpdb->get_results( $this->request );
       
  2643 			$this->post_count = count( $this->posts );
       
  2644 			$this->set_found_posts( $q, $limits );
  2622 
  2645 
  2623 			$r = array();
  2646 			$r = array();
  2624 			foreach ( $this->posts as $post )
  2647 			foreach ( $this->posts as $post )
  2625 				$r[ $post->ID ] = $post->post_parent;
  2648 				$r[ $post->ID ] = $post->post_parent;
  2626 
  2649 
  2638 			$this->request = apply_filters( 'posts_request_ids', $this->request, $this );
  2661 			$this->request = apply_filters( 'posts_request_ids', $this->request, $this );
  2639 
  2662 
  2640 			$ids = $wpdb->get_col( $this->request );
  2663 			$ids = $wpdb->get_col( $this->request );
  2641 
  2664 
  2642 			if ( $ids ) {
  2665 			if ( $ids ) {
       
  2666 				$this->posts = $ids;
  2643 				$this->set_found_posts( $q, $limits );
  2667 				$this->set_found_posts( $q, $limits );
  2644 
       
  2645 				_prime_post_caches( $ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
  2668 				_prime_post_caches( $ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
  2646 
       
  2647 				$this->posts = array_map( 'get_post', $ids );
       
  2648 			} else {
  2669 			} else {
  2649 				$this->found_posts = $this->max_num_pages = 0;
       
  2650 				$this->posts = array();
  2670 				$this->posts = array();
  2651 			}
  2671 			}
  2652 		} else {
  2672 		} else {
  2653 			$this->posts = $wpdb->get_results( $this->request );
  2673 			$this->posts = $wpdb->get_results( $this->request );
  2654 			$this->set_found_posts( $q, $limits );
  2674 			$this->set_found_posts( $q, $limits );
  2655 		}
  2675 		}
       
  2676 
       
  2677 		// Convert to WP_Post objects
       
  2678 		if ( $this->posts )
       
  2679 			$this->posts = array_map( 'get_post', $this->posts );
  2656 
  2680 
  2657 		// Raw results filter. Prior to status checks.
  2681 		// Raw results filter. Prior to status checks.
  2658 		if ( !$q['suppress_filters'] )
  2682 		if ( !$q['suppress_filters'] )
  2659 			$this->posts = apply_filters_ref_array('posts_results', array( $this->posts, &$this ) );
  2683 			$this->posts = apply_filters_ref_array('posts_results', array( $this->posts, &$this ) );
  2660 
  2684 
  2698 					}
  2722 					}
  2699 				}
  2723 				}
  2700 			}
  2724 			}
  2701 
  2725 
  2702 			if ( $this->is_preview && $this->posts && current_user_can( $edit_cap, $this->posts[0]->ID ) )
  2726 			if ( $this->is_preview && $this->posts && current_user_can( $edit_cap, $this->posts[0]->ID ) )
  2703 				$this->posts[0] = apply_filters_ref_array('the_preview', array( $this->posts[0], &$this ));
  2727 				$this->posts[0] = get_post( apply_filters_ref_array( 'the_preview', array( $this->posts[0], &$this ) ) );
  2704 		}
  2728 		}
  2705 
  2729 
  2706 		// Put sticky posts at the top of the posts array
  2730 		// Put sticky posts at the top of the posts array
  2707 		$sticky_posts = get_option('sticky_posts');
  2731 		$sticky_posts = get_option('sticky_posts');
  2708 		if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) {
  2732 		if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) {
  2728 			if ( !empty($sticky_posts) && !empty($q['post__not_in']) )
  2752 			if ( !empty($sticky_posts) && !empty($q['post__not_in']) )
  2729 				$sticky_posts = array_diff($sticky_posts, $q['post__not_in']);
  2753 				$sticky_posts = array_diff($sticky_posts, $q['post__not_in']);
  2730 
  2754 
  2731 			// Fetch sticky posts that weren't in the query results
  2755 			// Fetch sticky posts that weren't in the query results
  2732 			if ( !empty($sticky_posts) ) {
  2756 			if ( !empty($sticky_posts) ) {
  2733 				$stickies__in = implode(',', array_map( 'absint', $sticky_posts ));
  2757 				$stickies = get_posts( array(
  2734 				// honor post type(s) if not set to any
  2758 					'post__in' => $sticky_posts,
  2735 				$stickies_where = '';
  2759 					'post_type' => $post_type,
  2736 				if ( 'any' != $post_type && '' != $post_type ) {
  2760 					'post_status' => 'publish',
  2737 					if ( is_array( $post_type ) ) {
  2761 					'nopaging' => true
  2738 						$post_types = join( "', '", $post_type );
  2762 				) );
  2739 					} else {
  2763 
  2740 						$post_types = $post_type;
       
  2741 					}
       
  2742 					$stickies_where = "AND $wpdb->posts.post_type IN ('" . $post_types . "')";
       
  2743 				}
       
  2744 
       
  2745 				$stickies = $wpdb->get_results( "SELECT * FROM $wpdb->posts WHERE $wpdb->posts.ID IN ($stickies__in) $stickies_where" );
       
  2746 				foreach ( $stickies as $sticky_post ) {
  2764 				foreach ( $stickies as $sticky_post ) {
  2747 					// Ignore sticky posts the current user cannot read or are not published.
  2765 					array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) );
  2748 					if ( 'publish' != $sticky_post->post_status )
       
  2749 						continue;
       
  2750 					array_splice($this->posts, $sticky_offset, 0, array($sticky_post));
       
  2751 					$sticky_offset++;
  2766 					$sticky_offset++;
  2752 				}
  2767 				}
  2753 			}
  2768 			}
  2754 		}
  2769 		}
  2755 
  2770 
  2756 		if ( !$q['suppress_filters'] )
  2771 		if ( !$q['suppress_filters'] )
  2757 			$this->posts = apply_filters_ref_array('the_posts', array( $this->posts, &$this ) );
  2772 			$this->posts = apply_filters_ref_array('the_posts', array( $this->posts, &$this ) );
  2758 
  2773 
  2759 		$this->post_count = count($this->posts);
  2774 		// Ensure that any posts added/modified via one of the filters above are
  2760 
  2775 		// of the type WP_Post and are filtered.
  2761 		// Always sanitize
  2776 		if ( $this->posts ) {
  2762 		foreach ( $this->posts as $i => $post ) {
  2777 			$this->post_count = count( $this->posts );
  2763 			$this->posts[$i] = sanitize_post( $post, 'raw' );
  2778 
  2764 		}
  2779 			$this->posts = array_map( 'get_post', $this->posts );
  2765 
  2780 
  2766 		if ( $q['cache_results'] )
  2781 			if ( $q['cache_results'] )
  2767 			update_post_caches($this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache']);
  2782 				update_post_caches($this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache']);
  2768 
  2783 
  2769 		if ( $this->post_count > 0 ) {
  2784 			$this->post = reset( $this->posts );
  2770 			$this->post = $this->posts[0];
  2785 		} else {
       
  2786 			$this->post_count = 0;
       
  2787 			$this->posts = array();
  2771 		}
  2788 		}
  2772 
  2789 
  2773 		return $this->posts;
  2790 		return $this->posts;
  2774 	}
  2791 	}
  2775 
  2792 
       
  2793 	/**
       
  2794 	 * Set up the amount of found posts and the number of pages (if limit clause was used)
       
  2795 	 * for the current query.
       
  2796 	 *
       
  2797 	 * @since 3.5.0
       
  2798 	 * @access private
       
  2799 	 */
  2776 	function set_found_posts( $q, $limits ) {
  2800 	function set_found_posts( $q, $limits ) {
  2777 		global $wpdb;
  2801 		global $wpdb;
  2778 
  2802 
  2779 		if ( $q['no_found_rows'] || empty( $limits ) )
  2803 		// Bail if posts is an empty array. Continue if posts is an empty string
       
  2804 		// null, or false to accommodate caching plugins that fill posts later.
       
  2805 		if ( $q['no_found_rows'] || ( is_array( $this->posts ) && ! $this->posts ) )
  2780 			return;
  2806 			return;
  2781 
  2807 
  2782 		$this->found_posts = $wpdb->get_var( apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ) );
  2808 		if ( ! empty( $limits ) )
       
  2809 			$this->found_posts = $wpdb->get_var( apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ) );
       
  2810 		else
       
  2811 			$this->found_posts = count( $this->posts );
       
  2812 
  2783 		$this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
  2813 		$this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
  2784 
  2814 
  2785 		$this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] );
  2815 		if ( ! empty( $limits ) )
       
  2816 			$this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] );
  2786 	}
  2817 	}
  2787 
  2818 
  2788 	/**
  2819 	/**
  2789 	 * Set up the next post and iterate current post index.
  2820 	 * Set up the next post and iterate current post index.
  2790 	 *
  2821 	 *
  2791 	 * @since 1.5.0
  2822 	 * @since 1.5.0
  2792 	 * @access public
  2823 	 * @access public
  2793 	 *
  2824 	 *
  2794 	 * @return object Next post.
  2825 	 * @return WP_Post Next post.
  2795 	 */
  2826 	 */
  2796 	function next_post() {
  2827 	function next_post() {
  2797 
  2828 
  2798 		$this->current_post++;
  2829 		$this->current_post++;
  2799 
  2830 
  2933 	 * @access public
  2964 	 * @access public
  2934 	 *
  2965 	 *
  2935 	 * @param string $query URL query string.
  2966 	 * @param string $query URL query string.
  2936 	 * @return array List of posts.
  2967 	 * @return array List of posts.
  2937 	 */
  2968 	 */
  2938 	function &query( $query ) {
  2969 	function query( $query ) {
  2939 		$this->init();
  2970 		$this->init();
  2940 		$this->query = $this->query_vars = wp_parse_args( $query );
  2971 		$this->query = $this->query_vars = wp_parse_args( $query );
  2941 		return $this->get_posts();
  2972 		return $this->get_posts();
  2942 	}
  2973 	}
  2943 
  2974 
  2965 
  2996 
  2966 			$query = reset( $tax_query_in_and );
  2997 			$query = reset( $tax_query_in_and );
  2967 
  2998 
  2968 			if ( 'term_id' == $query['field'] )
  2999 			if ( 'term_id' == $query['field'] )
  2969 				$term = get_term( reset( $query['terms'] ), $query['taxonomy'] );
  3000 				$term = get_term( reset( $query['terms'] ), $query['taxonomy'] );
  2970 			else
  3001 			elseif ( $query['terms'] )
  2971 				$term = get_term_by( $query['field'], reset( $query['terms'] ), $query['taxonomy'] );
  3002 				$term = get_term_by( $query['field'], reset( $query['terms'] ), $query['taxonomy'] );
  2972 
  3003 
  2973 			if ( $term && ! is_wp_error($term) )  {
  3004 			if ( ! empty( $term ) && ! is_wp_error( $term ) )  {
  2974 				$this->queried_object = $term;
  3005 				$this->queried_object = $term;
  2975 				$this->queried_object_id = (int) $term->term_id;
  3006 				$this->queried_object_id = (int) $term->term_id;
  2976 
  3007 
  2977 				if ( $this->is_category )
  3008 				if ( $this->is_category )
  2978 					_make_cat_compat( $this->queried_object );
  3009 					_make_cat_compat( $this->queried_object );
  2979 			}
  3010 			}
  2980 		} elseif ( $this->is_post_type_archive ) {
  3011 		} elseif ( $this->is_post_type_archive ) {
  2981 			$this->queried_object = get_post_type_object( $this->get('post_type') );
  3012 			$this->queried_object = get_post_type_object( $this->get('post_type') );
  2982 		} elseif ( $this->is_posts_page ) {
  3013 		} elseif ( $this->is_posts_page ) {
  2983 			$page_for_posts = get_option('page_for_posts');
  3014 			$page_for_posts = get_option('page_for_posts');
  2984 			$this->queried_object = get_page( $page_for_posts );
  3015 			$this->queried_object = get_post( $page_for_posts );
  2985 			$this->queried_object_id = (int) $this->queried_object->ID;
  3016 			$this->queried_object_id = (int) $this->queried_object->ID;
  2986 		} elseif ( $this->is_singular && !is_null($this->post) ) {
  3017 		} elseif ( $this->is_singular && !is_null($this->post) ) {
  2987 			$this->queried_object = $this->post;
  3018 			$this->queried_object = $this->post;
  2988 			$this->queried_object_id = (int) $this->post->ID;
  3019 			$this->queried_object_id = (int) $this->post->ID;
  2989 		} elseif ( $this->is_author ) {
  3020 		} elseif ( $this->is_author ) {
  3028 			$this->query($query);
  3059 			$this->query($query);
  3029 		}
  3060 		}
  3030 	}
  3061 	}
  3031 
  3062 
  3032 	/**
  3063 	/**
  3033  	 * Is the query for an archive page?
  3064  	 * Is the query for an existing archive page?
  3034  	 *
  3065  	 *
  3035  	 * Month, Year, Category, Author, Post Type archive...
  3066  	 * Month, Year, Category, Author, Post Type archive...
  3036 	 *
  3067 	 *
  3037  	 * @since 3.1.0
  3068  	 * @since 3.1.0
  3038  	 *
  3069  	 *
  3041 	function is_archive() {
  3072 	function is_archive() {
  3042 		return (bool) $this->is_archive;
  3073 		return (bool) $this->is_archive;
  3043 	}
  3074 	}
  3044 
  3075 
  3045 	/**
  3076 	/**
  3046 	 * Is the query for a post type archive page?
  3077 	 * Is the query for an existing post type archive page?
  3047 	 *
  3078 	 *
  3048 	 * @since 3.1.0
  3079 	 * @since 3.1.0
  3049 	 *
  3080 	 *
  3050 	 * @param mixed $post_types Optional. Post type or array of posts types to check against.
  3081 	 * @param mixed $post_types Optional. Post type or array of posts types to check against.
  3051 	 * @return bool
  3082 	 * @return bool
  3058 
  3089 
  3059 		return in_array( $post_type_object->name, (array) $post_types );
  3090 		return in_array( $post_type_object->name, (array) $post_types );
  3060 	}
  3091 	}
  3061 
  3092 
  3062 	/**
  3093 	/**
  3063 	 * Is the query for an attachment page?
  3094 	 * Is the query for an existing attachment page?
  3064 	 *
  3095 	 *
  3065 	 * @since 3.1.0
  3096 	 * @since 3.1.0
  3066 	 *
  3097 	 *
  3067 	 * @return bool
  3098 	 * @return bool
  3068 	 */
  3099 	 */
  3069 	function is_attachment() {
  3100 	function is_attachment() {
  3070 		return (bool) $this->is_attachment;
  3101 		return (bool) $this->is_attachment;
  3071 	}
  3102 	}
  3072 
  3103 
  3073 	/**
  3104 	/**
  3074 	 * Is the query for an author archive page?
  3105 	 * Is the query for an existing author archive page?
  3075 	 *
  3106 	 *
  3076 	 * If the $author parameter is specified, this function will additionally
  3107 	 * If the $author parameter is specified, this function will additionally
  3077 	 * check if the query is for one of the authors specified.
  3108 	 * check if the query is for one of the authors specified.
  3078 	 *
  3109 	 *
  3079 	 * @since 3.1.0
  3110 	 * @since 3.1.0
  3101 
  3132 
  3102 		return false;
  3133 		return false;
  3103 	}
  3134 	}
  3104 
  3135 
  3105 	/**
  3136 	/**
  3106 	 * Is the query for a category archive page?
  3137 	 * Is the query for an existing category archive page?
  3107 	 *
  3138 	 *
  3108 	 * If the $category parameter is specified, this function will additionally
  3139 	 * If the $category parameter is specified, this function will additionally
  3109 	 * check if the query is for one of the categories specified.
  3140 	 * check if the query is for one of the categories specified.
  3110 	 *
  3141 	 *
  3111 	 * @since 3.1.0
  3142 	 * @since 3.1.0
  3133 
  3164 
  3134 		return false;
  3165 		return false;
  3135 	}
  3166 	}
  3136 
  3167 
  3137 	/**
  3168 	/**
  3138 	 * Is the query for a tag archive page?
  3169 	 * Is the query for an existing tag archive page?
  3139 	 *
  3170 	 *
  3140 	 * If the $tag parameter is specified, this function will additionally
  3171 	 * If the $tag parameter is specified, this function will additionally
  3141 	 * check if the query is for one of the tags specified.
  3172 	 * check if the query is for one of the tags specified.
  3142 	 *
  3173 	 *
  3143 	 * @since 3.1.0
  3174 	 * @since 3.1.0
  3161 
  3192 
  3162 		return false;
  3193 		return false;
  3163 	}
  3194 	}
  3164 
  3195 
  3165 	/**
  3196 	/**
  3166 	 * Is the query for a taxonomy archive page?
  3197 	 * Is the query for an existing taxonomy archive page?
  3167 	 *
  3198 	 *
  3168 	 * If the $taxonomy parameter is specified, this function will additionally
  3199 	 * If the $taxonomy parameter is specified, this function will additionally
  3169 	 * check if the query is for that specific $taxonomy.
  3200 	 * check if the query is for that specific $taxonomy.
  3170 	 *
  3201 	 *
  3171 	 * If the $term parameter is specified in addition to the $taxonomy parameter,
  3202 	 * If the $term parameter is specified in addition to the $taxonomy parameter,
  3189 
  3220 
  3190 		$queried_object = $this->get_queried_object();
  3221 		$queried_object = $this->get_queried_object();
  3191 		$tax_array = array_intersect( array_keys( $wp_taxonomies ), (array) $taxonomy );
  3222 		$tax_array = array_intersect( array_keys( $wp_taxonomies ), (array) $taxonomy );
  3192 		$term_array = (array) $term;
  3223 		$term_array = (array) $term;
  3193 
  3224 
  3194 		if ( empty( $term ) ) // Only a Taxonomy provided
  3225 		// Check that the taxonomy matches.
  3195 			return isset( $queried_object->taxonomy ) && count( $tax_array ) && in_array( $queried_object->taxonomy, $tax_array );
  3226 		if ( ! ( isset( $queried_object->taxonomy ) && count( $tax_array ) && in_array( $queried_object->taxonomy, $tax_array ) ) )
       
  3227 			return false;
       
  3228 
       
  3229 		// Only a Taxonomy provided.
       
  3230 		if ( empty( $term ) )
       
  3231 			return true;
  3196 
  3232 
  3197 		return isset( $queried_object->term_id ) &&
  3233 		return isset( $queried_object->term_id ) &&
  3198 			count( array_intersect(
  3234 			count( array_intersect(
  3199 				array( $queried_object->term_id, $queried_object->name, $queried_object->slug ),
  3235 				array( $queried_object->term_id, $queried_object->name, $queried_object->slug ),
  3200 				$term_array
  3236 				$term_array
  3211 	function is_comments_popup() {
  3247 	function is_comments_popup() {
  3212 		return (bool) $this->is_comments_popup;
  3248 		return (bool) $this->is_comments_popup;
  3213 	}
  3249 	}
  3214 
  3250 
  3215 	/**
  3251 	/**
  3216 	 * Is the query for a date archive?
  3252 	 * Is the query for an existing date archive?
  3217 	 *
  3253 	 *
  3218 	 * @since 3.1.0
  3254 	 * @since 3.1.0
  3219 	 *
  3255 	 *
  3220 	 * @return bool
  3256 	 * @return bool
  3221 	 */
  3257 	 */
  3222 	function is_date() {
  3258 	function is_date() {
  3223 		return (bool) $this->is_date;
  3259 		return (bool) $this->is_date;
  3224 	}
  3260 	}
  3225 
  3261 
  3226 	/**
  3262 	/**
  3227 	 * Is the query for a day archive?
  3263 	 * Is the query for an existing day archive?
  3228 	 *
  3264 	 *
  3229 	 * @since 3.1.0
  3265 	 * @since 3.1.0
  3230 	 *
  3266 	 *
  3231 	 * @return bool
  3267 	 * @return bool
  3232 	 */
  3268 	 */
  3309 	function is_home() {
  3345 	function is_home() {
  3310 		return (bool) $this->is_home;
  3346 		return (bool) $this->is_home;
  3311 	}
  3347 	}
  3312 
  3348 
  3313 	/**
  3349 	/**
  3314 	 * Is the query for a month archive?
  3350 	 * Is the query for an existing month archive?
  3315 	 *
  3351 	 *
  3316 	 * @since 3.1.0
  3352 	 * @since 3.1.0
  3317 	 *
  3353 	 *
  3318 	 * @return bool
  3354 	 * @return bool
  3319 	 */
  3355 	 */
  3320 	function is_month() {
  3356 	function is_month() {
  3321 		return (bool) $this->is_month;
  3357 		return (bool) $this->is_month;
  3322 	}
  3358 	}
  3323 
  3359 
  3324 	/**
  3360 	/**
  3325 	 * Is the query for a single page?
  3361 	 * Is the query for an existing single page?
  3326 	 *
  3362 	 *
  3327 	 * If the $page parameter is specified, this function will additionally
  3363 	 * If the $page parameter is specified, this function will additionally
  3328 	 * check if the query is for one of the pages specified.
  3364 	 * check if the query is for one of the pages specified.
  3329 	 *
  3365 	 *
  3330 	 * @see WP_Query::is_single()
  3366 	 * @see WP_Query::is_single()
  3399 	function is_search() {
  3435 	function is_search() {
  3400 		return (bool) $this->is_search;
  3436 		return (bool) $this->is_search;
  3401 	}
  3437 	}
  3402 
  3438 
  3403 	/**
  3439 	/**
  3404 	 * Is the query for a single post?
  3440 	 * Is the query for an existing single post?
  3405 	 *
  3441 	 *
  3406 	 * Works for any post type, except attachments and pages
  3442 	 * Works for any post type, except attachments and pages
  3407 	 *
  3443 	 *
  3408 	 * If the $post parameter is specified, this function will additionally
  3444 	 * If the $post parameter is specified, this function will additionally
  3409 	 * check if the query is for one of the Posts specified.
  3445 	 * check if the query is for one of the Posts specified.
  3436 
  3472 
  3437 		return false;
  3473 		return false;
  3438 	}
  3474 	}
  3439 
  3475 
  3440 	/**
  3476 	/**
  3441 	 * Is the query for a single post of any post type (post, attachment, page, ... )?
  3477 	 * Is the query for an existing single post of any post type (post, attachment, page, ... )?
  3442 	 *
  3478 	 *
  3443 	 * If the $post_types parameter is specified, this function will additionally
  3479 	 * If the $post_types parameter is specified, this function will additionally
  3444 	 * check if the query is for one of the Posts Types specified.
  3480 	 * check if the query is for one of the Posts Types specified.
  3445 	 *
  3481 	 *
  3446 	 * @see WP_Query::is_page()
  3482 	 * @see WP_Query::is_page()
  3481 	function is_trackback() {
  3517 	function is_trackback() {
  3482 		return (bool) $this->is_trackback;
  3518 		return (bool) $this->is_trackback;
  3483 	}
  3519 	}
  3484 
  3520 
  3485 	/**
  3521 	/**
  3486 	 * Is the query for a specific year?
  3522 	 * Is the query for an existing year archive?
  3487 	 *
  3523 	 *
  3488 	 * @since 3.1.0
  3524 	 * @since 3.1.0
  3489 	 *
  3525 	 *
  3490 	 * @return bool
  3526 	 * @return bool
  3491 	 */
  3527 	 */