wp/wp-includes/class-wp-query.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 13 d255fe9cd479
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
   324 	 * @var bool
   324 	 * @var bool
   325 	 */
   325 	 */
   326 	public $is_home = false;
   326 	public $is_home = false;
   327 
   327 
   328 	/**
   328 	/**
       
   329 	 * Signifies whether the current query is for the Privacy Policy page.
       
   330 	 *
       
   331 	 * @since 5.2.0
       
   332 	 * @var bool
       
   333 	 */
       
   334 	public $is_privacy_policy = false;
       
   335 
       
   336 	/**
   329 	 * Signifies whether the current query couldn't find anything.
   337 	 * Signifies whether the current query couldn't find anything.
   330 	 *
   338 	 *
   331 	 * @since 1.5.0
   339 	 * @since 1.5.0
   332 	 * @var bool
   340 	 * @var bool
   333 	 */
   341 	 */
   421 	 * Set if post thumbnails are cached
   429 	 * Set if post thumbnails are cached
   422 	 *
   430 	 *
   423 	 * @since 3.2.0
   431 	 * @since 3.2.0
   424 	 * @var bool
   432 	 * @var bool
   425 	 */
   433 	 */
   426 	 public $thumbnails_cached = false;
   434 	public $thumbnails_cached = false;
   427 
   435 
   428 	/**
   436 	/**
   429 	 * Cached list of search stopwords.
   437 	 * Cached list of search stopwords.
   430 	 *
   438 	 *
   431 	 * @since 3.7.0
   439 	 * @since 3.7.0
   443 	 * The query flags are what page info WordPress was able to figure out.
   451 	 * The query flags are what page info WordPress was able to figure out.
   444 	 *
   452 	 *
   445 	 * @since 2.0.0
   453 	 * @since 2.0.0
   446 	 */
   454 	 */
   447 	private function init_query_flags() {
   455 	private function init_query_flags() {
   448 		$this->is_single = false;
   456 		$this->is_single            = false;
   449 		$this->is_preview = false;
   457 		$this->is_preview           = false;
   450 		$this->is_page = false;
   458 		$this->is_page              = false;
   451 		$this->is_archive = false;
   459 		$this->is_archive           = false;
   452 		$this->is_date = false;
   460 		$this->is_date              = false;
   453 		$this->is_year = false;
   461 		$this->is_year              = false;
   454 		$this->is_month = false;
   462 		$this->is_month             = false;
   455 		$this->is_day = false;
   463 		$this->is_day               = false;
   456 		$this->is_time = false;
   464 		$this->is_time              = false;
   457 		$this->is_author = false;
   465 		$this->is_author            = false;
   458 		$this->is_category = false;
   466 		$this->is_category          = false;
   459 		$this->is_tag = false;
   467 		$this->is_tag               = false;
   460 		$this->is_tax = false;
   468 		$this->is_tax               = false;
   461 		$this->is_search = false;
   469 		$this->is_search            = false;
   462 		$this->is_feed = false;
   470 		$this->is_feed              = false;
   463 		$this->is_comment_feed = false;
   471 		$this->is_comment_feed      = false;
   464 		$this->is_trackback = false;
   472 		$this->is_trackback         = false;
   465 		$this->is_home = false;
   473 		$this->is_home              = false;
   466 		$this->is_404 = false;
   474 		$this->is_privacy_policy    = false;
   467 		$this->is_paged = false;
   475 		$this->is_404               = false;
   468 		$this->is_admin = false;
   476 		$this->is_paged             = false;
   469 		$this->is_attachment = false;
   477 		$this->is_admin             = false;
   470 		$this->is_singular = false;
   478 		$this->is_attachment        = false;
   471 		$this->is_robots = false;
   479 		$this->is_singular          = false;
   472 		$this->is_posts_page = false;
   480 		$this->is_robots            = false;
       
   481 		$this->is_posts_page        = false;
   473 		$this->is_post_type_archive = false;
   482 		$this->is_post_type_archive = false;
   474 	}
   483 	}
   475 
   484 
   476 	/**
   485 	/**
   477 	 * Initiates object properties and sets default values.
   486 	 * Initiates object properties and sets default values.
   478 	 *
   487 	 *
   479 	 * @since 1.5.0
   488 	 * @since 1.5.0
   480 	 */
   489 	 */
   481 	public function init() {
   490 	public function init() {
   482 		unset($this->posts);
   491 		unset( $this->posts );
   483 		unset($this->query);
   492 		unset( $this->query );
   484 		$this->query_vars = array();
   493 		$this->query_vars = array();
   485 		unset($this->queried_object);
   494 		unset( $this->queried_object );
   486 		unset($this->queried_object_id);
   495 		unset( $this->queried_object_id );
   487 		$this->post_count = 0;
   496 		$this->post_count   = 0;
   488 		$this->current_post = -1;
   497 		$this->current_post = -1;
   489 		$this->in_the_loop = false;
   498 		$this->in_the_loop  = false;
   490 		unset( $this->request );
   499 		unset( $this->request );
   491 		unset( $this->post );
   500 		unset( $this->post );
   492 		unset( $this->comments );
   501 		unset( $this->comments );
   493 		unset( $this->comment );
   502 		unset( $this->comment );
   494 		$this->comment_count = 0;
   503 		$this->comment_count         = 0;
   495 		$this->current_comment = -1;
   504 		$this->current_comment       = -1;
   496 		$this->found_posts = 0;
   505 		$this->found_posts           = 0;
   497 		$this->max_num_pages = 0;
   506 		$this->max_num_pages         = 0;
   498 		$this->max_num_comment_pages = 0;
   507 		$this->max_num_comment_pages = 0;
   499 
   508 
   500 		$this->init_query_flags();
   509 		$this->init_query_flags();
   501 	}
   510 	}
   502 
   511 
   516 	 * @since 4.4.0 Removed the `comments_popup` public query variable.
   525 	 * @since 4.4.0 Removed the `comments_popup` public query variable.
   517 	 *
   526 	 *
   518 	 * @param array $array Defined query variables.
   527 	 * @param array $array Defined query variables.
   519 	 * @return array Complete query variables with undefined ones filled in empty.
   528 	 * @return array Complete query variables with undefined ones filled in empty.
   520 	 */
   529 	 */
   521 	public function fill_query_vars($array) {
   530 	public function fill_query_vars( $array ) {
   522 		$keys = array(
   531 		$keys = array(
   523 			'error'
   532 			'error',
   524 			, 'm'
   533 			'm',
   525 			, 'p'
   534 			'p',
   526 			, 'post_parent'
   535 			'post_parent',
   527 			, 'subpost'
   536 			'subpost',
   528 			, 'subpost_id'
   537 			'subpost_id',
   529 			, 'attachment'
   538 			'attachment',
   530 			, 'attachment_id'
   539 			'attachment_id',
   531 			, 'name'
   540 			'name',
   532 			, 'static'
   541 			'static',
   533 			, 'pagename'
   542 			'pagename',
   534 			, 'page_id'
   543 			'page_id',
   535 			, 'second'
   544 			'second',
   536 			, 'minute'
   545 			'minute',
   537 			, 'hour'
   546 			'hour',
   538 			, 'day'
   547 			'day',
   539 			, 'monthnum'
   548 			'monthnum',
   540 			, 'year'
   549 			'year',
   541 			, 'w'
   550 			'w',
   542 			, 'category_name'
   551 			'category_name',
   543 			, 'tag'
   552 			'tag',
   544 			, 'cat'
   553 			'cat',
   545 			, 'tag_id'
   554 			'tag_id',
   546 			, 'author'
   555 			'author',
   547 			, 'author_name'
   556 			'author_name',
   548 			, 'feed'
   557 			'feed',
   549 			, 'tb'
   558 			'tb',
   550 			, 'paged'
   559 			'paged',
   551 			, 'meta_key'
   560 			'meta_key',
   552 			, 'meta_value'
   561 			'meta_value',
   553 			, 'preview'
   562 			'preview',
   554 			, 's'
   563 			's',
   555 			, 'sentence'
   564 			'sentence',
   556 			, 'title'
   565 			'title',
   557 			, 'fields'
   566 			'fields',
   558 			, 'menu_order'
   567 			'menu_order',
   559 			, 'embed'
   568 			'embed',
   560 		);
   569 		);
   561 
   570 
   562 		foreach ( $keys as $key ) {
   571 		foreach ( $keys as $key ) {
   563 			if ( !isset($array[$key]) )
   572 			if ( ! isset( $array[ $key ] ) ) {
   564 				$array[$key] = '';
   573 				$array[ $key ] = '';
   565 		}
   574 			}
   566 
   575 		}
   567 		$array_keys = array( 'category__in', 'category__not_in', 'category__and', 'post__in', 'post__not_in', 'post_name__in',
   576 
   568 			'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and', 'post_parent__in', 'post_parent__not_in',
   577 		$array_keys = array(
   569 			'author__in', 'author__not_in' );
   578 			'category__in',
       
   579 			'category__not_in',
       
   580 			'category__and',
       
   581 			'post__in',
       
   582 			'post__not_in',
       
   583 			'post_name__in',
       
   584 			'tag__in',
       
   585 			'tag__not_in',
       
   586 			'tag__and',
       
   587 			'tag_slug__in',
       
   588 			'tag_slug__and',
       
   589 			'post_parent__in',
       
   590 			'post_parent__not_in',
       
   591 			'author__in',
       
   592 			'author__not_in',
       
   593 		);
   570 
   594 
   571 		foreach ( $array_keys as $key ) {
   595 		foreach ( $array_keys as $key ) {
   572 			if ( !isset($array[$key]) )
   596 			if ( ! isset( $array[ $key ] ) ) {
   573 				$array[$key] = array();
   597 				$array[ $key ] = array();
       
   598 			}
   574 		}
   599 		}
   575 		return $array;
   600 		return $array;
   576 	}
   601 	}
   577 
   602 
   578 	/**
   603 	/**
   586 	 * @since 4.5.0 Removed the `$comments_popup` parameter.
   611 	 * @since 4.5.0 Removed the `$comments_popup` parameter.
   587 	 *              Introduced the `$comment_status` and `$ping_status` parameters.
   612 	 *              Introduced the `$comment_status` and `$ping_status` parameters.
   588 	 *              Introduced `RAND(x)` syntax for `$orderby`, which allows an integer seed value to random sorts.
   613 	 *              Introduced `RAND(x)` syntax for `$orderby`, which allows an integer seed value to random sorts.
   589 	 * @since 4.6.0 Added 'post_name__in' support for `$orderby`. Introduced the `$lazy_load_term_meta` argument.
   614 	 * @since 4.6.0 Added 'post_name__in' support for `$orderby`. Introduced the `$lazy_load_term_meta` argument.
   590 	 * @since 4.9.0 Introduced the `$comment_count` parameter.
   615 	 * @since 4.9.0 Introduced the `$comment_count` parameter.
       
   616 	 * @since 5.1.0 Introduced the `$meta_compare_key` parameter.
   591 	 *
   617 	 *
   592 	 * @param string|array $query {
   618 	 * @param string|array $query {
   593 	 *     Optional. Array or string of Query parameters.
   619 	 *     Optional. Array or string of Query parameters.
   594 	 *
   620 	 *
   595 	 *     @type int          $attachment_id           Attachment post ID. Used for 'attachment' post_type.
   621 	 *     @type int          $attachment_id           Attachment post ID. Used for 'attachment' post_type.
   622 	 *                                                 excludes stickies from 'post__in'. Accepts 1|true, 0|false.
   648 	 *                                                 excludes stickies from 'post__in'. Accepts 1|true, 0|false.
   623 	 *                                                 Default 0|false.
   649 	 *                                                 Default 0|false.
   624 	 *     @type int          $m                       Combination YearMonth. Accepts any four-digit year and month
   650 	 *     @type int          $m                       Combination YearMonth. Accepts any four-digit year and month
   625 	 *                                                 numbers 1-12. Default empty.
   651 	 *                                                 numbers 1-12. Default empty.
   626 	 *     @type string       $meta_compare            Comparison operator to test the 'meta_value'.
   652 	 *     @type string       $meta_compare            Comparison operator to test the 'meta_value'.
       
   653 	 *     @type string       $meta_compare_key        Comparison operator to test the 'meta_key'.
   627 	 *     @type string       $meta_key                Custom field key.
   654 	 *     @type string       $meta_key                Custom field key.
   628 	 *     @type array        $meta_query              An associative array of WP_Meta_Query arguments. See WP_Meta_Query.
   655 	 *     @type array        $meta_query              An associative array of WP_Meta_Query arguments. See WP_Meta_Query.
   629 	 *     @type string       $meta_value              Custom field value.
   656 	 *     @type string       $meta_value              Custom field value.
   630 	 *     @type int          $meta_value_num          Custom field value number.
   657 	 *     @type int          $meta_value_num          Custom field value number.
   631 	 *     @type int          $menu_order              The menu order of the posts.
   658 	 *     @type int          $menu_order              The menu order of the posts.
   699 	 *                                                 Defaults to the value of `$update_post_term_cache`.
   726 	 *                                                 Defaults to the value of `$update_post_term_cache`.
   700 	 *     @type int          $w                       The week number of the year. Default empty. Accepts numbers 0-53.
   727 	 *     @type int          $w                       The week number of the year. Default empty. Accepts numbers 0-53.
   701 	 *     @type int          $year                    The four-digit year. Default empty. Accepts any four-digit year.
   728 	 *     @type int          $year                    The four-digit year. Default empty. Accepts any four-digit year.
   702 	 * }
   729 	 * }
   703 	 */
   730 	 */
   704 	public function parse_query( $query =  '' ) {
   731 	public function parse_query( $query = '' ) {
   705 		if ( ! empty( $query ) ) {
   732 		if ( ! empty( $query ) ) {
   706 			$this->init();
   733 			$this->init();
   707 			$this->query = $this->query_vars = wp_parse_args( $query );
   734 			$this->query = $this->query_vars = wp_parse_args( $query );
   708 		} elseif ( ! isset( $this->query ) ) {
   735 		} elseif ( ! isset( $this->query ) ) {
   709 			$this->query = $this->query_vars;
   736 			$this->query = $this->query_vars;
   710 		}
   737 		}
   711 
   738 
   712 		$this->query_vars = $this->fill_query_vars($this->query_vars);
   739 		$this->query_vars         = $this->fill_query_vars( $this->query_vars );
   713 		$qv = &$this->query_vars;
   740 		$qv                       = &$this->query_vars;
   714 		$this->query_vars_changed = true;
   741 		$this->query_vars_changed = true;
   715 
   742 
   716 		if ( ! empty($qv['robots']) )
   743 		if ( ! empty( $qv['robots'] ) ) {
   717 			$this->is_robots = true;
   744 			$this->is_robots = true;
       
   745 		}
   718 
   746 
   719 		if ( ! is_scalar( $qv['p'] ) || $qv['p'] < 0 ) {
   747 		if ( ! is_scalar( $qv['p'] ) || $qv['p'] < 0 ) {
   720 			$qv['p'] = 0;
   748 			$qv['p']     = 0;
   721 			$qv['error'] = '404';
   749 			$qv['error'] = '404';
   722 		} else {
   750 		} else {
   723 			$qv['p'] = intval( $qv['p'] );
   751 			$qv['p'] = intval( $qv['p'] );
   724 		}
   752 		}
   725 
   753 
   726 		$qv['page_id'] =  absint($qv['page_id']);
   754 		$qv['page_id']  = absint( $qv['page_id'] );
   727 		$qv['year'] = absint($qv['year']);
   755 		$qv['year']     = absint( $qv['year'] );
   728 		$qv['monthnum'] = absint($qv['monthnum']);
   756 		$qv['monthnum'] = absint( $qv['monthnum'] );
   729 		$qv['day'] = absint($qv['day']);
   757 		$qv['day']      = absint( $qv['day'] );
   730 		$qv['w'] = absint($qv['w']);
   758 		$qv['w']        = absint( $qv['w'] );
   731 		$qv['m'] = is_scalar( $qv['m'] ) ? preg_replace( '|[^0-9]|', '', $qv['m'] ) : '';
   759 		$qv['m']        = is_scalar( $qv['m'] ) ? preg_replace( '|[^0-9]|', '', $qv['m'] ) : '';
   732 		$qv['paged'] = absint($qv['paged']);
   760 		$qv['paged']    = absint( $qv['paged'] );
   733 		$qv['cat'] = preg_replace( '|[^0-9,-]|', '', $qv['cat'] ); // comma separated list of positive or negative integers
   761 		$qv['cat']      = preg_replace( '|[^0-9,-]|', '', $qv['cat'] ); // comma separated list of positive or negative integers
   734 		$qv['author'] = preg_replace( '|[^0-9,-]|', '', $qv['author'] ); // comma separated list of positive or negative integers
   762 		$qv['author']   = preg_replace( '|[^0-9,-]|', '', $qv['author'] ); // comma separated list of positive or negative integers
   735 		$qv['pagename'] = trim( $qv['pagename'] );
   763 		$qv['pagename'] = trim( $qv['pagename'] );
   736 		$qv['name'] = trim( $qv['name'] );
   764 		$qv['name']     = trim( $qv['name'] );
   737 		$qv['title'] = trim( $qv['title'] );
   765 		$qv['title']    = trim( $qv['title'] );
   738 		if ( '' !== $qv['hour'] ) $qv['hour'] = absint($qv['hour']);
   766 		if ( '' !== $qv['hour'] ) {
   739 		if ( '' !== $qv['minute'] ) $qv['minute'] = absint($qv['minute']);
   767 			$qv['hour'] = absint( $qv['hour'] );
   740 		if ( '' !== $qv['second'] ) $qv['second'] = absint($qv['second']);
   768 		}
   741 		if ( '' !== $qv['menu_order'] ) $qv['menu_order'] = absint($qv['menu_order']);
   769 		if ( '' !== $qv['minute'] ) {
       
   770 			$qv['minute'] = absint( $qv['minute'] );
       
   771 		}
       
   772 		if ( '' !== $qv['second'] ) {
       
   773 			$qv['second'] = absint( $qv['second'] );
       
   774 		}
       
   775 		if ( '' !== $qv['menu_order'] ) {
       
   776 			$qv['menu_order'] = absint( $qv['menu_order'] );
       
   777 		}
   742 
   778 
   743 		// Fairly insane upper bound for search string lengths.
   779 		// Fairly insane upper bound for search string lengths.
   744 		if ( ! is_scalar( $qv['s'] ) || ( ! empty( $qv['s'] ) && strlen( $qv['s'] ) > 1600 ) ) {
   780 		if ( ! is_scalar( $qv['s'] ) || ( ! empty( $qv['s'] ) && strlen( $qv['s'] ) > 1600 ) ) {
   745 			$qv['s'] = '';
   781 			$qv['s'] = '';
   746 		}
   782 		}
   747 
   783 
   748 		// Compat. Map subpost to attachment.
   784 		// Compat. Map subpost to attachment.
   749 		if ( '' != $qv['subpost'] )
   785 		if ( '' != $qv['subpost'] ) {
   750 			$qv['attachment'] = $qv['subpost'];
   786 			$qv['attachment'] = $qv['subpost'];
   751 		if ( '' != $qv['subpost_id'] )
   787 		}
       
   788 		if ( '' != $qv['subpost_id'] ) {
   752 			$qv['attachment_id'] = $qv['subpost_id'];
   789 			$qv['attachment_id'] = $qv['subpost_id'];
   753 
   790 		}
   754 		$qv['attachment_id'] = absint($qv['attachment_id']);
   791 
   755 
   792 		$qv['attachment_id'] = absint( $qv['attachment_id'] );
   756 		if ( ('' != $qv['attachment']) || !empty($qv['attachment_id']) ) {
   793 
   757 			$this->is_single = true;
   794 		if ( ( '' != $qv['attachment'] ) || ! empty( $qv['attachment_id'] ) ) {
       
   795 			$this->is_single     = true;
   758 			$this->is_attachment = true;
   796 			$this->is_attachment = true;
   759 		} elseif ( '' != $qv['name'] ) {
   797 		} elseif ( '' != $qv['name'] ) {
   760 			$this->is_single = true;
   798 			$this->is_single = true;
   761 		} elseif ( $qv['p'] ) {
   799 		} elseif ( $qv['p'] ) {
   762 			$this->is_single = true;
   800 			$this->is_single = true;
   763 		} elseif ( ('' !== $qv['hour']) && ('' !== $qv['minute']) &&('' !== $qv['second']) && ('' != $qv['year']) && ('' != $qv['monthnum']) && ('' != $qv['day']) ) {
   801 		} elseif ( ( '' !== $qv['hour'] ) && ( '' !== $qv['minute'] ) && ( '' !== $qv['second'] ) && ( '' != $qv['year'] ) && ( '' != $qv['monthnum'] ) && ( '' != $qv['day'] ) ) {
   764 			// If year, month, day, hour, minute, and second are set, a single
   802 			// If year, month, day, hour, minute, and second are set, a single
   765 			// post is being queried.
   803 			// post is being queried.
   766 			$this->is_single = true;
   804 			$this->is_single = true;
   767 		} elseif ( '' != $qv['static'] || '' != $qv['pagename'] || !empty($qv['page_id']) ) {
   805 		} elseif ( '' != $qv['static'] || '' != $qv['pagename'] || ! empty( $qv['page_id'] ) ) {
   768 			$this->is_page = true;
   806 			$this->is_page   = true;
   769 			$this->is_single = false;
   807 			$this->is_single = false;
   770 		} else {
   808 		} else {
   771 			// Look for archive queries. Dates, categories, authors, search, post type archives.
   809 			// Look for archive queries. Dates, categories, authors, search, post type archives.
   772 
   810 
   773 			if ( isset( $this->query['s'] ) ) {
   811 			if ( isset( $this->query['s'] ) ) {
   793 				if ( ! $this->is_date ) {
   831 				if ( ! $this->is_date ) {
   794 					$date = sprintf( '%04d-%02d-%02d', $qv['year'], $qv['monthnum'], $qv['day'] );
   832 					$date = sprintf( '%04d-%02d-%02d', $qv['year'], $qv['monthnum'], $qv['day'] );
   795 					if ( $qv['monthnum'] && $qv['year'] && ! wp_checkdate( $qv['monthnum'], $qv['day'], $qv['year'], $date ) ) {
   833 					if ( $qv['monthnum'] && $qv['year'] && ! wp_checkdate( $qv['monthnum'], $qv['day'], $qv['year'], $date ) ) {
   796 						$qv['error'] = '404';
   834 						$qv['error'] = '404';
   797 					} else {
   835 					} else {
   798 						$this->is_day = true;
   836 						$this->is_day  = true;
   799 						$this->is_date = true;
   837 						$this->is_date = true;
   800 					}
   838 					}
   801 				}
   839 				}
   802 			}
   840 			}
   803 
   841 
   805 				if ( ! $this->is_date ) {
   843 				if ( ! $this->is_date ) {
   806 					if ( 12 < $qv['monthnum'] ) {
   844 					if ( 12 < $qv['monthnum'] ) {
   807 						$qv['error'] = '404';
   845 						$qv['error'] = '404';
   808 					} else {
   846 					} else {
   809 						$this->is_month = true;
   847 						$this->is_month = true;
   810 						$this->is_date = true;
   848 						$this->is_date  = true;
   811 					}
   849 					}
   812 				}
   850 				}
   813 			}
   851 			}
   814 
   852 
   815 			if ( $qv['year'] ) {
   853 			if ( $qv['year'] ) {
   819 				}
   857 				}
   820 			}
   858 			}
   821 
   859 
   822 			if ( $qv['m'] ) {
   860 			if ( $qv['m'] ) {
   823 				$this->is_date = true;
   861 				$this->is_date = true;
   824 				if ( strlen($qv['m']) > 9 ) {
   862 				if ( strlen( $qv['m'] ) > 9 ) {
   825 					$this->is_time = true;
   863 					$this->is_time = true;
   826 				} elseif ( strlen( $qv['m'] ) > 7 ) {
   864 				} elseif ( strlen( $qv['m'] ) > 7 ) {
   827 					$this->is_day = true;
   865 					$this->is_day = true;
   828 				} elseif ( strlen( $qv['m'] ) > 5 ) {
   866 				} elseif ( strlen( $qv['m'] ) > 5 ) {
   829 					$this->is_month = true;
   867 					$this->is_month = true;
   857 					}
   895 					}
   858 				}
   896 				}
   859 			}
   897 			}
   860 			unset( $tax_query );
   898 			unset( $tax_query );
   861 
   899 
   862 			if ( empty($qv['author']) || ($qv['author'] == '0') ) {
   900 			if ( empty( $qv['author'] ) || ( $qv['author'] == '0' ) ) {
   863 				$this->is_author = false;
   901 				$this->is_author = false;
   864 			} else {
   902 			} else {
   865 				$this->is_author = true;
   903 				$this->is_author = true;
   866 			}
   904 			}
   867 
   905 
   868 			if ( '' != $qv['author_name'] )
   906 			if ( '' != $qv['author_name'] ) {
   869 				$this->is_author = true;
   907 				$this->is_author = true;
   870 
   908 			}
   871 			if ( !empty( $qv['post_type'] ) && ! is_array( $qv['post_type'] ) ) {
   909 
       
   910 			if ( ! empty( $qv['post_type'] ) && ! is_array( $qv['post_type'] ) ) {
   872 				$post_type_obj = get_post_type_object( $qv['post_type'] );
   911 				$post_type_obj = get_post_type_object( $qv['post_type'] );
   873 				if ( ! empty( $post_type_obj->has_archive ) )
   912 				if ( ! empty( $post_type_obj->has_archive ) ) {
   874 					$this->is_post_type_archive = true;
   913 					$this->is_post_type_archive = true;
   875 			}
   914 				}
   876 
   915 			}
   877 			if ( $this->is_post_type_archive || $this->is_date || $this->is_author || $this->is_category || $this->is_tag || $this->is_tax )
   916 
       
   917 			if ( $this->is_post_type_archive || $this->is_date || $this->is_author || $this->is_category || $this->is_tag || $this->is_tax ) {
   878 				$this->is_archive = true;
   918 				$this->is_archive = true;
   879 		}
   919 			}
   880 
   920 		}
   881 		if ( '' != $qv['feed'] )
   921 
       
   922 		if ( '' != $qv['feed'] ) {
   882 			$this->is_feed = true;
   923 			$this->is_feed = true;
       
   924 		}
   883 
   925 
   884 		if ( '' != $qv['embed'] ) {
   926 		if ( '' != $qv['embed'] ) {
   885 			$this->is_embed = true;
   927 			$this->is_embed = true;
   886 		}
   928 		}
   887 
   929 
   888 		if ( '' != $qv['tb'] )
   930 		if ( '' != $qv['tb'] ) {
   889 			$this->is_trackback = true;
   931 			$this->is_trackback = true;
   890 
   932 		}
   891 		if ( '' != $qv['paged'] && ( intval($qv['paged']) > 1 ) )
   933 
       
   934 		if ( '' != $qv['paged'] && ( intval( $qv['paged'] ) > 1 ) ) {
   892 			$this->is_paged = true;
   935 			$this->is_paged = true;
       
   936 		}
   893 
   937 
   894 		// if we're previewing inside the write screen
   938 		// if we're previewing inside the write screen
   895 		if ( '' != $qv['preview'] )
   939 		if ( '' != $qv['preview'] ) {
   896 			$this->is_preview = true;
   940 			$this->is_preview = true;
   897 
   941 		}
   898 		if ( is_admin() )
   942 
       
   943 		if ( is_admin() ) {
   899 			$this->is_admin = true;
   944 			$this->is_admin = true;
   900 
   945 		}
   901 		if ( false !== strpos($qv['feed'], 'comments-') ) {
   946 
   902 			$qv['feed'] = str_replace('comments-', '', $qv['feed']);
   947 		if ( false !== strpos( $qv['feed'], 'comments-' ) ) {
       
   948 			$qv['feed']         = str_replace( 'comments-', '', $qv['feed'] );
   903 			$qv['withcomments'] = 1;
   949 			$qv['withcomments'] = 1;
   904 		}
   950 		}
   905 
   951 
   906 		$this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
   952 		$this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
   907 
   953 
   908 		if ( $this->is_feed && ( !empty($qv['withcomments']) || ( empty($qv['withoutcomments']) && $this->is_singular ) ) )
   954 		if ( $this->is_feed && ( ! empty( $qv['withcomments'] ) || ( empty( $qv['withoutcomments'] ) && $this->is_singular ) ) ) {
   909 			$this->is_comment_feed = true;
   955 			$this->is_comment_feed = true;
   910 
   956 		}
   911 		if ( !( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_robots ) )
   957 
       
   958 		if ( ! ( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_robots ) ) {
   912 			$this->is_home = true;
   959 			$this->is_home = true;
       
   960 		}
   913 
   961 
   914 		// Correct is_* for page_on_front and page_for_posts
   962 		// Correct is_* for page_on_front and page_for_posts
   915 		if ( $this->is_home && 'page' == get_option('show_on_front') && get_option('page_on_front') ) {
   963 		if ( $this->is_home && 'page' == get_option( 'show_on_front' ) && get_option( 'page_on_front' ) ) {
   916 			$_query = wp_parse_args($this->query);
   964 			$_query = wp_parse_args( $this->query );
   917 			// pagename can be set and empty depending on matched rewrite rules. Ignore an empty pagename.
   965 			// pagename can be set and empty depending on matched rewrite rules. Ignore an empty pagename.
   918 			if ( isset($_query['pagename']) && '' == $_query['pagename'] )
   966 			if ( isset( $_query['pagename'] ) && '' == $_query['pagename'] ) {
   919 				unset($_query['pagename']);
   967 				unset( $_query['pagename'] );
       
   968 			}
   920 
   969 
   921 			unset( $_query['embed'] );
   970 			unset( $_query['embed'] );
   922 
   971 
   923 			if ( empty($_query) || !array_diff( array_keys($_query), array('preview', 'page', 'paged', 'cpage') ) ) {
   972 			if ( empty( $_query ) || ! array_diff( array_keys( $_query ), array( 'preview', 'page', 'paged', 'cpage' ) ) ) {
   924 				$this->is_page = true;
   973 				$this->is_page = true;
   925 				$this->is_home = false;
   974 				$this->is_home = false;
   926 				$qv['page_id'] = get_option('page_on_front');
   975 				$qv['page_id'] = get_option( 'page_on_front' );
   927 				// Correct <!--nextpage--> for page_on_front
   976 				// Correct <!--nextpage--> for page_on_front
   928 				if ( !empty($qv['paged']) ) {
   977 				if ( ! empty( $qv['paged'] ) ) {
   929 					$qv['page'] = $qv['paged'];
   978 					$qv['page'] = $qv['paged'];
   930 					unset($qv['paged']);
   979 					unset( $qv['paged'] );
   931 				}
   980 				}
   932 			}
   981 			}
   933 		}
   982 		}
   934 
   983 
   935 		if ( '' != $qv['pagename'] ) {
   984 		if ( '' != $qv['pagename'] ) {
   936 			$this->queried_object = get_page_by_path( $qv['pagename'] );
   985 			$this->queried_object = get_page_by_path( $qv['pagename'] );
   937 
   986 
   938 			if ( $this->queried_object && 'attachment' == $this->queried_object->post_type ) {
   987 			if ( $this->queried_object && 'attachment' == $this->queried_object->post_type ) {
   939 				if ( preg_match( "/^[^%]*%(?:postname)%/", get_option( 'permalink_structure' ) ) ) {
   988 				if ( preg_match( '/^[^%]*%(?:postname)%/', get_option( 'permalink_structure' ) ) ) {
   940 					// See if we also have a post with the same slug
   989 					// See if we also have a post with the same slug
   941 					$post = get_page_by_path( $qv['pagename'], OBJECT, 'post' );
   990 					$post = get_page_by_path( $qv['pagename'], OBJECT, 'post' );
   942 					if ( $post ) {
   991 					if ( $post ) {
   943 						$this->queried_object = $post;
   992 						$this->queried_object = $post;
   944 						$this->is_page = false;
   993 						$this->is_page        = false;
   945 						$this->is_single = true;
   994 						$this->is_single      = true;
   946 					}
   995 					}
   947 				}
   996 				}
   948 			}
   997 			}
   949 
   998 
   950 			if ( ! empty( $this->queried_object ) ) {
   999 			if ( ! empty( $this->queried_object ) ) {
   951 				$this->queried_object_id = (int) $this->queried_object->ID;
  1000 				$this->queried_object_id = (int) $this->queried_object->ID;
   952 			} else {
  1001 			} else {
   953 				unset( $this->queried_object );
  1002 				unset( $this->queried_object );
   954 			}
  1003 			}
   955 
  1004 
   956 			if  ( 'page' == get_option('show_on_front') && isset($this->queried_object_id) && $this->queried_object_id == get_option('page_for_posts') ) {
  1005 			if ( 'page' == get_option( 'show_on_front' ) && isset( $this->queried_object_id ) && $this->queried_object_id == get_option( 'page_for_posts' ) ) {
   957 				$this->is_page = false;
  1006 				$this->is_page       = false;
   958 				$this->is_home = true;
  1007 				$this->is_home       = true;
   959 				$this->is_posts_page = true;
  1008 				$this->is_posts_page = true;
   960 			}
  1009 			}
       
  1010 
       
  1011 			if ( isset( $this->queried_object_id ) && $this->queried_object_id == get_option( 'wp_page_for_privacy_policy' ) ) {
       
  1012 				$this->is_privacy_policy = true;
       
  1013 			}
   961 		}
  1014 		}
   962 
  1015 
   963 		if ( $qv['page_id'] ) {
  1016 		if ( $qv['page_id'] ) {
   964 			if  ( 'page' == get_option('show_on_front') && $qv['page_id'] == get_option('page_for_posts') ) {
  1017 			if ( 'page' == get_option( 'show_on_front' ) && $qv['page_id'] == get_option( 'page_for_posts' ) ) {
   965 				$this->is_page = false;
  1018 				$this->is_page       = false;
   966 				$this->is_home = true;
  1019 				$this->is_home       = true;
   967 				$this->is_posts_page = true;
  1020 				$this->is_posts_page = true;
   968 			}
  1021 			}
   969 		}
  1022 
   970 
  1023 			if ( $qv['page_id'] == get_option( 'wp_page_for_privacy_policy' ) ) {
   971 		if ( !empty($qv['post_type']) ) {
  1024 				$this->is_privacy_policy = true;
   972 			if ( is_array($qv['post_type']) )
  1025 			}
   973 				$qv['post_type'] = array_map('sanitize_key', $qv['post_type']);
  1026 		}
   974 			else
  1027 
   975 				$qv['post_type'] = sanitize_key($qv['post_type']);
  1028 		if ( ! empty( $qv['post_type'] ) ) {
       
  1029 			if ( is_array( $qv['post_type'] ) ) {
       
  1030 				$qv['post_type'] = array_map( 'sanitize_key', $qv['post_type'] );
       
  1031 			} else {
       
  1032 				$qv['post_type'] = sanitize_key( $qv['post_type'] );
       
  1033 			}
   976 		}
  1034 		}
   977 
  1035 
   978 		if ( ! empty( $qv['post_status'] ) ) {
  1036 		if ( ! empty( $qv['post_status'] ) ) {
   979 			if ( is_array( $qv['post_status'] ) )
  1037 			if ( is_array( $qv['post_status'] ) ) {
   980 				$qv['post_status'] = array_map('sanitize_key', $qv['post_status']);
  1038 				$qv['post_status'] = array_map( 'sanitize_key', $qv['post_status'] );
   981 			else
  1039 			} else {
   982 				$qv['post_status'] = preg_replace('|[^a-z0-9_,-]|', '', $qv['post_status']);
  1040 				$qv['post_status'] = preg_replace( '|[^a-z0-9_,-]|', '', $qv['post_status'] );
   983 		}
  1041 			}
   984 
  1042 		}
   985 		if ( $this->is_posts_page && ( ! isset($qv['withcomments']) || ! $qv['withcomments'] ) )
  1043 
       
  1044 		if ( $this->is_posts_page && ( ! isset( $qv['withcomments'] ) || ! $qv['withcomments'] ) ) {
   986 			$this->is_comment_feed = false;
  1045 			$this->is_comment_feed = false;
       
  1046 		}
   987 
  1047 
   988 		$this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
  1048 		$this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
   989 		// Done correcting is_* for page_on_front and page_for_posts
  1049 		// Done correcting is_* for page_on_front and page_for_posts
   990 
  1050 
   991 		if ( '404' == $qv['error'] )
  1051 		if ( '404' == $qv['error'] ) {
   992 			$this->set_404();
  1052 			$this->set_404();
       
  1053 		}
   993 
  1054 
   994 		$this->is_embed = $this->is_embed && ( $this->is_singular || $this->is_404 );
  1055 		$this->is_embed = $this->is_embed && ( $this->is_singular || $this->is_404 );
   995 
  1056 
   996 		$this->query_vars_hash = md5( serialize( $this->query_vars ) );
  1057 		$this->query_vars_hash    = md5( serialize( $this->query_vars ) );
   997 		$this->query_vars_changed = false;
  1058 		$this->query_vars_changed = false;
   998 
  1059 
   999 		/**
  1060 		/**
  1000 		 * Fires after the main query vars have been parsed.
  1061 		 * Fires after the main query vars have been parsed.
  1001 		 *
  1062 		 *
  1020 			$tax_query = $q['tax_query'];
  1081 			$tax_query = $q['tax_query'];
  1021 		} else {
  1082 		} else {
  1022 			$tax_query = array();
  1083 			$tax_query = array();
  1023 		}
  1084 		}
  1024 
  1085 
  1025 		if ( !empty($q['taxonomy']) && !empty($q['term']) ) {
  1086 		if ( ! empty( $q['taxonomy'] ) && ! empty( $q['term'] ) ) {
  1026 			$tax_query[] = array(
  1087 			$tax_query[] = array(
  1027 				'taxonomy' => $q['taxonomy'],
  1088 				'taxonomy' => $q['taxonomy'],
  1028 				'terms' => array( $q['term'] ),
  1089 				'terms'    => array( $q['term'] ),
  1029 				'field' => 'slug',
  1090 				'field'    => 'slug',
  1030 			);
  1091 			);
  1031 		}
  1092 		}
  1032 
  1093 
  1033 		foreach ( get_taxonomies( array() , 'objects' ) as $taxonomy => $t ) {
  1094 		foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy => $t ) {
  1034 			if ( 'post_tag' == $taxonomy )
  1095 			if ( 'post_tag' == $taxonomy ) {
  1035 				continue;	// Handled further down in the $q['tag'] block
  1096 				continue;   // Handled further down in the $q['tag'] block
  1036 
  1097 			}
  1037 			if ( $t->query_var && !empty( $q[$t->query_var] ) ) {
  1098 
       
  1099 			if ( $t->query_var && ! empty( $q[ $t->query_var ] ) ) {
  1038 				$tax_query_defaults = array(
  1100 				$tax_query_defaults = array(
  1039 					'taxonomy' => $taxonomy,
  1101 					'taxonomy' => $taxonomy,
  1040 					'field' => 'slug',
  1102 					'field'    => 'slug',
  1041 				);
  1103 				);
  1042 
  1104 
  1043  				if ( isset( $t->rewrite['hierarchical'] ) && $t->rewrite['hierarchical'] ) {
  1105 				if ( isset( $t->rewrite['hierarchical'] ) && $t->rewrite['hierarchical'] ) {
  1044 					$q[$t->query_var] = wp_basename( $q[$t->query_var] );
  1106 					$q[ $t->query_var ] = wp_basename( $q[ $t->query_var ] );
  1045 				}
  1107 				}
  1046 
  1108 
  1047 				$term = $q[$t->query_var];
  1109 				$term = $q[ $t->query_var ];
  1048 
  1110 
  1049 				if ( is_array( $term ) ) {
  1111 				if ( is_array( $term ) ) {
  1050 					$term = implode( ',', $term );
  1112 					$term = implode( ',', $term );
  1051 				}
  1113 				}
  1052 
  1114 
  1053 				if ( strpos($term, '+') !== false ) {
  1115 				if ( strpos( $term, '+' ) !== false ) {
  1054 					$terms = preg_split( '/[+]+/', $term );
  1116 					$terms = preg_split( '/[+]+/', $term );
  1055 					foreach ( $terms as $term ) {
  1117 					foreach ( $terms as $term ) {
  1056 						$tax_query[] = array_merge( $tax_query_defaults, array(
  1118 						$tax_query[] = array_merge(
  1057 							'terms' => array( $term )
  1119 							$tax_query_defaults,
  1058 						) );
  1120 							array(
       
  1121 								'terms' => array( $term ),
       
  1122 							)
       
  1123 						);
  1059 					}
  1124 					}
  1060 				} else {
  1125 				} else {
  1061 					$tax_query[] = array_merge( $tax_query_defaults, array(
  1126 					$tax_query[] = array_merge(
  1062 						'terms' => preg_split( '/[,]+/', $term )
  1127 						$tax_query_defaults,
  1063 					) );
  1128 						array(
       
  1129 							'terms' => preg_split( '/[,]+/', $term ),
       
  1130 						)
       
  1131 					);
  1064 				}
  1132 				}
  1065 			}
  1133 			}
  1066 		}
  1134 		}
  1067 
  1135 
  1068 		// If querystring 'cat' is an array, implode it.
  1136 		// If querystring 'cat' is an array, implode it.
  1074 		if ( ! empty( $q['cat'] ) && ! $this->is_singular ) {
  1142 		if ( ! empty( $q['cat'] ) && ! $this->is_singular ) {
  1075 			$cat_in = $cat_not_in = array();
  1143 			$cat_in = $cat_not_in = array();
  1076 
  1144 
  1077 			$cat_array = preg_split( '/[,\s]+/', urldecode( $q['cat'] ) );
  1145 			$cat_array = preg_split( '/[,\s]+/', urldecode( $q['cat'] ) );
  1078 			$cat_array = array_map( 'intval', $cat_array );
  1146 			$cat_array = array_map( 'intval', $cat_array );
  1079 			$q['cat'] = implode( ',', $cat_array );
  1147 			$q['cat']  = implode( ',', $cat_array );
  1080 
  1148 
  1081 			foreach ( $cat_array as $cat ) {
  1149 			foreach ( $cat_array as $cat ) {
  1082 				if ( $cat > 0 )
  1150 				if ( $cat > 0 ) {
  1083 					$cat_in[] = $cat;
  1151 					$cat_in[] = $cat;
  1084 				elseif ( $cat < 0 )
  1152 				} elseif ( $cat < 0 ) {
  1085 					$cat_not_in[] = abs( $cat );
  1153 					$cat_not_in[] = abs( $cat );
       
  1154 				}
  1086 			}
  1155 			}
  1087 
  1156 
  1088 			if ( ! empty( $cat_in ) ) {
  1157 			if ( ! empty( $cat_in ) ) {
  1089 				$tax_query[] = array(
  1158 				$tax_query[] = array(
  1090 					'taxonomy' => 'category',
  1159 					'taxonomy'         => 'category',
  1091 					'terms' => $cat_in,
  1160 					'terms'            => $cat_in,
  1092 					'field' => 'term_id',
  1161 					'field'            => 'term_id',
  1093 					'include_children' => true
  1162 					'include_children' => true,
  1094 				);
  1163 				);
  1095 			}
  1164 			}
  1096 
  1165 
  1097 			if ( ! empty( $cat_not_in ) ) {
  1166 			if ( ! empty( $cat_not_in ) ) {
  1098 				$tax_query[] = array(
  1167 				$tax_query[] = array(
  1099 					'taxonomy' => 'category',
  1168 					'taxonomy'         => 'category',
  1100 					'terms' => $cat_not_in,
  1169 					'terms'            => $cat_not_in,
  1101 					'field' => 'term_id',
  1170 					'field'            => 'term_id',
  1102 					'operator' => 'NOT IN',
  1171 					'operator'         => 'NOT IN',
  1103 					'include_children' => true
  1172 					'include_children' => true,
  1104 				);
  1173 				);
  1105 			}
  1174 			}
  1106 			unset( $cat_array, $cat_in, $cat_not_in );
  1175 			unset( $cat_array, $cat_in, $cat_not_in );
  1107 		}
  1176 		}
  1108 
  1177 
  1109 		if ( ! empty( $q['category__and'] ) && 1 === count( (array) $q['category__and'] ) ) {
  1178 		if ( ! empty( $q['category__and'] ) && 1 === count( (array) $q['category__and'] ) ) {
  1110 			$q['category__and'] = (array) $q['category__and'];
  1179 			$q['category__and'] = (array) $q['category__and'];
  1111 			if ( ! isset( $q['category__in'] ) )
  1180 			if ( ! isset( $q['category__in'] ) ) {
  1112 				$q['category__in'] = array();
  1181 				$q['category__in'] = array();
       
  1182 			}
  1113 			$q['category__in'][] = absint( reset( $q['category__and'] ) );
  1183 			$q['category__in'][] = absint( reset( $q['category__and'] ) );
  1114 			unset( $q['category__and'] );
  1184 			unset( $q['category__and'] );
  1115 		}
  1185 		}
  1116 
  1186 
  1117 		if ( ! empty( $q['category__in'] ) ) {
  1187 		if ( ! empty( $q['category__in'] ) ) {
  1118 			$q['category__in'] = array_map( 'absint', array_unique( (array) $q['category__in'] ) );
  1188 			$q['category__in'] = array_map( 'absint', array_unique( (array) $q['category__in'] ) );
  1119 			$tax_query[] = array(
  1189 			$tax_query[]       = array(
  1120 				'taxonomy' => 'category',
  1190 				'taxonomy'         => 'category',
  1121 				'terms' => $q['category__in'],
  1191 				'terms'            => $q['category__in'],
  1122 				'field' => 'term_id',
  1192 				'field'            => 'term_id',
  1123 				'include_children' => false
  1193 				'include_children' => false,
  1124 			);
  1194 			);
  1125 		}
  1195 		}
  1126 
  1196 
  1127 		if ( ! empty($q['category__not_in']) ) {
  1197 		if ( ! empty( $q['category__not_in'] ) ) {
  1128 			$q['category__not_in'] = array_map( 'absint', array_unique( (array) $q['category__not_in'] ) );
  1198 			$q['category__not_in'] = array_map( 'absint', array_unique( (array) $q['category__not_in'] ) );
  1129 			$tax_query[] = array(
  1199 			$tax_query[]           = array(
  1130 				'taxonomy' => 'category',
  1200 				'taxonomy'         => 'category',
  1131 				'terms' => $q['category__not_in'],
  1201 				'terms'            => $q['category__not_in'],
  1132 				'operator' => 'NOT IN',
  1202 				'operator'         => 'NOT IN',
  1133 				'include_children' => false
  1203 				'include_children' => false,
  1134 			);
  1204 			);
  1135 		}
  1205 		}
  1136 
  1206 
  1137 		if ( ! empty($q['category__and']) ) {
  1207 		if ( ! empty( $q['category__and'] ) ) {
  1138 			$q['category__and'] = array_map( 'absint', array_unique( (array) $q['category__and'] ) );
  1208 			$q['category__and'] = array_map( 'absint', array_unique( (array) $q['category__and'] ) );
  1139 			$tax_query[] = array(
  1209 			$tax_query[]        = array(
  1140 				'taxonomy' => 'category',
  1210 				'taxonomy'         => 'category',
  1141 				'terms' => $q['category__and'],
  1211 				'terms'            => $q['category__and'],
  1142 				'field' => 'term_id',
  1212 				'field'            => 'term_id',
  1143 				'operator' => 'AND',
  1213 				'operator'         => 'AND',
  1144 				'include_children' => false
  1214 				'include_children' => false,
  1145 			);
  1215 			);
  1146 		}
  1216 		}
  1147 
  1217 
  1148 		// If querystring 'tag' is array, implode it.
  1218 		// If querystring 'tag' is array, implode it.
  1149 		if ( is_array( $q['tag'] ) ) {
  1219 		if ( is_array( $q['tag'] ) ) {
  1150 			$q['tag'] = implode( ',', $q['tag'] );
  1220 			$q['tag'] = implode( ',', $q['tag'] );
  1151 		}
  1221 		}
  1152 
  1222 
  1153 		// Tag stuff
  1223 		// Tag stuff
  1154 		if ( '' != $q['tag'] && !$this->is_singular && $this->query_vars_changed ) {
  1224 		if ( '' != $q['tag'] && ! $this->is_singular && $this->query_vars_changed ) {
  1155 			if ( strpos($q['tag'], ',') !== false ) {
  1225 			if ( strpos( $q['tag'], ',' ) !== false ) {
  1156 				$tags = preg_split('/[,\r\n\t ]+/', $q['tag']);
  1226 				$tags = preg_split( '/[,\r\n\t ]+/', $q['tag'] );
  1157 				foreach ( (array) $tags as $tag ) {
  1227 				foreach ( (array) $tags as $tag ) {
  1158 					$tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
  1228 					$tag                 = sanitize_term_field( 'slug', $tag, 0, 'post_tag', 'db' );
  1159 					$q['tag_slug__in'][] = $tag;
  1229 					$q['tag_slug__in'][] = $tag;
  1160 				}
  1230 				}
  1161 			} elseif ( preg_match('/[+\r\n\t ]+/', $q['tag'] ) || ! empty( $q['cat'] ) ) {
  1231 			} elseif ( preg_match( '/[+\r\n\t ]+/', $q['tag'] ) || ! empty( $q['cat'] ) ) {
  1162 				$tags = preg_split('/[+\r\n\t ]+/', $q['tag']);
  1232 				$tags = preg_split( '/[+\r\n\t ]+/', $q['tag'] );
  1163 				foreach ( (array) $tags as $tag ) {
  1233 				foreach ( (array) $tags as $tag ) {
  1164 					$tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
  1234 					$tag                  = sanitize_term_field( 'slug', $tag, 0, 'post_tag', 'db' );
  1165 					$q['tag_slug__and'][] = $tag;
  1235 					$q['tag_slug__and'][] = $tag;
  1166 				}
  1236 				}
  1167 			} else {
  1237 			} else {
  1168 				$q['tag'] = sanitize_term_field('slug', $q['tag'], 0, 'post_tag', 'db');
  1238 				$q['tag']            = sanitize_term_field( 'slug', $q['tag'], 0, 'post_tag', 'db' );
  1169 				$q['tag_slug__in'][] = $q['tag'];
  1239 				$q['tag_slug__in'][] = $q['tag'];
  1170 			}
  1240 			}
  1171 		}
  1241 		}
  1172 
  1242 
  1173 		if ( !empty($q['tag_id']) ) {
  1243 		if ( ! empty( $q['tag_id'] ) ) {
  1174 			$q['tag_id'] = absint( $q['tag_id'] );
  1244 			$q['tag_id'] = absint( $q['tag_id'] );
  1175 			$tax_query[] = array(
  1245 			$tax_query[] = array(
  1176 				'taxonomy' => 'post_tag',
  1246 				'taxonomy' => 'post_tag',
  1177 				'terms' => $q['tag_id']
  1247 				'terms'    => $q['tag_id'],
  1178 			);
  1248 			);
  1179 		}
  1249 		}
  1180 
  1250 
  1181 		if ( !empty($q['tag__in']) ) {
  1251 		if ( ! empty( $q['tag__in'] ) ) {
  1182 			$q['tag__in'] = array_map('absint', array_unique( (array) $q['tag__in'] ) );
  1252 			$q['tag__in'] = array_map( 'absint', array_unique( (array) $q['tag__in'] ) );
  1183 			$tax_query[] = array(
  1253 			$tax_query[]  = array(
  1184 				'taxonomy' => 'post_tag',
  1254 				'taxonomy' => 'post_tag',
  1185 				'terms' => $q['tag__in']
  1255 				'terms'    => $q['tag__in'],
  1186 			);
  1256 			);
  1187 		}
  1257 		}
  1188 
  1258 
  1189 		if ( !empty($q['tag__not_in']) ) {
  1259 		if ( ! empty( $q['tag__not_in'] ) ) {
  1190 			$q['tag__not_in'] = array_map('absint', array_unique( (array) $q['tag__not_in'] ) );
  1260 			$q['tag__not_in'] = array_map( 'absint', array_unique( (array) $q['tag__not_in'] ) );
  1191 			$tax_query[] = array(
  1261 			$tax_query[]      = array(
  1192 				'taxonomy' => 'post_tag',
  1262 				'taxonomy' => 'post_tag',
  1193 				'terms' => $q['tag__not_in'],
  1263 				'terms'    => $q['tag__not_in'],
  1194 				'operator' => 'NOT IN'
  1264 				'operator' => 'NOT IN',
  1195 			);
  1265 			);
  1196 		}
  1266 		}
  1197 
  1267 
  1198 		if ( !empty($q['tag__and']) ) {
  1268 		if ( ! empty( $q['tag__and'] ) ) {
  1199 			$q['tag__and'] = array_map('absint', array_unique( (array) $q['tag__and'] ) );
  1269 			$q['tag__and'] = array_map( 'absint', array_unique( (array) $q['tag__and'] ) );
  1200 			$tax_query[] = array(
  1270 			$tax_query[]   = array(
  1201 				'taxonomy' => 'post_tag',
  1271 				'taxonomy' => 'post_tag',
  1202 				'terms' => $q['tag__and'],
  1272 				'terms'    => $q['tag__and'],
  1203 				'operator' => 'AND'
  1273 				'operator' => 'AND',
  1204 			);
  1274 			);
  1205 		}
  1275 		}
  1206 
  1276 
  1207 		if ( !empty($q['tag_slug__in']) ) {
  1277 		if ( ! empty( $q['tag_slug__in'] ) ) {
  1208 			$q['tag_slug__in'] = array_map('sanitize_title_for_query', array_unique( (array) $q['tag_slug__in'] ) );
  1278 			$q['tag_slug__in'] = array_map( 'sanitize_title_for_query', array_unique( (array) $q['tag_slug__in'] ) );
  1209 			$tax_query[] = array(
  1279 			$tax_query[]       = array(
  1210 				'taxonomy' => 'post_tag',
  1280 				'taxonomy' => 'post_tag',
  1211 				'terms' => $q['tag_slug__in'],
  1281 				'terms'    => $q['tag_slug__in'],
  1212 				'field' => 'slug'
  1282 				'field'    => 'slug',
  1213 			);
  1283 			);
  1214 		}
  1284 		}
  1215 
  1285 
  1216 		if ( !empty($q['tag_slug__and']) ) {
  1286 		if ( ! empty( $q['tag_slug__and'] ) ) {
  1217 			$q['tag_slug__and'] = array_map('sanitize_title_for_query', array_unique( (array) $q['tag_slug__and'] ) );
  1287 			$q['tag_slug__and'] = array_map( 'sanitize_title_for_query', array_unique( (array) $q['tag_slug__and'] ) );
  1218 			$tax_query[] = array(
  1288 			$tax_query[]        = array(
  1219 				'taxonomy' => 'post_tag',
  1289 				'taxonomy' => 'post_tag',
  1220 				'terms' => $q['tag_slug__and'],
  1290 				'terms'    => $q['tag_slug__and'],
  1221 				'field' => 'slug',
  1291 				'field'    => 'slug',
  1222 				'operator' => 'AND'
  1292 				'operator' => 'AND',
  1223 			);
  1293 			);
  1224 		}
  1294 		}
  1225 
  1295 
  1226 		$this->tax_query = new WP_Tax_Query( $tax_query );
  1296 		$this->tax_query = new WP_Tax_Query( $tax_query );
  1227 
  1297 
  1250 
  1320 
  1251 		$search = '';
  1321 		$search = '';
  1252 
  1322 
  1253 		// added slashes screw with quote grouping when done early, so done later
  1323 		// added slashes screw with quote grouping when done early, so done later
  1254 		$q['s'] = stripslashes( $q['s'] );
  1324 		$q['s'] = stripslashes( $q['s'] );
  1255 		if ( empty( $_GET['s'] ) && $this->is_main_query() )
  1325 		if ( empty( $_GET['s'] ) && $this->is_main_query() ) {
  1256 			$q['s'] = urldecode( $q['s'] );
  1326 			$q['s'] = urldecode( $q['s'] );
       
  1327 		}
  1257 		// there are no line breaks in <input /> fields
  1328 		// there are no line breaks in <input /> fields
  1258 		$q['s'] = str_replace( array( "\r", "\n" ), '', $q['s'] );
  1329 		$q['s']                  = str_replace( array( "\r", "\n" ), '', $q['s'] );
  1259 		$q['search_terms_count'] = 1;
  1330 		$q['search_terms_count'] = 1;
  1260 		if ( ! empty( $q['sentence'] ) ) {
  1331 		if ( ! empty( $q['sentence'] ) ) {
  1261 			$q['search_terms'] = array( $q['s'] );
  1332 			$q['search_terms'] = array( $q['s'] );
  1262 		} else {
  1333 		} else {
  1263 			if ( preg_match_all( '/".*?("|$)|((?<=[\t ",+])|^)[^\t ",+]+/', $q['s'], $matches ) ) {
  1334 			if ( preg_match_all( '/".*?("|$)|((?<=[\t ",+])|^)[^\t ",+]+/', $q['s'], $matches ) ) {
  1264 				$q['search_terms_count'] = count( $matches[0] );
  1335 				$q['search_terms_count'] = count( $matches[0] );
  1265 				$q['search_terms'] = $this->parse_search_terms( $matches[0] );
  1336 				$q['search_terms']       = $this->parse_search_terms( $matches[0] );
  1266 				// if the search string has only short terms or stopwords, or is 10+ terms long, match it as sentence
  1337 				// if the search string has only short terms or stopwords, or is 10+ terms long, match it as sentence
  1267 				if ( empty( $q['search_terms'] ) || count( $q['search_terms'] ) > 9 )
  1338 				if ( empty( $q['search_terms'] ) || count( $q['search_terms'] ) > 9 ) {
  1268 					$q['search_terms'] = array( $q['s'] );
  1339 					$q['search_terms'] = array( $q['s'] );
       
  1340 				}
  1269 			} else {
  1341 			} else {
  1270 				$q['search_terms'] = array( $q['s'] );
  1342 				$q['search_terms'] = array( $q['s'] );
  1271 			}
  1343 			}
  1272 		}
  1344 		}
  1273 
  1345 
  1274 		$n = ! empty( $q['exact'] ) ? '' : '%';
  1346 		$n                         = ! empty( $q['exact'] ) ? '' : '%';
  1275 		$searchand = '';
  1347 		$searchand                 = '';
  1276 		$q['search_orderby_title'] = array();
  1348 		$q['search_orderby_title'] = array();
  1277 
  1349 
  1278 		/**
  1350 		/**
  1279 		 * Filters the prefix that indicates that a search term should be excluded from results.
  1351 		 * Filters the prefix that indicates that a search term should be excluded from results.
  1280 		 *
  1352 		 *
  1296 				$like_op  = 'LIKE';
  1368 				$like_op  = 'LIKE';
  1297 				$andor_op = 'OR';
  1369 				$andor_op = 'OR';
  1298 			}
  1370 			}
  1299 
  1371 
  1300 			if ( $n && ! $exclude ) {
  1372 			if ( $n && ! $exclude ) {
  1301 				$like = '%' . $wpdb->esc_like( $term ) . '%';
  1373 				$like                        = '%' . $wpdb->esc_like( $term ) . '%';
  1302 				$q['search_orderby_title'][] = $wpdb->prepare( "{$wpdb->posts}.post_title LIKE %s", $like );
  1374 				$q['search_orderby_title'][] = $wpdb->prepare( "{$wpdb->posts}.post_title LIKE %s", $like );
  1303 			}
  1375 			}
  1304 
  1376 
  1305 			$like = $n . $wpdb->esc_like( $term ) . $n;
  1377 			$like      = $n . $wpdb->esc_like( $term ) . $n;
  1306 			$search .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s))", $like, $like, $like );
  1378 			$search   .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s))", $like, $like, $like );
  1307 			$searchand = ' AND ';
  1379 			$searchand = ' AND ';
  1308 		}
  1380 		}
  1309 
  1381 
  1310 		if ( ! empty( $search ) ) {
  1382 		if ( ! empty( $search ) ) {
  1311 			$search = " AND ({$search}) ";
  1383 			$search = " AND ({$search}) ";
  1324 	 * term matching when searching for posts. The list of English stopwords is
  1396 	 * term matching when searching for posts. The list of English stopwords is
  1325 	 * the approximate search engines list, and is translatable.
  1397 	 * the approximate search engines list, and is translatable.
  1326 	 *
  1398 	 *
  1327 	 * @since 3.7.0
  1399 	 * @since 3.7.0
  1328 	 *
  1400 	 *
  1329 	 * @param array $terms Terms to check.
  1401 	 * @param string[] $terms Array of terms to check.
  1330 	 * @return array Terms that are not stopwords.
  1402 	 * @return array Terms that are not stopwords.
  1331 	 */
  1403 	 */
  1332 	protected function parse_search_terms( $terms ) {
  1404 	protected function parse_search_terms( $terms ) {
  1333 		$strtolower = function_exists( 'mb_strtolower' ) ? 'mb_strtolower' : 'strtolower';
  1405 		$strtolower = function_exists( 'mb_strtolower' ) ? 'mb_strtolower' : 'strtolower';
  1334 		$checked = array();
  1406 		$checked    = array();
  1335 
  1407 
  1336 		$stopwords = $this->get_search_stopwords();
  1408 		$stopwords = $this->get_search_stopwords();
  1337 
  1409 
  1338 		foreach ( $terms as $term ) {
  1410 		foreach ( $terms as $term ) {
  1339 			// keep before/after spaces when term is for exact match
  1411 			// keep before/after spaces when term is for exact match
  1340 			if ( preg_match( '/^".+"$/', $term ) )
  1412 			if ( preg_match( '/^".+"$/', $term ) ) {
  1341 				$term = trim( $term, "\"'" );
  1413 				$term = trim( $term, "\"'" );
  1342 			else
  1414 			} else {
  1343 				$term = trim( $term, "\"' " );
  1415 				$term = trim( $term, "\"' " );
       
  1416 			}
  1344 
  1417 
  1345 			// Avoid single A-Z and single dashes.
  1418 			// Avoid single A-Z and single dashes.
  1346 			if ( ! $term || ( 1 === strlen( $term ) && preg_match( '/^[a-z\-]$/i', $term ) ) )
  1419 			if ( ! $term || ( 1 === strlen( $term ) && preg_match( '/^[a-z\-]$/i', $term ) ) ) {
  1347 				continue;
  1420 				continue;
  1348 
  1421 			}
  1349 			if ( in_array( call_user_func( $strtolower, $term ), $stopwords, true ) )
  1422 
       
  1423 			if ( in_array( call_user_func( $strtolower, $term ), $stopwords, true ) ) {
  1350 				continue;
  1424 				continue;
       
  1425 			}
  1351 
  1426 
  1352 			$checked[] = $term;
  1427 			$checked[] = $term;
  1353 		}
  1428 		}
  1354 
  1429 
  1355 		return $checked;
  1430 		return $checked;
  1361 	 * @since 3.7.0
  1436 	 * @since 3.7.0
  1362 	 *
  1437 	 *
  1363 	 * @return array Stopwords.
  1438 	 * @return array Stopwords.
  1364 	 */
  1439 	 */
  1365 	protected function get_search_stopwords() {
  1440 	protected function get_search_stopwords() {
  1366 		if ( isset( $this->stopwords ) )
  1441 		if ( isset( $this->stopwords ) ) {
  1367 			return $this->stopwords;
  1442 			return $this->stopwords;
       
  1443 		}
  1368 
  1444 
  1369 		/* translators: This is a comma-separated list of very common words that should be excluded from a search,
  1445 		/* translators: This is a comma-separated list of very common words that should be excluded from a search,
  1370 		 * like a, an, and the. These are usually called "stopwords". You should not simply translate these individual
  1446 		 * like a, an, and the. These are usually called "stopwords". You should not simply translate these individual
  1371 		 * words into your language. Instead, look for and provide commonly accepted stopwords in your language.
  1447 		 * words into your language. Instead, look for and provide commonly accepted stopwords in your language.
  1372 		 */
  1448 		 */
  1373 		$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',
  1449 		$words = explode(
  1374 			'Comma-separated list of search stopwords in your language' ) );
  1450 			',',
       
  1451 			_x(
       
  1452 				'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',
       
  1453 				'Comma-separated list of search stopwords in your language'
       
  1454 			)
       
  1455 		);
  1375 
  1456 
  1376 		$stopwords = array();
  1457 		$stopwords = array();
  1377 		foreach ( $words as $word ) {
  1458 		foreach ( $words as $word ) {
  1378 			$word = trim( $word, "\r\n\t " );
  1459 			$word = trim( $word, "\r\n\t " );
  1379 			if ( $word )
  1460 			if ( $word ) {
  1380 				$stopwords[] = $word;
  1461 				$stopwords[] = $word;
       
  1462 			}
  1381 		}
  1463 		}
  1382 
  1464 
  1383 		/**
  1465 		/**
  1384 		 * Filters stopwords used when parsing search terms.
  1466 		 * Filters stopwords used when parsing search terms.
  1385 		 *
  1467 		 *
  1386 		 * @since 3.7.0
  1468 		 * @since 3.7.0
  1387 		 *
  1469 		 *
  1388 		 * @param array $stopwords Stopwords.
  1470 		 * @param string[] $stopwords Array of stopwords.
  1389 		 */
  1471 		 */
  1390 		$this->stopwords = apply_filters( 'wp_search_stopwords', $stopwords );
  1472 		$this->stopwords = apply_filters( 'wp_search_stopwords', $stopwords );
  1391 		return $this->stopwords;
  1473 		return $this->stopwords;
  1392 	}
  1474 	}
  1393 
  1475 
  1424 			// (few searches are longer than 6 terms and most titles are not)
  1506 			// (few searches are longer than 6 terms and most titles are not)
  1425 			if ( $num_terms < 7 ) {
  1507 			if ( $num_terms < 7 ) {
  1426 				// all words in title
  1508 				// all words in title
  1427 				$search_orderby .= 'WHEN ' . implode( ' AND ', $q['search_orderby_title'] ) . ' THEN 2 ';
  1509 				$search_orderby .= 'WHEN ' . implode( ' AND ', $q['search_orderby_title'] ) . ' THEN 2 ';
  1428 				// any word in title, not needed when $num_terms == 1
  1510 				// any word in title, not needed when $num_terms == 1
  1429 				if ( $num_terms > 1 )
  1511 				if ( $num_terms > 1 ) {
  1430 					$search_orderby .= 'WHEN ' . implode( ' OR ', $q['search_orderby_title'] ) . ' THEN 3 ';
  1512 					$search_orderby .= 'WHEN ' . implode( ' OR ', $q['search_orderby_title'] ) . ' THEN 3 ';
       
  1513 				}
  1431 			}
  1514 			}
  1432 
  1515 
  1433 			// Sentence match in 'post_content' and 'post_excerpt'.
  1516 			// Sentence match in 'post_content' and 'post_excerpt'.
  1434 			if ( $like ) {
  1517 			if ( $like ) {
  1435 				$search_orderby .= $wpdb->prepare( "WHEN {$wpdb->posts}.post_excerpt LIKE %s THEN 4 ", $like );
  1518 				$search_orderby .= $wpdb->prepare( "WHEN {$wpdb->posts}.post_excerpt LIKE %s THEN 4 ", $like );
  1460 	protected function parse_orderby( $orderby ) {
  1543 	protected function parse_orderby( $orderby ) {
  1461 		global $wpdb;
  1544 		global $wpdb;
  1462 
  1545 
  1463 		// Used to filter values.
  1546 		// Used to filter values.
  1464 		$allowed_keys = array(
  1547 		$allowed_keys = array(
  1465 			'post_name', 'post_author', 'post_date', 'post_title', 'post_modified',
  1548 			'post_name',
  1466 			'post_parent', 'post_type', 'name', 'author', 'date', 'title', 'modified',
  1549 			'post_author',
  1467 			'parent', 'type', 'ID', 'menu_order', 'comment_count', 'rand',
  1550 			'post_date',
       
  1551 			'post_title',
       
  1552 			'post_modified',
       
  1553 			'post_parent',
       
  1554 			'post_type',
       
  1555 			'name',
       
  1556 			'author',
       
  1557 			'date',
       
  1558 			'title',
       
  1559 			'modified',
       
  1560 			'parent',
       
  1561 			'type',
       
  1562 			'ID',
       
  1563 			'menu_order',
       
  1564 			'comment_count',
       
  1565 			'rand',
       
  1566 			'post__in',
       
  1567 			'post_parent__in',
       
  1568 			'post_name__in',
  1468 		);
  1569 		);
  1469 
  1570 
  1470 		$primary_meta_key = '';
  1571 		$primary_meta_key   = '';
  1471 		$primary_meta_query = false;
  1572 		$primary_meta_query = false;
  1472 		$meta_clauses = $this->meta_query->get_clauses();
  1573 		$meta_clauses       = $this->meta_query->get_clauses();
  1473 		if ( ! empty( $meta_clauses ) ) {
  1574 		if ( ! empty( $meta_clauses ) ) {
  1474 			$primary_meta_query = reset( $meta_clauses );
  1575 			$primary_meta_query = reset( $meta_clauses );
  1475 
  1576 
  1476 			if ( ! empty( $primary_meta_query['key'] ) ) {
  1577 			if ( ! empty( $primary_meta_query['key'] ) ) {
  1477 				$primary_meta_key = $primary_meta_query['key'];
  1578 				$primary_meta_key = $primary_meta_query['key'];
  1478 				$allowed_keys[] = $primary_meta_key;
  1579 				$allowed_keys[]   = $primary_meta_key;
  1479 			}
  1580 			}
  1480 
  1581 
  1481 			$allowed_keys[] = 'meta_value';
  1582 			$allowed_keys[] = 'meta_value';
  1482 			$allowed_keys[] = 'meta_value_num';
  1583 			$allowed_keys[] = 'meta_value_num';
  1483 			$allowed_keys   = array_merge( $allowed_keys, array_keys( $meta_clauses ) );
  1584 			$allowed_keys   = array_merge( $allowed_keys, array_keys( $meta_clauses ) );
  1484 		}
  1585 		}
  1485 
  1586 
  1486 		// If RAND() contains a seed value, sanitize and add to allowed keys.
  1587 		// If RAND() contains a seed value, sanitize and add to allowed keys.
  1487 		$rand_with_seed = false;
  1588 		$rand_with_seed = false;
  1488 		if ( preg_match( '/RAND\(([0-9]+)\)/i', $orderby, $matches ) ) {
  1589 		if ( preg_match( '/RAND\(([0-9]+)\)/i', $orderby, $matches ) ) {
  1489 			$orderby = sprintf( 'RAND(%s)', intval( $matches[1] ) );
  1590 			$orderby        = sprintf( 'RAND(%s)', intval( $matches[1] ) );
  1490 			$allowed_keys[] = $orderby;
  1591 			$allowed_keys[] = $orderby;
  1491 			$rand_with_seed = true;
  1592 			$rand_with_seed = true;
  1492 		}
  1593 		}
  1493 
  1594 
  1494 		if ( ! in_array( $orderby, $allowed_keys, true ) ) {
  1595 		if ( ! in_array( $orderby, $allowed_keys, true ) ) {
  1495 			return false;
  1596 			return false;
  1496 		}
  1597 		}
       
  1598 
       
  1599 		$orderby_clause = '';
  1497 
  1600 
  1498 		switch ( $orderby ) {
  1601 		switch ( $orderby ) {
  1499 			case 'post_name':
  1602 			case 'post_name':
  1500 			case 'post_author':
  1603 			case 'post_author':
  1501 			case 'post_date':
  1604 			case 'post_date':
  1520 				}
  1623 				}
  1521 				break;
  1624 				break;
  1522 			case 'meta_value_num':
  1625 			case 'meta_value_num':
  1523 				$orderby_clause = "{$primary_meta_query['alias']}.meta_value+0";
  1626 				$orderby_clause = "{$primary_meta_query['alias']}.meta_value+0";
  1524 				break;
  1627 				break;
       
  1628 			case 'post__in':
       
  1629 				if ( ! empty( $this->query_vars['post__in'] ) ) {
       
  1630 					$orderby_clause = "FIELD({$wpdb->posts}.ID," . implode( ',', array_map( 'absint', $this->query_vars['post__in'] ) ) . ')';
       
  1631 				}
       
  1632 				break;
       
  1633 			case 'post_parent__in':
       
  1634 				if ( ! empty( $this->query_vars['post_parent__in'] ) ) {
       
  1635 					$orderby_clause = "FIELD( {$wpdb->posts}.post_parent," . implode( ', ', array_map( 'absint', $this->query_vars['post_parent__in'] ) ) . ' )';
       
  1636 				}
       
  1637 				break;
       
  1638 			case 'post_name__in':
       
  1639 				if ( ! empty( $this->query_vars['post_name__in'] ) ) {
       
  1640 					$post_name__in        = array_map( 'sanitize_title_for_query', $this->query_vars['post_name__in'] );
       
  1641 					$post_name__in_string = "'" . implode( "','", $post_name__in ) . "'";
       
  1642 					$orderby_clause       = "FIELD( {$wpdb->posts}.post_name," . $post_name__in_string . ' )';
       
  1643 				}
       
  1644 				break;
  1525 			default:
  1645 			default:
  1526 				if ( array_key_exists( $orderby, $meta_clauses ) ) {
  1646 				if ( array_key_exists( $orderby, $meta_clauses ) ) {
  1527 					// $orderby corresponds to a meta_query clause.
  1647 					// $orderby corresponds to a meta_query clause.
  1528 					$meta_clause = $meta_clauses[ $orderby ];
  1648 					$meta_clause    = $meta_clauses[ $orderby ];
  1529 					$orderby_clause = "CAST({$meta_clause['alias']}.meta_value AS {$meta_clause['cast']})";
  1649 					$orderby_clause = "CAST({$meta_clause['alias']}.meta_value AS {$meta_clause['cast']})";
  1530 				} elseif ( $rand_with_seed ) {
  1650 				} elseif ( $rand_with_seed ) {
  1531 					$orderby_clause = $orderby;
  1651 					$orderby_clause = $orderby;
  1532 				} else {
  1652 				} else {
  1533 					// Default: order by post field.
  1653 					// Default: order by post field.
  1578 	 * Retrieve query variable.
  1698 	 * Retrieve query variable.
  1579 	 *
  1699 	 *
  1580 	 * @since 1.5.0
  1700 	 * @since 1.5.0
  1581 	 * @since 3.9.0 The `$default` argument was introduced.
  1701 	 * @since 3.9.0 The `$default` argument was introduced.
  1582 	 *
  1702 	 *
  1583 	 *
       
  1584 	 * @param string $query_var Query variable key.
  1703 	 * @param string $query_var Query variable key.
  1585 	 * @param mixed  $default   Optional. Value to return if the query variable is not set. Default empty.
  1704 	 * @param mixed  $default   Optional. Value to return if the query variable is not set. Default empty.
  1586 	 * @return mixed Contents of the query variable.
  1705 	 * @return mixed Contents of the query variable.
  1587 	 */
  1706 	 */
  1588 	public function get( $query_var, $default = '' ) {
  1707 	public function get( $query_var, $default = '' ) {
  1599 	 * @since 1.5.0
  1718 	 * @since 1.5.0
  1600 	 *
  1719 	 *
  1601 	 * @param string $query_var Query variable key.
  1720 	 * @param string $query_var Query variable key.
  1602 	 * @param mixed  $value     Query variable value.
  1721 	 * @param mixed  $value     Query variable value.
  1603 	 */
  1722 	 */
  1604 	public function set($query_var, $value) {
  1723 	public function set( $query_var, $value ) {
  1605 		$this->query_vars[$query_var] = $value;
  1724 		$this->query_vars[ $query_var ] = $value;
  1606 	}
  1725 	}
  1607 
  1726 
  1608 	/**
  1727 	/**
  1609 	 * Retrieve the posts based on query variables.
  1728 	 * Retrieves an array of posts based on query variables.
  1610 	 *
  1729 	 *
  1611 	 * There are a few filters and actions that can be used to modify the post
  1730 	 * There are a few filters and actions that can be used to modify the post
  1612 	 * database query.
  1731 	 * database query.
  1613 	 *
  1732 	 *
  1614 	 * @since 1.5.0
  1733 	 * @since 1.5.0
  1615 	 *
  1734 	 *
  1616 	 * @return array List of posts.
  1735 	 * @return WP_Post[]|int[] Array of post objects or post IDs.
  1617 	 */
  1736 	 */
  1618 	public function get_posts() {
  1737 	public function get_posts() {
  1619 		global $wpdb;
  1738 		global $wpdb;
  1620 
  1739 
  1621 		$this->parse_query();
  1740 		$this->parse_query();
  1635 
  1754 
  1636 		// Shorthand.
  1755 		// Shorthand.
  1637 		$q = &$this->query_vars;
  1756 		$q = &$this->query_vars;
  1638 
  1757 
  1639 		// Fill again in case pre_get_posts unset some vars.
  1758 		// Fill again in case pre_get_posts unset some vars.
  1640 		$q = $this->fill_query_vars($q);
  1759 		$q = $this->fill_query_vars( $q );
  1641 
  1760 
  1642 		// Parse meta query
  1761 		// Parse meta query
  1643 		$this->meta_query = new WP_Meta_Query();
  1762 		$this->meta_query = new WP_Meta_Query();
  1644 		$this->meta_query->parse_query_vars( $q );
  1763 		$this->meta_query->parse_query_vars( $q );
  1645 
  1764 
  1646 		// Set a flag if a pre_get_posts hook changed the query vars.
  1765 		// Set a flag if a pre_get_posts hook changed the query vars.
  1647 		$hash = md5( serialize( $this->query_vars ) );
  1766 		$hash = md5( serialize( $this->query_vars ) );
  1648 		if ( $hash != $this->query_vars_hash ) {
  1767 		if ( $hash != $this->query_vars_hash ) {
  1649 			$this->query_vars_changed = true;
  1768 			$this->query_vars_changed = true;
  1650 			$this->query_vars_hash = $hash;
  1769 			$this->query_vars_hash    = $hash;
  1651 		}
  1770 		}
  1652 		unset($hash);
  1771 		unset( $hash );
  1653 
  1772 
  1654 		// First let's clear some variables
  1773 		// First let's clear some variables
  1655 		$distinct = '';
  1774 		$distinct         = '';
  1656 		$whichauthor = '';
  1775 		$whichauthor      = '';
  1657 		$whichmimetype = '';
  1776 		$whichmimetype    = '';
  1658 		$where = '';
  1777 		$where            = '';
  1659 		$limits = '';
  1778 		$limits           = '';
  1660 		$join = '';
  1779 		$join             = '';
  1661 		$search = '';
  1780 		$search           = '';
  1662 		$groupby = '';
  1781 		$groupby          = '';
  1663 		$post_status_join = false;
  1782 		$post_status_join = false;
  1664 		$page = 1;
  1783 		$page             = 1;
  1665 
  1784 
  1666 		if ( isset( $q['caller_get_posts'] ) ) {
  1785 		if ( isset( $q['caller_get_posts'] ) ) {
  1667 			_deprecated_argument( 'WP_Query', '3.1.0',
  1786 			_deprecated_argument(
       
  1787 				'WP_Query',
       
  1788 				'3.1.0',
  1668 				/* translators: 1: caller_get_posts, 2: ignore_sticky_posts */
  1789 				/* translators: 1: caller_get_posts, 2: ignore_sticky_posts */
  1669 				sprintf( __( '%1$s is deprecated. Use %2$s instead.' ),
  1790 				sprintf(
       
  1791 					__( '%1$s is deprecated. Use %2$s instead.' ),
  1670 					'<code>caller_get_posts</code>',
  1792 					'<code>caller_get_posts</code>',
  1671 					'<code>ignore_sticky_posts</code>'
  1793 					'<code>ignore_sticky_posts</code>'
  1672 				)
  1794 				)
  1673 			);
  1795 			);
  1674 
  1796 
  1675 			if ( ! isset( $q['ignore_sticky_posts'] ) ) {
  1797 			if ( ! isset( $q['ignore_sticky_posts'] ) ) {
  1676 				$q['ignore_sticky_posts'] = $q['caller_get_posts'];
  1798 				$q['ignore_sticky_posts'] = $q['caller_get_posts'];
  1677 			}
  1799 			}
  1678 		}
  1800 		}
  1679 
  1801 
  1680 		if ( !isset( $q['ignore_sticky_posts'] ) )
  1802 		if ( ! isset( $q['ignore_sticky_posts'] ) ) {
  1681 			$q['ignore_sticky_posts'] = false;
  1803 			$q['ignore_sticky_posts'] = false;
  1682 
  1804 		}
  1683 		if ( !isset($q['suppress_filters']) )
  1805 
       
  1806 		if ( ! isset( $q['suppress_filters'] ) ) {
  1684 			$q['suppress_filters'] = false;
  1807 			$q['suppress_filters'] = false;
  1685 
  1808 		}
  1686 		if ( !isset($q['cache_results']) ) {
  1809 
  1687 			if ( wp_using_ext_object_cache() )
  1810 		if ( ! isset( $q['cache_results'] ) ) {
       
  1811 			if ( wp_using_ext_object_cache() ) {
  1688 				$q['cache_results'] = false;
  1812 				$q['cache_results'] = false;
  1689 			else
  1813 			} else {
  1690 				$q['cache_results'] = true;
  1814 				$q['cache_results'] = true;
  1691 		}
  1815 			}
  1692 
  1816 		}
  1693 		if ( !isset($q['update_post_term_cache']) )
  1817 
       
  1818 		if ( ! isset( $q['update_post_term_cache'] ) ) {
  1694 			$q['update_post_term_cache'] = true;
  1819 			$q['update_post_term_cache'] = true;
       
  1820 		}
  1695 
  1821 
  1696 		if ( ! isset( $q['lazy_load_term_meta'] ) ) {
  1822 		if ( ! isset( $q['lazy_load_term_meta'] ) ) {
  1697 			$q['lazy_load_term_meta'] = $q['update_post_term_cache'];
  1823 			$q['lazy_load_term_meta'] = $q['update_post_term_cache'];
  1698 		}
  1824 		}
  1699 
  1825 
  1700 		if ( !isset($q['update_post_meta_cache']) )
  1826 		if ( ! isset( $q['update_post_meta_cache'] ) ) {
  1701 			$q['update_post_meta_cache'] = true;
  1827 			$q['update_post_meta_cache'] = true;
  1702 
  1828 		}
  1703 		if ( !isset($q['post_type']) ) {
  1829 
  1704 			if ( $this->is_search )
  1830 		if ( ! isset( $q['post_type'] ) ) {
       
  1831 			if ( $this->is_search ) {
  1705 				$q['post_type'] = 'any';
  1832 				$q['post_type'] = 'any';
  1706 			else
  1833 			} else {
  1707 				$q['post_type'] = '';
  1834 				$q['post_type'] = '';
       
  1835 			}
  1708 		}
  1836 		}
  1709 		$post_type = $q['post_type'];
  1837 		$post_type = $q['post_type'];
  1710 		if ( empty( $q['posts_per_page'] ) ) {
  1838 		if ( empty( $q['posts_per_page'] ) ) {
  1711 			$q['posts_per_page'] = get_option( 'posts_per_page' );
  1839 			$q['posts_per_page'] = get_option( 'posts_per_page' );
  1712 		}
  1840 		}
  1713 		if ( isset($q['showposts']) && $q['showposts'] ) {
  1841 		if ( isset( $q['showposts'] ) && $q['showposts'] ) {
  1714 			$q['showposts'] = (int) $q['showposts'];
  1842 			$q['showposts']      = (int) $q['showposts'];
  1715 			$q['posts_per_page'] = $q['showposts'];
  1843 			$q['posts_per_page'] = $q['showposts'];
  1716 		}
  1844 		}
  1717 		if ( (isset($q['posts_per_archive_page']) && $q['posts_per_archive_page'] != 0) && ($this->is_archive || $this->is_search) )
  1845 		if ( ( isset( $q['posts_per_archive_page'] ) && $q['posts_per_archive_page'] != 0 ) && ( $this->is_archive || $this->is_search ) ) {
  1718 			$q['posts_per_page'] = $q['posts_per_archive_page'];
  1846 			$q['posts_per_page'] = $q['posts_per_archive_page'];
  1719 		if ( !isset($q['nopaging']) ) {
  1847 		}
       
  1848 		if ( ! isset( $q['nopaging'] ) ) {
  1720 			if ( $q['posts_per_page'] == -1 ) {
  1849 			if ( $q['posts_per_page'] == -1 ) {
  1721 				$q['nopaging'] = true;
  1850 				$q['nopaging'] = true;
  1722 			} else {
  1851 			} else {
  1723 				$q['nopaging'] = false;
  1852 				$q['nopaging'] = false;
  1724 			}
  1853 			}
  1732 				$q['posts_per_page'] = get_option( 'posts_per_rss' );
  1861 				$q['posts_per_page'] = get_option( 'posts_per_rss' );
  1733 			}
  1862 			}
  1734 			$q['nopaging'] = false;
  1863 			$q['nopaging'] = false;
  1735 		}
  1864 		}
  1736 		$q['posts_per_page'] = (int) $q['posts_per_page'];
  1865 		$q['posts_per_page'] = (int) $q['posts_per_page'];
  1737 		if ( $q['posts_per_page'] < -1 )
  1866 		if ( $q['posts_per_page'] < -1 ) {
  1738 			$q['posts_per_page'] = abs($q['posts_per_page']);
  1867 			$q['posts_per_page'] = abs( $q['posts_per_page'] );
  1739 		elseif ( $q['posts_per_page'] == 0 )
  1868 		} elseif ( $q['posts_per_page'] == 0 ) {
  1740 			$q['posts_per_page'] = 1;
  1869 			$q['posts_per_page'] = 1;
  1741 
  1870 		}
  1742 		if ( !isset($q['comments_per_page']) || $q['comments_per_page'] == 0 )
  1871 
  1743 			$q['comments_per_page'] = get_option('comments_per_page');
  1872 		if ( ! isset( $q['comments_per_page'] ) || $q['comments_per_page'] == 0 ) {
  1744 
  1873 			$q['comments_per_page'] = get_option( 'comments_per_page' );
  1745 		if ( $this->is_home && (empty($this->query) || $q['preview'] == 'true') && ( 'page' == get_option('show_on_front') ) && get_option('page_on_front') ) {
  1874 		}
       
  1875 
       
  1876 		if ( $this->is_home && ( empty( $this->query ) || $q['preview'] == 'true' ) && ( 'page' == get_option( 'show_on_front' ) ) && get_option( 'page_on_front' ) ) {
  1746 			$this->is_page = true;
  1877 			$this->is_page = true;
  1747 			$this->is_home = false;
  1878 			$this->is_home = false;
  1748 			$q['page_id'] = get_option('page_on_front');
  1879 			$q['page_id']  = get_option( 'page_on_front' );
  1749 		}
  1880 		}
  1750 
  1881 
  1751 		if ( isset($q['page']) ) {
  1882 		if ( isset( $q['page'] ) ) {
  1752 			$q['page'] = trim($q['page'], '/');
  1883 			$q['page'] = trim( $q['page'], '/' );
  1753 			$q['page'] = absint($q['page']);
  1884 			$q['page'] = absint( $q['page'] );
  1754 		}
  1885 		}
  1755 
  1886 
  1756 		// If true, forcibly turns off SQL_CALC_FOUND_ROWS even when limits are present.
  1887 		// If true, forcibly turns off SQL_CALC_FOUND_ROWS even when limits are present.
  1757 		if ( isset($q['no_found_rows']) )
  1888 		if ( isset( $q['no_found_rows'] ) ) {
  1758 			$q['no_found_rows'] = (bool) $q['no_found_rows'];
  1889 			$q['no_found_rows'] = (bool) $q['no_found_rows'];
  1759 		else
  1890 		} else {
  1760 			$q['no_found_rows'] = false;
  1891 			$q['no_found_rows'] = false;
       
  1892 		}
  1761 
  1893 
  1762 		switch ( $q['fields'] ) {
  1894 		switch ( $q['fields'] ) {
  1763 			case 'ids':
  1895 			case 'ids':
  1764 				$fields = "{$wpdb->posts}.ID";
  1896 				$fields = "{$wpdb->posts}.ID";
  1765 				break;
  1897 				break;
  1773 		if ( '' !== $q['menu_order'] ) {
  1905 		if ( '' !== $q['menu_order'] ) {
  1774 			$where .= " AND {$wpdb->posts}.menu_order = " . $q['menu_order'];
  1906 			$where .= " AND {$wpdb->posts}.menu_order = " . $q['menu_order'];
  1775 		}
  1907 		}
  1776 		// The "m" parameter is meant for months but accepts datetimes of varying specificity
  1908 		// The "m" parameter is meant for months but accepts datetimes of varying specificity
  1777 		if ( $q['m'] ) {
  1909 		if ( $q['m'] ) {
  1778 			$where .= " AND YEAR({$wpdb->posts}.post_date)=" . substr($q['m'], 0, 4);
  1910 			$where .= " AND YEAR({$wpdb->posts}.post_date)=" . substr( $q['m'], 0, 4 );
  1779 			if ( strlen($q['m']) > 5 ) {
  1911 			if ( strlen( $q['m'] ) > 5 ) {
  1780 				$where .= " AND MONTH({$wpdb->posts}.post_date)=" . substr($q['m'], 4, 2);
  1912 				$where .= " AND MONTH({$wpdb->posts}.post_date)=" . substr( $q['m'], 4, 2 );
  1781 			}
  1913 			}
  1782 			if ( strlen($q['m']) > 7 ) {
  1914 			if ( strlen( $q['m'] ) > 7 ) {
  1783 				$where .= " AND DAYOFMONTH({$wpdb->posts}.post_date)=" . substr($q['m'], 6, 2);
  1915 				$where .= " AND DAYOFMONTH({$wpdb->posts}.post_date)=" . substr( $q['m'], 6, 2 );
  1784 			}
  1916 			}
  1785 			if ( strlen($q['m']) > 9 ) {
  1917 			if ( strlen( $q['m'] ) > 9 ) {
  1786 				$where .= " AND HOUR({$wpdb->posts}.post_date)=" . substr($q['m'], 8, 2);
  1918 				$where .= " AND HOUR({$wpdb->posts}.post_date)=" . substr( $q['m'], 8, 2 );
  1787 			}
  1919 			}
  1788 			if ( strlen($q['m']) > 11 ) {
  1920 			if ( strlen( $q['m'] ) > 11 ) {
  1789 				$where .= " AND MINUTE({$wpdb->posts}.post_date)=" . substr($q['m'], 10, 2);
  1921 				$where .= " AND MINUTE({$wpdb->posts}.post_date)=" . substr( $q['m'], 10, 2 );
  1790 			}
  1922 			}
  1791 			if ( strlen($q['m']) > 13 ) {
  1923 			if ( strlen( $q['m'] ) > 13 ) {
  1792 				$where .= " AND SECOND({$wpdb->posts}.post_date)=" . substr($q['m'], 12, 2);
  1924 				$where .= " AND SECOND({$wpdb->posts}.post_date)=" . substr( $q['m'], 12, 2 );
  1793 			}
  1925 			}
  1794 		}
  1926 		}
  1795 
  1927 
  1796 		// Handle the other individual date parameters
  1928 		// Handle the other individual date parameters
  1797 		$date_parameters = array();
  1929 		$date_parameters = array();
  1798 
  1930 
  1799 		if ( '' !== $q['hour'] )
  1931 		if ( '' !== $q['hour'] ) {
  1800 			$date_parameters['hour'] = $q['hour'];
  1932 			$date_parameters['hour'] = $q['hour'];
  1801 
  1933 		}
  1802 		if ( '' !== $q['minute'] )
  1934 
       
  1935 		if ( '' !== $q['minute'] ) {
  1803 			$date_parameters['minute'] = $q['minute'];
  1936 			$date_parameters['minute'] = $q['minute'];
  1804 
  1937 		}
  1805 		if ( '' !== $q['second'] )
  1938 
       
  1939 		if ( '' !== $q['second'] ) {
  1806 			$date_parameters['second'] = $q['second'];
  1940 			$date_parameters['second'] = $q['second'];
  1807 
  1941 		}
  1808 		if ( $q['year'] )
  1942 
       
  1943 		if ( $q['year'] ) {
  1809 			$date_parameters['year'] = $q['year'];
  1944 			$date_parameters['year'] = $q['year'];
  1810 
  1945 		}
  1811 		if ( $q['monthnum'] )
  1946 
       
  1947 		if ( $q['monthnum'] ) {
  1812 			$date_parameters['monthnum'] = $q['monthnum'];
  1948 			$date_parameters['monthnum'] = $q['monthnum'];
  1813 
  1949 		}
  1814 		if ( $q['w'] )
  1950 
       
  1951 		if ( $q['w'] ) {
  1815 			$date_parameters['week'] = $q['w'];
  1952 			$date_parameters['week'] = $q['w'];
  1816 
  1953 		}
  1817 		if ( $q['day'] )
  1954 
       
  1955 		if ( $q['day'] ) {
  1818 			$date_parameters['day'] = $q['day'];
  1956 			$date_parameters['day'] = $q['day'];
       
  1957 		}
  1819 
  1958 
  1820 		if ( $date_parameters ) {
  1959 		if ( $date_parameters ) {
  1821 			$date_query = new WP_Date_Query( array( $date_parameters ) );
  1960 			$date_query = new WP_Date_Query( array( $date_parameters ) );
  1822 			$where .= $date_query->get_sql();
  1961 			$where     .= $date_query->get_sql();
  1823 		}
  1962 		}
  1824 		unset( $date_parameters, $date_query );
  1963 		unset( $date_parameters, $date_query );
  1825 
  1964 
  1826 		// Handle complex date queries
  1965 		// Handle complex date queries
  1827 		if ( ! empty( $q['date_query'] ) ) {
  1966 		if ( ! empty( $q['date_query'] ) ) {
  1828 			$this->date_query = new WP_Date_Query( $q['date_query'] );
  1967 			$this->date_query = new WP_Date_Query( $q['date_query'] );
  1829 			$where .= $this->date_query->get_sql();
  1968 			$where           .= $this->date_query->get_sql();
  1830 		}
  1969 		}
  1831 
       
  1832 
  1970 
  1833 		// If we've got a post_type AND it's not "any" post_type.
  1971 		// If we've got a post_type AND it's not "any" post_type.
  1834 		if ( !empty($q['post_type']) && 'any' != $q['post_type'] ) {
  1972 		if ( ! empty( $q['post_type'] ) && 'any' != $q['post_type'] ) {
  1835 			foreach ( (array)$q['post_type'] as $_post_type ) {
  1973 			foreach ( (array) $q['post_type'] as $_post_type ) {
  1836 				$ptype_obj = get_post_type_object($_post_type);
  1974 				$ptype_obj = get_post_type_object( $_post_type );
  1837 				if ( !$ptype_obj || !$ptype_obj->query_var || empty($q[ $ptype_obj->query_var ]) )
  1975 				if ( ! $ptype_obj || ! $ptype_obj->query_var || empty( $q[ $ptype_obj->query_var ] ) ) {
  1838 					continue;
  1976 					continue;
       
  1977 				}
  1839 
  1978 
  1840 				if ( ! $ptype_obj->hierarchical ) {
  1979 				if ( ! $ptype_obj->hierarchical ) {
  1841 					// Non-hierarchical post types can directly use 'name'.
  1980 					// Non-hierarchical post types can directly use 'name'.
  1842 					$q['name'] = $q[ $ptype_obj->query_var ];
  1981 					$q['name'] = $q[ $ptype_obj->query_var ];
  1843 				} else {
  1982 				} else {
  1844 					// Hierarchical post types will operate through 'pagename'.
  1983 					// Hierarchical post types will operate through 'pagename'.
  1845 					$q['pagename'] = $q[ $ptype_obj->query_var ];
  1984 					$q['pagename'] = $q[ $ptype_obj->query_var ];
  1846 					$q['name'] = '';
  1985 					$q['name']     = '';
  1847 				}
  1986 				}
  1848 
  1987 
  1849 				// Only one request for a slug is possible, this is why name & pagename are overwritten above.
  1988 				// Only one request for a slug is possible, this is why name & pagename are overwritten above.
  1850 				break;
  1989 				break;
  1851 			} //end foreach
  1990 			} //end foreach
  1852 			unset($ptype_obj);
  1991 			unset( $ptype_obj );
  1853 		}
  1992 		}
  1854 
  1993 
  1855 		if ( '' !== $q['title'] ) {
  1994 		if ( '' !== $q['title'] ) {
  1856 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.post_title = %s", stripslashes( $q['title'] ) );
  1995 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.post_title = %s", stripslashes( $q['title'] ) );
  1857 		}
  1996 		}
  1858 
  1997 
  1859 		// Parameters related to 'post_name'.
  1998 		// Parameters related to 'post_name'.
  1860 		if ( '' != $q['name'] ) {
  1999 		if ( '' != $q['name'] ) {
  1861 			$q['name'] = sanitize_title_for_query( $q['name'] );
  2000 			$q['name'] = sanitize_title_for_query( $q['name'] );
  1862 			$where .= " AND {$wpdb->posts}.post_name = '" . $q['name'] . "'";
  2001 			$where    .= " AND {$wpdb->posts}.post_name = '" . $q['name'] . "'";
  1863 		} elseif ( '' != $q['pagename'] ) {
  2002 		} elseif ( '' != $q['pagename'] ) {
  1864 			if ( isset($this->queried_object_id) ) {
  2003 			if ( isset( $this->queried_object_id ) ) {
  1865 				$reqpage = $this->queried_object_id;
  2004 				$reqpage = $this->queried_object_id;
  1866 			} else {
  2005 			} else {
  1867 				if ( 'page' != $q['post_type'] ) {
  2006 				if ( 'page' != $q['post_type'] ) {
  1868 					foreach ( (array)$q['post_type'] as $_post_type ) {
  2007 					foreach ( (array) $q['post_type'] as $_post_type ) {
  1869 						$ptype_obj = get_post_type_object($_post_type);
  2008 						$ptype_obj = get_post_type_object( $_post_type );
  1870 						if ( !$ptype_obj || !$ptype_obj->hierarchical )
  2009 						if ( ! $ptype_obj || ! $ptype_obj->hierarchical ) {
  1871 							continue;
  2010 							continue;
  1872 
  2011 						}
  1873 						$reqpage = get_page_by_path($q['pagename'], OBJECT, $_post_type);
  2012 
  1874 						if ( $reqpage )
  2013 						$reqpage = get_page_by_path( $q['pagename'], OBJECT, $_post_type );
       
  2014 						if ( $reqpage ) {
  1875 							break;
  2015 							break;
       
  2016 						}
  1876 					}
  2017 					}
  1877 					unset($ptype_obj);
  2018 					unset( $ptype_obj );
  1878 				} else {
  2019 				} else {
  1879 					$reqpage = get_page_by_path($q['pagename']);
  2020 					$reqpage = get_page_by_path( $q['pagename'] );
  1880 				}
  2021 				}
  1881 				if ( !empty($reqpage) )
  2022 				if ( ! empty( $reqpage ) ) {
  1882 					$reqpage = $reqpage->ID;
  2023 					$reqpage = $reqpage->ID;
  1883 				else
  2024 				} else {
  1884 					$reqpage = 0;
  2025 					$reqpage = 0;
  1885 			}
  2026 				}
  1886 
  2027 			}
  1887 			$page_for_posts = get_option('page_for_posts');
  2028 
  1888 			if  ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) {
  2029 			$page_for_posts = get_option( 'page_for_posts' );
       
  2030 			if ( ( 'page' != get_option( 'show_on_front' ) ) || empty( $page_for_posts ) || ( $reqpage != $page_for_posts ) ) {
  1889 				$q['pagename'] = sanitize_title_for_query( wp_basename( $q['pagename'] ) );
  2031 				$q['pagename'] = sanitize_title_for_query( wp_basename( $q['pagename'] ) );
  1890 				$q['name'] = $q['pagename'];
  2032 				$q['name']     = $q['pagename'];
  1891 				$where .= " AND ({$wpdb->posts}.ID = '$reqpage')";
  2033 				$where        .= " AND ({$wpdb->posts}.ID = '$reqpage')";
  1892 				$reqpage_obj = get_post( $reqpage );
  2034 				$reqpage_obj   = get_post( $reqpage );
  1893 				if ( is_object($reqpage_obj) && 'attachment' == $reqpage_obj->post_type ) {
  2035 				if ( is_object( $reqpage_obj ) && 'attachment' == $reqpage_obj->post_type ) {
  1894 					$this->is_attachment = true;
  2036 					$this->is_attachment = true;
  1895 					$post_type = $q['post_type'] = 'attachment';
  2037 					$post_type           = $q['post_type'] = 'attachment';
  1896 					$this->is_page = true;
  2038 					$this->is_page       = true;
  1897 					$q['attachment_id'] = $reqpage;
  2039 					$q['attachment_id']  = $reqpage;
  1898 				}
  2040 				}
  1899 			}
  2041 			}
  1900 		} elseif ( '' != $q['attachment'] ) {
  2042 		} elseif ( '' != $q['attachment'] ) {
  1901 			$q['attachment'] = sanitize_title_for_query( wp_basename( $q['attachment'] ) );
  2043 			$q['attachment'] = sanitize_title_for_query( wp_basename( $q['attachment'] ) );
  1902 			$q['name'] = $q['attachment'];
  2044 			$q['name']       = $q['attachment'];
  1903 			$where .= " AND {$wpdb->posts}.post_name = '" . $q['attachment'] . "'";
  2045 			$where          .= " AND {$wpdb->posts}.post_name = '" . $q['attachment'] . "'";
  1904 		} elseif ( is_array( $q['post_name__in'] ) && ! empty( $q['post_name__in'] ) ) {
  2046 		} elseif ( is_array( $q['post_name__in'] ) && ! empty( $q['post_name__in'] ) ) {
  1905 			$q['post_name__in'] = array_map( 'sanitize_title_for_query', $q['post_name__in'] );
  2047 			$q['post_name__in'] = array_map( 'sanitize_title_for_query', $q['post_name__in'] );
  1906 			$post_name__in = "'" . implode( "','", $q['post_name__in'] ) . "'";
  2048 			$post_name__in      = "'" . implode( "','", $q['post_name__in'] ) . "'";
  1907 			$where .= " AND {$wpdb->posts}.post_name IN ($post_name__in)";
  2049 			$where             .= " AND {$wpdb->posts}.post_name IN ($post_name__in)";
  1908 		}
  2050 		}
  1909 
  2051 
  1910 		// If an attachment is requested by number, let it supersede any post number.
  2052 		// If an attachment is requested by number, let it supersede any post number.
  1911 		if ( $q['attachment_id'] )
  2053 		if ( $q['attachment_id'] ) {
  1912 			$q['p'] = absint($q['attachment_id']);
  2054 			$q['p'] = absint( $q['attachment_id'] );
       
  2055 		}
  1913 
  2056 
  1914 		// If a post number is specified, load that post
  2057 		// If a post number is specified, load that post
  1915 		if ( $q['p'] ) {
  2058 		if ( $q['p'] ) {
  1916 			$where .= " AND {$wpdb->posts}.ID = " . $q['p'];
  2059 			$where .= " AND {$wpdb->posts}.ID = " . $q['p'];
  1917 		} elseif ( $q['post__in'] ) {
  2060 		} elseif ( $q['post__in'] ) {
  1918 			$post__in = implode(',', array_map( 'absint', $q['post__in'] ));
  2061 			$post__in = implode( ',', array_map( 'absint', $q['post__in'] ) );
  1919 			$where .= " AND {$wpdb->posts}.ID IN ($post__in)";
  2062 			$where   .= " AND {$wpdb->posts}.ID IN ($post__in)";
  1920 		} elseif ( $q['post__not_in'] ) {
  2063 		} elseif ( $q['post__not_in'] ) {
  1921 			$post__not_in = implode(',',  array_map( 'absint', $q['post__not_in'] ));
  2064 			$post__not_in = implode( ',', array_map( 'absint', $q['post__not_in'] ) );
  1922 			$where .= " AND {$wpdb->posts}.ID NOT IN ($post__not_in)";
  2065 			$where       .= " AND {$wpdb->posts}.ID NOT IN ($post__not_in)";
  1923 		}
  2066 		}
  1924 
  2067 
  1925 		if ( is_numeric( $q['post_parent'] ) ) {
  2068 		if ( is_numeric( $q['post_parent'] ) ) {
  1926 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.post_parent = %d ", $q['post_parent'] );
  2069 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.post_parent = %d ", $q['post_parent'] );
  1927 		} elseif ( $q['post_parent__in'] ) {
  2070 		} elseif ( $q['post_parent__in'] ) {
  1928 			$post_parent__in = implode( ',', array_map( 'absint', $q['post_parent__in'] ) );
  2071 			$post_parent__in = implode( ',', array_map( 'absint', $q['post_parent__in'] ) );
  1929 			$where .= " AND {$wpdb->posts}.post_parent IN ($post_parent__in)";
  2072 			$where          .= " AND {$wpdb->posts}.post_parent IN ($post_parent__in)";
  1930 		} elseif ( $q['post_parent__not_in'] ) {
  2073 		} elseif ( $q['post_parent__not_in'] ) {
  1931 			$post_parent__not_in = implode( ',',  array_map( 'absint', $q['post_parent__not_in'] ) );
  2074 			$post_parent__not_in = implode( ',', array_map( 'absint', $q['post_parent__not_in'] ) );
  1932 			$where .= " AND {$wpdb->posts}.post_parent NOT IN ($post_parent__not_in)";
  2075 			$where              .= " AND {$wpdb->posts}.post_parent NOT IN ($post_parent__not_in)";
  1933 		}
  2076 		}
  1934 
  2077 
  1935 		if ( $q['page_id'] ) {
  2078 		if ( $q['page_id'] ) {
  1936 			if  ( ('page' != get_option('show_on_front') ) || ( $q['page_id'] != get_option('page_for_posts') ) ) {
  2079 			if ( ( 'page' != get_option( 'show_on_front' ) ) || ( $q['page_id'] != get_option( 'page_for_posts' ) ) ) {
  1937 				$q['p'] = $q['page_id'];
  2080 				$q['p'] = $q['page_id'];
  1938 				$where = " AND {$wpdb->posts}.ID = " . $q['page_id'];
  2081 				$where  = " AND {$wpdb->posts}.ID = " . $q['page_id'];
  1939 			}
  2082 			}
  1940 		}
  2083 		}
  1941 
  2084 
  1942 		// If a search pattern is specified, load the posts that match.
  2085 		// If a search pattern is specified, load the posts that match.
  1943 		if ( strlen( $q['s'] ) ) {
  2086 		if ( strlen( $q['s'] ) ) {
  1955 			 */
  2098 			 */
  1956 			$search = apply_filters_ref_array( 'posts_search', array( $search, &$this ) );
  2099 			$search = apply_filters_ref_array( 'posts_search', array( $search, &$this ) );
  1957 		}
  2100 		}
  1958 
  2101 
  1959 		// Taxonomies
  2102 		// Taxonomies
  1960 		if ( !$this->is_singular ) {
  2103 		if ( ! $this->is_singular ) {
  1961 			$this->parse_tax_query( $q );
  2104 			$this->parse_tax_query( $q );
  1962 
  2105 
  1963 			$clauses = $this->tax_query->get_sql( $wpdb->posts, 'ID' );
  2106 			$clauses = $this->tax_query->get_sql( $wpdb->posts, 'ID' );
  1964 
  2107 
  1965 			$join .= $clauses['join'];
  2108 			$join  .= $clauses['join'];
  1966 			$where .= $clauses['where'];
  2109 			$where .= $clauses['where'];
  1967 		}
  2110 		}
  1968 
  2111 
  1969 		if ( $this->is_tax ) {
  2112 		if ( $this->is_tax ) {
  1970 			if ( empty($post_type) ) {
  2113 			if ( empty( $post_type ) ) {
  1971 				// Do a fully inclusive search for currently registered post types of queried taxonomies
  2114 				// Do a fully inclusive search for currently registered post types of queried taxonomies
  1972 				$post_type = array();
  2115 				$post_type  = array();
  1973 				$taxonomies = array_keys( $this->tax_query->queried_terms );
  2116 				$taxonomies = array_keys( $this->tax_query->queried_terms );
  1974 				foreach ( get_post_types( array( 'exclude_from_search' => false ) ) as $pt ) {
  2117 				foreach ( get_post_types( array( 'exclude_from_search' => false ) ) as $pt ) {
  1975 					$object_taxonomies = $pt === 'attachment' ? get_taxonomies_for_attachments() : get_object_taxonomies( $pt );
  2118 					$object_taxonomies = $pt === 'attachment' ? get_taxonomies_for_attachments() : get_object_taxonomies( $pt );
  1976 					if ( array_intersect( $taxonomies, $object_taxonomies ) )
  2119 					if ( array_intersect( $taxonomies, $object_taxonomies ) ) {
  1977 						$post_type[] = $pt;
  2120 						$post_type[] = $pt;
  1978 				}
  2121 					}
  1979 				if ( ! $post_type )
  2122 				}
       
  2123 				if ( ! $post_type ) {
  1980 					$post_type = 'any';
  2124 					$post_type = 'any';
  1981 				elseif ( count( $post_type ) == 1 )
  2125 				} elseif ( count( $post_type ) == 1 ) {
  1982 					$post_type = $post_type[0];
  2126 					$post_type = $post_type[0];
       
  2127 				}
  1983 
  2128 
  1984 				$post_status_join = true;
  2129 				$post_status_join = true;
  1985 			} elseif ( in_array('attachment', (array) $post_type) ) {
  2130 			} elseif ( in_array( 'attachment', (array) $post_type ) ) {
  1986 				$post_status_join = true;
  2131 				$post_status_join = true;
  1987 			}
  2132 			}
  1988 		}
  2133 		}
  1989 
  2134 
  1990 		/*
  2135 		/*
  2041 					unset( $the_tag );
  2186 					unset( $the_tag );
  2042 				}
  2187 				}
  2043 			}
  2188 			}
  2044 		}
  2189 		}
  2045 
  2190 
  2046 		if ( !empty( $this->tax_query->queries ) || !empty( $this->meta_query->queries ) ) {
  2191 		if ( ! empty( $this->tax_query->queries ) || ! empty( $this->meta_query->queries ) ) {
  2047 			$groupby = "{$wpdb->posts}.ID";
  2192 			$groupby = "{$wpdb->posts}.ID";
  2048 		}
  2193 		}
  2049 
  2194 
  2050 		// Author/user stuff
  2195 		// Author/user stuff
  2051 
  2196 
  2052 		if ( ! empty( $q['author'] ) && $q['author'] != '0' ) {
  2197 		if ( ! empty( $q['author'] ) && $q['author'] != '0' ) {
  2053 			$q['author'] = addslashes_gpc( '' . urldecode( $q['author'] ) );
  2198 			$q['author'] = addslashes_gpc( '' . urldecode( $q['author'] ) );
  2054 			$authors = array_unique( array_map( 'intval', preg_split( '/[,\s]+/', $q['author'] ) ) );
  2199 			$authors     = array_unique( array_map( 'intval', preg_split( '/[,\s]+/', $q['author'] ) ) );
  2055 			foreach ( $authors as $author ) {
  2200 			foreach ( $authors as $author ) {
  2056 				$key = $author > 0 ? 'author__in' : 'author__not_in';
  2201 				$key         = $author > 0 ? 'author__in' : 'author__not_in';
  2057 				$q[$key][] = abs( $author );
  2202 				$q[ $key ][] = abs( $author );
  2058 			}
  2203 			}
  2059 			$q['author'] = implode( ',', $authors );
  2204 			$q['author'] = implode( ',', $authors );
  2060 		}
  2205 		}
  2061 
  2206 
  2062 		if ( ! empty( $q['author__not_in'] ) ) {
  2207 		if ( ! empty( $q['author__not_in'] ) ) {
  2063 			$author__not_in = implode( ',', array_map( 'absint', array_unique( (array) $q['author__not_in'] ) ) );
  2208 			$author__not_in = implode( ',', array_map( 'absint', array_unique( (array) $q['author__not_in'] ) ) );
  2064 			$where .= " AND {$wpdb->posts}.post_author NOT IN ($author__not_in) ";
  2209 			$where         .= " AND {$wpdb->posts}.post_author NOT IN ($author__not_in) ";
  2065 		} elseif ( ! empty( $q['author__in'] ) ) {
  2210 		} elseif ( ! empty( $q['author__in'] ) ) {
  2066 			$author__in = implode( ',', array_map( 'absint', array_unique( (array) $q['author__in'] ) ) );
  2211 			$author__in = implode( ',', array_map( 'absint', array_unique( (array) $q['author__in'] ) ) );
  2067 			$where .= " AND {$wpdb->posts}.post_author IN ($author__in) ";
  2212 			$where     .= " AND {$wpdb->posts}.post_author IN ($author__in) ";
  2068 		}
  2213 		}
  2069 
  2214 
  2070 		// Author stuff for nice URLs
  2215 		// Author stuff for nice URLs
  2071 
  2216 
  2072 		if ( '' != $q['author_name'] ) {
  2217 		if ( '' != $q['author_name'] ) {
  2073 			if ( strpos($q['author_name'], '/') !== false ) {
  2218 			if ( strpos( $q['author_name'], '/' ) !== false ) {
  2074 				$q['author_name'] = explode('/', $q['author_name']);
  2219 				$q['author_name'] = explode( '/', $q['author_name'] );
  2075 				if ( $q['author_name'][ count($q['author_name'])-1 ] ) {
  2220 				if ( $q['author_name'][ count( $q['author_name'] ) - 1 ] ) {
  2076 					$q['author_name'] = $q['author_name'][count($q['author_name'])-1]; // no trailing slash
  2221 					$q['author_name'] = $q['author_name'][ count( $q['author_name'] ) - 1 ]; // no trailing slash
  2077 				} else {
  2222 				} else {
  2078 					$q['author_name'] = $q['author_name'][count($q['author_name'])-2]; // there was a trailing slash
  2223 					$q['author_name'] = $q['author_name'][ count( $q['author_name'] ) - 2 ]; // there was a trailing slash
  2079 				}
  2224 				}
  2080 			}
  2225 			}
  2081 			$q['author_name'] = sanitize_title_for_query( $q['author_name'] );
  2226 			$q['author_name'] = sanitize_title_for_query( $q['author_name'] );
  2082 			$q['author'] = get_user_by('slug', $q['author_name']);
  2227 			$q['author']      = get_user_by( 'slug', $q['author_name'] );
  2083 			if ( $q['author'] )
  2228 			if ( $q['author'] ) {
  2084 				$q['author'] = $q['author']->ID;
  2229 				$q['author'] = $q['author']->ID;
  2085 			$whichauthor .= " AND ({$wpdb->posts}.post_author = " . absint($q['author']) . ')';
  2230 			}
       
  2231 			$whichauthor .= " AND ({$wpdb->posts}.post_author = " . absint( $q['author'] ) . ')';
  2086 		}
  2232 		}
  2087 
  2233 
  2088 		// Matching by comment count.
  2234 		// Matching by comment count.
  2089 		if ( isset( $q['comment_count'] ) ) {
  2235 		if ( isset( $q['comment_count'] ) ) {
  2090 			// Numeric comment count is converted to array format.
  2236 			// Numeric comment count is converted to array format.
  2093 					'value' => intval( $q['comment_count'] ),
  2239 					'value' => intval( $q['comment_count'] ),
  2094 				);
  2240 				);
  2095 			}
  2241 			}
  2096 
  2242 
  2097 			if ( isset( $q['comment_count']['value'] ) ) {
  2243 			if ( isset( $q['comment_count']['value'] ) ) {
  2098 				$q['comment_count'] = array_merge( array(
  2244 				$q['comment_count'] = array_merge(
  2099 					'compare' => '=',
  2245 					array(
  2100 				), $q['comment_count'] );
  2246 						'compare' => '=',
       
  2247 					),
       
  2248 					$q['comment_count']
       
  2249 				);
  2101 
  2250 
  2102 				// Fallback for invalid compare operators is '='.
  2251 				// Fallback for invalid compare operators is '='.
  2103 				$compare_operators = array( '=', '!=', '>', '>=', '<', '<=' );
  2252 				$compare_operators = array( '=', '!=', '>', '>=', '<', '<=' );
  2104 				if ( ! in_array( $q['comment_count']['compare'], $compare_operators, true ) ) {
  2253 				if ( ! in_array( $q['comment_count']['compare'], $compare_operators, true ) ) {
  2105 					$q['comment_count']['compare'] = '=';
  2254 					$q['comment_count']['compare'] = '=';
  2125 		$rand = ( isset( $q['orderby'] ) && 'rand' === $q['orderby'] );
  2274 		$rand = ( isset( $q['orderby'] ) && 'rand' === $q['orderby'] );
  2126 		if ( ! isset( $q['order'] ) ) {
  2275 		if ( ! isset( $q['order'] ) ) {
  2127 			$q['order'] = $rand ? '' : 'DESC';
  2276 			$q['order'] = $rand ? '' : 'DESC';
  2128 		} else {
  2277 		} else {
  2129 			$q['order'] = $rand ? '' : $this->parse_order( $q['order'] );
  2278 			$q['order'] = $rand ? '' : $this->parse_order( $q['order'] );
       
  2279 		}
       
  2280 
       
  2281 		// These values of orderby should ignore the 'order' parameter.
       
  2282 		$force_asc = array( 'post__in', 'post_name__in', 'post_parent__in' );
       
  2283 		if ( isset( $q['orderby'] ) && in_array( $q['orderby'], $force_asc, true ) ) {
       
  2284 			$q['order'] = '';
  2130 		}
  2285 		}
  2131 
  2286 
  2132 		// Order by.
  2287 		// Order by.
  2133 		if ( empty( $q['orderby'] ) ) {
  2288 		if ( empty( $q['orderby'] ) ) {
  2134 			/*
  2289 			/*
  2140 			} else {
  2295 			} else {
  2141 				$orderby = "{$wpdb->posts}.post_date " . $q['order'];
  2296 				$orderby = "{$wpdb->posts}.post_date " . $q['order'];
  2142 			}
  2297 			}
  2143 		} elseif ( 'none' == $q['orderby'] ) {
  2298 		} elseif ( 'none' == $q['orderby'] ) {
  2144 			$orderby = '';
  2299 			$orderby = '';
  2145 		} elseif ( $q['orderby'] == 'post__in' && ! empty( $post__in ) ) {
       
  2146 			$orderby = "FIELD( {$wpdb->posts}.ID, $post__in )";
       
  2147 		} elseif ( $q['orderby'] == 'post_parent__in' && ! empty( $post_parent__in ) ) {
       
  2148 			$orderby = "FIELD( {$wpdb->posts}.post_parent, $post_parent__in )";
       
  2149 		} elseif ( $q['orderby'] == 'post_name__in' && ! empty( $post_name__in ) ) {
       
  2150 			$orderby = "FIELD( {$wpdb->posts}.post_name, $post_name__in )";
       
  2151 		} else {
  2300 		} else {
  2152 			$orderby_array = array();
  2301 			$orderby_array = array();
  2153 			if ( is_array( $q['orderby'] ) ) {
  2302 			if ( is_array( $q['orderby'] ) ) {
  2154 				foreach ( $q['orderby'] as $_orderby => $order ) {
  2303 				foreach ( $q['orderby'] as $_orderby => $order ) {
  2155 					$orderby = addslashes_gpc( urldecode( $_orderby ) );
  2304 					$orderby = addslashes_gpc( urldecode( $_orderby ) );
  2187 		}
  2336 		}
  2188 
  2337 
  2189 		// Order search results by relevance only when another "orderby" is not specified in the query.
  2338 		// Order search results by relevance only when another "orderby" is not specified in the query.
  2190 		if ( ! empty( $q['s'] ) ) {
  2339 		if ( ! empty( $q['s'] ) ) {
  2191 			$search_orderby = '';
  2340 			$search_orderby = '';
  2192 			if ( ! empty( $q['search_orderby_title'] ) && ( empty( $q['orderby'] ) && ! $this->is_feed ) || ( isset( $q['orderby'] ) && 'relevance' === $q['orderby'] ) )
  2341 			if ( ! empty( $q['search_orderby_title'] ) && ( empty( $q['orderby'] ) && ! $this->is_feed ) || ( isset( $q['orderby'] ) && 'relevance' === $q['orderby'] ) ) {
  2193 				$search_orderby = $this->parse_search_order( $q );
  2342 				$search_orderby = $this->parse_search_order( $q );
       
  2343 			}
  2194 
  2344 
  2195 			if ( ! $q['suppress_filters'] ) {
  2345 			if ( ! $q['suppress_filters'] ) {
  2196 				/**
  2346 				/**
  2197 				 * Filters the ORDER BY used when ordering search results.
  2347 				 * Filters the ORDER BY used when ordering search results.
  2198 				 *
  2348 				 *
  2202 				 * @param WP_Query $this           The current WP_Query instance.
  2352 				 * @param WP_Query $this           The current WP_Query instance.
  2203 				 */
  2353 				 */
  2204 				$search_orderby = apply_filters( 'posts_search_orderby', $search_orderby, $this );
  2354 				$search_orderby = apply_filters( 'posts_search_orderby', $search_orderby, $this );
  2205 			}
  2355 			}
  2206 
  2356 
  2207 			if ( $search_orderby )
  2357 			if ( $search_orderby ) {
  2208 				$orderby = $orderby ? $search_orderby . ', ' . $orderby : $search_orderby;
  2358 				$orderby = $orderby ? $search_orderby . ', ' . $orderby : $search_orderby;
       
  2359 			}
  2209 		}
  2360 		}
  2210 
  2361 
  2211 		if ( is_array( $post_type ) && count( $post_type ) > 1 ) {
  2362 		if ( is_array( $post_type ) && count( $post_type ) > 1 ) {
  2212 			$post_type_cap = 'multiple_post_type';
  2363 			$post_type_cap = 'multiple_post_type';
  2213 		} else {
  2364 		} else {
  2214 			if ( is_array( $post_type ) )
  2365 			if ( is_array( $post_type ) ) {
  2215 				$post_type = reset( $post_type );
  2366 				$post_type = reset( $post_type );
       
  2367 			}
  2216 			$post_type_object = get_post_type_object( $post_type );
  2368 			$post_type_object = get_post_type_object( $post_type );
  2217 			if ( empty( $post_type_object ) )
  2369 			if ( empty( $post_type_object ) ) {
  2218 				$post_type_cap = $post_type;
  2370 				$post_type_cap = $post_type;
       
  2371 			}
  2219 		}
  2372 		}
  2220 
  2373 
  2221 		if ( isset( $q['post_password'] ) ) {
  2374 		if ( isset( $q['post_password'] ) ) {
  2222 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.post_password = %s", $q['post_password'] );
  2375 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.post_password = %s", $q['post_password'] );
  2223 			if ( empty( $q['perm'] ) ) {
  2376 			if ( empty( $q['perm'] ) ) {
  2229 
  2382 
  2230 		if ( ! empty( $q['comment_status'] ) ) {
  2383 		if ( ! empty( $q['comment_status'] ) ) {
  2231 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.comment_status = %s ", $q['comment_status'] );
  2384 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.comment_status = %s ", $q['comment_status'] );
  2232 		}
  2385 		}
  2233 
  2386 
  2234 		if ( ! empty( $q['ping_status'] ) )  {
  2387 		if ( ! empty( $q['ping_status'] ) ) {
  2235 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.ping_status = %s ", $q['ping_status'] );
  2388 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.ping_status = %s ", $q['ping_status'] );
  2236 		}
  2389 		}
  2237 
  2390 
  2238 		if ( 'any' == $post_type ) {
  2391 		if ( 'any' == $post_type ) {
  2239 			$in_search_post_types = get_post_types( array('exclude_from_search' => false) );
  2392 			$in_search_post_types = get_post_types( array( 'exclude_from_search' => false ) );
  2240 			if ( empty( $in_search_post_types ) ) {
  2393 			if ( empty( $in_search_post_types ) ) {
  2241 				$where .= ' AND 1=0 ';
  2394 				$where .= ' AND 1=0 ';
  2242 			} else {
  2395 			} else {
  2243 				$where .= " AND {$wpdb->posts}.post_type IN ('" . join( "', '", array_map( 'esc_sql', $in_search_post_types ) ) . "')";
  2396 				$where .= " AND {$wpdb->posts}.post_type IN ('" . join( "', '", array_map( 'esc_sql', $in_search_post_types ) ) . "')";
  2244 			}
  2397 			}
  2245 		} elseif ( !empty( $post_type ) && is_array( $post_type ) ) {
  2398 		} elseif ( ! empty( $post_type ) && is_array( $post_type ) ) {
  2246 			$where .= " AND {$wpdb->posts}.post_type IN ('" . join("', '", esc_sql( $post_type ) ) . "')";
  2399 			$where .= " AND {$wpdb->posts}.post_type IN ('" . join( "', '", esc_sql( $post_type ) ) . "')";
  2247 		} elseif ( ! empty( $post_type ) ) {
  2400 		} elseif ( ! empty( $post_type ) ) {
  2248 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.post_type = %s", $post_type );
  2401 			$where           .= $wpdb->prepare( " AND {$wpdb->posts}.post_type = %s", $post_type );
  2249 			$post_type_object = get_post_type_object ( $post_type );
  2402 			$post_type_object = get_post_type_object( $post_type );
  2250 		} elseif ( $this->is_attachment ) {
  2403 		} elseif ( $this->is_attachment ) {
  2251 			$where .= " AND {$wpdb->posts}.post_type = 'attachment'";
  2404 			$where           .= " AND {$wpdb->posts}.post_type = 'attachment'";
  2252 			$post_type_object = get_post_type_object ( 'attachment' );
  2405 			$post_type_object = get_post_type_object( 'attachment' );
  2253 		} elseif ( $this->is_page ) {
  2406 		} elseif ( $this->is_page ) {
  2254 			$where .= " AND {$wpdb->posts}.post_type = 'page'";
  2407 			$where           .= " AND {$wpdb->posts}.post_type = 'page'";
  2255 			$post_type_object = get_post_type_object ( 'page' );
  2408 			$post_type_object = get_post_type_object( 'page' );
  2256 		} else {
  2409 		} else {
  2257 			$where .= " AND {$wpdb->posts}.post_type = 'post'";
  2410 			$where           .= " AND {$wpdb->posts}.post_type = 'post'";
  2258 			$post_type_object = get_post_type_object ( 'post' );
  2411 			$post_type_object = get_post_type_object( 'post' );
  2259 		}
  2412 		}
  2260 
  2413 
  2261 		$edit_cap = 'edit_post';
  2414 		$edit_cap = 'edit_post';
  2262 		$read_cap = 'read_post';
  2415 		$read_cap = 'read_post';
  2263 
  2416 
  2264 		if ( ! empty( $post_type_object ) ) {
  2417 		if ( ! empty( $post_type_object ) ) {
  2265 			$edit_others_cap = $post_type_object->cap->edit_others_posts;
  2418 			$edit_others_cap  = $post_type_object->cap->edit_others_posts;
  2266 			$read_private_cap = $post_type_object->cap->read_private_posts;
  2419 			$read_private_cap = $post_type_object->cap->read_private_posts;
  2267 		} else {
  2420 		} else {
  2268 			$edit_others_cap = 'edit_others_' . $post_type_cap . 's';
  2421 			$edit_others_cap  = 'edit_others_' . $post_type_cap . 's';
  2269 			$read_private_cap = 'read_private_' . $post_type_cap . 's';
  2422 			$read_private_cap = 'read_private_' . $post_type_cap . 's';
  2270 		}
  2423 		}
  2271 
  2424 
  2272 		$user_id = get_current_user_id();
  2425 		$user_id = get_current_user_id();
  2273 
  2426 
  2274 		$q_status = array();
  2427 		$q_status = array();
  2275 		if ( ! empty( $q['post_status'] ) ) {
  2428 		if ( ! empty( $q['post_status'] ) ) {
  2276 			$statuswheres = array();
  2429 			$statuswheres = array();
  2277 			$q_status = $q['post_status'];
  2430 			$q_status     = $q['post_status'];
  2278 			if ( ! is_array( $q_status ) )
  2431 			if ( ! is_array( $q_status ) ) {
  2279 				$q_status = explode(',', $q_status);
  2432 				$q_status = explode( ',', $q_status );
       
  2433 			}
  2280 			$r_status = array();
  2434 			$r_status = array();
  2281 			$p_status = array();
  2435 			$p_status = array();
  2282 			$e_status = array();
  2436 			$e_status = array();
  2283 			if ( in_array( 'any', $q_status ) ) {
  2437 			if ( in_array( 'any', $q_status ) ) {
  2284 				foreach ( get_post_stati( array( 'exclude_from_search' => true ) ) as $status ) {
  2438 				foreach ( get_post_stati( array( 'exclude_from_search' => true ) ) as $status ) {
  2296 						}
  2450 						}
  2297 					}
  2451 					}
  2298 				}
  2452 				}
  2299 			}
  2453 			}
  2300 
  2454 
  2301 			if ( empty($q['perm'] ) || 'readable' != $q['perm'] ) {
  2455 			if ( empty( $q['perm'] ) || 'readable' != $q['perm'] ) {
  2302 				$r_status = array_merge($r_status, $p_status);
  2456 				$r_status = array_merge( $r_status, $p_status );
  2303 				unset($p_status);
  2457 				unset( $p_status );
  2304 			}
  2458 			}
  2305 
  2459 
  2306 			if ( !empty($e_status) ) {
  2460 			if ( ! empty( $e_status ) ) {
  2307 				$statuswheres[] = "(" . join( ' AND ', $e_status ) . ")";
  2461 				$statuswheres[] = '(' . join( ' AND ', $e_status ) . ')';
  2308 			}
  2462 			}
  2309 			if ( !empty($r_status) ) {
  2463 			if ( ! empty( $r_status ) ) {
  2310 				if ( !empty($q['perm'] ) && 'editable' == $q['perm'] && !current_user_can($edit_others_cap) ) {
  2464 				if ( ! empty( $q['perm'] ) && 'editable' == $q['perm'] && ! current_user_can( $edit_others_cap ) ) {
  2311 					$statuswheres[] = "({$wpdb->posts}.post_author = $user_id " . "AND (" . join( ' OR ', $r_status ) . "))";
  2465 					$statuswheres[] = "({$wpdb->posts}.post_author = $user_id " . 'AND (' . join( ' OR ', $r_status ) . '))';
  2312 				} else {
  2466 				} else {
  2313 					$statuswheres[] = "(" . join( ' OR ', $r_status ) . ")";
  2467 					$statuswheres[] = '(' . join( ' OR ', $r_status ) . ')';
  2314 				}
  2468 				}
  2315 			}
  2469 			}
  2316 			if ( !empty($p_status) ) {
  2470 			if ( ! empty( $p_status ) ) {
  2317 				if ( !empty($q['perm'] ) && 'readable' == $q['perm'] && !current_user_can($read_private_cap) ) {
  2471 				if ( ! empty( $q['perm'] ) && 'readable' == $q['perm'] && ! current_user_can( $read_private_cap ) ) {
  2318 					$statuswheres[] = "({$wpdb->posts}.post_author = $user_id " . "AND (" . join( ' OR ', $p_status ) . "))";
  2472 					$statuswheres[] = "({$wpdb->posts}.post_author = $user_id " . 'AND (' . join( ' OR ', $p_status ) . '))';
  2319 				} else {
  2473 				} else {
  2320 					$statuswheres[] = "(" . join( ' OR ', $p_status ) . ")";
  2474 					$statuswheres[] = '(' . join( ' OR ', $p_status ) . ')';
  2321 				}
  2475 				}
  2322 			}
  2476 			}
  2323 			if ( $post_status_join ) {
  2477 			if ( $post_status_join ) {
  2324 				$join .= " LEFT JOIN {$wpdb->posts} AS p2 ON ({$wpdb->posts}.post_parent = p2.ID) ";
  2478 				$join .= " LEFT JOIN {$wpdb->posts} AS p2 ON ({$wpdb->posts}.post_parent = p2.ID) ";
  2325 				foreach ( $statuswheres as $index => $statuswhere ) {
  2479 				foreach ( $statuswheres as $index => $statuswhere ) {
  2326 					$statuswheres[$index] = "($statuswhere OR ({$wpdb->posts}.post_status = 'inherit' AND " . str_replace( $wpdb->posts, 'p2', $statuswhere ) . "))";
  2480 					$statuswheres[ $index ] = "($statuswhere OR ({$wpdb->posts}.post_status = 'inherit' AND " . str_replace( $wpdb->posts, 'p2', $statuswhere ) . '))';
  2327 				}
  2481 				}
  2328 			}
  2482 			}
  2329 			$where_status = implode( ' OR ', $statuswheres );
  2483 			$where_status = implode( ' OR ', $statuswheres );
  2330 			if ( ! empty( $where_status ) ) {
  2484 			if ( ! empty( $where_status ) ) {
  2331 				$where .= " AND ($where_status)";
  2485 				$where .= " AND ($where_status)";
  2332 			}
  2486 			}
  2333 		} elseif ( !$this->is_singular ) {
  2487 		} elseif ( ! $this->is_singular ) {
  2334 			$where .= " AND ({$wpdb->posts}.post_status = 'publish'";
  2488 			$where .= " AND ({$wpdb->posts}.post_status = 'publish'";
  2335 
  2489 
  2336 			// Add public states.
  2490 			// Add public states.
  2337 			$public_states = get_post_stati( array('public' => true) );
  2491 			$public_states = get_post_stati( array( 'public' => true ) );
  2338 			foreach ( (array) $public_states as $state ) {
  2492 			foreach ( (array) $public_states as $state ) {
  2339 				if ( 'publish' == $state ) // Publish is hard-coded above.
  2493 				if ( 'publish' == $state ) { // Publish is hard-coded above.
  2340 					continue;
  2494 					continue;
       
  2495 				}
  2341 				$where .= " OR {$wpdb->posts}.post_status = '$state'";
  2496 				$where .= " OR {$wpdb->posts}.post_status = '$state'";
  2342 			}
  2497 			}
  2343 
  2498 
  2344 			if ( $this->is_admin ) {
  2499 			if ( $this->is_admin ) {
  2345 				// Add protected states that should show in the admin all list.
  2500 				// Add protected states that should show in the admin all list.
  2346 				$admin_all_states = get_post_stati( array('protected' => true, 'show_in_admin_all_list' => true) );
  2501 				$admin_all_states = get_post_stati(
       
  2502 					array(
       
  2503 						'protected'              => true,
       
  2504 						'show_in_admin_all_list' => true,
       
  2505 					)
       
  2506 				);
  2347 				foreach ( (array) $admin_all_states as $state ) {
  2507 				foreach ( (array) $admin_all_states as $state ) {
  2348 					$where .= " OR {$wpdb->posts}.post_status = '$state'";
  2508 					$where .= " OR {$wpdb->posts}.post_status = '$state'";
  2349 				}
  2509 				}
  2350 			}
  2510 			}
  2351 
  2511 
  2352 			if ( is_user_logged_in() ) {
  2512 			if ( is_user_logged_in() ) {
  2353 				// Add private states that are limited to viewing by the author of a post or someone who has caps to read private states.
  2513 				// Add private states that are limited to viewing by the author of a post or someone who has caps to read private states.
  2354 				$private_states = get_post_stati( array('private' => true) );
  2514 				$private_states = get_post_stati( array( 'private' => true ) );
  2355 				foreach ( (array) $private_states as $state ) {
  2515 				foreach ( (array) $private_states as $state ) {
  2356 					$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'";
  2516 					$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'";
  2357 				}
  2517 				}
  2358 			}
  2518 			}
  2359 
  2519 
  2362 
  2522 
  2363 		/*
  2523 		/*
  2364 		 * Apply filters on where and join prior to paging so that any
  2524 		 * Apply filters on where and join prior to paging so that any
  2365 		 * manipulations to them are reflected in the paging by day queries.
  2525 		 * manipulations to them are reflected in the paging by day queries.
  2366 		 */
  2526 		 */
  2367 		if ( !$q['suppress_filters'] ) {
  2527 		if ( ! $q['suppress_filters'] ) {
  2368 			/**
  2528 			/**
  2369 			 * Filters the WHERE clause of the query.
  2529 			 * Filters the WHERE clause of the query.
  2370 			 *
  2530 			 *
  2371 			 * @since 1.5.0
  2531 			 * @since 1.5.0
  2372 			 *
  2532 			 *
  2385 			 */
  2545 			 */
  2386 			$join = apply_filters_ref_array( 'posts_join', array( $join, &$this ) );
  2546 			$join = apply_filters_ref_array( 'posts_join', array( $join, &$this ) );
  2387 		}
  2547 		}
  2388 
  2548 
  2389 		// Paging
  2549 		// Paging
  2390 		if ( empty($q['nopaging']) && !$this->is_singular ) {
  2550 		if ( empty( $q['nopaging'] ) && ! $this->is_singular ) {
  2391 			$page = absint($q['paged']);
  2551 			$page = absint( $q['paged'] );
  2392 			if ( !$page )
  2552 			if ( ! $page ) {
  2393 				$page = 1;
  2553 				$page = 1;
       
  2554 			}
  2394 
  2555 
  2395 			// If 'offset' is provided, it takes precedence over 'paged'.
  2556 			// If 'offset' is provided, it takes precedence over 'paged'.
  2396 			if ( isset( $q['offset'] ) && is_numeric( $q['offset'] ) ) {
  2557 			if ( isset( $q['offset'] ) && is_numeric( $q['offset'] ) ) {
  2397 				$q['offset'] = absint( $q['offset'] );
  2558 				$q['offset'] = absint( $q['offset'] );
  2398 				$pgstrt = $q['offset'] . ', ';
  2559 				$pgstrt      = $q['offset'] . ', ';
  2399 			} else {
  2560 			} else {
  2400 				$pgstrt = absint( ( $page - 1 ) * $q['posts_per_page'] ) . ', ';
  2561 				$pgstrt = absint( ( $page - 1 ) * $q['posts_per_page'] ) . ', ';
  2401 			}
  2562 			}
  2402 			$limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
  2563 			$limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
  2403 		}
  2564 		}
  2404 
  2565 
  2405 		// Comments feeds
  2566 		// Comments feeds
  2406 		if ( $this->is_comment_feed && ! $this->is_singular ) {
  2567 		if ( $this->is_comment_feed && ! $this->is_singular ) {
  2407 			if ( $this->is_archive || $this->is_search ) {
  2568 			if ( $this->is_archive || $this->is_search ) {
  2408 				$cjoin = "JOIN {$wpdb->posts} ON ({$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID) $join ";
  2569 				$cjoin    = "JOIN {$wpdb->posts} ON ({$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID) $join ";
  2409 				$cwhere = "WHERE comment_approved = '1' $where";
  2570 				$cwhere   = "WHERE comment_approved = '1' $where";
  2410 				$cgroupby = "{$wpdb->comments}.comment_id";
  2571 				$cgroupby = "{$wpdb->comments}.comment_id";
  2411 			} else { // Other non singular e.g. front
  2572 			} else { // Other non singular e.g. front
  2412 				$cjoin = "JOIN {$wpdb->posts} ON ( {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID )";
  2573 				$cjoin    = "JOIN {$wpdb->posts} ON ( {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID )";
  2413 				$cwhere = "WHERE ( post_status = 'publish' OR ( post_status = 'inherit' AND post_type = 'attachment' ) ) AND comment_approved = '1'";
  2574 				$cwhere   = "WHERE ( post_status = 'publish' OR ( post_status = 'inherit' AND post_type = 'attachment' ) ) AND comment_approved = '1'";
  2414 				$cgroupby = '';
  2575 				$cgroupby = '';
  2415 			}
  2576 			}
  2416 
  2577 
  2417 			if ( !$q['suppress_filters'] ) {
  2578 			if ( ! $q['suppress_filters'] ) {
  2418 				/**
  2579 				/**
  2419 				 * Filters the JOIN clause of the comments feed query before sending.
  2580 				 * Filters the JOIN clause of the comments feed query before sending.
  2420 				 *
  2581 				 *
  2421 				 * @since 2.2.0
  2582 				 * @since 2.2.0
  2422 				 *
  2583 				 *
  2461 				 * @since 2.8.0
  2622 				 * @since 2.8.0
  2462 				 *
  2623 				 *
  2463 				 * @param string   $climits The JOIN clause of the query.
  2624 				 * @param string   $climits The JOIN clause of the query.
  2464 				 * @param WP_Query $this    The WP_Query instance (passed by reference).
  2625 				 * @param WP_Query $this    The WP_Query instance (passed by reference).
  2465 				 */
  2626 				 */
  2466 				$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) );
  2627 				$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option( 'posts_per_rss' ), &$this ) );
  2467 			}
  2628 			}
  2468 			$cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
  2629 			$cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
  2469 			$corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
  2630 			$corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
  2470 
  2631 
  2471 			$comments = (array) $wpdb->get_results("SELECT $distinct {$wpdb->comments}.* FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits");
  2632 			$comments = (array) $wpdb->get_results( "SELECT $distinct {$wpdb->comments}.* FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits" );
  2472 			// Convert to WP_Comment
  2633 			// Convert to WP_Comment
  2473 			$this->comments = array_map( 'get_comment', $comments );
  2634 			$this->comments      = array_map( 'get_comment', $comments );
  2474 			$this->comment_count = count($this->comments);
  2635 			$this->comment_count = count( $this->comments );
  2475 
  2636 
  2476 			$post_ids = array();
  2637 			$post_ids = array();
  2477 
  2638 
  2478 			foreach ( $this->comments as $comment )
  2639 			foreach ( $this->comments as $comment ) {
  2479 				$post_ids[] = (int) $comment->comment_post_ID;
  2640 				$post_ids[] = (int) $comment->comment_post_ID;
  2480 
  2641 			}
  2481 			$post_ids = join(',', $post_ids);
  2642 
  2482 			$join = '';
  2643 			$post_ids = join( ',', $post_ids );
       
  2644 			$join     = '';
  2483 			if ( $post_ids ) {
  2645 			if ( $post_ids ) {
  2484 				$where = "AND {$wpdb->posts}.ID IN ($post_ids) ";
  2646 				$where = "AND {$wpdb->posts}.ID IN ($post_ids) ";
  2485 			} else {
  2647 			} else {
  2486 				$where = "AND 0";
  2648 				$where = 'AND 0';
  2487 			}
  2649 			}
  2488 		}
  2650 		}
  2489 
  2651 
  2490 		$pieces = array( 'where', 'groupby', 'join', 'orderby', 'distinct', 'fields', 'limits' );
  2652 		$pieces = array( 'where', 'groupby', 'join', 'orderby', 'distinct', 'fields', 'limits' );
  2491 
  2653 
  2492 		/*
  2654 		/*
  2493 		 * Apply post-paging filters on where and join. Only plugins that
  2655 		 * Apply post-paging filters on where and join. Only plugins that
  2494 		 * manipulate paging queries should use these hooks.
  2656 		 * manipulate paging queries should use these hooks.
  2495 		 */
  2657 		 */
  2496 		if ( !$q['suppress_filters'] ) {
  2658 		if ( ! $q['suppress_filters'] ) {
  2497 			/**
  2659 			/**
  2498 			 * Filters the WHERE clause of the query.
  2660 			 * Filters the WHERE clause of the query.
  2499 			 *
  2661 			 *
  2500 			 * Specifically for manipulating paging queries.
  2662 			 * Specifically for manipulating paging queries.
  2501 			 *
  2663 			 *
  2574 			 * Covers the WHERE, GROUP BY, JOIN, ORDER BY, DISTINCT,
  2736 			 * Covers the WHERE, GROUP BY, JOIN, ORDER BY, DISTINCT,
  2575 			 * fields (SELECT), and LIMITS clauses.
  2737 			 * fields (SELECT), and LIMITS clauses.
  2576 			 *
  2738 			 *
  2577 			 * @since 3.1.0
  2739 			 * @since 3.1.0
  2578 			 *
  2740 			 *
  2579 			 * @param array    $clauses The list of clauses for the query.
  2741 			 * @param string[] $clauses Associative array of the clauses for the query.
  2580 			 * @param WP_Query $this    The WP_Query instance (passed by reference).
  2742 			 * @param WP_Query $this    The WP_Query instance (passed by reference).
  2581 			 */
  2743 			 */
  2582 			$clauses = (array) apply_filters_ref_array( 'posts_clauses', array( compact( $pieces ), &$this ) );
  2744 			$clauses = (array) apply_filters_ref_array( 'posts_clauses', array( compact( $pieces ), &$this ) );
  2583 
  2745 
  2584 			$where = isset( $clauses[ 'where' ] ) ? $clauses[ 'where' ] : '';
  2746 			$where    = isset( $clauses['where'] ) ? $clauses['where'] : '';
  2585 			$groupby = isset( $clauses[ 'groupby' ] ) ? $clauses[ 'groupby' ] : '';
  2747 			$groupby  = isset( $clauses['groupby'] ) ? $clauses['groupby'] : '';
  2586 			$join = isset( $clauses[ 'join' ] ) ? $clauses[ 'join' ] : '';
  2748 			$join     = isset( $clauses['join'] ) ? $clauses['join'] : '';
  2587 			$orderby = isset( $clauses[ 'orderby' ] ) ? $clauses[ 'orderby' ] : '';
  2749 			$orderby  = isset( $clauses['orderby'] ) ? $clauses['orderby'] : '';
  2588 			$distinct = isset( $clauses[ 'distinct' ] ) ? $clauses[ 'distinct' ] : '';
  2750 			$distinct = isset( $clauses['distinct'] ) ? $clauses['distinct'] : '';
  2589 			$fields = isset( $clauses[ 'fields' ] ) ? $clauses[ 'fields' ] : '';
  2751 			$fields   = isset( $clauses['fields'] ) ? $clauses['fields'] : '';
  2590 			$limits = isset( $clauses[ 'limits' ] ) ? $clauses[ 'limits' ] : '';
  2752 			$limits   = isset( $clauses['limits'] ) ? $clauses['limits'] : '';
  2591 		}
  2753 		}
  2592 
  2754 
  2593 		/**
  2755 		/**
  2594 		 * Fires to announce the query's current selection parameters.
  2756 		 * Fires to announce the query's current selection parameters.
  2595 		 *
  2757 		 *
  2603 
  2765 
  2604 		/*
  2766 		/*
  2605 		 * Filters again for the benefit of caching plugins.
  2767 		 * Filters again for the benefit of caching plugins.
  2606 		 * Regular plugins should use the hooks above.
  2768 		 * Regular plugins should use the hooks above.
  2607 		 */
  2769 		 */
  2608 		if ( !$q['suppress_filters'] ) {
  2770 		if ( ! $q['suppress_filters'] ) {
  2609 			/**
  2771 			/**
  2610 			 * Filters the WHERE clause of the query.
  2772 			 * Filters the WHERE clause of the query.
  2611 			 *
  2773 			 *
  2612 			 * For use by caching plugins.
  2774 			 * For use by caching plugins.
  2613 			 *
  2775 			 *
  2698 			 * Covers the WHERE, GROUP BY, JOIN, ORDER BY, DISTINCT,
  2860 			 * Covers the WHERE, GROUP BY, JOIN, ORDER BY, DISTINCT,
  2699 			 * fields (SELECT), and LIMITS clauses.
  2861 			 * fields (SELECT), and LIMITS clauses.
  2700 			 *
  2862 			 *
  2701 			 * @since 3.1.0
  2863 			 * @since 3.1.0
  2702 			 *
  2864 			 *
  2703 			 * @param array    $pieces The pieces of the query.
  2865 			 * @param string[] $pieces Associative array of the pieces of the query.
  2704 			 * @param WP_Query $this   The WP_Query instance (passed by reference).
  2866 			 * @param WP_Query $this   The WP_Query instance (passed by reference).
  2705 			 */
  2867 			 */
  2706 			$clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) );
  2868 			$clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) );
  2707 
  2869 
  2708 			$where = isset( $clauses[ 'where' ] ) ? $clauses[ 'where' ] : '';
  2870 			$where    = isset( $clauses['where'] ) ? $clauses['where'] : '';
  2709 			$groupby = isset( $clauses[ 'groupby' ] ) ? $clauses[ 'groupby' ] : '';
  2871 			$groupby  = isset( $clauses['groupby'] ) ? $clauses['groupby'] : '';
  2710 			$join = isset( $clauses[ 'join' ] ) ? $clauses[ 'join' ] : '';
  2872 			$join     = isset( $clauses['join'] ) ? $clauses['join'] : '';
  2711 			$orderby = isset( $clauses[ 'orderby' ] ) ? $clauses[ 'orderby' ] : '';
  2873 			$orderby  = isset( $clauses['orderby'] ) ? $clauses['orderby'] : '';
  2712 			$distinct = isset( $clauses[ 'distinct' ] ) ? $clauses[ 'distinct' ] : '';
  2874 			$distinct = isset( $clauses['distinct'] ) ? $clauses['distinct'] : '';
  2713 			$fields = isset( $clauses[ 'fields' ] ) ? $clauses[ 'fields' ] : '';
  2875 			$fields   = isset( $clauses['fields'] ) ? $clauses['fields'] : '';
  2714 			$limits = isset( $clauses[ 'limits' ] ) ? $clauses[ 'limits' ] : '';
  2876 			$limits   = isset( $clauses['limits'] ) ? $clauses['limits'] : '';
  2715 		}
  2877 		}
  2716 
  2878 
  2717 		if ( ! empty($groupby) )
  2879 		if ( ! empty( $groupby ) ) {
  2718 			$groupby = 'GROUP BY ' . $groupby;
  2880 			$groupby = 'GROUP BY ' . $groupby;
  2719 		if ( !empty( $orderby ) )
  2881 		}
       
  2882 		if ( ! empty( $orderby ) ) {
  2720 			$orderby = 'ORDER BY ' . $orderby;
  2883 			$orderby = 'ORDER BY ' . $orderby;
       
  2884 		}
  2721 
  2885 
  2722 		$found_rows = '';
  2886 		$found_rows = '';
  2723 		if ( !$q['no_found_rows'] && !empty($limits) )
  2887 		if ( ! $q['no_found_rows'] && ! empty( $limits ) ) {
  2724 			$found_rows = 'SQL_CALC_FOUND_ROWS';
  2888 			$found_rows = 'SQL_CALC_FOUND_ROWS';
       
  2889 		}
  2725 
  2890 
  2726 		$this->request = $old_request = "SELECT $found_rows $distinct $fields FROM {$wpdb->posts} $join WHERE 1=1 $where $groupby $orderby $limits";
  2891 		$this->request = $old_request = "SELECT $found_rows $distinct $fields FROM {$wpdb->posts} $join WHERE 1=1 $where $groupby $orderby $limits";
  2727 
  2892 
  2728 		if ( !$q['suppress_filters'] ) {
  2893 		if ( ! $q['suppress_filters'] ) {
  2729 			/**
  2894 			/**
  2730 			 * Filters the completed SQL query before sending.
  2895 			 * Filters the completed SQL query before sending.
  2731 			 *
  2896 			 *
  2732 			 * @since 2.0.0
  2897 			 * @since 2.0.0
  2733 			 *
  2898 			 *
  2758 		if ( 'ids' == $q['fields'] ) {
  2923 		if ( 'ids' == $q['fields'] ) {
  2759 			if ( null === $this->posts ) {
  2924 			if ( null === $this->posts ) {
  2760 				$this->posts = $wpdb->get_col( $this->request );
  2925 				$this->posts = $wpdb->get_col( $this->request );
  2761 			}
  2926 			}
  2762 
  2927 
  2763 			$this->posts = array_map( 'intval', $this->posts );
  2928 			$this->posts      = array_map( 'intval', $this->posts );
  2764 			$this->post_count = count( $this->posts );
  2929 			$this->post_count = count( $this->posts );
  2765 			$this->set_found_posts( $q, $limits );
  2930 			$this->set_found_posts( $q, $limits );
  2766 
  2931 
  2767 			return $this->posts;
  2932 			return $this->posts;
  2768 		}
  2933 		}
  2775 			$this->post_count = count( $this->posts );
  2940 			$this->post_count = count( $this->posts );
  2776 			$this->set_found_posts( $q, $limits );
  2941 			$this->set_found_posts( $q, $limits );
  2777 
  2942 
  2778 			$r = array();
  2943 			$r = array();
  2779 			foreach ( $this->posts as $key => $post ) {
  2944 			foreach ( $this->posts as $key => $post ) {
  2780 				$this->posts[ $key ]->ID = (int) $post->ID;
  2945 				$this->posts[ $key ]->ID          = (int) $post->ID;
  2781 				$this->posts[ $key ]->post_parent = (int) $post->post_parent;
  2946 				$this->posts[ $key ]->post_parent = (int) $post->post_parent;
  2782 
  2947 
  2783 				$r[ (int) $post->ID ] = (int) $post->post_parent;
  2948 				$r[ (int) $post->ID ] = (int) $post->post_parent;
  2784 			}
  2949 			}
  2785 
  2950 
  2786 			return $r;
  2951 			return $r;
  2787 		}
  2952 		}
  2788 
  2953 
  2789 		if ( null === $this->posts ) {
  2954 		if ( null === $this->posts ) {
  2790 			$split_the_query = ( $old_request == $this->request && "{$wpdb->posts}.*" == $fields && !empty( $limits ) && $q['posts_per_page'] < 500 );
  2955 			$split_the_query = ( $old_request == $this->request && "{$wpdb->posts}.*" == $fields && ! empty( $limits ) && $q['posts_per_page'] < 500 );
  2791 
  2956 
  2792 			/**
  2957 			/**
  2793 			 * Filters whether to split the query.
  2958 			 * Filters whether to split the query.
  2794 			 *
  2959 			 *
  2795 			 * Splitting the query will cause it to fetch just the IDs of the found posts
  2960 			 * Splitting the query will cause it to fetch just the IDs of the found posts
  2842 			/**
  3007 			/**
  2843 			 * Filters the raw post results array, prior to status checks.
  3008 			 * Filters the raw post results array, prior to status checks.
  2844 			 *
  3009 			 *
  2845 			 * @since 2.3.0
  3010 			 * @since 2.3.0
  2846 			 *
  3011 			 *
  2847 			 * @param array    $posts The post results array.
  3012 			 * @param WP_Post[] $posts Array of post objects.
  2848 			 * @param WP_Query $this The WP_Query instance (passed by reference).
  3013 			 * @param WP_Query  $this  The WP_Query instance (passed by reference).
  2849 			 */
  3014 			 */
  2850 			$this->posts = apply_filters_ref_array( 'posts_results', array( $this->posts, &$this ) );
  3015 			$this->posts = apply_filters_ref_array( 'posts_results', array( $this->posts, &$this ) );
  2851 		}
  3016 		}
  2852 
  3017 
  2853 		if ( !empty($this->posts) && $this->is_comment_feed && $this->is_singular ) {
  3018 		if ( ! empty( $this->posts ) && $this->is_comment_feed && $this->is_singular ) {
  2854 			/** This filter is documented in wp-includes/query.php */
  3019 			/** This filter is documented in wp-includes/query.php */
  2855 			$cjoin = apply_filters_ref_array( 'comment_feed_join', array( '', &$this ) );
  3020 			$cjoin = apply_filters_ref_array( 'comment_feed_join', array( '', &$this ) );
  2856 
  3021 
  2857 			/** This filter is documented in wp-includes/query.php */
  3022 			/** This filter is documented in wp-includes/query.php */
  2858 			$cwhere = apply_filters_ref_array( 'comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'", &$this ) );
  3023 			$cwhere = apply_filters_ref_array( 'comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'", &$this ) );
  2864 			/** This filter is documented in wp-includes/query.php */
  3029 			/** This filter is documented in wp-includes/query.php */
  2865 			$corderby = apply_filters_ref_array( 'comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
  3030 			$corderby = apply_filters_ref_array( 'comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
  2866 			$corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
  3031 			$corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
  2867 
  3032 
  2868 			/** This filter is documented in wp-includes/query.php */
  3033 			/** This filter is documented in wp-includes/query.php */
  2869 			$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) );
  3034 			$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option( 'posts_per_rss' ), &$this ) );
  2870 
  3035 
  2871 			$comments_request = "SELECT {$wpdb->comments}.* FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits";
  3036 			$comments_request = "SELECT {$wpdb->comments}.* FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits";
  2872 			$comments = $wpdb->get_results($comments_request);
  3037 			$comments         = $wpdb->get_results( $comments_request );
  2873 			// Convert to WP_Comment
  3038 			// Convert to WP_Comment
  2874 			$this->comments = array_map( 'get_comment', $comments );
  3039 			$this->comments      = array_map( 'get_comment', $comments );
  2875 			$this->comment_count = count($this->comments);
  3040 			$this->comment_count = count( $this->comments );
  2876 		}
  3041 		}
  2877 
  3042 
  2878 		// Check post status to determine if post should be displayed.
  3043 		// Check post status to determine if post should be displayed.
  2879 		if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) {
  3044 		if ( ! empty( $this->posts ) && ( $this->is_single || $this->is_page ) ) {
  2880 			$status = get_post_status($this->posts[0]);
  3045 			$status = get_post_status( $this->posts[0] );
  2881 			if ( 'attachment' === $this->posts[0]->post_type && 0 === (int) $this->posts[0]->post_parent ) {
  3046 			if ( 'attachment' === $this->posts[0]->post_type && 0 === (int) $this->posts[0]->post_parent ) {
  2882 				$this->is_page = false;
  3047 				$this->is_page       = false;
  2883 				$this->is_single = true;
  3048 				$this->is_single     = true;
  2884 				$this->is_attachment = true;
  3049 				$this->is_attachment = true;
  2885 			}
  3050 			}
  2886 			$post_status_obj = get_post_status_object($status);
  3051 			$post_status_obj = get_post_status_object( $status );
  2887 
  3052 
  2888 			// If the post_status was specifically requested, let it pass through.
  3053 			// If the post_status was specifically requested, let it pass through.
  2889 			if ( !$post_status_obj->public && ! in_array( $status, $q_status ) ) {
  3054 			if ( ! $post_status_obj->public && ! in_array( $status, $q_status ) ) {
  2890 
  3055 
  2891 				if ( ! is_user_logged_in() ) {
  3056 				if ( ! is_user_logged_in() ) {
  2892 					// User must be logged in to view unpublished posts.
  3057 					// User must be logged in to view unpublished posts.
  2893 					$this->posts = array();
  3058 					$this->posts = array();
  2894 				} else {
  3059 				} else {
  2895 					if  ( $post_status_obj->protected ) {
  3060 					if ( $post_status_obj->protected ) {
  2896 						// User must have edit permissions on the draft to preview.
  3061 						// User must have edit permissions on the draft to preview.
  2897 						if ( ! current_user_can($edit_cap, $this->posts[0]->ID) ) {
  3062 						if ( ! current_user_can( $edit_cap, $this->posts[0]->ID ) ) {
  2898 							$this->posts = array();
  3063 							$this->posts = array();
  2899 						} else {
  3064 						} else {
  2900 							$this->is_preview = true;
  3065 							$this->is_preview = true;
  2901 							if ( 'future' != $status )
  3066 							if ( 'future' != $status ) {
  2902 								$this->posts[0]->post_date = current_time('mysql');
  3067 								$this->posts[0]->post_date = current_time( 'mysql' );
       
  3068 							}
  2903 						}
  3069 						}
  2904 					} elseif ( $post_status_obj->private ) {
  3070 					} elseif ( $post_status_obj->private ) {
  2905 						if ( ! current_user_can($read_cap, $this->posts[0]->ID) )
  3071 						if ( ! current_user_can( $read_cap, $this->posts[0]->ID ) ) {
  2906 							$this->posts = array();
  3072 							$this->posts = array();
       
  3073 						}
  2907 					} else {
  3074 					} else {
  2908 						$this->posts = array();
  3075 						$this->posts = array();
  2909 					}
  3076 					}
  2910 				}
  3077 				}
  2911 			}
  3078 			}
  2922 				$this->posts[0] = get_post( apply_filters_ref_array( 'the_preview', array( $this->posts[0], &$this ) ) );
  3089 				$this->posts[0] = get_post( apply_filters_ref_array( 'the_preview', array( $this->posts[0], &$this ) ) );
  2923 			}
  3090 			}
  2924 		}
  3091 		}
  2925 
  3092 
  2926 		// Put sticky posts at the top of the posts array
  3093 		// Put sticky posts at the top of the posts array
  2927 		$sticky_posts = get_option('sticky_posts');
  3094 		$sticky_posts = get_option( 'sticky_posts' );
  2928 		if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) {
  3095 		if ( $this->is_home && $page <= 1 && is_array( $sticky_posts ) && ! empty( $sticky_posts ) && ! $q['ignore_sticky_posts'] ) {
  2929 			$num_posts = count($this->posts);
  3096 			$num_posts     = count( $this->posts );
  2930 			$sticky_offset = 0;
  3097 			$sticky_offset = 0;
  2931 			// Loop over posts and relocate stickies to the front.
  3098 			// Loop over posts and relocate stickies to the front.
  2932 			for ( $i = 0; $i < $num_posts; $i++ ) {
  3099 			for ( $i = 0; $i < $num_posts; $i++ ) {
  2933 				if ( in_array($this->posts[$i]->ID, $sticky_posts) ) {
  3100 				if ( in_array( $this->posts[ $i ]->ID, $sticky_posts ) ) {
  2934 					$sticky_post = $this->posts[$i];
  3101 					$sticky_post = $this->posts[ $i ];
  2935 					// Remove sticky from current position
  3102 					// Remove sticky from current position
  2936 					array_splice($this->posts, $i, 1);
  3103 					array_splice( $this->posts, $i, 1 );
  2937 					// Move to front, after other stickies
  3104 					// Move to front, after other stickies
  2938 					array_splice($this->posts, $sticky_offset, 0, array($sticky_post));
  3105 					array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) );
  2939 					// Increment the sticky offset. The next sticky will be placed at this offset.
  3106 					// Increment the sticky offset. The next sticky will be placed at this offset.
  2940 					$sticky_offset++;
  3107 					$sticky_offset++;
  2941 					// Remove post from sticky posts array
  3108 					// Remove post from sticky posts array
  2942 					$offset = array_search($sticky_post->ID, $sticky_posts);
  3109 					$offset = array_search( $sticky_post->ID, $sticky_posts );
  2943 					unset( $sticky_posts[$offset] );
  3110 					unset( $sticky_posts[ $offset ] );
  2944 				}
  3111 				}
  2945 			}
  3112 			}
  2946 
  3113 
  2947 			// If any posts have been excluded specifically, Ignore those that are sticky.
  3114 			// If any posts have been excluded specifically, Ignore those that are sticky.
  2948 			if ( !empty($sticky_posts) && !empty($q['post__not_in']) )
  3115 			if ( ! empty( $sticky_posts ) && ! empty( $q['post__not_in'] ) ) {
  2949 				$sticky_posts = array_diff($sticky_posts, $q['post__not_in']);
  3116 				$sticky_posts = array_diff( $sticky_posts, $q['post__not_in'] );
       
  3117 			}
  2950 
  3118 
  2951 			// Fetch sticky posts that weren't in the query results
  3119 			// Fetch sticky posts that weren't in the query results
  2952 			if ( !empty($sticky_posts) ) {
  3120 			if ( ! empty( $sticky_posts ) ) {
  2953 				$stickies = get_posts( array(
  3121 				$stickies = get_posts(
  2954 					'post__in' => $sticky_posts,
  3122 					array(
  2955 					'post_type' => $post_type,
  3123 						'post__in'    => $sticky_posts,
  2956 					'post_status' => 'publish',
  3124 						'post_type'   => $post_type,
  2957 					'nopaging' => true
  3125 						'post_status' => 'publish',
  2958 				) );
  3126 						'nopaging'    => true,
       
  3127 					)
       
  3128 				);
  2959 
  3129 
  2960 				foreach ( $stickies as $sticky_post ) {
  3130 				foreach ( $stickies as $sticky_post ) {
  2961 					array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) );
  3131 					array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) );
  2962 					$sticky_offset++;
  3132 					$sticky_offset++;
  2963 				}
  3133 				}
  2974 			 * Filters the array of retrieved posts after they've been fetched and
  3144 			 * Filters the array of retrieved posts after they've been fetched and
  2975 			 * internally processed.
  3145 			 * internally processed.
  2976 			 *
  3146 			 *
  2977 			 * @since 1.5.0
  3147 			 * @since 1.5.0
  2978 			 *
  3148 			 *
  2979 			 * @param array    $posts The array of retrieved posts.
  3149 			 * @param WP_Post[] $posts Array of post objects.
  2980 			 * @param WP_Query $this The WP_Query instance (passed by reference).
  3150 			 * @param WP_Query  $this The WP_Query instance (passed by reference).
  2981 			 */
  3151 			 */
  2982 			$this->posts = apply_filters_ref_array( 'the_posts', array( $this->posts, &$this ) );
  3152 			$this->posts = apply_filters_ref_array( 'the_posts', array( $this->posts, &$this ) );
  2983 		}
  3153 		}
  2984 
  3154 
  2985 		// Ensure that any posts added/modified via one of the filters above are
  3155 		// Ensure that any posts added/modified via one of the filters above are
  2987 		if ( $this->posts ) {
  3157 		if ( $this->posts ) {
  2988 			$this->post_count = count( $this->posts );
  3158 			$this->post_count = count( $this->posts );
  2989 
  3159 
  2990 			$this->posts = array_map( 'get_post', $this->posts );
  3160 			$this->posts = array_map( 'get_post', $this->posts );
  2991 
  3161 
  2992 			if ( $q['cache_results'] )
  3162 			if ( $q['cache_results'] ) {
  2993 				update_post_caches($this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache']);
  3163 				update_post_caches( $this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
       
  3164 			}
  2994 
  3165 
  2995 			$this->post = reset( $this->posts );
  3166 			$this->post = reset( $this->posts );
  2996 		} else {
  3167 		} else {
  2997 			$this->post_count = 0;
  3168 			$this->post_count = 0;
  2998 			$this->posts = array();
  3169 			$this->posts      = array();
  2999 		}
  3170 		}
  3000 
  3171 
  3001 		if ( $q['lazy_load_term_meta'] ) {
  3172 		if ( $q['lazy_load_term_meta'] ) {
  3002 			wp_queue_posts_for_term_meta_lazyload( $this->posts );
  3173 			wp_queue_posts_for_term_meta_lazyload( $this->posts );
  3003 		}
  3174 		}
  3016 	 */
  3187 	 */
  3017 	private function set_found_posts( $q, $limits ) {
  3188 	private function set_found_posts( $q, $limits ) {
  3018 		global $wpdb;
  3189 		global $wpdb;
  3019 		// Bail if posts is an empty array. Continue if posts is an empty string,
  3190 		// Bail if posts is an empty array. Continue if posts is an empty string,
  3020 		// null, or false to accommodate caching plugins that fill posts later.
  3191 		// null, or false to accommodate caching plugins that fill posts later.
  3021 		if ( $q['no_found_rows'] || ( is_array( $this->posts ) && ! $this->posts ) )
  3192 		if ( $q['no_found_rows'] || ( is_array( $this->posts ) && ! $this->posts ) ) {
  3022 			return;
  3193 			return;
       
  3194 		}
  3023 
  3195 
  3024 		if ( ! empty( $limits ) ) {
  3196 		if ( ! empty( $limits ) ) {
  3025 			/**
  3197 			/**
  3026 			 * Filters the query to run for retrieving the found posts.
  3198 			 * Filters the query to run for retrieving the found posts.
  3027 			 *
  3199 			 *
  3033 			$this->found_posts = $wpdb->get_var( apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ) );
  3205 			$this->found_posts = $wpdb->get_var( apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ) );
  3034 		} else {
  3206 		} else {
  3035 			if ( is_array( $this->posts ) ) {
  3207 			if ( is_array( $this->posts ) ) {
  3036 				$this->found_posts = count( $this->posts );
  3208 				$this->found_posts = count( $this->posts );
  3037 			} else {
  3209 			} else {
  3038 				if ( null === $this->posts ) {  
  3210 				if ( null === $this->posts ) {
  3039 					$this->found_posts = 0;
  3211 					$this->found_posts = 0;
  3040 				} else {
  3212 				} else {
  3041 					$this->found_posts = 1;
  3213 					$this->found_posts = 1;
  3042 				}
  3214 				}
  3043 			}
  3215 			}
  3051 		 * @param int      $found_posts The number of posts found.
  3223 		 * @param int      $found_posts The number of posts found.
  3052 		 * @param WP_Query $this        The WP_Query instance (passed by reference).
  3224 		 * @param WP_Query $this        The WP_Query instance (passed by reference).
  3053 		 */
  3225 		 */
  3054 		$this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
  3226 		$this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
  3055 
  3227 
  3056 		if ( ! empty( $limits ) )
  3228 		if ( ! empty( $limits ) ) {
  3057 			$this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] );
  3229 			$this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] );
       
  3230 		}
  3058 	}
  3231 	}
  3059 
  3232 
  3060 	/**
  3233 	/**
  3061 	 * Set up the next post and iterate current post index.
  3234 	 * Set up the next post and iterate current post index.
  3062 	 *
  3235 	 *
  3066 	 */
  3239 	 */
  3067 	public function next_post() {
  3240 	public function next_post() {
  3068 
  3241 
  3069 		$this->current_post++;
  3242 		$this->current_post++;
  3070 
  3243 
  3071 		$this->post = $this->posts[$this->current_post];
  3244 		$this->post = $this->posts[ $this->current_post ];
  3072 		return $this->post;
  3245 		return $this->post;
  3073 	}
  3246 	}
  3074 
  3247 
  3075 	/**
  3248 	/**
  3076 	 * Sets up the current post.
  3249 	 * Sets up the current post.
  3084 	 */
  3257 	 */
  3085 	public function the_post() {
  3258 	public function the_post() {
  3086 		global $post;
  3259 		global $post;
  3087 		$this->in_the_loop = true;
  3260 		$this->in_the_loop = true;
  3088 
  3261 
  3089 		if ( $this->current_post == -1 ) // loop has just started
  3262 		if ( $this->current_post == -1 ) { // loop has just started
  3090 			/**
  3263 			/**
  3091 			 * Fires once the loop is started.
  3264 			 * Fires once the loop is started.
  3092 			 *
  3265 			 *
  3093 			 * @since 2.0.0
  3266 			 * @since 2.0.0
  3094 			 *
  3267 			 *
  3095 			 * @param WP_Query $this The WP_Query instance (passed by reference).
  3268 			 * @param WP_Query $this The WP_Query instance (passed by reference).
  3096 			 */
  3269 			 */
  3097 			do_action_ref_array( 'loop_start', array( &$this ) );
  3270 			do_action_ref_array( 'loop_start', array( &$this ) );
       
  3271 		}
  3098 
  3272 
  3099 		$post = $this->next_post();
  3273 		$post = $this->next_post();
  3100 		$this->setup_postdata( $post );
  3274 		$this->setup_postdata( $post );
  3101 	}
  3275 	}
  3102 
  3276 
  3158 	 * @return WP_Comment Comment object.
  3332 	 * @return WP_Comment Comment object.
  3159 	 */
  3333 	 */
  3160 	public function next_comment() {
  3334 	public function next_comment() {
  3161 		$this->current_comment++;
  3335 		$this->current_comment++;
  3162 
  3336 
  3163 		$this->comment = $this->comments[$this->current_comment];
  3337 		$this->comment = $this->comments[ $this->current_comment ];
  3164 		return $this->comment;
  3338 		return $this->comment;
  3165 	}
  3339 	}
  3166 
  3340 
  3167 	/**
  3341 	/**
  3168 	 * Sets up the current comment.
  3342 	 * Sets up the current comment.
  3220 	 * Sets up the WordPress query by parsing query string.
  3394 	 * Sets up the WordPress query by parsing query string.
  3221 	 *
  3395 	 *
  3222 	 * @since 1.5.0
  3396 	 * @since 1.5.0
  3223 	 *
  3397 	 *
  3224 	 * @param string|array $query URL query string or array of query arguments.
  3398 	 * @param string|array $query URL query string or array of query arguments.
  3225 	 * @return array List of posts.
  3399 	 * @return WP_Post[]|int[] Array of post objects or post IDs.
  3226 	 */
  3400 	 */
  3227 	public function query( $query ) {
  3401 	public function query( $query ) {
  3228 		$this->init();
  3402 		$this->init();
  3229 		$this->query = $this->query_vars = wp_parse_args( $query );
  3403 		$this->query = $this->query_vars = wp_parse_args( $query );
  3230 		return $this->get_posts();
  3404 		return $this->get_posts();
  3240 	 * @since 1.5.0
  3414 	 * @since 1.5.0
  3241 	 *
  3415 	 *
  3242 	 * @return object
  3416 	 * @return object
  3243 	 */
  3417 	 */
  3244 	public function get_queried_object() {
  3418 	public function get_queried_object() {
  3245 		if ( isset($this->queried_object) )
  3419 		if ( isset( $this->queried_object ) ) {
  3246 			return $this->queried_object;
  3420 			return $this->queried_object;
  3247 
  3421 		}
  3248 		$this->queried_object = null;
  3422 
       
  3423 		$this->queried_object    = null;
  3249 		$this->queried_object_id = null;
  3424 		$this->queried_object_id = null;
  3250 
  3425 
  3251 		if ( $this->is_category || $this->is_tag || $this->is_tax ) {
  3426 		if ( $this->is_category || $this->is_tag || $this->is_tax ) {
  3252 			if ( $this->is_category ) {
  3427 			if ( $this->is_category ) {
  3253 				if ( $this->get( 'cat' ) ) {
  3428 				if ( $this->get( 'cat' ) ) {
  3263 				}
  3438 				}
  3264 			} else {
  3439 			} else {
  3265 				// For other tax queries, grab the first term from the first clause.
  3440 				// For other tax queries, grab the first term from the first clause.
  3266 				if ( ! empty( $this->tax_query->queried_terms ) ) {
  3441 				if ( ! empty( $this->tax_query->queried_terms ) ) {
  3267 					$queried_taxonomies = array_keys( $this->tax_query->queried_terms );
  3442 					$queried_taxonomies = array_keys( $this->tax_query->queried_terms );
  3268 					$matched_taxonomy = reset( $queried_taxonomies );
  3443 					$matched_taxonomy   = reset( $queried_taxonomies );
  3269 					$query = $this->tax_query->queried_terms[ $matched_taxonomy ];
  3444 					$query              = $this->tax_query->queried_terms[ $matched_taxonomy ];
  3270 
  3445 
  3271 					if ( ! empty( $query['terms'] ) ) {
  3446 					if ( ! empty( $query['terms'] ) ) {
  3272 						if ( 'term_id' == $query['field'] ) {
  3447 						if ( 'term_id' == $query['field'] ) {
  3273 							$term = get_term( reset( $query['terms'] ), $matched_taxonomy );
  3448 							$term = get_term( reset( $query['terms'] ), $matched_taxonomy );
  3274 						} else {
  3449 						} else {
  3276 						}
  3451 						}
  3277 					}
  3452 					}
  3278 				}
  3453 				}
  3279 			}
  3454 			}
  3280 
  3455 
  3281 			if ( ! empty( $term ) && ! is_wp_error( $term ) )  {
  3456 			if ( ! empty( $term ) && ! is_wp_error( $term ) ) {
  3282 				$this->queried_object = $term;
  3457 				$this->queried_object    = $term;
  3283 				$this->queried_object_id = (int) $term->term_id;
  3458 				$this->queried_object_id = (int) $term->term_id;
  3284 
  3459 
  3285 				if ( $this->is_category && 'category' === $this->queried_object->taxonomy )
  3460 				if ( $this->is_category && 'category' === $this->queried_object->taxonomy ) {
  3286 					_make_cat_compat( $this->queried_object );
  3461 					_make_cat_compat( $this->queried_object );
       
  3462 				}
  3287 			}
  3463 			}
  3288 		} elseif ( $this->is_post_type_archive ) {
  3464 		} elseif ( $this->is_post_type_archive ) {
  3289 			$post_type = $this->get( 'post_type' );
  3465 			$post_type = $this->get( 'post_type' );
  3290 			if ( is_array( $post_type ) )
  3466 			if ( is_array( $post_type ) ) {
  3291 				$post_type = reset( $post_type );
  3467 				$post_type = reset( $post_type );
       
  3468 			}
  3292 			$this->queried_object = get_post_type_object( $post_type );
  3469 			$this->queried_object = get_post_type_object( $post_type );
  3293 		} elseif ( $this->is_posts_page ) {
  3470 		} elseif ( $this->is_posts_page ) {
  3294 			$page_for_posts = get_option('page_for_posts');
  3471 			$page_for_posts          = get_option( 'page_for_posts' );
  3295 			$this->queried_object = get_post( $page_for_posts );
  3472 			$this->queried_object    = get_post( $page_for_posts );
  3296 			$this->queried_object_id = (int) $this->queried_object->ID;
  3473 			$this->queried_object_id = (int) $this->queried_object->ID;
  3297 		} elseif ( $this->is_singular && ! empty( $this->post ) ) {
  3474 		} elseif ( $this->is_singular && ! empty( $this->post ) ) {
  3298 			$this->queried_object = $this->post;
  3475 			$this->queried_object    = $this->post;
  3299 			$this->queried_object_id = (int) $this->post->ID;
  3476 			$this->queried_object_id = (int) $this->post->ID;
  3300 		} elseif ( $this->is_author ) {
  3477 		} elseif ( $this->is_author ) {
  3301 			$this->queried_object_id = (int) $this->get('author');
  3478 			$this->queried_object_id = (int) $this->get( 'author' );
  3302 			$this->queried_object = get_userdata( $this->queried_object_id );
  3479 			$this->queried_object    = get_userdata( $this->queried_object_id );
  3303 		}
  3480 		}
  3304 
  3481 
  3305 		return $this->queried_object;
  3482 		return $this->queried_object;
  3306 	}
  3483 	}
  3307 
  3484 
  3313 	 * @return int
  3490 	 * @return int
  3314 	 */
  3491 	 */
  3315 	public function get_queried_object_id() {
  3492 	public function get_queried_object_id() {
  3316 		$this->get_queried_object();
  3493 		$this->get_queried_object();
  3317 
  3494 
  3318 		if ( isset($this->queried_object_id) ) {
  3495 		if ( isset( $this->queried_object_id ) ) {
  3319 			return $this->queried_object_id;
  3496 			return $this->queried_object_id;
  3320 		}
  3497 		}
  3321 
  3498 
  3322 		return 0;
  3499 		return 0;
  3323 	}
  3500 	}
  3368 	/**
  3545 	/**
  3369 	 * Make private/protected methods readable for backward compatibility.
  3546 	 * Make private/protected methods readable for backward compatibility.
  3370 	 *
  3547 	 *
  3371 	 * @since 4.0.0
  3548 	 * @since 4.0.0
  3372 	 *
  3549 	 *
  3373 	 * @param callable $name      Method to call.
  3550 	 * @param string   $name      Method to call.
  3374 	 * @param array    $arguments Arguments to pass when calling.
  3551 	 * @param array    $arguments Arguments to pass when calling.
  3375 	 * @return mixed|false Return value of the callback, false otherwise.
  3552 	 * @return mixed|false Return value of the callback, false otherwise.
  3376 	 */
  3553 	 */
  3377 	public function __call( $name, $arguments ) {
  3554 	public function __call( $name, $arguments ) {
  3378 		if ( in_array( $name, $this->compat_methods ) ) {
  3555 		if ( in_array( $name, $this->compat_methods ) ) {
  3380 		}
  3557 		}
  3381 		return false;
  3558 		return false;
  3382 	}
  3559 	}
  3383 
  3560 
  3384 	/**
  3561 	/**
  3385  	 * Is the query for an existing archive page?
  3562 	 * Is the query for an existing archive page?
  3386  	 *
  3563 	 *
  3387  	 * Month, Year, Category, Author, Post Type archive...
  3564 	 * Month, Year, Category, Author, Post Type archive...
  3388 	 *
  3565 	 *
  3389  	 * @since 3.1.0
  3566 	 * @since 3.1.0
  3390  	 *
  3567 	 *
  3391  	 * @return bool
  3568 	 * @return bool
  3392  	 */
  3569 	 */
  3393 	public function is_archive() {
  3570 	public function is_archive() {
  3394 		return (bool) $this->is_archive;
  3571 		return (bool) $this->is_archive;
  3395 	}
  3572 	}
  3396 
  3573 
  3397 	/**
  3574 	/**
  3401 	 *
  3578 	 *
  3402 	 * @param mixed $post_types Optional. Post type or array of posts types to check against.
  3579 	 * @param mixed $post_types Optional. Post type or array of posts types to check against.
  3403 	 * @return bool
  3580 	 * @return bool
  3404 	 */
  3581 	 */
  3405 	public function is_post_type_archive( $post_types = '' ) {
  3582 	public function is_post_type_archive( $post_types = '' ) {
  3406 		if ( empty( $post_types ) || ! $this->is_post_type_archive )
  3583 		if ( empty( $post_types ) || ! $this->is_post_type_archive ) {
  3407 			return (bool) $this->is_post_type_archive;
  3584 			return (bool) $this->is_post_type_archive;
       
  3585 		}
  3408 
  3586 
  3409 		$post_type = $this->get( 'post_type' );
  3587 		$post_type = $this->get( 'post_type' );
  3410 		if ( is_array( $post_type ) )
  3588 		if ( is_array( $post_type ) ) {
  3411 			$post_type = reset( $post_type );
  3589 			$post_type = reset( $post_type );
       
  3590 		}
  3412 		$post_type_object = get_post_type_object( $post_type );
  3591 		$post_type_object = get_post_type_object( $post_type );
  3413 
  3592 
  3414 		return in_array( $post_type_object->name, (array) $post_types );
  3593 		return in_array( $post_type_object->name, (array) $post_types );
  3415 	}
  3594 	}
  3416 
  3595 
  3455 	 *
  3634 	 *
  3456 	 * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames
  3635 	 * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames
  3457 	 * @return bool
  3636 	 * @return bool
  3458 	 */
  3637 	 */
  3459 	public function is_author( $author = '' ) {
  3638 	public function is_author( $author = '' ) {
  3460 		if ( !$this->is_author )
  3639 		if ( ! $this->is_author ) {
  3461 			return false;
  3640 			return false;
  3462 
  3641 		}
  3463 		if ( empty($author) )
  3642 
       
  3643 		if ( empty( $author ) ) {
  3464 			return true;
  3644 			return true;
       
  3645 		}
  3465 
  3646 
  3466 		$author_obj = $this->get_queried_object();
  3647 		$author_obj = $this->get_queried_object();
  3467 
  3648 
  3468 		$author = array_map( 'strval', (array) $author );
  3649 		$author = array_map( 'strval', (array) $author );
  3469 
  3650 
  3470 		if ( in_array( (string) $author_obj->ID, $author ) )
  3651 		if ( in_array( (string) $author_obj->ID, $author ) ) {
  3471 			return true;
  3652 			return true;
  3472 		elseif ( in_array( $author_obj->nickname, $author ) )
  3653 		} elseif ( in_array( $author_obj->nickname, $author ) ) {
  3473 			return true;
  3654 			return true;
  3474 		elseif ( in_array( $author_obj->user_nicename, $author ) )
  3655 		} elseif ( in_array( $author_obj->user_nicename, $author ) ) {
  3475 			return true;
  3656 			return true;
       
  3657 		}
  3476 
  3658 
  3477 		return false;
  3659 		return false;
  3478 	}
  3660 	}
  3479 
  3661 
  3480 	/**
  3662 	/**
  3487 	 *
  3669 	 *
  3488 	 * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs.
  3670 	 * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs.
  3489 	 * @return bool
  3671 	 * @return bool
  3490 	 */
  3672 	 */
  3491 	public function is_category( $category = '' ) {
  3673 	public function is_category( $category = '' ) {
  3492 		if ( !$this->is_category )
  3674 		if ( ! $this->is_category ) {
  3493 			return false;
  3675 			return false;
  3494 
  3676 		}
  3495 		if ( empty($category) )
  3677 
       
  3678 		if ( empty( $category ) ) {
  3496 			return true;
  3679 			return true;
       
  3680 		}
  3497 
  3681 
  3498 		$cat_obj = $this->get_queried_object();
  3682 		$cat_obj = $this->get_queried_object();
  3499 
  3683 
  3500 		$category = array_map( 'strval', (array) $category );
  3684 		$category = array_map( 'strval', (array) $category );
  3501 
  3685 
  3502 		if ( in_array( (string) $cat_obj->term_id, $category ) )
  3686 		if ( in_array( (string) $cat_obj->term_id, $category ) ) {
  3503 			return true;
  3687 			return true;
  3504 		elseif ( in_array( $cat_obj->name, $category ) )
  3688 		} elseif ( in_array( $cat_obj->name, $category ) ) {
  3505 			return true;
  3689 			return true;
  3506 		elseif ( in_array( $cat_obj->slug, $category ) )
  3690 		} elseif ( in_array( $cat_obj->slug, $category ) ) {
  3507 			return true;
  3691 			return true;
       
  3692 		}
  3508 
  3693 
  3509 		return false;
  3694 		return false;
  3510 	}
  3695 	}
  3511 
  3696 
  3512 	/**
  3697 	/**
  3519 	 *
  3704 	 *
  3520 	 * @param mixed $tag Optional. Tag ID, name, slug, or array of Tag IDs, names, and slugs.
  3705 	 * @param mixed $tag Optional. Tag ID, name, slug, or array of Tag IDs, names, and slugs.
  3521 	 * @return bool
  3706 	 * @return bool
  3522 	 */
  3707 	 */
  3523 	public function is_tag( $tag = '' ) {
  3708 	public function is_tag( $tag = '' ) {
  3524 		if ( ! $this->is_tag )
  3709 		if ( ! $this->is_tag ) {
  3525 			return false;
  3710 			return false;
  3526 
  3711 		}
  3527 		if ( empty( $tag ) )
  3712 
       
  3713 		if ( empty( $tag ) ) {
  3528 			return true;
  3714 			return true;
       
  3715 		}
  3529 
  3716 
  3530 		$tag_obj = $this->get_queried_object();
  3717 		$tag_obj = $this->get_queried_object();
  3531 
  3718 
  3532 		$tag = array_map( 'strval', (array) $tag );
  3719 		$tag = array_map( 'strval', (array) $tag );
  3533 
  3720 
  3534 		if ( in_array( (string) $tag_obj->term_id, $tag ) )
  3721 		if ( in_array( (string) $tag_obj->term_id, $tag ) ) {
  3535 			return true;
  3722 			return true;
  3536 		elseif ( in_array( $tag_obj->name, $tag ) )
  3723 		} elseif ( in_array( $tag_obj->name, $tag ) ) {
  3537 			return true;
  3724 			return true;
  3538 		elseif ( in_array( $tag_obj->slug, $tag ) )
  3725 		} elseif ( in_array( $tag_obj->slug, $tag ) ) {
  3539 			return true;
  3726 			return true;
       
  3727 		}
  3540 
  3728 
  3541 		return false;
  3729 		return false;
  3542 	}
  3730 	}
  3543 
  3731 
  3544 	/**
  3732 	/**
  3560 	 * @return bool True for custom taxonomy archive pages, false for built-in taxonomies (category and tag archives).
  3748 	 * @return bool True for custom taxonomy archive pages, false for built-in taxonomies (category and tag archives).
  3561 	 */
  3749 	 */
  3562 	public function is_tax( $taxonomy = '', $term = '' ) {
  3750 	public function is_tax( $taxonomy = '', $term = '' ) {
  3563 		global $wp_taxonomies;
  3751 		global $wp_taxonomies;
  3564 
  3752 
  3565 		if ( !$this->is_tax )
  3753 		if ( ! $this->is_tax ) {
  3566 			return false;
  3754 			return false;
  3567 
  3755 		}
  3568 		if ( empty( $taxonomy ) )
  3756 
       
  3757 		if ( empty( $taxonomy ) ) {
  3569 			return true;
  3758 			return true;
       
  3759 		}
  3570 
  3760 
  3571 		$queried_object = $this->get_queried_object();
  3761 		$queried_object = $this->get_queried_object();
  3572 		$tax_array = array_intersect( array_keys( $wp_taxonomies ), (array) $taxonomy );
  3762 		$tax_array      = array_intersect( array_keys( $wp_taxonomies ), (array) $taxonomy );
  3573 		$term_array = (array) $term;
  3763 		$term_array     = (array) $term;
  3574 
  3764 
  3575 		// Check that the taxonomy matches.
  3765 		// Check that the taxonomy matches.
  3576 		if ( ! ( isset( $queried_object->taxonomy ) && count( $tax_array ) && in_array( $queried_object->taxonomy, $tax_array ) ) )
  3766 		if ( ! ( isset( $queried_object->taxonomy ) && count( $tax_array ) && in_array( $queried_object->taxonomy, $tax_array ) ) ) {
  3577 			return false;
  3767 			return false;
       
  3768 		}
  3578 
  3769 
  3579 		// Only a Taxonomy provided.
  3770 		// Only a Taxonomy provided.
  3580 		if ( empty( $term ) )
  3771 		if ( empty( $term ) ) {
  3581 			return true;
  3772 			return true;
       
  3773 		}
  3582 
  3774 
  3583 		return isset( $queried_object->term_id ) &&
  3775 		return isset( $queried_object->term_id ) &&
  3584 			count( array_intersect(
  3776 			count(
  3585 				array( $queried_object->term_id, $queried_object->name, $queried_object->slug ),
  3777 				array_intersect(
  3586 				$term_array
  3778 					array( $queried_object->term_id, $queried_object->name, $queried_object->slug ),
  3587 			) );
  3779 					$term_array
       
  3780 				)
       
  3781 			);
  3588 	}
  3782 	}
  3589 
  3783 
  3590 	/**
  3784 	/**
  3591 	 * Whether the current URL is within the comments popup window.
  3785 	 * Whether the current URL is within the comments popup window.
  3592 	 *
  3786 	 *
  3630 	 *
  3824 	 *
  3631 	 * @param string|array $feeds Optional feed types to check.
  3825 	 * @param string|array $feeds Optional feed types to check.
  3632 	 * @return bool
  3826 	 * @return bool
  3633 	 */
  3827 	 */
  3634 	public function is_feed( $feeds = '' ) {
  3828 	public function is_feed( $feeds = '' ) {
  3635 		if ( empty( $feeds ) || ! $this->is_feed )
  3829 		if ( empty( $feeds ) || ! $this->is_feed ) {
  3636 			return (bool) $this->is_feed;
  3830 			return (bool) $this->is_feed;
       
  3831 		}
  3637 		$qv = $this->get( 'feed' );
  3832 		$qv = $this->get( 'feed' );
  3638 		if ( 'feed' == $qv )
  3833 		if ( 'feed' == $qv ) {
  3639 			$qv = get_default_feed();
  3834 			$qv = get_default_feed();
       
  3835 		}
  3640 		return in_array( $qv, (array) $feeds );
  3836 		return in_array( $qv, (array) $feeds );
  3641 	}
  3837 	}
  3642 
  3838 
  3643 	/**
  3839 	/**
  3644 	 * Is the query for a comments feed?
  3840 	 * Is the query for a comments feed?
  3667 	 *
  3863 	 *
  3668 	 * @return bool True, if front of site.
  3864 	 * @return bool True, if front of site.
  3669 	 */
  3865 	 */
  3670 	public function is_front_page() {
  3866 	public function is_front_page() {
  3671 		// most likely case
  3867 		// most likely case
  3672 		if ( 'posts' == get_option( 'show_on_front') && $this->is_home() )
  3868 		if ( 'posts' == get_option( 'show_on_front' ) && $this->is_home() ) {
  3673 			return true;
  3869 			return true;
  3674 		elseif ( 'page' == get_option( 'show_on_front') && get_option( 'page_on_front' ) && $this->is_page( get_option( 'page_on_front' ) ) )
  3870 		} elseif ( 'page' == get_option( 'show_on_front' ) && get_option( 'page_on_front' ) && $this->is_page( get_option( 'page_on_front' ) ) ) {
  3675 			return true;
  3871 			return true;
  3676 		else
  3872 		} else {
  3677 			return false;
  3873 			return false;
       
  3874 		}
  3678 	}
  3875 	}
  3679 
  3876 
  3680 	/**
  3877 	/**
  3681 	 * Is the query for the blog homepage?
  3878 	 * Is the query for the blog homepage?
  3682 	 *
  3879 	 *
  3696 	public function is_home() {
  3893 	public function is_home() {
  3697 		return (bool) $this->is_home;
  3894 		return (bool) $this->is_home;
  3698 	}
  3895 	}
  3699 
  3896 
  3700 	/**
  3897 	/**
       
  3898 	 * Is the query for the Privacy Policy page?
       
  3899 	 *
       
  3900 	 * This is the page which shows the Privacy Policy content of your site.
       
  3901 	 *
       
  3902 	 * Depends on the site's "Change your Privacy Policy page" Privacy Settings 'wp_page_for_privacy_policy'.
       
  3903 	 *
       
  3904 	 * This function will return true only on the page you set as the "Privacy Policy page".
       
  3905 	 *
       
  3906 	 * @since 5.2.0
       
  3907 	 *
       
  3908 	 * @return bool True, if Privacy Policy page.
       
  3909 	 */
       
  3910 	public function is_privacy_policy() {
       
  3911 		if ( get_option( 'wp_page_for_privacy_policy' ) && $this->is_page( get_option( 'wp_page_for_privacy_policy' ) ) ) {
       
  3912 			return true;
       
  3913 		} else {
       
  3914 			return false;
       
  3915 		}
       
  3916 	}
       
  3917 
       
  3918 	/**
  3701 	 * Is the query for an existing month archive?
  3919 	 * Is the query for an existing month archive?
  3702 	 *
  3920 	 *
  3703 	 * @since 3.1.0
  3921 	 * @since 3.1.0
  3704 	 *
  3922 	 *
  3705 	 * @return bool
  3923 	 * @return bool
  3721 	 *
  3939 	 *
  3722 	 * @param int|string|array $page Optional. Page ID, title, slug, path, or array of such. Default empty.
  3940 	 * @param int|string|array $page Optional. Page ID, title, slug, path, or array of such. Default empty.
  3723 	 * @return bool Whether the query is for an existing single page.
  3941 	 * @return bool Whether the query is for an existing single page.
  3724 	 */
  3942 	 */
  3725 	public function is_page( $page = '' ) {
  3943 	public function is_page( $page = '' ) {
  3726 		if ( !$this->is_page )
  3944 		if ( ! $this->is_page ) {
  3727 			return false;
  3945 			return false;
  3728 
  3946 		}
  3729 		if ( empty( $page ) )
  3947 
       
  3948 		if ( empty( $page ) ) {
  3730 			return true;
  3949 			return true;
       
  3950 		}
  3731 
  3951 
  3732 		$page_obj = $this->get_queried_object();
  3952 		$page_obj = $this->get_queried_object();
  3733 
  3953 
  3734 		$page = array_map( 'strval', (array) $page );
  3954 		$page = array_map( 'strval', (array) $page );
  3735 
  3955 
  3814 	 *
  4034 	 *
  3815 	 * @param int|string|array $post Optional. Post ID, title, slug, path, or array of such. Default empty.
  4035 	 * @param int|string|array $post Optional. Post ID, title, slug, path, or array of such. Default empty.
  3816 	 * @return bool Whether the query is for an existing single post.
  4036 	 * @return bool Whether the query is for an existing single post.
  3817 	 */
  4037 	 */
  3818 	public function is_single( $post = '' ) {
  4038 	public function is_single( $post = '' ) {
  3819 		if ( !$this->is_single )
  4039 		if ( ! $this->is_single ) {
  3820 			return false;
  4040 			return false;
  3821 
  4041 		}
  3822 		if ( empty($post) )
  4042 
       
  4043 		if ( empty( $post ) ) {
  3823 			return true;
  4044 			return true;
       
  4045 		}
  3824 
  4046 
  3825 		$post_obj = $this->get_queried_object();
  4047 		$post_obj = $this->get_queried_object();
  3826 
  4048 
  3827 		$post = array_map( 'strval', (array) $post );
  4049 		$post = array_map( 'strval', (array) $post );
  3828 
  4050 
  3861 	 *
  4083 	 *
  3862 	 * @param string|array $post_types Optional. Post type or array of post types. Default empty.
  4084 	 * @param string|array $post_types Optional. Post type or array of post types. Default empty.
  3863 	 * @return bool Whether the query is for an existing single post of any of the given post types.
  4085 	 * @return bool Whether the query is for an existing single post of any of the given post types.
  3864 	 */
  4086 	 */
  3865 	public function is_singular( $post_types = '' ) {
  4087 	public function is_singular( $post_types = '' ) {
  3866 		if ( empty( $post_types ) || !$this->is_singular )
  4088 		if ( empty( $post_types ) || ! $this->is_singular ) {
  3867 			return (bool) $this->is_singular;
  4089 			return (bool) $this->is_singular;
       
  4090 		}
  3868 
  4091 
  3869 		$post_obj = $this->get_queried_object();
  4092 		$post_obj = $this->get_queried_object();
  3870 
  4093 
  3871 		return in_array( $post_obj->post_type, (array) $post_types );
  4094 		return in_array( $post_obj->post_type, (array) $post_types );
  3872 	}
  4095 	}
  3968 
  4191 
  3969 		if ( ! $post ) {
  4192 		if ( ! $post ) {
  3970 			return;
  4193 			return;
  3971 		}
  4194 		}
  3972 
  4195 
       
  4196 		$elements = $this->generate_postdata( $post );
       
  4197 		if ( false === $elements ) {
       
  4198 			return;
       
  4199 		}
       
  4200 
       
  4201 		$id           = $elements['id'];
       
  4202 		$authordata   = $elements['authordata'];
       
  4203 		$currentday   = $elements['currentday'];
       
  4204 		$currentmonth = $elements['currentmonth'];
       
  4205 		$page         = $elements['page'];
       
  4206 		$pages        = $elements['pages'];
       
  4207 		$multipage    = $elements['multipage'];
       
  4208 		$more         = $elements['more'];
       
  4209 		$numpages     = $elements['numpages'];
       
  4210 
       
  4211 		/**
       
  4212 		 * Fires once the post data has been setup.
       
  4213 		 *
       
  4214 		 * @since 2.8.0
       
  4215 		 * @since 4.1.0 Introduced `$this` parameter.
       
  4216 		 *
       
  4217 		 * @param WP_Post  $post The Post object (passed by reference).
       
  4218 		 * @param WP_Query $this The current Query object (passed by reference).
       
  4219 		 */
       
  4220 		do_action_ref_array( 'the_post', array( &$post, &$this ) );
       
  4221 
       
  4222 		return true;
       
  4223 	}
       
  4224 
       
  4225 	/**
       
  4226 	 * Generate post data.
       
  4227 	 *
       
  4228 	 * @since 5.2.0
       
  4229 	 *
       
  4230 	 * @param WP_Post|object|int $post WP_Post instance or Post ID/object.
       
  4231 	 * @return array|bool $elements Elements of post or false on failure.
       
  4232 	 */
       
  4233 	public function generate_postdata( $post ) {
       
  4234 
       
  4235 		if ( ! ( $post instanceof WP_Post ) ) {
       
  4236 			$post = get_post( $post );
       
  4237 		}
       
  4238 
       
  4239 		if ( ! $post ) {
       
  4240 			return false;
       
  4241 		}
       
  4242 
  3973 		$id = (int) $post->ID;
  4243 		$id = (int) $post->ID;
  3974 
  4244 
  3975 		$authordata = get_userdata($post->post_author);
  4245 		$authordata = get_userdata( $post->post_author );
  3976 
  4246 
  3977 		$currentday = mysql2date('d.m.y', $post->post_date, false);
  4247 		$currentday   = mysql2date( 'd.m.y', $post->post_date, false );
  3978 		$currentmonth = mysql2date('m', $post->post_date, false);
  4248 		$currentmonth = mysql2date( 'm', $post->post_date, false );
  3979 		$numpages = 1;
  4249 		$numpages     = 1;
  3980 		$multipage = 0;
  4250 		$multipage    = 0;
  3981 		$page = $this->get( 'page' );
  4251 		$page         = $this->get( 'page' );
  3982 		if ( ! $page )
  4252 		if ( ! $page ) {
  3983 			$page = 1;
  4253 			$page = 1;
       
  4254 		}
  3984 
  4255 
  3985 		/*
  4256 		/*
  3986 		 * Force full post content when viewing the permalink for the $post,
  4257 		 * Force full post content when viewing the permalink for the $post,
  3987 		 * or when on an RSS feed. Otherwise respect the 'more' tag.
  4258 		 * or when on an RSS feed. Otherwise respect the 'more' tag.
  3988 		 */
  4259 		 */
  3998 		if ( false !== strpos( $content, '<!--nextpage-->' ) ) {
  4269 		if ( false !== strpos( $content, '<!--nextpage-->' ) ) {
  3999 			$content = str_replace( "\n<!--nextpage-->\n", '<!--nextpage-->', $content );
  4270 			$content = str_replace( "\n<!--nextpage-->\n", '<!--nextpage-->', $content );
  4000 			$content = str_replace( "\n<!--nextpage-->", '<!--nextpage-->', $content );
  4271 			$content = str_replace( "\n<!--nextpage-->", '<!--nextpage-->', $content );
  4001 			$content = str_replace( "<!--nextpage-->\n", '<!--nextpage-->', $content );
  4272 			$content = str_replace( "<!--nextpage-->\n", '<!--nextpage-->', $content );
  4002 
  4273 
       
  4274 			// Remove the nextpage block delimiters, to avoid invalid block structures in the split content.
       
  4275 			$content = str_replace( '<!-- wp:nextpage -->', '', $content );
       
  4276 			$content = str_replace( '<!-- /wp:nextpage -->', '', $content );
       
  4277 
  4003 			// Ignore nextpage at the beginning of the content.
  4278 			// Ignore nextpage at the beginning of the content.
  4004 			if ( 0 === strpos( $content, '<!--nextpage-->' ) )
  4279 			if ( 0 === strpos( $content, '<!--nextpage-->' ) ) {
  4005 				$content = substr( $content, 15 );
  4280 				$content = substr( $content, 15 );
  4006 
  4281 			}
  4007 			$pages = explode('<!--nextpage-->', $content);
  4282 
       
  4283 			$pages = explode( '<!--nextpage-->', $content );
  4008 		} else {
  4284 		} else {
  4009 			$pages = array( $post->post_content );
  4285 			$pages = array( $post->post_content );
  4010 		}
  4286 		}
  4011 
  4287 
  4012 		/**
  4288 		/**
  4015 		 * "Pages" are determined by splitting the post content based on the presence
  4291 		 * "Pages" are determined by splitting the post content based on the presence
  4016 		 * of `<!-- nextpage -->` tags.
  4292 		 * of `<!-- nextpage -->` tags.
  4017 		 *
  4293 		 *
  4018 		 * @since 4.4.0
  4294 		 * @since 4.4.0
  4019 		 *
  4295 		 *
  4020 		 * @param array   $pages Array of "pages" derived from the post content.
  4296 		 * @param string[] $pages Array of "pages" from the post content split by `<!-- nextpage -->` tags.
  4021 		 *                       of `<!-- nextpage -->` tags..
  4297 		 * @param WP_Post  $post  Current post object.
  4022 		 * @param WP_Post $post  Current post object.
       
  4023 		 */
  4298 		 */
  4024 		$pages = apply_filters( 'content_pagination', $pages, $post );
  4299 		$pages = apply_filters( 'content_pagination', $pages, $post );
  4025 
  4300 
  4026 		$numpages = count( $pages );
  4301 		$numpages = count( $pages );
  4027 
  4302 
  4029 			if ( $page > 1 ) {
  4304 			if ( $page > 1 ) {
  4030 				$more = 1;
  4305 				$more = 1;
  4031 			}
  4306 			}
  4032 			$multipage = 1;
  4307 			$multipage = 1;
  4033 		} else {
  4308 		} else {
  4034 	 		$multipage = 0;
  4309 			$multipage = 0;
  4035 	 	}
  4310 		}
  4036 
  4311 
  4037 		/**
  4312 		$elements = compact( 'id', 'authordata', 'currentday', 'currentmonth', 'page', 'pages', 'multipage', 'more', 'numpages' );
  4038 		 * Fires once the post data has been setup.
  4313 
  4039 		 *
  4314 		return $elements;
  4040 		 * @since 2.8.0
       
  4041 		 * @since 4.1.0 Introduced `$this` parameter.
       
  4042 		 *
       
  4043 		 * @param WP_Post  $post The Post object (passed by reference).
       
  4044 		 * @param WP_Query $this The current Query object (passed by reference).
       
  4045 		 */
       
  4046 		do_action_ref_array( 'the_post', array( &$post, &$this ) );
       
  4047 
       
  4048 		return true;
       
  4049 	}
  4315 	}
  4050 	/**
  4316 	/**
  4051 	 * After looping through a nested query, this function
  4317 	 * After looping through a nested query, this function
  4052 	 * restores the $post global to the current post in this query.
  4318 	 * restores the $post global to the current post in this query.
  4053 	 *
  4319 	 *