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