wp/wp-includes/class-wp-query.php
changeset 16 a86126ab1dd4
parent 13 d255fe9cd479
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
     8  */
     8  */
     9 
     9 
    10 /**
    10 /**
    11  * The WordPress Query class.
    11  * The WordPress Query class.
    12  *
    12  *
    13  * @link https://codex.wordpress.org/Function_Reference/WP_Query Codex page.
    13  * @link https://developer.wordpress.org/reference/classes/wp_query/
    14  *
    14  *
    15  * @since 1.5.0
    15  * @since 1.5.0
    16  * @since 4.5.0 Removed the `$comments_popup` property.
    16  * @since 4.5.0 Removed the `$comments_popup` property.
    17  */
    17  */
    18 class WP_Query {
    18 class WP_Query {
    35 
    35 
    36 	/**
    36 	/**
    37 	 * Taxonomy query, as passed to get_tax_sql()
    37 	 * Taxonomy query, as passed to get_tax_sql()
    38 	 *
    38 	 *
    39 	 * @since 3.1.0
    39 	 * @since 3.1.0
    40 	 * @var object WP_Tax_Query
    40 	 * @var WP_Tax_Query A taxonomy query instance.
    41 	 */
    41 	 */
    42 	public $tax_query;
    42 	public $tax_query;
    43 
    43 
    44 	/**
    44 	/**
    45 	 * Metadata query container
    45 	 * Metadata query container
    46 	 *
    46 	 *
    47 	 * @since 3.2.0
    47 	 * @since 3.2.0
    48 	 * @var object WP_Meta_Query
    48 	 * @var WP_Meta_Query A meta query instance.
    49 	 */
    49 	 */
    50 	public $meta_query = false;
    50 	public $meta_query = false;
    51 
    51 
    52 	/**
    52 	/**
    53 	 * Date query container
    53 	 * Date query container
    54 	 *
    54 	 *
    55 	 * @since 3.7.0
    55 	 * @since 3.7.0
    56 	 * @var object WP_Date_Query
    56 	 * @var WP_Date_Query A date query instance.
    57 	 */
    57 	 */
    58 	public $date_query = false;
    58 	public $date_query = false;
    59 
    59 
    60 	/**
    60 	/**
    61 	 * Holds the data for a single object that is queried.
    61 	 * Holds the data for a single object that is queried.
   387 	 *
   387 	 *
   388 	 * @since 2.1.0
   388 	 * @since 2.1.0
   389 	 * @var bool
   389 	 * @var bool
   390 	 */
   390 	 */
   391 	public $is_robots = false;
   391 	public $is_robots = false;
       
   392 
       
   393 	/**
       
   394 	 * Signifies whether the current query is for the favicon.ico file.
       
   395 	 *
       
   396 	 * @since 5.4.0
       
   397 	 * @var bool
       
   398 	 */
       
   399 	public $is_favicon = false;
   392 
   400 
   393 	/**
   401 	/**
   394 	 * Signifies whether the current query is for the page_for_posts page.
   402 	 * Signifies whether the current query is for the page_for_posts page.
   395 	 *
   403 	 *
   396 	 * Basically, the homepage if the option isn't set for the static homepage.
   404 	 * Basically, the homepage if the option isn't set for the static homepage.
   476 		$this->is_paged             = false;
   484 		$this->is_paged             = false;
   477 		$this->is_admin             = false;
   485 		$this->is_admin             = false;
   478 		$this->is_attachment        = false;
   486 		$this->is_attachment        = false;
   479 		$this->is_singular          = false;
   487 		$this->is_singular          = false;
   480 		$this->is_robots            = false;
   488 		$this->is_robots            = false;
       
   489 		$this->is_favicon           = false;
   481 		$this->is_posts_page        = false;
   490 		$this->is_posts_page        = false;
   482 		$this->is_post_type_archive = false;
   491 		$this->is_post_type_archive = false;
   483 	}
   492 	}
   484 
   493 
   485 	/**
   494 	/**
   520 
   529 
   521 	/**
   530 	/**
   522 	 * Fills in the query variables, which do not exist within the parameter.
   531 	 * Fills in the query variables, which do not exist within the parameter.
   523 	 *
   532 	 *
   524 	 * @since 2.1.0
   533 	 * @since 2.1.0
   525 	 * @since 4.4.0 Removed the `comments_popup` public query variable.
   534 	 * @since 4.5.0 Removed the `comments_popup` public query variable.
   526 	 *
   535 	 *
   527 	 * @param array $array Defined query variables.
   536 	 * @param array $array Defined query variables.
   528 	 * @return array Complete query variables with undefined ones filled in empty.
   537 	 * @return array Complete query variables with undefined ones filled in empty.
   529 	 */
   538 	 */
   530 	public function fill_query_vars( $array ) {
   539 	public function fill_query_vars( $array ) {
   611 	 *              Introduced the `$comment_status` and `$ping_status` parameters.
   620 	 *              Introduced the `$comment_status` and `$ping_status` parameters.
   612 	 *              Introduced `RAND(x)` syntax for `$orderby`, which allows an integer seed value to random sorts.
   621 	 *              Introduced `RAND(x)` syntax for `$orderby`, which allows an integer seed value to random sorts.
   613 	 * @since 4.6.0 Added 'post_name__in' support for `$orderby`. Introduced the `$lazy_load_term_meta` argument.
   622 	 * @since 4.6.0 Added 'post_name__in' support for `$orderby`. Introduced the `$lazy_load_term_meta` argument.
   614 	 * @since 4.9.0 Introduced the `$comment_count` parameter.
   623 	 * @since 4.9.0 Introduced the `$comment_count` parameter.
   615 	 * @since 5.1.0 Introduced the `$meta_compare_key` parameter.
   624 	 * @since 5.1.0 Introduced the `$meta_compare_key` parameter.
       
   625 	 * @since 5.3.0 Introduced the `$meta_type_key` parameter.
   616 	 *
   626 	 *
   617 	 * @param string|array $query {
   627 	 * @param string|array $query {
   618 	 *     Optional. Array or string of Query parameters.
   628 	 *     Optional. Array or string of Query parameters.
   619 	 *
   629 	 *
   620 	 *     @type int          $attachment_id           Attachment post ID. Used for 'attachment' post_type.
   630 	 *     @type int          $attachment_id           Attachment post ID. Used for 'attachment' post_type.
   637 	 *                                                 Default 'comments_per_page' option.
   647 	 *                                                 Default 'comments_per_page' option.
   638 	 *     @type array        $date_query              An associative array of WP_Date_Query arguments.
   648 	 *     @type array        $date_query              An associative array of WP_Date_Query arguments.
   639 	 *                                                 See WP_Date_Query::__construct().
   649 	 *                                                 See WP_Date_Query::__construct().
   640 	 *     @type int          $day                     Day of the month. Default empty. Accepts numbers 1-31.
   650 	 *     @type int          $day                     Day of the month. Default empty. Accepts numbers 1-31.
   641 	 *     @type bool         $exact                   Whether to search by exact keyword. Default false.
   651 	 *     @type bool         $exact                   Whether to search by exact keyword. Default false.
   642 	 *     @type string|array $fields                  Which fields to return. Single field or all fields (string),
   652 	 *     @type string       $fields                  Post fields to query for. Accepts:
   643 	 *                                                 or array of fields. 'id=>parent' uses 'id' and 'post_parent'.
   653 	 *                                                 - '' Returns an array of complete post objects (`WP_Post[]`).
   644 	 *                                                 Default all fields. Accepts 'ids', 'id=>parent'.
   654 	 *                                                 - 'ids' Returns an array of post IDs (`int[]`).
       
   655 	 *                                                 - 'id=>parent' Returns an associative array of parent post IDs,
       
   656 	 *                                                   keyed by post ID (`int[]`).
       
   657 	 *                                                 Default ''.
   645 	 *     @type int          $hour                    Hour of the day. Default empty. Accepts numbers 0-23.
   658 	 *     @type int          $hour                    Hour of the day. Default empty. Accepts numbers 0-23.
   646 	 *     @type int|bool     $ignore_sticky_posts     Whether to ignore sticky posts or not. Setting this to false
   659 	 *     @type int|bool     $ignore_sticky_posts     Whether to ignore sticky posts or not. Setting this to false
   647 	 *                                                 excludes stickies from 'post__in'. Accepts 1|true, 0|false.
   660 	 *                                                 excludes stickies from 'post__in'. Accepts 1|true, 0|false.
   648 	 *                                                 Default 0|false.
   661 	 *                                                 Default false.
   649 	 *     @type int          $m                       Combination YearMonth. Accepts any four-digit year and month
   662 	 *     @type int          $m                       Combination YearMonth. Accepts any four-digit year and month
   650 	 *                                                 numbers 1-12. Default empty.
   663 	 *                                                 numbers 1-12. Default empty.
   651 	 *     @type string       $meta_compare            Comparison operator to test the 'meta_value'.
   664 	 *     @type string       $meta_compare            Comparison operator to test the 'meta_value'.
   652 	 *     @type string       $meta_compare_key        Comparison operator to test the 'meta_key'.
   665 	 *     @type string       $meta_compare_key        Comparison operator to test the 'meta_key'.
   653 	 *     @type string       $meta_key                Custom field key.
   666 	 *     @type string       $meta_key                Custom field key.
   654 	 *     @type array        $meta_query              An associative array of WP_Meta_Query arguments. See WP_Meta_Query.
   667 	 *     @type array        $meta_query              An associative array of WP_Meta_Query arguments. See WP_Meta_Query.
   655 	 *     @type string       $meta_value              Custom field value.
   668 	 *     @type string       $meta_value              Custom field value.
   656 	 *     @type int          $meta_value_num          Custom field value number.
   669 	 *     @type int          $meta_value_num          Custom field value number.
       
   670 	 *     @type string       $meta_type_key           Cast for 'meta_key'. See WP_Meta_Query::construct().
   657 	 *     @type int          $menu_order              The menu order of the posts.
   671 	 *     @type int          $menu_order              The menu order of the posts.
   658 	 *     @type int          $monthnum                The two-digit month. Default empty. Accepts numbers 1-12.
   672 	 *     @type int          $monthnum                The two-digit month. Default empty. Accepts numbers 1-12.
   659 	 *     @type string       $name                    Post slug.
   673 	 *     @type string       $name                    Post slug.
   660 	 *     @type bool         $nopaging                Show all posts (true) or paginate (false). Default false.
   674 	 *     @type bool         $nopaging                Show all posts (true) or paginate (false). Default false.
   661 	 *     @type bool         $no_found_rows           Whether to skip counting the total rows found. Enabling can improve
   675 	 *     @type bool         $no_found_rows           Whether to skip counting the total rows found. Enabling can improve
   672 	 *                                                 'relevance', 'RAND(x)' (where 'x' is an integer seed value),
   686 	 *                                                 'relevance', 'RAND(x)' (where 'x' is an integer seed value),
   673 	 *                                                 'comment_count', 'meta_value', 'meta_value_num', 'post__in',
   687 	 *                                                 'comment_count', 'meta_value', 'meta_value_num', 'post__in',
   674 	 *                                                 'post_name__in', 'post_parent__in', and the array keys
   688 	 *                                                 'post_name__in', 'post_parent__in', and the array keys
   675 	 *                                                 of `$meta_query`. Default is 'date', except when a search
   689 	 *                                                 of `$meta_query`. Default is 'date', except when a search
   676 	 *                                                 is being performed, when the default is 'relevance'.
   690 	 *                                                 is being performed, when the default is 'relevance'.
   677 	 *
       
   678 	 *     @type int          $p                       Post ID.
   691 	 *     @type int          $p                       Post ID.
   679 	 *     @type int          $page                    Show the number of posts that would show up on page X of a
   692 	 *     @type int          $page                    Show the number of posts that would show up on page X of a
   680 	 *                                                 static front page.
   693 	 *                                                 static front page.
   681 	 *     @type int          $paged                   The number of the current page.
   694 	 *     @type int          $paged                   The number of the current page.
   682 	 *     @type int          $page_id                 Page ID.
   695 	 *     @type int          $page_id                 Page ID.
   683 	 *     @type string       $pagename                Page slug.
   696 	 *     @type string       $pagename                Page slug.
   684 	 *     @type string       $perm                    Show posts if user has the appropriate capability.
   697 	 *     @type string       $perm                    Show posts if user has the appropriate capability.
   685 	 *     @type string       $ping_status             Ping status.
   698 	 *     @type string       $ping_status             Ping status.
   686 	 *     @type array        $post__in                An array of post IDs to retrieve, sticky posts will be included
   699 	 *     @type array        $post__in                An array of post IDs to retrieve, sticky posts will be included.
   687 	 *     @type string       $post_mime_type          The mime type of the post. Used for 'attachment' post_type.
       
   688 	 *     @type array        $post__not_in            An array of post IDs not to retrieve. Note: a string of comma-
   700 	 *     @type array        $post__not_in            An array of post IDs not to retrieve. Note: a string of comma-
   689 	 *                                                 separated IDs will NOT work.
   701 	 *                                                 separated IDs will NOT work.
       
   702 	 *     @type string       $post_mime_type          The mime type of the post. Used for 'attachment' post_type.
       
   703 	 *     @type array        $post_name__in           An array of post slugs that results must match.
   690 	 *     @type int          $post_parent             Page ID to retrieve child pages for. Use 0 to only retrieve
   704 	 *     @type int          $post_parent             Page ID to retrieve child pages for. Use 0 to only retrieve
   691 	 *                                                 top-level pages.
   705 	 *                                                 top-level pages.
   692 	 *     @type array        $post_parent__in         An array containing parent page IDs to query child pages from.
   706 	 *     @type array        $post_parent__in         An array containing parent page IDs to query child pages from.
   693 	 *     @type array        $post_parent__not_in     An array containing parent page IDs not to query child pages from.
   707 	 *     @type array        $post_parent__not_in     An array containing parent page IDs not to query child pages from.
   694 	 *     @type string|array $post_type               A post type slug (string) or array of post type slugs.
   708 	 *     @type string|array $post_type               A post type slug (string) or array of post type slugs.
   695 	 *                                                 Default 'any' if using 'tax_query'.
   709 	 *                                                 Default 'any' if using 'tax_query'.
   696 	 *     @type string|array $post_status             A post status (string) or array of post statuses.
   710 	 *     @type string|array $post_status             A post status (string) or array of post statuses.
   697 	 *     @type int          $posts_per_page          The number of posts to query for. Use -1 to request all posts.
   711 	 *     @type int          $posts_per_page          The number of posts to query for. Use -1 to request all posts.
   698 	 *     @type int          $posts_per_archive_page  The number of posts to query for by archive page. Overrides
   712 	 *     @type int          $posts_per_archive_page  The number of posts to query for by archive page. Overrides
   699 	 *                                                 'posts_per_page' when is_archive(), or is_search() are true.
   713 	 *                                                 'posts_per_page' when is_archive(), or is_search() are true.
   700 	 *     @type array        $post_name__in           An array of post slugs that results must match.
       
   701 	 *     @type string       $s                       Search keyword(s). Prepending a term with a hyphen will
   714 	 *     @type string       $s                       Search keyword(s). Prepending a term with a hyphen will
   702 	 *                                                 exclude posts matching that term. Eg, 'pillow -sofa' will
   715 	 *                                                 exclude posts matching that term. Eg, 'pillow -sofa' will
   703 	 *                                                 return posts containing 'pillow' but not 'sofa'. The
   716 	 *                                                 return posts containing 'pillow' but not 'sofa'. The
   704 	 *                                                 character used for exclusion can be modified using the
   717 	 *                                                 character used for exclusion can be modified using the
   705 	 *                                                 the 'wp_query_search_exclusion_prefix' filter.
   718 	 *                                                 the 'wp_query_search_exclusion_prefix' filter.
   706 	 *     @type int          $second                  Second of the minute. Default empty. Accepts numbers 0-60.
   719 	 *     @type int          $second                  Second of the minute. Default empty. Accepts numbers 0-60.
   707 	 *     @type bool         $sentence                Whether to search by phrase. Default false.
   720 	 *     @type bool         $sentence                Whether to search by phrase. Default false.
   708 	 *     @type bool         $suppress_filters        Whether to suppress filters. Default false.
   721 	 *     @type bool         $suppress_filters        Whether to suppress filters. Default false.
   709 	 *     @type string       $tag                     Tag slug. Comma-separated (either), Plus-separated (all).
   722 	 *     @type string       $tag                     Tag slug. Comma-separated (either), Plus-separated (all).
   710 	 *     @type array        $tag__and                An array of tag ids (AND in).
   723 	 *     @type array        $tag__and                An array of tag IDs (AND in).
   711 	 *     @type array        $tag__in                 An array of tag ids (OR in).
   724 	 *     @type array        $tag__in                 An array of tag IDs (OR in).
   712 	 *     @type array        $tag__not_in             An array of tag ids (NOT in).
   725 	 *     @type array        $tag__not_in             An array of tag IDs (NOT in).
   713 	 *     @type int          $tag_id                  Tag id or comma-separated list of IDs.
   726 	 *     @type int          $tag_id                  Tag id or comma-separated list of IDs.
   714 	 *     @type array        $tag_slug__and           An array of tag slugs (AND in).
   727 	 *     @type array        $tag_slug__and           An array of tag slugs (AND in).
   715 	 *     @type array        $tag_slug__in            An array of tag slugs (OR in). unless 'ignore_sticky_posts' is
   728 	 *     @type array        $tag_slug__in            An array of tag slugs (OR in). unless 'ignore_sticky_posts' is
   716 	 *                                                 true. Note: a string of comma-separated IDs will NOT work.
   729 	 *                                                 true. Note: a string of comma-separated IDs will NOT work.
   717 	 *     @type array        $tax_query               An associative array of WP_Tax_Query arguments.
   730 	 *     @type array        $tax_query               An associative array of WP_Tax_Query arguments.
   728 	 * }
   741 	 * }
   729 	 */
   742 	 */
   730 	public function parse_query( $query = '' ) {
   743 	public function parse_query( $query = '' ) {
   731 		if ( ! empty( $query ) ) {
   744 		if ( ! empty( $query ) ) {
   732 			$this->init();
   745 			$this->init();
   733 			$this->query = $this->query_vars = wp_parse_args( $query );
   746 			$this->query      = wp_parse_args( $query );
       
   747 			$this->query_vars = $this->query;
   734 		} elseif ( ! isset( $this->query ) ) {
   748 		} elseif ( ! isset( $this->query ) ) {
   735 			$this->query = $this->query_vars;
   749 			$this->query = $this->query_vars;
   736 		}
   750 		}
   737 
   751 
   738 		$this->query_vars         = $this->fill_query_vars( $this->query_vars );
   752 		$this->query_vars         = $this->fill_query_vars( $this->query_vars );
   739 		$qv                       = &$this->query_vars;
   753 		$qv                       = &$this->query_vars;
   740 		$this->query_vars_changed = true;
   754 		$this->query_vars_changed = true;
   741 
   755 
   742 		if ( ! empty( $qv['robots'] ) ) {
   756 		if ( ! empty( $qv['robots'] ) ) {
   743 			$this->is_robots = true;
   757 			$this->is_robots = true;
       
   758 		} elseif ( ! empty( $qv['favicon'] ) ) {
       
   759 			$this->is_favicon = true;
   744 		}
   760 		}
   745 
   761 
   746 		if ( ! is_scalar( $qv['p'] ) || $qv['p'] < 0 ) {
   762 		if ( ! is_scalar( $qv['p'] ) || $qv['p'] < 0 ) {
   747 			$qv['p']     = 0;
   763 			$qv['p']     = 0;
   748 			$qv['error'] = '404';
   764 			$qv['error'] = '404';
   755 		$qv['monthnum'] = absint( $qv['monthnum'] );
   771 		$qv['monthnum'] = absint( $qv['monthnum'] );
   756 		$qv['day']      = absint( $qv['day'] );
   772 		$qv['day']      = absint( $qv['day'] );
   757 		$qv['w']        = absint( $qv['w'] );
   773 		$qv['w']        = absint( $qv['w'] );
   758 		$qv['m']        = is_scalar( $qv['m'] ) ? preg_replace( '|[^0-9]|', '', $qv['m'] ) : '';
   774 		$qv['m']        = is_scalar( $qv['m'] ) ? preg_replace( '|[^0-9]|', '', $qv['m'] ) : '';
   759 		$qv['paged']    = absint( $qv['paged'] );
   775 		$qv['paged']    = absint( $qv['paged'] );
   760 		$qv['cat']      = preg_replace( '|[^0-9,-]|', '', $qv['cat'] ); // comma separated list of positive or negative integers
   776 		$qv['cat']      = preg_replace( '|[^0-9,-]|', '', $qv['cat'] );    // Comma-separated list of positive or negative integers.
   761 		$qv['author']   = preg_replace( '|[^0-9,-]|', '', $qv['author'] ); // comma separated list of positive or negative integers
   777 		$qv['author']   = preg_replace( '|[^0-9,-]|', '', $qv['author'] ); // Comma-separated list of positive or negative integers.
   762 		$qv['pagename'] = trim( $qv['pagename'] );
   778 		$qv['pagename'] = trim( $qv['pagename'] );
   763 		$qv['name']     = trim( $qv['name'] );
   779 		$qv['name']     = trim( $qv['name'] );
   764 		$qv['title']    = trim( $qv['title'] );
   780 		$qv['title']    = trim( $qv['title'] );
   765 		if ( '' !== $qv['hour'] ) {
   781 		if ( '' !== $qv['hour'] ) {
   766 			$qv['hour'] = absint( $qv['hour'] );
   782 			$qv['hour'] = absint( $qv['hour'] );
   788 			$qv['attachment_id'] = $qv['subpost_id'];
   804 			$qv['attachment_id'] = $qv['subpost_id'];
   789 		}
   805 		}
   790 
   806 
   791 		$qv['attachment_id'] = absint( $qv['attachment_id'] );
   807 		$qv['attachment_id'] = absint( $qv['attachment_id'] );
   792 
   808 
   793 		if ( ( '' != $qv['attachment'] ) || ! empty( $qv['attachment_id'] ) ) {
   809 		if ( ( '' !== $qv['attachment'] ) || ! empty( $qv['attachment_id'] ) ) {
   794 			$this->is_single     = true;
   810 			$this->is_single     = true;
   795 			$this->is_attachment = true;
   811 			$this->is_attachment = true;
   796 		} elseif ( '' != $qv['name'] ) {
   812 		} elseif ( '' !== $qv['name'] ) {
   797 			$this->is_single = true;
   813 			$this->is_single = true;
   798 		} elseif ( $qv['p'] ) {
   814 		} elseif ( $qv['p'] ) {
   799 			$this->is_single = true;
   815 			$this->is_single = true;
   800 		} elseif ( ( '' !== $qv['hour'] ) && ( '' !== $qv['minute'] ) && ( '' !== $qv['second'] ) && ( '' != $qv['year'] ) && ( '' != $qv['monthnum'] ) && ( '' != $qv['day'] ) ) {
   816 		} elseif ( '' !== $qv['pagename'] || ! empty( $qv['page_id'] ) ) {
   801 			// If year, month, day, hour, minute, and second are set, a single
       
   802 			// post is being queried.
       
   803 			$this->is_single = true;
       
   804 		} elseif ( '' != $qv['pagename'] || ! empty( $qv['page_id'] ) ) {
       
   805 			$this->is_page   = true;
   817 			$this->is_page   = true;
   806 			$this->is_single = false;
   818 			$this->is_single = false;
   807 		} else {
   819 		} else {
   808 			// Look for archive queries. Dates, categories, authors, search, post type archives.
   820 			// Look for archive queries. Dates, categories, authors, search, post type archives.
   809 
   821 
   867 				} else {
   879 				} else {
   868 					$this->is_year = true;
   880 					$this->is_year = true;
   869 				}
   881 				}
   870 			}
   882 			}
   871 
   883 
   872 			if ( '' != $qv['w'] ) {
   884 			if ( $qv['w'] ) {
   873 				$this->is_date = true;
   885 				$this->is_date = true;
   874 			}
   886 			}
   875 
   887 
   876 			$this->query_vars_hash = false;
   888 			$this->query_vars_hash = false;
   877 			$this->parse_tax_query( $qv );
   889 			$this->parse_tax_query( $qv );
   879 			foreach ( $this->tax_query->queries as $tax_query ) {
   891 			foreach ( $this->tax_query->queries as $tax_query ) {
   880 				if ( ! is_array( $tax_query ) ) {
   892 				if ( ! is_array( $tax_query ) ) {
   881 					continue;
   893 					continue;
   882 				}
   894 				}
   883 
   895 
   884 				if ( isset( $tax_query['operator'] ) && 'NOT IN' != $tax_query['operator'] ) {
   896 				if ( isset( $tax_query['operator'] ) && 'NOT IN' !== $tax_query['operator'] ) {
   885 					switch ( $tax_query['taxonomy'] ) {
   897 					switch ( $tax_query['taxonomy'] ) {
   886 						case 'category':
   898 						case 'category':
   887 							$this->is_category = true;
   899 							$this->is_category = true;
   888 							break;
   900 							break;
   889 						case 'post_tag':
   901 						case 'post_tag':
   894 					}
   906 					}
   895 				}
   907 				}
   896 			}
   908 			}
   897 			unset( $tax_query );
   909 			unset( $tax_query );
   898 
   910 
   899 			if ( empty( $qv['author'] ) || ( $qv['author'] == '0' ) ) {
   911 			if ( empty( $qv['author'] ) || ( '0' == $qv['author'] ) ) {
   900 				$this->is_author = false;
   912 				$this->is_author = false;
   901 			} else {
   913 			} else {
   902 				$this->is_author = true;
   914 				$this->is_author = true;
   903 			}
   915 			}
   904 
   916 
   905 			if ( '' != $qv['author_name'] ) {
   917 			if ( '' !== $qv['author_name'] ) {
   906 				$this->is_author = true;
   918 				$this->is_author = true;
   907 			}
   919 			}
   908 
   920 
   909 			if ( ! empty( $qv['post_type'] ) && ! is_array( $qv['post_type'] ) ) {
   921 			if ( ! empty( $qv['post_type'] ) && ! is_array( $qv['post_type'] ) ) {
   910 				$post_type_obj = get_post_type_object( $qv['post_type'] );
   922 				$post_type_obj = get_post_type_object( $qv['post_type'] );
   932 
   944 
   933 		if ( '' != $qv['paged'] && ( intval( $qv['paged'] ) > 1 ) ) {
   945 		if ( '' != $qv['paged'] && ( intval( $qv['paged'] ) > 1 ) ) {
   934 			$this->is_paged = true;
   946 			$this->is_paged = true;
   935 		}
   947 		}
   936 
   948 
   937 		// if we're previewing inside the write screen
   949 		// If we're previewing inside the write screen.
   938 		if ( '' != $qv['preview'] ) {
   950 		if ( '' != $qv['preview'] ) {
   939 			$this->is_preview = true;
   951 			$this->is_preview = true;
   940 		}
   952 		}
   941 
   953 
   942 		if ( is_admin() ) {
   954 		if ( is_admin() ) {
   952 
   964 
   953 		if ( $this->is_feed && ( ! empty( $qv['withcomments'] ) || ( empty( $qv['withoutcomments'] ) && $this->is_singular ) ) ) {
   965 		if ( $this->is_feed && ( ! empty( $qv['withcomments'] ) || ( empty( $qv['withoutcomments'] ) && $this->is_singular ) ) ) {
   954 			$this->is_comment_feed = true;
   966 			$this->is_comment_feed = true;
   955 		}
   967 		}
   956 
   968 
   957 		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 ) ) {
   969 		if ( ! ( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed
       
   970 				|| ( defined( 'REST_REQUEST' ) && REST_REQUEST && $this->is_main_query() )
       
   971 				|| $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_robots || $this->is_favicon ) ) {
   958 			$this->is_home = true;
   972 			$this->is_home = true;
   959 		}
   973 		}
   960 
   974 
   961 		// Correct is_* for page_on_front and page_for_posts
   975 		// Correct `is_*` for 'page_on_front' and 'page_for_posts'.
   962 		if ( $this->is_home && 'page' == get_option( 'show_on_front' ) && get_option( 'page_on_front' ) ) {
   976 		if ( $this->is_home && 'page' === get_option( 'show_on_front' ) && get_option( 'page_on_front' ) ) {
   963 			$_query = wp_parse_args( $this->query );
   977 			$_query = wp_parse_args( $this->query );
   964 			// pagename can be set and empty depending on matched rewrite rules. Ignore an empty pagename.
   978 			// 'pagename' can be set and empty depending on matched rewrite rules. Ignore an empty 'pagename'.
   965 			if ( isset( $_query['pagename'] ) && '' == $_query['pagename'] ) {
   979 			if ( isset( $_query['pagename'] ) && '' === $_query['pagename'] ) {
   966 				unset( $_query['pagename'] );
   980 				unset( $_query['pagename'] );
   967 			}
   981 			}
   968 
   982 
   969 			unset( $_query['embed'] );
   983 			unset( $_query['embed'] );
   970 
   984 
   971 			if ( empty( $_query ) || ! array_diff( array_keys( $_query ), array( 'preview', 'page', 'paged', 'cpage' ) ) ) {
   985 			if ( empty( $_query ) || ! array_diff( array_keys( $_query ), array( 'preview', 'page', 'paged', 'cpage' ) ) ) {
   972 				$this->is_page = true;
   986 				$this->is_page = true;
   973 				$this->is_home = false;
   987 				$this->is_home = false;
   974 				$qv['page_id'] = get_option( 'page_on_front' );
   988 				$qv['page_id'] = get_option( 'page_on_front' );
   975 				// Correct <!--nextpage--> for page_on_front
   989 				// Correct <!--nextpage--> for 'page_on_front'.
   976 				if ( ! empty( $qv['paged'] ) ) {
   990 				if ( ! empty( $qv['paged'] ) ) {
   977 					$qv['page'] = $qv['paged'];
   991 					$qv['page'] = $qv['paged'];
   978 					unset( $qv['paged'] );
   992 					unset( $qv['paged'] );
   979 				}
   993 				}
   980 			}
   994 			}
   981 		}
   995 		}
   982 
   996 
   983 		if ( '' != $qv['pagename'] ) {
   997 		if ( '' !== $qv['pagename'] ) {
   984 			$this->queried_object = get_page_by_path( $qv['pagename'] );
   998 			$this->queried_object = get_page_by_path( $qv['pagename'] );
   985 
   999 
   986 			if ( $this->queried_object && 'attachment' == $this->queried_object->post_type ) {
  1000 			if ( $this->queried_object && 'attachment' === $this->queried_object->post_type ) {
   987 				if ( preg_match( '/^[^%]*%(?:postname)%/', get_option( 'permalink_structure' ) ) ) {
  1001 				if ( preg_match( '/^[^%]*%(?:postname)%/', get_option( 'permalink_structure' ) ) ) {
   988 					// See if we also have a post with the same slug
  1002 					// See if we also have a post with the same slug.
   989 					$post = get_page_by_path( $qv['pagename'], OBJECT, 'post' );
  1003 					$post = get_page_by_path( $qv['pagename'], OBJECT, 'post' );
   990 					if ( $post ) {
  1004 					if ( $post ) {
   991 						$this->queried_object = $post;
  1005 						$this->queried_object = $post;
   992 						$this->is_page        = false;
  1006 						$this->is_page        = false;
   993 						$this->is_single      = true;
  1007 						$this->is_single      = true;
   999 				$this->queried_object_id = (int) $this->queried_object->ID;
  1013 				$this->queried_object_id = (int) $this->queried_object->ID;
  1000 			} else {
  1014 			} else {
  1001 				unset( $this->queried_object );
  1015 				unset( $this->queried_object );
  1002 			}
  1016 			}
  1003 
  1017 
  1004 			if ( 'page' == get_option( 'show_on_front' ) && isset( $this->queried_object_id ) && $this->queried_object_id == get_option( 'page_for_posts' ) ) {
  1018 			if ( 'page' === get_option( 'show_on_front' ) && isset( $this->queried_object_id ) && get_option( 'page_for_posts' ) == $this->queried_object_id ) {
  1005 				$this->is_page       = false;
  1019 				$this->is_page       = false;
  1006 				$this->is_home       = true;
  1020 				$this->is_home       = true;
  1007 				$this->is_posts_page = true;
  1021 				$this->is_posts_page = true;
  1008 			}
  1022 			}
  1009 
  1023 
  1010 			if ( isset( $this->queried_object_id ) && $this->queried_object_id == get_option( 'wp_page_for_privacy_policy' ) ) {
  1024 			if ( isset( $this->queried_object_id ) && get_option( 'wp_page_for_privacy_policy' ) == $this->queried_object_id ) {
  1011 				$this->is_privacy_policy = true;
  1025 				$this->is_privacy_policy = true;
  1012 			}
  1026 			}
  1013 		}
  1027 		}
  1014 
  1028 
  1015 		if ( $qv['page_id'] ) {
  1029 		if ( $qv['page_id'] ) {
  1016 			if ( 'page' == get_option( 'show_on_front' ) && $qv['page_id'] == get_option( 'page_for_posts' ) ) {
  1030 			if ( 'page' === get_option( 'show_on_front' ) && get_option( 'page_for_posts' ) == $qv['page_id'] ) {
  1017 				$this->is_page       = false;
  1031 				$this->is_page       = false;
  1018 				$this->is_home       = true;
  1032 				$this->is_home       = true;
  1019 				$this->is_posts_page = true;
  1033 				$this->is_posts_page = true;
  1020 			}
  1034 			}
  1021 
  1035 
  1022 			if ( $qv['page_id'] == get_option( 'wp_page_for_privacy_policy' ) ) {
  1036 			if ( get_option( 'wp_page_for_privacy_policy' ) == $qv['page_id'] ) {
  1023 				$this->is_privacy_policy = true;
  1037 				$this->is_privacy_policy = true;
  1024 			}
  1038 			}
  1025 		}
  1039 		}
  1026 
  1040 
  1027 		if ( ! empty( $qv['post_type'] ) ) {
  1041 		if ( ! empty( $qv['post_type'] ) ) {
  1043 		if ( $this->is_posts_page && ( ! isset( $qv['withcomments'] ) || ! $qv['withcomments'] ) ) {
  1057 		if ( $this->is_posts_page && ( ! isset( $qv['withcomments'] ) || ! $qv['withcomments'] ) ) {
  1044 			$this->is_comment_feed = false;
  1058 			$this->is_comment_feed = false;
  1045 		}
  1059 		}
  1046 
  1060 
  1047 		$this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
  1061 		$this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
  1048 		// Done correcting is_* for page_on_front and page_for_posts
  1062 		// Done correcting `is_*` for 'page_on_front' and 'page_for_posts'.
  1049 
  1063 
  1050 		if ( '404' == $qv['error'] ) {
  1064 		if ( '404' == $qv['error'] ) {
  1051 			$this->set_404();
  1065 			$this->set_404();
  1052 		}
  1066 		}
  1053 
  1067 
  1089 				'field'    => 'slug',
  1103 				'field'    => 'slug',
  1090 			);
  1104 			);
  1091 		}
  1105 		}
  1092 
  1106 
  1093 		foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy => $t ) {
  1107 		foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy => $t ) {
  1094 			if ( 'post_tag' == $taxonomy ) {
  1108 			if ( 'post_tag' === $taxonomy ) {
  1095 				continue;   // Handled further down in the $q['tag'] block
  1109 				continue; // Handled further down in the $q['tag'] block.
  1096 			}
  1110 			}
  1097 
  1111 
  1098 			if ( $t->query_var && ! empty( $q[ $t->query_var ] ) ) {
  1112 			if ( $t->query_var && ! empty( $q[ $t->query_var ] ) ) {
  1099 				$tax_query_defaults = array(
  1113 				$tax_query_defaults = array(
  1100 					'taxonomy' => $taxonomy,
  1114 					'taxonomy' => $taxonomy,
  1130 					);
  1144 					);
  1131 				}
  1145 				}
  1132 			}
  1146 			}
  1133 		}
  1147 		}
  1134 
  1148 
  1135 		// If querystring 'cat' is an array, implode it.
  1149 		// If query string 'cat' is an array, implode it.
  1136 		if ( is_array( $q['cat'] ) ) {
  1150 		if ( is_array( $q['cat'] ) ) {
  1137 			$q['cat'] = implode( ',', $q['cat'] );
  1151 			$q['cat'] = implode( ',', $q['cat'] );
  1138 		}
  1152 		}
  1139 
  1153 
  1140 		// Category stuff
  1154 		// Category stuff.
       
  1155 
  1141 		if ( ! empty( $q['cat'] ) && ! $this->is_singular ) {
  1156 		if ( ! empty( $q['cat'] ) && ! $this->is_singular ) {
  1142 			$cat_in = $cat_not_in = array();
  1157 			$cat_in     = array();
       
  1158 			$cat_not_in = array();
  1143 
  1159 
  1144 			$cat_array = preg_split( '/[,\s]+/', urldecode( $q['cat'] ) );
  1160 			$cat_array = preg_split( '/[,\s]+/', urldecode( $q['cat'] ) );
  1145 			$cat_array = array_map( 'intval', $cat_array );
  1161 			$cat_array = array_map( 'intval', $cat_array );
  1146 			$q['cat']  = implode( ',', $cat_array );
  1162 			$q['cat']  = implode( ',', $cat_array );
  1147 
  1163 
  1212 				'operator'         => 'AND',
  1228 				'operator'         => 'AND',
  1213 				'include_children' => false,
  1229 				'include_children' => false,
  1214 			);
  1230 			);
  1215 		}
  1231 		}
  1216 
  1232 
  1217 		// If querystring 'tag' is array, implode it.
  1233 		// If query string 'tag' is array, implode it.
  1218 		if ( is_array( $q['tag'] ) ) {
  1234 		if ( is_array( $q['tag'] ) ) {
  1219 			$q['tag'] = implode( ',', $q['tag'] );
  1235 			$q['tag'] = implode( ',', $q['tag'] );
  1220 		}
  1236 		}
  1221 
  1237 
  1222 		// Tag stuff
  1238 		// Tag stuff.
  1223 		if ( '' != $q['tag'] && ! $this->is_singular && $this->query_vars_changed ) {
  1239 
       
  1240 		if ( '' !== $q['tag'] && ! $this->is_singular && $this->query_vars_changed ) {
  1224 			if ( strpos( $q['tag'], ',' ) !== false ) {
  1241 			if ( strpos( $q['tag'], ',' ) !== false ) {
  1225 				$tags = preg_split( '/[,\r\n\t ]+/', $q['tag'] );
  1242 				$tags = preg_split( '/[,\r\n\t ]+/', $q['tag'] );
  1226 				foreach ( (array) $tags as $tag ) {
  1243 				foreach ( (array) $tags as $tag ) {
  1227 					$tag                 = sanitize_term_field( 'slug', $tag, 0, 'post_tag', 'db' );
  1244 					$tag                 = sanitize_term_field( 'slug', $tag, 0, 'post_tag', 'db' );
  1228 					$q['tag_slug__in'][] = $tag;
  1245 					$q['tag_slug__in'][] = $tag;
  1317 	protected function parse_search( &$q ) {
  1334 	protected function parse_search( &$q ) {
  1318 		global $wpdb;
  1335 		global $wpdb;
  1319 
  1336 
  1320 		$search = '';
  1337 		$search = '';
  1321 
  1338 
  1322 		// added slashes screw with quote grouping when done early, so done later
  1339 		// Added slashes screw with quote grouping when done early, so done later.
  1323 		$q['s'] = stripslashes( $q['s'] );
  1340 		$q['s'] = stripslashes( $q['s'] );
  1324 		if ( empty( $_GET['s'] ) && $this->is_main_query() ) {
  1341 		if ( empty( $_GET['s'] ) && $this->is_main_query() ) {
  1325 			$q['s'] = urldecode( $q['s'] );
  1342 			$q['s'] = urldecode( $q['s'] );
  1326 		}
  1343 		}
  1327 		// there are no line breaks in <input /> fields
  1344 		// There are no line breaks in <input /> fields.
  1328 		$q['s']                  = str_replace( array( "\r", "\n" ), '', $q['s'] );
  1345 		$q['s']                  = str_replace( array( "\r", "\n" ), '', $q['s'] );
  1329 		$q['search_terms_count'] = 1;
  1346 		$q['search_terms_count'] = 1;
  1330 		if ( ! empty( $q['sentence'] ) ) {
  1347 		if ( ! empty( $q['sentence'] ) ) {
  1331 			$q['search_terms'] = array( $q['s'] );
  1348 			$q['search_terms'] = array( $q['s'] );
  1332 		} else {
  1349 		} else {
  1333 			if ( preg_match_all( '/".*?("|$)|((?<=[\t ",+])|^)[^\t ",+]+/', $q['s'], $matches ) ) {
  1350 			if ( preg_match_all( '/".*?("|$)|((?<=[\t ",+])|^)[^\t ",+]+/', $q['s'], $matches ) ) {
  1334 				$q['search_terms_count'] = count( $matches[0] );
  1351 				$q['search_terms_count'] = count( $matches[0] );
  1335 				$q['search_terms']       = $this->parse_search_terms( $matches[0] );
  1352 				$q['search_terms']       = $this->parse_search_terms( $matches[0] );
  1336 				// if the search string has only short terms or stopwords, or is 10+ terms long, match it as sentence
  1353 				// If the search string has only short terms or stopwords, or is 10+ terms long, match it as sentence.
  1337 				if ( empty( $q['search_terms'] ) || count( $q['search_terms'] ) > 9 ) {
  1354 				if ( empty( $q['search_terms'] ) || count( $q['search_terms'] ) > 9 ) {
  1338 					$q['search_terms'] = array( $q['s'] );
  1355 					$q['search_terms'] = array( $q['s'] );
  1339 				}
  1356 				}
  1340 			} else {
  1357 			} else {
  1341 				$q['search_terms'] = array( $q['s'] );
  1358 				$q['search_terms'] = array( $q['s'] );
  1356 		 */
  1373 		 */
  1357 		$exclusion_prefix = apply_filters( 'wp_query_search_exclusion_prefix', '-' );
  1374 		$exclusion_prefix = apply_filters( 'wp_query_search_exclusion_prefix', '-' );
  1358 
  1375 
  1359 		foreach ( $q['search_terms'] as $term ) {
  1376 		foreach ( $q['search_terms'] as $term ) {
  1360 			// If there is an $exclusion_prefix, terms prefixed with it should be excluded.
  1377 			// If there is an $exclusion_prefix, terms prefixed with it should be excluded.
  1361 			$exclude = $exclusion_prefix && ( $exclusion_prefix === substr( $term, 0, 1 ) );
  1378 			$exclude = $exclusion_prefix && ( substr( $term, 0, 1 ) === $exclusion_prefix );
  1362 			if ( $exclude ) {
  1379 			if ( $exclude ) {
  1363 				$like_op  = 'NOT LIKE';
  1380 				$like_op  = 'NOT LIKE';
  1364 				$andor_op = 'AND';
  1381 				$andor_op = 'AND';
  1365 				$term     = substr( $term, 1 );
  1382 				$term     = substr( $term, 1 );
  1366 			} else {
  1383 			} else {
  1396 	 * the approximate search engines list, and is translatable.
  1413 	 * the approximate search engines list, and is translatable.
  1397 	 *
  1414 	 *
  1398 	 * @since 3.7.0
  1415 	 * @since 3.7.0
  1399 	 *
  1416 	 *
  1400 	 * @param string[] $terms Array of terms to check.
  1417 	 * @param string[] $terms Array of terms to check.
  1401 	 * @return array Terms that are not stopwords.
  1418 	 * @return string[] Terms that are not stopwords.
  1402 	 */
  1419 	 */
  1403 	protected function parse_search_terms( $terms ) {
  1420 	protected function parse_search_terms( $terms ) {
  1404 		$strtolower = function_exists( 'mb_strtolower' ) ? 'mb_strtolower' : 'strtolower';
  1421 		$strtolower = function_exists( 'mb_strtolower' ) ? 'mb_strtolower' : 'strtolower';
  1405 		$checked    = array();
  1422 		$checked    = array();
  1406 
  1423 
  1407 		$stopwords = $this->get_search_stopwords();
  1424 		$stopwords = $this->get_search_stopwords();
  1408 
  1425 
  1409 		foreach ( $terms as $term ) {
  1426 		foreach ( $terms as $term ) {
  1410 			// keep before/after spaces when term is for exact match
  1427 			// Keep before/after spaces when term is for exact match.
  1411 			if ( preg_match( '/^".+"$/', $term ) ) {
  1428 			if ( preg_match( '/^".+"$/', $term ) ) {
  1412 				$term = trim( $term, "\"'" );
  1429 				$term = trim( $term, "\"'" );
  1413 			} else {
  1430 			} else {
  1414 				$term = trim( $term, "\"' " );
  1431 				$term = trim( $term, "\"' " );
  1415 			}
  1432 			}
  1432 	/**
  1449 	/**
  1433 	 * Retrieve stopwords used when parsing search terms.
  1450 	 * Retrieve stopwords used when parsing search terms.
  1434 	 *
  1451 	 *
  1435 	 * @since 3.7.0
  1452 	 * @since 3.7.0
  1436 	 *
  1453 	 *
  1437 	 * @return array Stopwords.
  1454 	 * @return string[] Stopwords.
  1438 	 */
  1455 	 */
  1439 	protected function get_search_stopwords() {
  1456 	protected function get_search_stopwords() {
  1440 		if ( isset( $this->stopwords ) ) {
  1457 		if ( isset( $this->stopwords ) ) {
  1441 			return $this->stopwords;
  1458 			return $this->stopwords;
  1442 		}
  1459 		}
  1443 
  1460 
  1444 		/* translators: This is a comma-separated list of very common words that should be excluded from a search,
  1461 		/*
       
  1462 		 * translators: This is a comma-separated list of very common words that should be excluded from a search,
  1445 		 * like a, an, and the. These are usually called "stopwords". You should not simply translate these individual
  1463 		 * like a, an, and the. These are usually called "stopwords". You should not simply translate these individual
  1446 		 * words into your language. Instead, look for and provide commonly accepted stopwords in your language.
  1464 		 * words into your language. Instead, look for and provide commonly accepted stopwords in your language.
  1447 		 */
  1465 		 */
  1448 		$words = explode(
  1466 		$words = explode(
  1449 			',',
  1467 			',',
  1494 				$like = '%' . $wpdb->esc_like( $q['s'] ) . '%';
  1512 				$like = '%' . $wpdb->esc_like( $q['s'] ) . '%';
  1495 			}
  1513 			}
  1496 
  1514 
  1497 			$search_orderby = '';
  1515 			$search_orderby = '';
  1498 
  1516 
  1499 			// sentence match in 'post_title'
  1517 			// Sentence match in 'post_title'.
  1500 			if ( $like ) {
  1518 			if ( $like ) {
  1501 				$search_orderby .= $wpdb->prepare( "WHEN {$wpdb->posts}.post_title LIKE %s THEN 1 ", $like );
  1519 				$search_orderby .= $wpdb->prepare( "WHEN {$wpdb->posts}.post_title LIKE %s THEN 1 ", $like );
  1502 			}
  1520 			}
  1503 
  1521 
  1504 			// sanity limit, sort as sentence when more than 6 terms
  1522 			// Sanity limit, sort as sentence when more than 6 terms
  1505 			// (few searches are longer than 6 terms and most titles are not)
  1523 			// (few searches are longer than 6 terms and most titles are not).
  1506 			if ( $num_terms < 7 ) {
  1524 			if ( $num_terms < 7 ) {
  1507 				// all words in title
  1525 				// All words in title.
  1508 				$search_orderby .= 'WHEN ' . implode( ' AND ', $q['search_orderby_title'] ) . ' THEN 2 ';
  1526 				$search_orderby .= 'WHEN ' . implode( ' AND ', $q['search_orderby_title'] ) . ' THEN 2 ';
  1509 				// any word in title, not needed when $num_terms == 1
  1527 				// Any word in title, not needed when $num_terms == 1.
  1510 				if ( $num_terms > 1 ) {
  1528 				if ( $num_terms > 1 ) {
  1511 					$search_orderby .= 'WHEN ' . implode( ' OR ', $q['search_orderby_title'] ) . ' THEN 3 ';
  1529 					$search_orderby .= 'WHEN ' . implode( ' OR ', $q['search_orderby_title'] ) . ' THEN 3 ';
  1512 				}
  1530 				}
  1513 			}
  1531 			}
  1514 
  1532 
  1520 
  1538 
  1521 			if ( $search_orderby ) {
  1539 			if ( $search_orderby ) {
  1522 				$search_orderby = '(CASE ' . $search_orderby . 'ELSE 6 END)';
  1540 				$search_orderby = '(CASE ' . $search_orderby . 'ELSE 6 END)';
  1523 			}
  1541 			}
  1524 		} else {
  1542 		} else {
  1525 			// single word or sentence search
  1543 			// Single word or sentence search.
  1526 			$search_orderby = reset( $q['search_orderby_title'] ) . ' DESC';
  1544 			$search_orderby = reset( $q['search_orderby_title'] ) . ' DESC';
  1527 		}
  1545 		}
  1528 
  1546 
  1529 		return $search_orderby;
  1547 		return $search_orderby;
  1530 	}
  1548 	}
  1689 
  1707 
  1690 		$this->init_query_flags();
  1708 		$this->init_query_flags();
  1691 		$this->is_404 = true;
  1709 		$this->is_404 = true;
  1692 
  1710 
  1693 		$this->is_feed = $is_feed;
  1711 		$this->is_feed = $is_feed;
       
  1712 
       
  1713 		/**
       
  1714 		 * Fires after a 404 is triggered.
       
  1715 		 *
       
  1716 		 * @since 5.5.0
       
  1717 		 *
       
  1718 		 * @param WP_Query $this The WP_Query instance (passed by reference).
       
  1719 		 */
       
  1720 		do_action_ref_array( 'set_404', array( $this ) );
  1694 	}
  1721 	}
  1695 
  1722 
  1696 	/**
  1723 	/**
  1697 	 * Retrieve query variable.
  1724 	 * Retrieve query variable.
  1698 	 *
  1725 	 *
  1752 		do_action_ref_array( 'pre_get_posts', array( &$this ) );
  1779 		do_action_ref_array( 'pre_get_posts', array( &$this ) );
  1753 
  1780 
  1754 		// Shorthand.
  1781 		// Shorthand.
  1755 		$q = &$this->query_vars;
  1782 		$q = &$this->query_vars;
  1756 
  1783 
  1757 		// Fill again in case pre_get_posts unset some vars.
  1784 		// Fill again in case 'pre_get_posts' unset some vars.
  1758 		$q = $this->fill_query_vars( $q );
  1785 		$q = $this->fill_query_vars( $q );
  1759 
  1786 
  1760 		// Parse meta query
  1787 		// Parse meta query.
  1761 		$this->meta_query = new WP_Meta_Query();
  1788 		$this->meta_query = new WP_Meta_Query();
  1762 		$this->meta_query->parse_query_vars( $q );
  1789 		$this->meta_query->parse_query_vars( $q );
  1763 
  1790 
  1764 		// Set a flag if a pre_get_posts hook changed the query vars.
  1791 		// Set a flag if a 'pre_get_posts' hook changed the query vars.
  1765 		$hash = md5( serialize( $this->query_vars ) );
  1792 		$hash = md5( serialize( $this->query_vars ) );
  1766 		if ( $hash != $this->query_vars_hash ) {
  1793 		if ( $hash != $this->query_vars_hash ) {
  1767 			$this->query_vars_changed = true;
  1794 			$this->query_vars_changed = true;
  1768 			$this->query_vars_hash    = $hash;
  1795 			$this->query_vars_hash    = $hash;
  1769 		}
  1796 		}
  1770 		unset( $hash );
  1797 		unset( $hash );
  1771 
  1798 
  1772 		// First let's clear some variables
  1799 		// First let's clear some variables.
  1773 		$distinct         = '';
  1800 		$distinct         = '';
  1774 		$whichauthor      = '';
  1801 		$whichauthor      = '';
  1775 		$whichmimetype    = '';
  1802 		$whichmimetype    = '';
  1776 		$where            = '';
  1803 		$where            = '';
  1777 		$limits           = '';
  1804 		$limits           = '';
  1783 
  1810 
  1784 		if ( isset( $q['caller_get_posts'] ) ) {
  1811 		if ( isset( $q['caller_get_posts'] ) ) {
  1785 			_deprecated_argument(
  1812 			_deprecated_argument(
  1786 				'WP_Query',
  1813 				'WP_Query',
  1787 				'3.1.0',
  1814 				'3.1.0',
  1788 				/* translators: 1: caller_get_posts, 2: ignore_sticky_posts */
       
  1789 				sprintf(
  1815 				sprintf(
       
  1816 					/* translators: 1: caller_get_posts, 2: ignore_sticky_posts */
  1790 					__( '%1$s is deprecated. Use %2$s instead.' ),
  1817 					__( '%1$s is deprecated. Use %2$s instead.' ),
  1791 					'<code>caller_get_posts</code>',
  1818 					'<code>caller_get_posts</code>',
  1792 					'<code>ignore_sticky_posts</code>'
  1819 					'<code>ignore_sticky_posts</code>'
  1793 				)
  1820 				)
  1794 			);
  1821 			);
  1839 		}
  1866 		}
  1840 		if ( isset( $q['showposts'] ) && $q['showposts'] ) {
  1867 		if ( isset( $q['showposts'] ) && $q['showposts'] ) {
  1841 			$q['showposts']      = (int) $q['showposts'];
  1868 			$q['showposts']      = (int) $q['showposts'];
  1842 			$q['posts_per_page'] = $q['showposts'];
  1869 			$q['posts_per_page'] = $q['showposts'];
  1843 		}
  1870 		}
  1844 		if ( ( isset( $q['posts_per_archive_page'] ) && $q['posts_per_archive_page'] != 0 ) && ( $this->is_archive || $this->is_search ) ) {
  1871 		if ( ( isset( $q['posts_per_archive_page'] ) && 0 != $q['posts_per_archive_page'] ) && ( $this->is_archive || $this->is_search ) ) {
  1845 			$q['posts_per_page'] = $q['posts_per_archive_page'];
  1872 			$q['posts_per_page'] = $q['posts_per_archive_page'];
  1846 		}
  1873 		}
  1847 		if ( ! isset( $q['nopaging'] ) ) {
  1874 		if ( ! isset( $q['nopaging'] ) ) {
  1848 			if ( $q['posts_per_page'] == -1 ) {
  1875 			if ( -1 == $q['posts_per_page'] ) {
  1849 				$q['nopaging'] = true;
  1876 				$q['nopaging'] = true;
  1850 			} else {
  1877 			} else {
  1851 				$q['nopaging'] = false;
  1878 				$q['nopaging'] = false;
  1852 			}
  1879 			}
  1853 		}
  1880 		}
  1854 
  1881 
  1855 		if ( $this->is_feed ) {
  1882 		if ( $this->is_feed ) {
  1856 			// This overrides posts_per_page.
  1883 			// This overrides 'posts_per_page'.
  1857 			if ( ! empty( $q['posts_per_rss'] ) ) {
  1884 			if ( ! empty( $q['posts_per_rss'] ) ) {
  1858 				$q['posts_per_page'] = $q['posts_per_rss'];
  1885 				$q['posts_per_page'] = $q['posts_per_rss'];
  1859 			} else {
  1886 			} else {
  1860 				$q['posts_per_page'] = get_option( 'posts_per_rss' );
  1887 				$q['posts_per_page'] = get_option( 'posts_per_rss' );
  1861 			}
  1888 			}
  1862 			$q['nopaging'] = false;
  1889 			$q['nopaging'] = false;
  1863 		}
  1890 		}
  1864 		$q['posts_per_page'] = (int) $q['posts_per_page'];
  1891 		$q['posts_per_page'] = (int) $q['posts_per_page'];
  1865 		if ( $q['posts_per_page'] < -1 ) {
  1892 		if ( $q['posts_per_page'] < -1 ) {
  1866 			$q['posts_per_page'] = abs( $q['posts_per_page'] );
  1893 			$q['posts_per_page'] = abs( $q['posts_per_page'] );
  1867 		} elseif ( $q['posts_per_page'] == 0 ) {
  1894 		} elseif ( 0 == $q['posts_per_page'] ) {
  1868 			$q['posts_per_page'] = 1;
  1895 			$q['posts_per_page'] = 1;
  1869 		}
  1896 		}
  1870 
  1897 
  1871 		if ( ! isset( $q['comments_per_page'] ) || $q['comments_per_page'] == 0 ) {
  1898 		if ( ! isset( $q['comments_per_page'] ) || 0 == $q['comments_per_page'] ) {
  1872 			$q['comments_per_page'] = get_option( 'comments_per_page' );
  1899 			$q['comments_per_page'] = get_option( 'comments_per_page' );
  1873 		}
  1900 		}
  1874 
  1901 
  1875 		if ( $this->is_home && ( empty( $this->query ) || $q['preview'] == 'true' ) && ( 'page' == get_option( 'show_on_front' ) ) && get_option( 'page_on_front' ) ) {
  1902 		if ( $this->is_home && ( empty( $this->query ) || 'true' === $q['preview'] ) && ( 'page' === get_option( 'show_on_front' ) ) && get_option( 'page_on_front' ) ) {
  1876 			$this->is_page = true;
  1903 			$this->is_page = true;
  1877 			$this->is_home = false;
  1904 			$this->is_home = false;
  1878 			$q['page_id']  = get_option( 'page_on_front' );
  1905 			$q['page_id']  = get_option( 'page_on_front' );
  1879 		}
  1906 		}
  1880 
  1907 
  1902 		}
  1929 		}
  1903 
  1930 
  1904 		if ( '' !== $q['menu_order'] ) {
  1931 		if ( '' !== $q['menu_order'] ) {
  1905 			$where .= " AND {$wpdb->posts}.menu_order = " . $q['menu_order'];
  1932 			$where .= " AND {$wpdb->posts}.menu_order = " . $q['menu_order'];
  1906 		}
  1933 		}
  1907 		// The "m" parameter is meant for months but accepts datetimes of varying specificity
  1934 		// The "m" parameter is meant for months but accepts datetimes of varying specificity.
  1908 		if ( $q['m'] ) {
  1935 		if ( $q['m'] ) {
  1909 			$where .= " AND YEAR({$wpdb->posts}.post_date)=" . substr( $q['m'], 0, 4 );
  1936 			$where .= " AND YEAR({$wpdb->posts}.post_date)=" . substr( $q['m'], 0, 4 );
  1910 			if ( strlen( $q['m'] ) > 5 ) {
  1937 			if ( strlen( $q['m'] ) > 5 ) {
  1911 				$where .= " AND MONTH({$wpdb->posts}.post_date)=" . substr( $q['m'], 4, 2 );
  1938 				$where .= " AND MONTH({$wpdb->posts}.post_date)=" . substr( $q['m'], 4, 2 );
  1912 			}
  1939 			}
  1922 			if ( strlen( $q['m'] ) > 13 ) {
  1949 			if ( strlen( $q['m'] ) > 13 ) {
  1923 				$where .= " AND SECOND({$wpdb->posts}.post_date)=" . substr( $q['m'], 12, 2 );
  1950 				$where .= " AND SECOND({$wpdb->posts}.post_date)=" . substr( $q['m'], 12, 2 );
  1924 			}
  1951 			}
  1925 		}
  1952 		}
  1926 
  1953 
  1927 		// Handle the other individual date parameters
  1954 		// Handle the other individual date parameters.
  1928 		$date_parameters = array();
  1955 		$date_parameters = array();
  1929 
  1956 
  1930 		if ( '' !== $q['hour'] ) {
  1957 		if ( '' !== $q['hour'] ) {
  1931 			$date_parameters['hour'] = $q['hour'];
  1958 			$date_parameters['hour'] = $q['hour'];
  1932 		}
  1959 		}
  1959 			$date_query = new WP_Date_Query( array( $date_parameters ) );
  1986 			$date_query = new WP_Date_Query( array( $date_parameters ) );
  1960 			$where     .= $date_query->get_sql();
  1987 			$where     .= $date_query->get_sql();
  1961 		}
  1988 		}
  1962 		unset( $date_parameters, $date_query );
  1989 		unset( $date_parameters, $date_query );
  1963 
  1990 
  1964 		// Handle complex date queries
  1991 		// Handle complex date queries.
  1965 		if ( ! empty( $q['date_query'] ) ) {
  1992 		if ( ! empty( $q['date_query'] ) ) {
  1966 			$this->date_query = new WP_Date_Query( $q['date_query'] );
  1993 			$this->date_query = new WP_Date_Query( $q['date_query'] );
  1967 			$where           .= $this->date_query->get_sql();
  1994 			$where           .= $this->date_query->get_sql();
  1968 		}
  1995 		}
  1969 
  1996 
  1970 		// If we've got a post_type AND it's not "any" post_type.
  1997 		// If we've got a post_type AND it's not "any" post_type.
  1971 		if ( ! empty( $q['post_type'] ) && 'any' != $q['post_type'] ) {
  1998 		if ( ! empty( $q['post_type'] ) && 'any' !== $q['post_type'] ) {
  1972 			foreach ( (array) $q['post_type'] as $_post_type ) {
  1999 			foreach ( (array) $q['post_type'] as $_post_type ) {
  1973 				$ptype_obj = get_post_type_object( $_post_type );
  2000 				$ptype_obj = get_post_type_object( $_post_type );
  1974 				if ( ! $ptype_obj || ! $ptype_obj->query_var || empty( $q[ $ptype_obj->query_var ] ) ) {
  2001 				if ( ! $ptype_obj || ! $ptype_obj->query_var || empty( $q[ $ptype_obj->query_var ] ) ) {
  1975 					continue;
  2002 					continue;
  1976 				}
  2003 				}
  1984 					$q['name']     = '';
  2011 					$q['name']     = '';
  1985 				}
  2012 				}
  1986 
  2013 
  1987 				// Only one request for a slug is possible, this is why name & pagename are overwritten above.
  2014 				// Only one request for a slug is possible, this is why name & pagename are overwritten above.
  1988 				break;
  2015 				break;
  1989 			} //end foreach
  2016 			} // End foreach.
  1990 			unset( $ptype_obj );
  2017 			unset( $ptype_obj );
  1991 		}
  2018 		}
  1992 
  2019 
  1993 		if ( '' !== $q['title'] ) {
  2020 		if ( '' !== $q['title'] ) {
  1994 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.post_title = %s", stripslashes( $q['title'] ) );
  2021 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.post_title = %s", stripslashes( $q['title'] ) );
  1995 		}
  2022 		}
  1996 
  2023 
  1997 		// Parameters related to 'post_name'.
  2024 		// Parameters related to 'post_name'.
  1998 		if ( '' != $q['name'] ) {
  2025 		if ( '' !== $q['name'] ) {
  1999 			$q['name'] = sanitize_title_for_query( $q['name'] );
  2026 			$q['name'] = sanitize_title_for_query( $q['name'] );
  2000 			$where    .= " AND {$wpdb->posts}.post_name = '" . $q['name'] . "'";
  2027 			$where    .= " AND {$wpdb->posts}.post_name = '" . $q['name'] . "'";
  2001 		} elseif ( '' != $q['pagename'] ) {
  2028 		} elseif ( '' !== $q['pagename'] ) {
  2002 			if ( isset( $this->queried_object_id ) ) {
  2029 			if ( isset( $this->queried_object_id ) ) {
  2003 				$reqpage = $this->queried_object_id;
  2030 				$reqpage = $this->queried_object_id;
  2004 			} else {
  2031 			} else {
  2005 				if ( 'page' != $q['post_type'] ) {
  2032 				if ( 'page' !== $q['post_type'] ) {
  2006 					foreach ( (array) $q['post_type'] as $_post_type ) {
  2033 					foreach ( (array) $q['post_type'] as $_post_type ) {
  2007 						$ptype_obj = get_post_type_object( $_post_type );
  2034 						$ptype_obj = get_post_type_object( $_post_type );
  2008 						if ( ! $ptype_obj || ! $ptype_obj->hierarchical ) {
  2035 						if ( ! $ptype_obj || ! $ptype_obj->hierarchical ) {
  2009 							continue;
  2036 							continue;
  2010 						}
  2037 						}
  2024 					$reqpage = 0;
  2051 					$reqpage = 0;
  2025 				}
  2052 				}
  2026 			}
  2053 			}
  2027 
  2054 
  2028 			$page_for_posts = get_option( 'page_for_posts' );
  2055 			$page_for_posts = get_option( 'page_for_posts' );
  2029 			if ( ( 'page' != get_option( 'show_on_front' ) ) || empty( $page_for_posts ) || ( $reqpage != $page_for_posts ) ) {
  2056 			if ( ( 'page' !== get_option( 'show_on_front' ) ) || empty( $page_for_posts ) || ( $reqpage != $page_for_posts ) ) {
  2030 				$q['pagename'] = sanitize_title_for_query( wp_basename( $q['pagename'] ) );
  2057 				$q['pagename'] = sanitize_title_for_query( wp_basename( $q['pagename'] ) );
  2031 				$q['name']     = $q['pagename'];
  2058 				$q['name']     = $q['pagename'];
  2032 				$where        .= " AND ({$wpdb->posts}.ID = '$reqpage')";
  2059 				$where        .= " AND ({$wpdb->posts}.ID = '$reqpage')";
  2033 				$reqpage_obj   = get_post( $reqpage );
  2060 				$reqpage_obj   = get_post( $reqpage );
  2034 				if ( is_object( $reqpage_obj ) && 'attachment' == $reqpage_obj->post_type ) {
  2061 				if ( is_object( $reqpage_obj ) && 'attachment' === $reqpage_obj->post_type ) {
  2035 					$this->is_attachment = true;
  2062 					$this->is_attachment = true;
  2036 					$post_type           = $q['post_type'] = 'attachment';
  2063 					$post_type           = 'attachment';
       
  2064 					$q['post_type']      = 'attachment';
  2037 					$this->is_page       = true;
  2065 					$this->is_page       = true;
  2038 					$q['attachment_id']  = $reqpage;
  2066 					$q['attachment_id']  = $reqpage;
  2039 				}
  2067 				}
  2040 			}
  2068 			}
  2041 		} elseif ( '' != $q['attachment'] ) {
  2069 		} elseif ( '' !== $q['attachment'] ) {
  2042 			$q['attachment'] = sanitize_title_for_query( wp_basename( $q['attachment'] ) );
  2070 			$q['attachment'] = sanitize_title_for_query( wp_basename( $q['attachment'] ) );
  2043 			$q['name']       = $q['attachment'];
  2071 			$q['name']       = $q['attachment'];
  2044 			$where          .= " AND {$wpdb->posts}.post_name = '" . $q['attachment'] . "'";
  2072 			$where          .= " AND {$wpdb->posts}.post_name = '" . $q['attachment'] . "'";
  2045 		} elseif ( is_array( $q['post_name__in'] ) && ! empty( $q['post_name__in'] ) ) {
  2073 		} elseif ( is_array( $q['post_name__in'] ) && ! empty( $q['post_name__in'] ) ) {
  2046 			$q['post_name__in'] = array_map( 'sanitize_title_for_query', $q['post_name__in'] );
  2074 			$q['post_name__in'] = array_map( 'sanitize_title_for_query', $q['post_name__in'] );
  2051 		// If an attachment is requested by number, let it supersede any post number.
  2079 		// If an attachment is requested by number, let it supersede any post number.
  2052 		if ( $q['attachment_id'] ) {
  2080 		if ( $q['attachment_id'] ) {
  2053 			$q['p'] = absint( $q['attachment_id'] );
  2081 			$q['p'] = absint( $q['attachment_id'] );
  2054 		}
  2082 		}
  2055 
  2083 
  2056 		// If a post number is specified, load that post
  2084 		// If a post number is specified, load that post.
  2057 		if ( $q['p'] ) {
  2085 		if ( $q['p'] ) {
  2058 			$where .= " AND {$wpdb->posts}.ID = " . $q['p'];
  2086 			$where .= " AND {$wpdb->posts}.ID = " . $q['p'];
  2059 		} elseif ( $q['post__in'] ) {
  2087 		} elseif ( $q['post__in'] ) {
  2060 			$post__in = implode( ',', array_map( 'absint', $q['post__in'] ) );
  2088 			$post__in = implode( ',', array_map( 'absint', $q['post__in'] ) );
  2061 			$where   .= " AND {$wpdb->posts}.ID IN ($post__in)";
  2089 			$where   .= " AND {$wpdb->posts}.ID IN ($post__in)";
  2073 			$post_parent__not_in = implode( ',', array_map( 'absint', $q['post_parent__not_in'] ) );
  2101 			$post_parent__not_in = implode( ',', array_map( 'absint', $q['post_parent__not_in'] ) );
  2074 			$where              .= " AND {$wpdb->posts}.post_parent NOT IN ($post_parent__not_in)";
  2102 			$where              .= " AND {$wpdb->posts}.post_parent NOT IN ($post_parent__not_in)";
  2075 		}
  2103 		}
  2076 
  2104 
  2077 		if ( $q['page_id'] ) {
  2105 		if ( $q['page_id'] ) {
  2078 			if ( ( 'page' != get_option( 'show_on_front' ) ) || ( $q['page_id'] != get_option( 'page_for_posts' ) ) ) {
  2106 			if ( ( 'page' !== get_option( 'show_on_front' ) ) || ( get_option( 'page_for_posts' ) != $q['page_id'] ) ) {
  2079 				$q['p'] = $q['page_id'];
  2107 				$q['p'] = $q['page_id'];
  2080 				$where  = " AND {$wpdb->posts}.ID = " . $q['page_id'];
  2108 				$where  = " AND {$wpdb->posts}.ID = " . $q['page_id'];
  2081 			}
  2109 			}
  2082 		}
  2110 		}
  2083 
  2111 
  2096 			 * @param WP_Query $this   The current WP_Query object.
  2124 			 * @param WP_Query $this   The current WP_Query object.
  2097 			 */
  2125 			 */
  2098 			$search = apply_filters_ref_array( 'posts_search', array( $search, &$this ) );
  2126 			$search = apply_filters_ref_array( 'posts_search', array( $search, &$this ) );
  2099 		}
  2127 		}
  2100 
  2128 
  2101 		// Taxonomies
  2129 		// Taxonomies.
  2102 		if ( ! $this->is_singular ) {
  2130 		if ( ! $this->is_singular ) {
  2103 			$this->parse_tax_query( $q );
  2131 			$this->parse_tax_query( $q );
  2104 
  2132 
  2105 			$clauses = $this->tax_query->get_sql( $wpdb->posts, 'ID' );
  2133 			$clauses = $this->tax_query->get_sql( $wpdb->posts, 'ID' );
  2106 
  2134 
  2108 			$where .= $clauses['where'];
  2136 			$where .= $clauses['where'];
  2109 		}
  2137 		}
  2110 
  2138 
  2111 		if ( $this->is_tax ) {
  2139 		if ( $this->is_tax ) {
  2112 			if ( empty( $post_type ) ) {
  2140 			if ( empty( $post_type ) ) {
  2113 				// Do a fully inclusive search for currently registered post types of queried taxonomies
  2141 				// Do a fully inclusive search for currently registered post types of queried taxonomies.
  2114 				$post_type  = array();
  2142 				$post_type  = array();
  2115 				$taxonomies = array_keys( $this->tax_query->queried_terms );
  2143 				$taxonomies = array_keys( $this->tax_query->queried_terms );
  2116 				foreach ( get_post_types( array( 'exclude_from_search' => false ) ) as $pt ) {
  2144 				foreach ( get_post_types( array( 'exclude_from_search' => false ) ) as $pt ) {
  2117 					$object_taxonomies = $pt === 'attachment' ? get_taxonomies_for_attachments() : get_object_taxonomies( $pt );
  2145 					$object_taxonomies = 'attachment' === $pt ? get_taxonomies_for_attachments() : get_object_taxonomies( $pt );
  2118 					if ( array_intersect( $taxonomies, $object_taxonomies ) ) {
  2146 					if ( array_intersect( $taxonomies, $object_taxonomies ) ) {
  2119 						$post_type[] = $pt;
  2147 						$post_type[] = $pt;
  2120 					}
  2148 					}
  2121 				}
  2149 				}
  2122 				if ( ! $post_type ) {
  2150 				if ( ! $post_type ) {
  2124 				} elseif ( count( $post_type ) == 1 ) {
  2152 				} elseif ( count( $post_type ) == 1 ) {
  2125 					$post_type = $post_type[0];
  2153 					$post_type = $post_type[0];
  2126 				}
  2154 				}
  2127 
  2155 
  2128 				$post_status_join = true;
  2156 				$post_status_join = true;
  2129 			} elseif ( in_array( 'attachment', (array) $post_type ) ) {
  2157 			} elseif ( in_array( 'attachment', (array) $post_type, true ) ) {
  2130 				$post_status_join = true;
  2158 				$post_status_join = true;
  2131 			}
  2159 			}
  2132 		}
  2160 		}
  2133 
  2161 
  2134 		/*
  2162 		/*
  2145 				foreach ( $this->tax_query->queried_terms as $queried_taxonomy => $queried_items ) {
  2173 				foreach ( $this->tax_query->queried_terms as $queried_taxonomy => $queried_items ) {
  2146 					if ( empty( $queried_items['terms'][0] ) ) {
  2174 					if ( empty( $queried_items['terms'][0] ) ) {
  2147 						continue;
  2175 						continue;
  2148 					}
  2176 					}
  2149 
  2177 
  2150 					if ( ! in_array( $queried_taxonomy, array( 'category', 'post_tag' ) ) ) {
  2178 					if ( ! in_array( $queried_taxonomy, array( 'category', 'post_tag' ), true ) ) {
  2151 						$q['taxonomy'] = $queried_taxonomy;
  2179 						$q['taxonomy'] = $queried_taxonomy;
  2152 
  2180 
  2153 						if ( 'slug' === $queried_items['field'] ) {
  2181 						if ( 'slug' === $queried_items['field'] ) {
  2154 							$q['term'] = $queried_items['terms'][0];
  2182 							$q['term'] = $queried_items['terms'][0];
  2155 						} else {
  2183 						} else {
  2160 						break;
  2188 						break;
  2161 					}
  2189 					}
  2162 				}
  2190 				}
  2163 			}
  2191 			}
  2164 
  2192 
  2165 			// 'cat', 'category_name', 'tag_id'
  2193 			// 'cat', 'category_name', 'tag_id'.
  2166 			foreach ( $this->tax_query->queried_terms as $queried_taxonomy => $queried_items ) {
  2194 			foreach ( $this->tax_query->queried_terms as $queried_taxonomy => $queried_items ) {
  2167 				if ( empty( $queried_items['terms'][0] ) ) {
  2195 				if ( empty( $queried_items['terms'][0] ) ) {
  2168 					continue;
  2196 					continue;
  2169 				}
  2197 				}
  2170 
  2198 
  2189 
  2217 
  2190 		if ( ! empty( $this->tax_query->queries ) || ! empty( $this->meta_query->queries ) ) {
  2218 		if ( ! empty( $this->tax_query->queries ) || ! empty( $this->meta_query->queries ) ) {
  2191 			$groupby = "{$wpdb->posts}.ID";
  2219 			$groupby = "{$wpdb->posts}.ID";
  2192 		}
  2220 		}
  2193 
  2221 
  2194 		// Author/user stuff
  2222 		// Author/user stuff.
  2195 
  2223 
  2196 		if ( ! empty( $q['author'] ) && $q['author'] != '0' ) {
  2224 		if ( ! empty( $q['author'] ) && '0' != $q['author'] ) {
  2197 			$q['author'] = addslashes_gpc( '' . urldecode( $q['author'] ) );
  2225 			$q['author'] = addslashes_gpc( '' . urldecode( $q['author'] ) );
  2198 			$authors     = array_unique( array_map( 'intval', preg_split( '/[,\s]+/', $q['author'] ) ) );
  2226 			$authors     = array_unique( array_map( 'intval', preg_split( '/[,\s]+/', $q['author'] ) ) );
  2199 			foreach ( $authors as $author ) {
  2227 			foreach ( $authors as $author ) {
  2200 				$key         = $author > 0 ? 'author__in' : 'author__not_in';
  2228 				$key         = $author > 0 ? 'author__in' : 'author__not_in';
  2201 				$q[ $key ][] = abs( $author );
  2229 				$q[ $key ][] = abs( $author );
  2209 		} elseif ( ! empty( $q['author__in'] ) ) {
  2237 		} elseif ( ! empty( $q['author__in'] ) ) {
  2210 			$author__in = implode( ',', array_map( 'absint', array_unique( (array) $q['author__in'] ) ) );
  2238 			$author__in = implode( ',', array_map( 'absint', array_unique( (array) $q['author__in'] ) ) );
  2211 			$where     .= " AND {$wpdb->posts}.post_author IN ($author__in) ";
  2239 			$where     .= " AND {$wpdb->posts}.post_author IN ($author__in) ";
  2212 		}
  2240 		}
  2213 
  2241 
  2214 		// Author stuff for nice URLs
  2242 		// Author stuff for nice URLs.
  2215 
  2243 
  2216 		if ( '' != $q['author_name'] ) {
  2244 		if ( '' !== $q['author_name'] ) {
  2217 			if ( strpos( $q['author_name'], '/' ) !== false ) {
  2245 			if ( strpos( $q['author_name'], '/' ) !== false ) {
  2218 				$q['author_name'] = explode( '/', $q['author_name'] );
  2246 				$q['author_name'] = explode( '/', $q['author_name'] );
  2219 				if ( $q['author_name'][ count( $q['author_name'] ) - 1 ] ) {
  2247 				if ( $q['author_name'][ count( $q['author_name'] ) - 1 ] ) {
  2220 					$q['author_name'] = $q['author_name'][ count( $q['author_name'] ) - 1 ]; // no trailing slash
  2248 					$q['author_name'] = $q['author_name'][ count( $q['author_name'] ) - 1 ]; // No trailing slash.
  2221 				} else {
  2249 				} else {
  2222 					$q['author_name'] = $q['author_name'][ count( $q['author_name'] ) - 2 ]; // there was a trailing slash
  2250 					$q['author_name'] = $q['author_name'][ count( $q['author_name'] ) - 2 ]; // There was a trailing slash.
  2223 				}
  2251 				}
  2224 			}
  2252 			}
  2225 			$q['author_name'] = sanitize_title_for_query( $q['author_name'] );
  2253 			$q['author_name'] = sanitize_title_for_query( $q['author_name'] );
  2226 			$q['author']      = get_user_by( 'slug', $q['author_name'] );
  2254 			$q['author']      = get_user_by( 'slug', $q['author_name'] );
  2227 			if ( $q['author'] ) {
  2255 			if ( $q['author'] ) {
  2255 
  2283 
  2256 				$where .= $wpdb->prepare( " AND {$wpdb->posts}.comment_count {$q['comment_count']['compare']} %d", $q['comment_count']['value'] );
  2284 				$where .= $wpdb->prepare( " AND {$wpdb->posts}.comment_count {$q['comment_count']['compare']} %d", $q['comment_count']['value'] );
  2257 			}
  2285 			}
  2258 		}
  2286 		}
  2259 
  2287 
  2260 		// MIME-Type stuff for attachment browsing
  2288 		// MIME-Type stuff for attachment browsing.
  2261 
  2289 
  2262 		if ( isset( $q['post_mime_type'] ) && '' != $q['post_mime_type'] ) {
  2290 		if ( isset( $q['post_mime_type'] ) && '' !== $q['post_mime_type'] ) {
  2263 			$whichmimetype = wp_post_mime_type_where( $q['post_mime_type'], $wpdb->posts );
  2291 			$whichmimetype = wp_post_mime_type_where( $q['post_mime_type'], $wpdb->posts );
  2264 		}
  2292 		}
  2265 		$where .= $search . $whichauthor . $whichmimetype;
  2293 		$where .= $search . $whichauthor . $whichmimetype;
  2266 
  2294 
  2267 		if ( ! empty( $this->meta_query->queries ) ) {
  2295 		if ( ! empty( $this->meta_query->queries ) ) {
  2292 			if ( isset( $q['orderby'] ) && ( is_array( $q['orderby'] ) || false === $q['orderby'] ) ) {
  2320 			if ( isset( $q['orderby'] ) && ( is_array( $q['orderby'] ) || false === $q['orderby'] ) ) {
  2293 				$orderby = '';
  2321 				$orderby = '';
  2294 			} else {
  2322 			} else {
  2295 				$orderby = "{$wpdb->posts}.post_date " . $q['order'];
  2323 				$orderby = "{$wpdb->posts}.post_date " . $q['order'];
  2296 			}
  2324 			}
  2297 		} elseif ( 'none' == $q['orderby'] ) {
  2325 		} elseif ( 'none' === $q['orderby'] ) {
  2298 			$orderby = '';
  2326 			$orderby = '';
  2299 		} else {
  2327 		} else {
  2300 			$orderby_array = array();
  2328 			$orderby_array = array();
  2301 			if ( is_array( $q['orderby'] ) ) {
  2329 			if ( is_array( $q['orderby'] ) ) {
  2302 				foreach ( $q['orderby'] as $_orderby => $order ) {
  2330 				foreach ( $q['orderby'] as $_orderby => $order ) {
  2385 
  2413 
  2386 		if ( ! empty( $q['ping_status'] ) ) {
  2414 		if ( ! empty( $q['ping_status'] ) ) {
  2387 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.ping_status = %s ", $q['ping_status'] );
  2415 			$where .= $wpdb->prepare( " AND {$wpdb->posts}.ping_status = %s ", $q['ping_status'] );
  2388 		}
  2416 		}
  2389 
  2417 
  2390 		if ( 'any' == $post_type ) {
  2418 		if ( 'any' === $post_type ) {
  2391 			$in_search_post_types = get_post_types( array( 'exclude_from_search' => false ) );
  2419 			$in_search_post_types = get_post_types( array( 'exclude_from_search' => false ) );
  2392 			if ( empty( $in_search_post_types ) ) {
  2420 			if ( empty( $in_search_post_types ) ) {
  2393 				$where .= ' AND 1=0 ';
  2421 				$where .= ' AND 1=0 ';
  2394 			} else {
  2422 			} else {
  2395 				$where .= " AND {$wpdb->posts}.post_type IN ('" . join( "', '", array_map( 'esc_sql', $in_search_post_types ) ) . "')";
  2423 				$where .= " AND {$wpdb->posts}.post_type IN ('" . join( "', '", array_map( 'esc_sql', $in_search_post_types ) ) . "')";
  2431 				$q_status = explode( ',', $q_status );
  2459 				$q_status = explode( ',', $q_status );
  2432 			}
  2460 			}
  2433 			$r_status = array();
  2461 			$r_status = array();
  2434 			$p_status = array();
  2462 			$p_status = array();
  2435 			$e_status = array();
  2463 			$e_status = array();
  2436 			if ( in_array( 'any', $q_status ) ) {
  2464 			if ( in_array( 'any', $q_status, true ) ) {
  2437 				foreach ( get_post_stati( array( 'exclude_from_search' => true ) ) as $status ) {
  2465 				foreach ( get_post_stati( array( 'exclude_from_search' => true ) ) as $status ) {
  2438 					if ( ! in_array( $status, $q_status ) ) {
  2466 					if ( ! in_array( $status, $q_status, true ) ) {
  2439 						$e_status[] = "{$wpdb->posts}.post_status <> '$status'";
  2467 						$e_status[] = "{$wpdb->posts}.post_status <> '$status'";
  2440 					}
  2468 					}
  2441 				}
  2469 				}
  2442 			} else {
  2470 			} else {
  2443 				foreach ( get_post_stati() as $status ) {
  2471 				foreach ( get_post_stati() as $status ) {
  2444 					if ( in_array( $status, $q_status ) ) {
  2472 					if ( in_array( $status, $q_status, true ) ) {
  2445 						if ( 'private' == $status ) {
  2473 						if ( 'private' === $status ) {
  2446 							$p_status[] = "{$wpdb->posts}.post_status = '$status'";
  2474 							$p_status[] = "{$wpdb->posts}.post_status = '$status'";
  2447 						} else {
  2475 						} else {
  2448 							$r_status[] = "{$wpdb->posts}.post_status = '$status'";
  2476 							$r_status[] = "{$wpdb->posts}.post_status = '$status'";
  2449 						}
  2477 						}
  2450 					}
  2478 					}
  2451 				}
  2479 				}
  2452 			}
  2480 			}
  2453 
  2481 
  2454 			if ( empty( $q['perm'] ) || 'readable' != $q['perm'] ) {
  2482 			if ( empty( $q['perm'] ) || 'readable' !== $q['perm'] ) {
  2455 				$r_status = array_merge( $r_status, $p_status );
  2483 				$r_status = array_merge( $r_status, $p_status );
  2456 				unset( $p_status );
  2484 				unset( $p_status );
  2457 			}
  2485 			}
  2458 
  2486 
  2459 			if ( ! empty( $e_status ) ) {
  2487 			if ( ! empty( $e_status ) ) {
  2460 				$statuswheres[] = '(' . join( ' AND ', $e_status ) . ')';
  2488 				$statuswheres[] = '(' . join( ' AND ', $e_status ) . ')';
  2461 			}
  2489 			}
  2462 			if ( ! empty( $r_status ) ) {
  2490 			if ( ! empty( $r_status ) ) {
  2463 				if ( ! empty( $q['perm'] ) && 'editable' == $q['perm'] && ! current_user_can( $edit_others_cap ) ) {
  2491 				if ( ! empty( $q['perm'] ) && 'editable' === $q['perm'] && ! current_user_can( $edit_others_cap ) ) {
  2464 					$statuswheres[] = "({$wpdb->posts}.post_author = $user_id " . 'AND (' . join( ' OR ', $r_status ) . '))';
  2492 					$statuswheres[] = "({$wpdb->posts}.post_author = $user_id " . 'AND (' . join( ' OR ', $r_status ) . '))';
  2465 				} else {
  2493 				} else {
  2466 					$statuswheres[] = '(' . join( ' OR ', $r_status ) . ')';
  2494 					$statuswheres[] = '(' . join( ' OR ', $r_status ) . ')';
  2467 				}
  2495 				}
  2468 			}
  2496 			}
  2469 			if ( ! empty( $p_status ) ) {
  2497 			if ( ! empty( $p_status ) ) {
  2470 				if ( ! empty( $q['perm'] ) && 'readable' == $q['perm'] && ! current_user_can( $read_private_cap ) ) {
  2498 				if ( ! empty( $q['perm'] ) && 'readable' === $q['perm'] && ! current_user_can( $read_private_cap ) ) {
  2471 					$statuswheres[] = "({$wpdb->posts}.post_author = $user_id " . 'AND (' . join( ' OR ', $p_status ) . '))';
  2499 					$statuswheres[] = "({$wpdb->posts}.post_author = $user_id " . 'AND (' . join( ' OR ', $p_status ) . '))';
  2472 				} else {
  2500 				} else {
  2473 					$statuswheres[] = '(' . join( ' OR ', $p_status ) . ')';
  2501 					$statuswheres[] = '(' . join( ' OR ', $p_status ) . ')';
  2474 				}
  2502 				}
  2475 			}
  2503 			}
  2487 			$where .= " AND ({$wpdb->posts}.post_status = 'publish'";
  2515 			$where .= " AND ({$wpdb->posts}.post_status = 'publish'";
  2488 
  2516 
  2489 			// Add public states.
  2517 			// Add public states.
  2490 			$public_states = get_post_stati( array( 'public' => true ) );
  2518 			$public_states = get_post_stati( array( 'public' => true ) );
  2491 			foreach ( (array) $public_states as $state ) {
  2519 			foreach ( (array) $public_states as $state ) {
  2492 				if ( 'publish' == $state ) { // Publish is hard-coded above.
  2520 				if ( 'publish' === $state ) { // Publish is hard-coded above.
  2493 					continue;
  2521 					continue;
  2494 				}
  2522 				}
  2495 				$where .= " OR {$wpdb->posts}.post_status = '$state'";
  2523 				$where .= " OR {$wpdb->posts}.post_status = '$state'";
  2496 			}
  2524 			}
  2497 
  2525 
  2543 			 * @param WP_Query $this The WP_Query instance (passed by reference).
  2571 			 * @param WP_Query $this The WP_Query instance (passed by reference).
  2544 			 */
  2572 			 */
  2545 			$join = apply_filters_ref_array( 'posts_join', array( $join, &$this ) );
  2573 			$join = apply_filters_ref_array( 'posts_join', array( $join, &$this ) );
  2546 		}
  2574 		}
  2547 
  2575 
  2548 		// Paging
  2576 		// Paging.
  2549 		if ( empty( $q['nopaging'] ) && ! $this->is_singular ) {
  2577 		if ( empty( $q['nopaging'] ) && ! $this->is_singular ) {
  2550 			$page = absint( $q['paged'] );
  2578 			$page = absint( $q['paged'] );
  2551 			if ( ! $page ) {
  2579 			if ( ! $page ) {
  2552 				$page = 1;
  2580 				$page = 1;
  2553 			}
  2581 			}
  2560 				$pgstrt = absint( ( $page - 1 ) * $q['posts_per_page'] ) . ', ';
  2588 				$pgstrt = absint( ( $page - 1 ) * $q['posts_per_page'] ) . ', ';
  2561 			}
  2589 			}
  2562 			$limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
  2590 			$limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
  2563 		}
  2591 		}
  2564 
  2592 
  2565 		// Comments feeds
  2593 		// Comments feeds.
  2566 		if ( $this->is_comment_feed && ! $this->is_singular ) {
  2594 		if ( $this->is_comment_feed && ! $this->is_singular ) {
  2567 			if ( $this->is_archive || $this->is_search ) {
  2595 			if ( $this->is_archive || $this->is_search ) {
  2568 				$cjoin    = "JOIN {$wpdb->posts} ON ({$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID) $join ";
  2596 				$cjoin    = "JOIN {$wpdb->posts} ON ({$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID) $join ";
  2569 				$cwhere   = "WHERE comment_approved = '1' $where";
  2597 				$cwhere   = "WHERE comment_approved = '1' $where";
  2570 				$cgroupby = "{$wpdb->comments}.comment_id";
  2598 				$cgroupby = "{$wpdb->comments}.comment_id";
  2571 			} else { // Other non singular e.g. front
  2599 			} else { // Other non-singular, e.g. front.
  2572 				$cjoin    = "JOIN {$wpdb->posts} ON ( {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID )";
  2600 				$cjoin    = "JOIN {$wpdb->posts} ON ( {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID )";
  2573 				$cwhere   = "WHERE ( post_status = 'publish' OR ( post_status = 'inherit' AND post_type = 'attachment' ) ) AND comment_approved = '1'";
  2601 				$cwhere   = "WHERE ( post_status = 'publish' OR ( post_status = 'inherit' AND post_type = 'attachment' ) ) AND comment_approved = '1'";
  2574 				$cgroupby = '';
  2602 				$cgroupby = '';
  2575 			}
  2603 			}
  2576 
  2604 
  2623 				 * @param string   $climits The JOIN clause of the query.
  2651 				 * @param string   $climits The JOIN clause of the query.
  2624 				 * @param WP_Query $this    The WP_Query instance (passed by reference).
  2652 				 * @param WP_Query $this    The WP_Query instance (passed by reference).
  2625 				 */
  2653 				 */
  2626 				$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option( 'posts_per_rss' ), &$this ) );
  2654 				$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option( 'posts_per_rss' ), &$this ) );
  2627 			}
  2655 			}
       
  2656 
  2628 			$cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
  2657 			$cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
  2629 			$corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
  2658 			$corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
       
  2659 			$climits  = ( ! empty( $climits ) ) ? $climits : '';
  2630 
  2660 
  2631 			$comments = (array) $wpdb->get_results( "SELECT $distinct {$wpdb->comments}.* FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits" );
  2661 			$comments = (array) $wpdb->get_results( "SELECT $distinct {$wpdb->comments}.* FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits" );
  2632 			// Convert to WP_Comment
  2662 			// Convert to WP_Comment.
  2633 			$this->comments      = array_map( 'get_comment', $comments );
  2663 			$this->comments      = array_map( 'get_comment', $comments );
  2634 			$this->comment_count = count( $this->comments );
  2664 			$this->comment_count = count( $this->comments );
  2635 
  2665 
  2636 			$post_ids = array();
  2666 			$post_ids = array();
  2637 
  2667 
  2885 		$found_rows = '';
  2915 		$found_rows = '';
  2886 		if ( ! $q['no_found_rows'] && ! empty( $limits ) ) {
  2916 		if ( ! $q['no_found_rows'] && ! empty( $limits ) ) {
  2887 			$found_rows = 'SQL_CALC_FOUND_ROWS';
  2917 			$found_rows = 'SQL_CALC_FOUND_ROWS';
  2888 		}
  2918 		}
  2889 
  2919 
  2890 		$this->request = $old_request = "SELECT $found_rows $distinct $fields FROM {$wpdb->posts} $join WHERE 1=1 $where $groupby $orderby $limits";
  2920 		$old_request   = "SELECT $found_rows $distinct $fields FROM {$wpdb->posts} $join WHERE 1=1 $where $groupby $orderby $limits";
       
  2921 		$this->request = $old_request;
  2891 
  2922 
  2892 		if ( ! $q['suppress_filters'] ) {
  2923 		if ( ! $q['suppress_filters'] ) {
  2893 			/**
  2924 			/**
  2894 			 * Filters the completed SQL query before sending.
  2925 			 * Filters the completed SQL query before sending.
  2895 			 *
  2926 			 *
  2917 		 *                          or null to allow WP to run its normal queries.
  2948 		 *                          or null to allow WP to run its normal queries.
  2918 		 * @param WP_Query   $this  The WP_Query instance (passed by reference).
  2949 		 * @param WP_Query   $this  The WP_Query instance (passed by reference).
  2919 		 */
  2950 		 */
  2920 		$this->posts = apply_filters_ref_array( 'posts_pre_query', array( null, &$this ) );
  2951 		$this->posts = apply_filters_ref_array( 'posts_pre_query', array( null, &$this ) );
  2921 
  2952 
  2922 		if ( 'ids' == $q['fields'] ) {
  2953 		if ( 'ids' === $q['fields'] ) {
  2923 			if ( null === $this->posts ) {
  2954 			if ( null === $this->posts ) {
  2924 				$this->posts = $wpdb->get_col( $this->request );
  2955 				$this->posts = $wpdb->get_col( $this->request );
  2925 			}
  2956 			}
  2926 
  2957 
  2927 			$this->posts      = array_map( 'intval', $this->posts );
  2958 			$this->posts      = array_map( 'intval', $this->posts );
  2929 			$this->set_found_posts( $q, $limits );
  2960 			$this->set_found_posts( $q, $limits );
  2930 
  2961 
  2931 			return $this->posts;
  2962 			return $this->posts;
  2932 		}
  2963 		}
  2933 
  2964 
  2934 		if ( 'id=>parent' == $q['fields'] ) {
  2965 		if ( 'id=>parent' === $q['fields'] ) {
  2935 			if ( null === $this->posts ) {
  2966 			if ( null === $this->posts ) {
  2936 				$this->posts = $wpdb->get_results( $this->request );
  2967 				$this->posts = $wpdb->get_results( $this->request );
  2937 			}
  2968 			}
  2938 
  2969 
  2939 			$this->post_count = count( $this->posts );
  2970 			$this->post_count = count( $this->posts );
  2949 
  2980 
  2950 			return $r;
  2981 			return $r;
  2951 		}
  2982 		}
  2952 
  2983 
  2953 		if ( null === $this->posts ) {
  2984 		if ( null === $this->posts ) {
  2954 			$split_the_query = ( $old_request == $this->request && "{$wpdb->posts}.*" == $fields && ! empty( $limits ) && $q['posts_per_page'] < 500 );
  2985 			$split_the_query = ( $old_request == $this->request && "{$wpdb->posts}.*" === $fields && ! empty( $limits ) && $q['posts_per_page'] < 500 );
  2955 
  2986 
  2956 			/**
  2987 			/**
  2957 			 * Filters whether to split the query.
  2988 			 * Filters whether to split the query.
  2958 			 *
  2989 			 *
  2959 			 * Splitting the query will cause it to fetch just the IDs of the found posts
  2990 			 * Splitting the query will cause it to fetch just the IDs of the found posts
  2966 			 * @param WP_Query $this            The WP_Query instance.
  2997 			 * @param WP_Query $this            The WP_Query instance.
  2967 			 */
  2998 			 */
  2968 			$split_the_query = apply_filters( 'split_the_query', $split_the_query, $this );
  2999 			$split_the_query = apply_filters( 'split_the_query', $split_the_query, $this );
  2969 
  3000 
  2970 			if ( $split_the_query ) {
  3001 			if ( $split_the_query ) {
  2971 				// First get the IDs and then fill in the objects
  3002 				// First get the IDs and then fill in the objects.
  2972 
  3003 
  2973 				$this->request = "SELECT $found_rows $distinct {$wpdb->posts}.ID FROM {$wpdb->posts} $join WHERE 1=1 $where $groupby $orderby $limits";
  3004 				$this->request = "SELECT $found_rows $distinct {$wpdb->posts}.ID FROM {$wpdb->posts} $join WHERE 1=1 $where $groupby $orderby $limits";
  2974 
  3005 
  2975 				/**
  3006 				/**
  2976 				 * Filters the Post IDs SQL request before sending.
  3007 				 * Filters the Post IDs SQL request before sending.
  3032 			/** This filter is documented in wp-includes/query.php */
  3063 			/** This filter is documented in wp-includes/query.php */
  3033 			$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option( 'posts_per_rss' ), &$this ) );
  3064 			$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option( 'posts_per_rss' ), &$this ) );
  3034 
  3065 
  3035 			$comments_request = "SELECT {$wpdb->comments}.* FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits";
  3066 			$comments_request = "SELECT {$wpdb->comments}.* FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits";
  3036 			$comments         = $wpdb->get_results( $comments_request );
  3067 			$comments         = $wpdb->get_results( $comments_request );
  3037 			// Convert to WP_Comment
  3068 			// Convert to WP_Comment.
  3038 			$this->comments      = array_map( 'get_comment', $comments );
  3069 			$this->comments      = array_map( 'get_comment', $comments );
  3039 			$this->comment_count = count( $this->comments );
  3070 			$this->comment_count = count( $this->comments );
  3040 		}
  3071 		}
  3041 
  3072 
  3042 		// Check post status to determine if post should be displayed.
  3073 		// Check post status to determine if post should be displayed.
  3043 		if ( ! empty( $this->posts ) && ( $this->is_single || $this->is_page ) ) {
  3074 		if ( ! empty( $this->posts ) && ( $this->is_single || $this->is_page ) ) {
  3044 			$status = get_post_status( $this->posts[0] );
  3075 			$status = get_post_status( $this->posts[0] );
       
  3076 
  3045 			if ( 'attachment' === $this->posts[0]->post_type && 0 === (int) $this->posts[0]->post_parent ) {
  3077 			if ( 'attachment' === $this->posts[0]->post_type && 0 === (int) $this->posts[0]->post_parent ) {
  3046 				$this->is_page       = false;
  3078 				$this->is_page       = false;
  3047 				$this->is_single     = true;
  3079 				$this->is_single     = true;
  3048 				$this->is_attachment = true;
  3080 				$this->is_attachment = true;
  3049 			}
  3081 			}
  3050 			$post_status_obj = get_post_status_object( $status );
       
  3051 
  3082 
  3052 			// If the post_status was specifically requested, let it pass through.
  3083 			// If the post_status was specifically requested, let it pass through.
  3053 			if ( ! $post_status_obj->public && ! in_array( $status, $q_status ) ) {
  3084 			if ( ! in_array( $status, $q_status, true ) ) {
  3054 
  3085 				$post_status_obj = get_post_status_object( $status );
  3055 				if ( ! is_user_logged_in() ) {
  3086 
  3056 					// User must be logged in to view unpublished posts.
  3087 				if ( $post_status_obj && ! $post_status_obj->public ) {
  3057 					$this->posts = array();
  3088 					if ( ! is_user_logged_in() ) {
  3058 				} else {
  3089 						// User must be logged in to view unpublished posts.
  3059 					if ( $post_status_obj->protected ) {
  3090 						$this->posts = array();
  3060 						// User must have edit permissions on the draft to preview.
  3091 					} else {
  3061 						if ( ! current_user_can( $edit_cap, $this->posts[0]->ID ) ) {
  3092 						if ( $post_status_obj->protected ) {
  3062 							$this->posts = array();
  3093 							// User must have edit permissions on the draft to preview.
       
  3094 							if ( ! current_user_can( $edit_cap, $this->posts[0]->ID ) ) {
       
  3095 								$this->posts = array();
       
  3096 							} else {
       
  3097 								$this->is_preview = true;
       
  3098 								if ( 'future' !== $status ) {
       
  3099 									$this->posts[0]->post_date = current_time( 'mysql' );
       
  3100 								}
       
  3101 							}
       
  3102 						} elseif ( $post_status_obj->private ) {
       
  3103 							if ( ! current_user_can( $read_cap, $this->posts[0]->ID ) ) {
       
  3104 								$this->posts = array();
       
  3105 							}
  3063 						} else {
  3106 						} else {
  3064 							$this->is_preview = true;
       
  3065 							if ( 'future' != $status ) {
       
  3066 								$this->posts[0]->post_date = current_time( 'mysql' );
       
  3067 							}
       
  3068 						}
       
  3069 					} elseif ( $post_status_obj->private ) {
       
  3070 						if ( ! current_user_can( $read_cap, $this->posts[0]->ID ) ) {
       
  3071 							$this->posts = array();
  3107 							$this->posts = array();
  3072 						}
  3108 						}
  3073 					} else {
  3109 					}
       
  3110 				} elseif ( ! $post_status_obj ) {
       
  3111 					// Post status is not registered, assume it's not public.
       
  3112 					if ( ! current_user_can( $edit_cap, $this->posts[0]->ID ) ) {
  3074 						$this->posts = array();
  3113 						$this->posts = array();
  3075 					}
  3114 					}
  3076 				}
  3115 				}
  3077 			}
  3116 			}
  3078 
  3117 
  3087 				 */
  3126 				 */
  3088 				$this->posts[0] = get_post( apply_filters_ref_array( 'the_preview', array( $this->posts[0], &$this ) ) );
  3127 				$this->posts[0] = get_post( apply_filters_ref_array( 'the_preview', array( $this->posts[0], &$this ) ) );
  3089 			}
  3128 			}
  3090 		}
  3129 		}
  3091 
  3130 
  3092 		// Put sticky posts at the top of the posts array
  3131 		// Put sticky posts at the top of the posts array.
  3093 		$sticky_posts = get_option( 'sticky_posts' );
  3132 		$sticky_posts = get_option( 'sticky_posts' );
  3094 		if ( $this->is_home && $page <= 1 && is_array( $sticky_posts ) && ! empty( $sticky_posts ) && ! $q['ignore_sticky_posts'] ) {
  3133 		if ( $this->is_home && $page <= 1 && is_array( $sticky_posts ) && ! empty( $sticky_posts ) && ! $q['ignore_sticky_posts'] ) {
  3095 			$num_posts     = count( $this->posts );
  3134 			$num_posts     = count( $this->posts );
  3096 			$sticky_offset = 0;
  3135 			$sticky_offset = 0;
  3097 			// Loop over posts and relocate stickies to the front.
  3136 			// Loop over posts and relocate stickies to the front.
  3098 			for ( $i = 0; $i < $num_posts; $i++ ) {
  3137 			for ( $i = 0; $i < $num_posts; $i++ ) {
  3099 				if ( in_array( $this->posts[ $i ]->ID, $sticky_posts ) ) {
  3138 				if ( in_array( $this->posts[ $i ]->ID, $sticky_posts, true ) ) {
  3100 					$sticky_post = $this->posts[ $i ];
  3139 					$sticky_post = $this->posts[ $i ];
  3101 					// Remove sticky from current position
  3140 					// Remove sticky from current position.
  3102 					array_splice( $this->posts, $i, 1 );
  3141 					array_splice( $this->posts, $i, 1 );
  3103 					// Move to front, after other stickies
  3142 					// Move to front, after other stickies.
  3104 					array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) );
  3143 					array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) );
  3105 					// Increment the sticky offset. The next sticky will be placed at this offset.
  3144 					// Increment the sticky offset. The next sticky will be placed at this offset.
  3106 					$sticky_offset++;
  3145 					$sticky_offset++;
  3107 					// Remove post from sticky posts array
  3146 					// Remove post from sticky posts array.
  3108 					$offset = array_search( $sticky_post->ID, $sticky_posts );
  3147 					$offset = array_search( $sticky_post->ID, $sticky_posts, true );
  3109 					unset( $sticky_posts[ $offset ] );
  3148 					unset( $sticky_posts[ $offset ] );
  3110 				}
  3149 				}
  3111 			}
  3150 			}
  3112 
  3151 
  3113 			// If any posts have been excluded specifically, Ignore those that are sticky.
  3152 			// If any posts have been excluded specifically, Ignore those that are sticky.
  3114 			if ( ! empty( $sticky_posts ) && ! empty( $q['post__not_in'] ) ) {
  3153 			if ( ! empty( $sticky_posts ) && ! empty( $q['post__not_in'] ) ) {
  3115 				$sticky_posts = array_diff( $sticky_posts, $q['post__not_in'] );
  3154 				$sticky_posts = array_diff( $sticky_posts, $q['post__not_in'] );
  3116 			}
  3155 			}
  3117 
  3156 
  3118 			// Fetch sticky posts that weren't in the query results
  3157 			// Fetch sticky posts that weren't in the query results.
  3119 			if ( ! empty( $sticky_posts ) ) {
  3158 			if ( ! empty( $sticky_posts ) ) {
  3120 				$stickies = get_posts(
  3159 				$stickies = get_posts(
  3121 					array(
  3160 					array(
  3122 						'post__in'    => $sticky_posts,
  3161 						'post__in'    => $sticky_posts,
  3123 						'post_type'   => $post_type,
  3162 						'post_type'   => $post_type,
  3196 			/**
  3235 			/**
  3197 			 * Filters the query to run for retrieving the found posts.
  3236 			 * Filters the query to run for retrieving the found posts.
  3198 			 *
  3237 			 *
  3199 			 * @since 2.1.0
  3238 			 * @since 2.1.0
  3200 			 *
  3239 			 *
  3201 			 * @param string   $found_posts The query to run to find the found posts.
  3240 			 * @param string   $found_posts_query The query to run to find the found posts.
  3202 			 * @param WP_Query $this        The WP_Query instance (passed by reference).
  3241 			 * @param WP_Query $this              The WP_Query instance (passed by reference).
  3203 			 */
  3242 			 */
  3204 			$this->found_posts = $wpdb->get_var( apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ) );
  3243 			$found_posts_query = apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) );
       
  3244 
       
  3245 			$this->found_posts = (int) $wpdb->get_var( $found_posts_query );
  3205 		} else {
  3246 		} else {
  3206 			if ( is_array( $this->posts ) ) {
  3247 			if ( is_array( $this->posts ) ) {
  3207 				$this->found_posts = count( $this->posts );
  3248 				$this->found_posts = count( $this->posts );
  3208 			} else {
  3249 			} else {
  3209 				if ( null === $this->posts ) {
  3250 				if ( null === $this->posts ) {
  3220 		 * @since 2.1.0
  3261 		 * @since 2.1.0
  3221 		 *
  3262 		 *
  3222 		 * @param int      $found_posts The number of posts found.
  3263 		 * @param int      $found_posts The number of posts found.
  3223 		 * @param WP_Query $this        The WP_Query instance (passed by reference).
  3264 		 * @param WP_Query $this        The WP_Query instance (passed by reference).
  3224 		 */
  3265 		 */
  3225 		$this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
  3266 		$this->found_posts = (int) apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
  3226 
  3267 
  3227 		if ( ! empty( $limits ) ) {
  3268 		if ( ! empty( $limits ) ) {
  3228 			$this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] );
  3269 			$this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] );
  3229 		}
  3270 		}
  3230 	}
  3271 	}
  3250 	 * Retrieves the next post, sets up the post, sets the 'in the loop'
  3291 	 * Retrieves the next post, sets up the post, sets the 'in the loop'
  3251 	 * property to true.
  3292 	 * property to true.
  3252 	 *
  3293 	 *
  3253 	 * @since 1.5.0
  3294 	 * @since 1.5.0
  3254 	 *
  3295 	 *
  3255 	 * @global WP_Post $post
  3296 	 * @global WP_Post $post Global post object.
  3256 	 */
  3297 	 */
  3257 	public function the_post() {
  3298 	public function the_post() {
  3258 		global $post;
  3299 		global $post;
  3259 		$this->in_the_loop = true;
  3300 		$this->in_the_loop = true;
  3260 
  3301 
  3261 		if ( $this->current_post == -1 ) { // loop has just started
  3302 		if ( -1 == $this->current_post ) { // Loop has just started.
  3262 			/**
  3303 			/**
  3263 			 * Fires once the loop is started.
  3304 			 * Fires once the loop is started.
  3264 			 *
  3305 			 *
  3265 			 * @since 2.0.0
  3306 			 * @since 2.0.0
  3266 			 *
  3307 			 *
  3278 	 *
  3319 	 *
  3279 	 * Calls the {@see 'loop_end'} action when the loop is complete.
  3320 	 * Calls the {@see 'loop_end'} action when the loop is complete.
  3280 	 *
  3321 	 *
  3281 	 * @since 1.5.0
  3322 	 * @since 1.5.0
  3282 	 *
  3323 	 *
  3283 	 * @return bool True if posts are available, false if end of loop.
  3324 	 * @return bool True if posts are available, false if end of the loop.
  3284 	 */
  3325 	 */
  3285 	public function have_posts() {
  3326 	public function have_posts() {
  3286 		if ( $this->current_post + 1 < $this->post_count ) {
  3327 		if ( $this->current_post + 1 < $this->post_count ) {
  3287 			return true;
  3328 			return true;
  3288 		} elseif ( $this->current_post + 1 == $this->post_count && $this->post_count > 0 ) {
  3329 		} elseif ( $this->current_post + 1 == $this->post_count && $this->post_count > 0 ) {
  3292 			 * @since 2.0.0
  3333 			 * @since 2.0.0
  3293 			 *
  3334 			 *
  3294 			 * @param WP_Query $this The WP_Query instance (passed by reference).
  3335 			 * @param WP_Query $this The WP_Query instance (passed by reference).
  3295 			 */
  3336 			 */
  3296 			do_action_ref_array( 'loop_end', array( &$this ) );
  3337 			do_action_ref_array( 'loop_end', array( &$this ) );
  3297 			// Do some cleaning up after the loop
  3338 			// Do some cleaning up after the loop.
  3298 			$this->rewind_posts();
  3339 			$this->rewind_posts();
  3299 		} elseif ( 0 === $this->post_count ) {
  3340 		} elseif ( 0 === $this->post_count ) {
  3300 			/**
  3341 			/**
  3301 			 * Fires if no results are found in a post query.
  3342 			 * Fires if no results are found in a post query.
  3302 			 *
  3343 			 *
  3339 
  3380 
  3340 	/**
  3381 	/**
  3341 	 * Sets up the current comment.
  3382 	 * Sets up the current comment.
  3342 	 *
  3383 	 *
  3343 	 * @since 2.2.0
  3384 	 * @since 2.2.0
  3344 	 * @global WP_Comment $comment Current comment.
  3385 	 *
       
  3386 	 * @global WP_Comment $comment Global comment object.
  3345 	 */
  3387 	 */
  3346 	public function the_comment() {
  3388 	public function the_comment() {
  3347 		global $comment;
  3389 		global $comment;
  3348 
  3390 
  3349 		$comment = $this->next_comment();
  3391 		$comment = $this->next_comment();
  3350 
  3392 
  3351 		if ( $this->current_comment == 0 ) {
  3393 		if ( 0 == $this->current_comment ) {
  3352 			/**
  3394 			/**
  3353 			 * Fires once the comment loop is started.
  3395 			 * Fires once the comment loop is started.
  3354 			 *
  3396 			 *
  3355 			 * @since 2.2.0
  3397 			 * @since 2.2.0
  3356 			 */
  3398 			 */
  3363 	 *
  3405 	 *
  3364 	 * Automatically rewinds comments when finished.
  3406 	 * Automatically rewinds comments when finished.
  3365 	 *
  3407 	 *
  3366 	 * @since 2.2.0
  3408 	 * @since 2.2.0
  3367 	 *
  3409 	 *
  3368 	 * @return bool True, if more comments. False, if no more posts.
  3410 	 * @return bool True if comments are available, false if no more comments.
  3369 	 */
  3411 	 */
  3370 	public function have_comments() {
  3412 	public function have_comments() {
  3371 		if ( $this->current_comment + 1 < $this->comment_count ) {
  3413 		if ( $this->current_comment + 1 < $this->comment_count ) {
  3372 			return true;
  3414 			return true;
  3373 		} elseif ( $this->current_comment + 1 == $this->comment_count ) {
  3415 		} elseif ( $this->current_comment + 1 == $this->comment_count ) {
  3392 	/**
  3434 	/**
  3393 	 * Sets up the WordPress query by parsing query string.
  3435 	 * Sets up the WordPress query by parsing query string.
  3394 	 *
  3436 	 *
  3395 	 * @since 1.5.0
  3437 	 * @since 1.5.0
  3396 	 *
  3438 	 *
       
  3439 	 * @see WP_Query::parse_query() for all available arguments.
       
  3440 	 *
  3397 	 * @param string|array $query URL query string or array of query arguments.
  3441 	 * @param string|array $query URL query string or array of query arguments.
  3398 	 * @return WP_Post[]|int[] Array of post objects or post IDs.
  3442 	 * @return WP_Post[]|int[] Array of post objects or post IDs.
  3399 	 */
  3443 	 */
  3400 	public function query( $query ) {
  3444 	public function query( $query ) {
  3401 		$this->init();
  3445 		$this->init();
  3402 		$this->query = $this->query_vars = wp_parse_args( $query );
  3446 		$this->query      = wp_parse_args( $query );
       
  3447 		$this->query_vars = $this->query;
  3403 		return $this->get_posts();
  3448 		return $this->get_posts();
  3404 	}
  3449 	}
  3405 
  3450 
  3406 	/**
  3451 	/**
  3407 	 * Retrieve queried object.
  3452 	 * Retrieve queried object.
  3441 					$queried_taxonomies = array_keys( $this->tax_query->queried_terms );
  3486 					$queried_taxonomies = array_keys( $this->tax_query->queried_terms );
  3442 					$matched_taxonomy   = reset( $queried_taxonomies );
  3487 					$matched_taxonomy   = reset( $queried_taxonomies );
  3443 					$query              = $this->tax_query->queried_terms[ $matched_taxonomy ];
  3488 					$query              = $this->tax_query->queried_terms[ $matched_taxonomy ];
  3444 
  3489 
  3445 					if ( ! empty( $query['terms'] ) ) {
  3490 					if ( ! empty( $query['terms'] ) ) {
  3446 						if ( 'term_id' == $query['field'] ) {
  3491 						if ( 'term_id' === $query['field'] ) {
  3447 							$term = get_term( reset( $query['terms'] ), $matched_taxonomy );
  3492 							$term = get_term( reset( $query['terms'] ), $matched_taxonomy );
  3448 						} else {
  3493 						} else {
  3449 							$term = get_term_by( $query['field'], reset( $query['terms'] ), $matched_taxonomy );
  3494 							$term = get_term_by( $query['field'], reset( $query['terms'] ), $matched_taxonomy );
  3450 						}
  3495 						}
  3451 					}
  3496 					}
  3503 	 *
  3548 	 *
  3504 	 * Sets up the WordPress query, if parameter is not empty.
  3549 	 * Sets up the WordPress query, if parameter is not empty.
  3505 	 *
  3550 	 *
  3506 	 * @since 1.5.0
  3551 	 * @since 1.5.0
  3507 	 *
  3552 	 *
       
  3553 	 * @see WP_Query::parse_query() for all available arguments.
       
  3554 	 *
  3508 	 * @param string|array $query URL query string or array of vars.
  3555 	 * @param string|array $query URL query string or array of vars.
  3509 	 */
  3556 	 */
  3510 	public function __construct( $query = '' ) {
  3557 	public function __construct( $query = '' ) {
  3511 		if ( ! empty( $query ) ) {
  3558 		if ( ! empty( $query ) ) {
  3512 			$this->query( $query );
  3559 			$this->query( $query );
  3520 	 *
  3567 	 *
  3521 	 * @param string $name Property to get.
  3568 	 * @param string $name Property to get.
  3522 	 * @return mixed Property.
  3569 	 * @return mixed Property.
  3523 	 */
  3570 	 */
  3524 	public function __get( $name ) {
  3571 	public function __get( $name ) {
  3525 		if ( in_array( $name, $this->compat_fields ) ) {
  3572 		if ( in_array( $name, $this->compat_fields, true ) ) {
  3526 			return $this->$name;
  3573 			return $this->$name;
  3527 		}
  3574 		}
  3528 	}
  3575 	}
  3529 
  3576 
  3530 	/**
  3577 	/**
  3534 	 *
  3581 	 *
  3535 	 * @param string $name Property to check if set.
  3582 	 * @param string $name Property to check if set.
  3536 	 * @return bool Whether the property is set.
  3583 	 * @return bool Whether the property is set.
  3537 	 */
  3584 	 */
  3538 	public function __isset( $name ) {
  3585 	public function __isset( $name ) {
  3539 		if ( in_array( $name, $this->compat_fields ) ) {
  3586 		if ( in_array( $name, $this->compat_fields, true ) ) {
  3540 			return isset( $this->$name );
  3587 			return isset( $this->$name );
  3541 		}
  3588 		}
  3542 	}
  3589 	}
  3543 
  3590 
  3544 	/**
  3591 	/**
  3545 	 * Make private/protected methods readable for backward compatibility.
  3592 	 * Make private/protected methods readable for backward compatibility.
  3546 	 *
  3593 	 *
  3547 	 * @since 4.0.0
  3594 	 * @since 4.0.0
  3548 	 *
  3595 	 *
  3549 	 * @param string   $name      Method to call.
  3596 	 * @param string $name      Method to call.
  3550 	 * @param array    $arguments Arguments to pass when calling.
  3597 	 * @param array  $arguments Arguments to pass when calling.
  3551 	 * @return mixed|false Return value of the callback, false otherwise.
  3598 	 * @return mixed|false Return value of the callback, false otherwise.
  3552 	 */
  3599 	 */
  3553 	public function __call( $name, $arguments ) {
  3600 	public function __call( $name, $arguments ) {
  3554 		if ( in_array( $name, $this->compat_methods ) ) {
  3601 		if ( in_array( $name, $this->compat_methods, true ) ) {
  3555 			return call_user_func_array( array( $this, $name ), $arguments );
  3602 			return $this->$name( ...$arguments );
  3556 		}
  3603 		}
  3557 		return false;
  3604 		return false;
  3558 	}
  3605 	}
  3559 
  3606 
  3560 	/**
  3607 	/**
  3562 	 *
  3609 	 *
  3563 	 * Month, Year, Category, Author, Post Type archive...
  3610 	 * Month, Year, Category, Author, Post Type archive...
  3564 	 *
  3611 	 *
  3565 	 * @since 3.1.0
  3612 	 * @since 3.1.0
  3566 	 *
  3613 	 *
  3567 	 * @return bool
  3614 	 * @return bool Whether the query is for an existing archive page.
  3568 	 */
  3615 	 */
  3569 	public function is_archive() {
  3616 	public function is_archive() {
  3570 		return (bool) $this->is_archive;
  3617 		return (bool) $this->is_archive;
  3571 	}
  3618 	}
  3572 
  3619 
  3573 	/**
  3620 	/**
  3574 	 * Is the query for an existing post type archive page?
  3621 	 * Is the query for an existing post type archive page?
  3575 	 *
  3622 	 *
  3576 	 * @since 3.1.0
  3623 	 * @since 3.1.0
  3577 	 *
  3624 	 *
  3578 	 * @param mixed $post_types Optional. Post type or array of posts types to check against.
  3625 	 * @param string|string[] $post_types Optional. Post type or array of posts types
  3579 	 * @return bool
  3626 	 *                                    to check against. Default empty.
       
  3627 	 * @return bool Whether the query is for an existing post type archive page.
  3580 	 */
  3628 	 */
  3581 	public function is_post_type_archive( $post_types = '' ) {
  3629 	public function is_post_type_archive( $post_types = '' ) {
  3582 		if ( empty( $post_types ) || ! $this->is_post_type_archive ) {
  3630 		if ( empty( $post_types ) || ! $this->is_post_type_archive ) {
  3583 			return (bool) $this->is_post_type_archive;
  3631 			return (bool) $this->is_post_type_archive;
  3584 		}
  3632 		}
  3587 		if ( is_array( $post_type ) ) {
  3635 		if ( is_array( $post_type ) ) {
  3588 			$post_type = reset( $post_type );
  3636 			$post_type = reset( $post_type );
  3589 		}
  3637 		}
  3590 		$post_type_object = get_post_type_object( $post_type );
  3638 		$post_type_object = get_post_type_object( $post_type );
  3591 
  3639 
  3592 		return in_array( $post_type_object->name, (array) $post_types );
  3640 		return in_array( $post_type_object->name, (array) $post_types, true );
  3593 	}
  3641 	}
  3594 
  3642 
  3595 	/**
  3643 	/**
  3596 	 * Is the query for an existing attachment page?
  3644 	 * Is the query for an existing attachment page?
  3597 	 *
  3645 	 *
  3598 	 * @since 3.1.0
  3646 	 * @since 3.1.0
  3599 	 *
  3647 	 *
  3600 	 * @param mixed $attachment Attachment ID, title, slug, or array of such.
  3648 	 * @param int|string|int[]|string[] $attachment Optional. Attachment ID, title, slug, or array of such
  3601 	 * @return bool
  3649 	 *                                              to check against. Default empty.
       
  3650 	 * @return bool Whether the query is for an existing attachment page.
  3602 	 */
  3651 	 */
  3603 	public function is_attachment( $attachment = '' ) {
  3652 	public function is_attachment( $attachment = '' ) {
  3604 		if ( ! $this->is_attachment ) {
  3653 		if ( ! $this->is_attachment ) {
  3605 			return false;
  3654 			return false;
  3606 		}
  3655 		}
  3611 
  3660 
  3612 		$attachment = array_map( 'strval', (array) $attachment );
  3661 		$attachment = array_map( 'strval', (array) $attachment );
  3613 
  3662 
  3614 		$post_obj = $this->get_queried_object();
  3663 		$post_obj = $this->get_queried_object();
  3615 
  3664 
  3616 		if ( in_array( (string) $post_obj->ID, $attachment ) ) {
  3665 		if ( in_array( (string) $post_obj->ID, $attachment, true ) ) {
  3617 			return true;
  3666 			return true;
  3618 		} elseif ( in_array( $post_obj->post_title, $attachment ) ) {
  3667 		} elseif ( in_array( $post_obj->post_title, $attachment, true ) ) {
  3619 			return true;
  3668 			return true;
  3620 		} elseif ( in_array( $post_obj->post_name, $attachment ) ) {
  3669 		} elseif ( in_array( $post_obj->post_name, $attachment, true ) ) {
  3621 			return true;
  3670 			return true;
  3622 		}
  3671 		}
  3623 		return false;
  3672 		return false;
  3624 	}
  3673 	}
  3625 
  3674 
  3629 	 * If the $author parameter is specified, this function will additionally
  3678 	 * If the $author parameter is specified, this function will additionally
  3630 	 * check if the query is for one of the authors specified.
  3679 	 * check if the query is for one of the authors specified.
  3631 	 *
  3680 	 *
  3632 	 * @since 3.1.0
  3681 	 * @since 3.1.0
  3633 	 *
  3682 	 *
  3634 	 * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames
  3683 	 * @param int|string|int[]|string[] $author Optional. User ID, nickname, nicename, or array of such
  3635 	 * @return bool
  3684 	 *                                          to check against. Default empty.
       
  3685 	 * @return bool Whether the query is for an existing author archive page.
  3636 	 */
  3686 	 */
  3637 	public function is_author( $author = '' ) {
  3687 	public function is_author( $author = '' ) {
  3638 		if ( ! $this->is_author ) {
  3688 		if ( ! $this->is_author ) {
  3639 			return false;
  3689 			return false;
  3640 		}
  3690 		}
  3645 
  3695 
  3646 		$author_obj = $this->get_queried_object();
  3696 		$author_obj = $this->get_queried_object();
  3647 
  3697 
  3648 		$author = array_map( 'strval', (array) $author );
  3698 		$author = array_map( 'strval', (array) $author );
  3649 
  3699 
  3650 		if ( in_array( (string) $author_obj->ID, $author ) ) {
  3700 		if ( in_array( (string) $author_obj->ID, $author, true ) ) {
  3651 			return true;
  3701 			return true;
  3652 		} elseif ( in_array( $author_obj->nickname, $author ) ) {
  3702 		} elseif ( in_array( $author_obj->nickname, $author, true ) ) {
  3653 			return true;
  3703 			return true;
  3654 		} elseif ( in_array( $author_obj->user_nicename, $author ) ) {
  3704 		} elseif ( in_array( $author_obj->user_nicename, $author, true ) ) {
  3655 			return true;
  3705 			return true;
  3656 		}
  3706 		}
  3657 
  3707 
  3658 		return false;
  3708 		return false;
  3659 	}
  3709 	}
  3664 	 * If the $category parameter is specified, this function will additionally
  3714 	 * If the $category parameter is specified, this function will additionally
  3665 	 * check if the query is for one of the categories specified.
  3715 	 * check if the query is for one of the categories specified.
  3666 	 *
  3716 	 *
  3667 	 * @since 3.1.0
  3717 	 * @since 3.1.0
  3668 	 *
  3718 	 *
  3669 	 * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs.
  3719 	 * @param int|string|int[]|string[] $category Optional. Category ID, name, slug, or array of such
  3670 	 * @return bool
  3720 	 *                                            to check against. Default empty.
       
  3721 	 * @return bool Whether the query is for an existing category archive page.
  3671 	 */
  3722 	 */
  3672 	public function is_category( $category = '' ) {
  3723 	public function is_category( $category = '' ) {
  3673 		if ( ! $this->is_category ) {
  3724 		if ( ! $this->is_category ) {
  3674 			return false;
  3725 			return false;
  3675 		}
  3726 		}
  3680 
  3731 
  3681 		$cat_obj = $this->get_queried_object();
  3732 		$cat_obj = $this->get_queried_object();
  3682 
  3733 
  3683 		$category = array_map( 'strval', (array) $category );
  3734 		$category = array_map( 'strval', (array) $category );
  3684 
  3735 
  3685 		if ( in_array( (string) $cat_obj->term_id, $category ) ) {
  3736 		if ( in_array( (string) $cat_obj->term_id, $category, true ) ) {
  3686 			return true;
  3737 			return true;
  3687 		} elseif ( in_array( $cat_obj->name, $category ) ) {
  3738 		} elseif ( in_array( $cat_obj->name, $category, true ) ) {
  3688 			return true;
  3739 			return true;
  3689 		} elseif ( in_array( $cat_obj->slug, $category ) ) {
  3740 		} elseif ( in_array( $cat_obj->slug, $category, true ) ) {
  3690 			return true;
  3741 			return true;
  3691 		}
  3742 		}
  3692 
  3743 
  3693 		return false;
  3744 		return false;
  3694 	}
  3745 	}
  3699 	 * If the $tag parameter is specified, this function will additionally
  3750 	 * If the $tag parameter is specified, this function will additionally
  3700 	 * check if the query is for one of the tags specified.
  3751 	 * check if the query is for one of the tags specified.
  3701 	 *
  3752 	 *
  3702 	 * @since 3.1.0
  3753 	 * @since 3.1.0
  3703 	 *
  3754 	 *
  3704 	 * @param mixed $tag Optional. Tag ID, name, slug, or array of Tag IDs, names, and slugs.
  3755 	 * @param int|string|int[]|string[] $tag Optional. Tag ID, name, slug, or array of such
  3705 	 * @return bool
  3756 	 *                                       to check against. Default empty.
       
  3757 	 * @return bool Whether the query is for an existing tag archive page.
  3706 	 */
  3758 	 */
  3707 	public function is_tag( $tag = '' ) {
  3759 	public function is_tag( $tag = '' ) {
  3708 		if ( ! $this->is_tag ) {
  3760 		if ( ! $this->is_tag ) {
  3709 			return false;
  3761 			return false;
  3710 		}
  3762 		}
  3715 
  3767 
  3716 		$tag_obj = $this->get_queried_object();
  3768 		$tag_obj = $this->get_queried_object();
  3717 
  3769 
  3718 		$tag = array_map( 'strval', (array) $tag );
  3770 		$tag = array_map( 'strval', (array) $tag );
  3719 
  3771 
  3720 		if ( in_array( (string) $tag_obj->term_id, $tag ) ) {
  3772 		if ( in_array( (string) $tag_obj->term_id, $tag, true ) ) {
  3721 			return true;
  3773 			return true;
  3722 		} elseif ( in_array( $tag_obj->name, $tag ) ) {
  3774 		} elseif ( in_array( $tag_obj->name, $tag, true ) ) {
  3723 			return true;
  3775 			return true;
  3724 		} elseif ( in_array( $tag_obj->slug, $tag ) ) {
  3776 		} elseif ( in_array( $tag_obj->slug, $tag, true ) ) {
  3725 			return true;
  3777 			return true;
  3726 		}
  3778 		}
  3727 
  3779 
  3728 		return false;
  3780 		return false;
  3729 	}
  3781 	}
  3740 	 *
  3792 	 *
  3741 	 * @since 3.1.0
  3793 	 * @since 3.1.0
  3742 	 *
  3794 	 *
  3743 	 * @global array $wp_taxonomies
  3795 	 * @global array $wp_taxonomies
  3744 	 *
  3796 	 *
  3745 	 * @param mixed $taxonomy Optional. Taxonomy slug or slugs.
  3797 	 * @param string|string[]           $taxonomy Optional. Taxonomy slug or slugs to check against.
  3746 	 * @param mixed $term     Optional. Term ID, name, slug or array of Term IDs, names, and slugs.
  3798 	 *                                            Default empty.
  3747 	 * @return bool True for custom taxonomy archive pages, false for built-in taxonomies (category and tag archives).
  3799 	 * @param int|string|int[]|string[] $term     Optional. Term ID, name, slug, or array of such
       
  3800 	 *                                            to check against. Default empty.
       
  3801 	 * @return bool Whether the query is for an existing custom taxonomy archive page.
       
  3802 	 *              True for custom taxonomy archive pages, false for built-in taxonomies
       
  3803 	 *              (category and tag archives).
  3748 	 */
  3804 	 */
  3749 	public function is_tax( $taxonomy = '', $term = '' ) {
  3805 	public function is_tax( $taxonomy = '', $term = '' ) {
  3750 		global $wp_taxonomies;
  3806 		global $wp_taxonomies;
  3751 
  3807 
  3752 		if ( ! $this->is_tax ) {
  3808 		if ( ! $this->is_tax ) {
  3760 		$queried_object = $this->get_queried_object();
  3816 		$queried_object = $this->get_queried_object();
  3761 		$tax_array      = array_intersect( array_keys( $wp_taxonomies ), (array) $taxonomy );
  3817 		$tax_array      = array_intersect( array_keys( $wp_taxonomies ), (array) $taxonomy );
  3762 		$term_array     = (array) $term;
  3818 		$term_array     = (array) $term;
  3763 
  3819 
  3764 		// Check that the taxonomy matches.
  3820 		// Check that the taxonomy matches.
  3765 		if ( ! ( isset( $queried_object->taxonomy ) && count( $tax_array ) && in_array( $queried_object->taxonomy, $tax_array ) ) ) {
  3821 		if ( ! ( isset( $queried_object->taxonomy ) && count( $tax_array ) && in_array( $queried_object->taxonomy, $tax_array, true ) ) ) {
  3766 			return false;
  3822 			return false;
  3767 		}
  3823 		}
  3768 
  3824 
  3769 		// Only a Taxonomy provided.
  3825 		// Only a taxonomy provided.
  3770 		if ( empty( $term ) ) {
  3826 		if ( empty( $term ) ) {
  3771 			return true;
  3827 			return true;
  3772 		}
  3828 		}
  3773 
  3829 
  3774 		return isset( $queried_object->term_id ) &&
  3830 		return isset( $queried_object->term_id ) &&
  3784 	 * Whether the current URL is within the comments popup window.
  3840 	 * Whether the current URL is within the comments popup window.
  3785 	 *
  3841 	 *
  3786 	 * @since 3.1.0
  3842 	 * @since 3.1.0
  3787 	 * @deprecated 4.5.0
  3843 	 * @deprecated 4.5.0
  3788 	 *
  3844 	 *
  3789 	 * @return bool
  3845 	 * @return false Always returns false.
  3790 	 */
  3846 	 */
  3791 	public function is_comments_popup() {
  3847 	public function is_comments_popup() {
  3792 		_deprecated_function( __FUNCTION__, '4.5.0' );
  3848 		_deprecated_function( __FUNCTION__, '4.5.0' );
  3793 
  3849 
  3794 		return false;
  3850 		return false;
  3797 	/**
  3853 	/**
  3798 	 * Is the query for an existing date archive?
  3854 	 * Is the query for an existing date archive?
  3799 	 *
  3855 	 *
  3800 	 * @since 3.1.0
  3856 	 * @since 3.1.0
  3801 	 *
  3857 	 *
  3802 	 * @return bool
  3858 	 * @return bool Whether the query is for an existing date archive.
  3803 	 */
  3859 	 */
  3804 	public function is_date() {
  3860 	public function is_date() {
  3805 		return (bool) $this->is_date;
  3861 		return (bool) $this->is_date;
  3806 	}
  3862 	}
  3807 
  3863 
  3808 	/**
  3864 	/**
  3809 	 * Is the query for an existing day archive?
  3865 	 * Is the query for an existing day archive?
  3810 	 *
  3866 	 *
  3811 	 * @since 3.1.0
  3867 	 * @since 3.1.0
  3812 	 *
  3868 	 *
  3813 	 * @return bool
  3869 	 * @return bool Whether the query is for an existing day archive.
  3814 	 */
  3870 	 */
  3815 	public function is_day() {
  3871 	public function is_day() {
  3816 		return (bool) $this->is_day;
  3872 		return (bool) $this->is_day;
  3817 	}
  3873 	}
  3818 
  3874 
  3819 	/**
  3875 	/**
  3820 	 * Is the query for a feed?
  3876 	 * Is the query for a feed?
  3821 	 *
  3877 	 *
  3822 	 * @since 3.1.0
  3878 	 * @since 3.1.0
  3823 	 *
  3879 	 *
  3824 	 * @param string|array $feeds Optional feed types to check.
  3880 	 * @param string|string[] $feeds Optional. Feed type or array of feed types
  3825 	 * @return bool
  3881 	 *                                         to check against. Default empty.
       
  3882 	 * @return bool Whether the query is for a feed.
  3826 	 */
  3883 	 */
  3827 	public function is_feed( $feeds = '' ) {
  3884 	public function is_feed( $feeds = '' ) {
  3828 		if ( empty( $feeds ) || ! $this->is_feed ) {
  3885 		if ( empty( $feeds ) || ! $this->is_feed ) {
  3829 			return (bool) $this->is_feed;
  3886 			return (bool) $this->is_feed;
  3830 		}
  3887 		}
       
  3888 
  3831 		$qv = $this->get( 'feed' );
  3889 		$qv = $this->get( 'feed' );
  3832 		if ( 'feed' == $qv ) {
  3890 		if ( 'feed' === $qv ) {
  3833 			$qv = get_default_feed();
  3891 			$qv = get_default_feed();
  3834 		}
  3892 		}
  3835 		return in_array( $qv, (array) $feeds );
  3893 
       
  3894 		return in_array( $qv, (array) $feeds, true );
  3836 	}
  3895 	}
  3837 
  3896 
  3838 	/**
  3897 	/**
  3839 	 * Is the query for a comments feed?
  3898 	 * Is the query for a comments feed?
  3840 	 *
  3899 	 *
  3841 	 * @since 3.1.0
  3900 	 * @since 3.1.0
  3842 	 *
  3901 	 *
  3843 	 * @return bool
  3902 	 * @return bool Whether the query is for a comments feed.
  3844 	 */
  3903 	 */
  3845 	public function is_comment_feed() {
  3904 	public function is_comment_feed() {
  3846 		return (bool) $this->is_comment_feed;
  3905 		return (bool) $this->is_comment_feed;
  3847 	}
  3906 	}
  3848 
  3907 
  3858 	 *
  3917 	 *
  3859 	 * Otherwise the same as @see WP_Query::is_home()
  3918 	 * Otherwise the same as @see WP_Query::is_home()
  3860 	 *
  3919 	 *
  3861 	 * @since 3.1.0
  3920 	 * @since 3.1.0
  3862 	 *
  3921 	 *
  3863 	 * @return bool True, if front of site.
  3922 	 * @return bool Whether the query is for the front page of the site.
  3864 	 */
  3923 	 */
  3865 	public function is_front_page() {
  3924 	public function is_front_page() {
  3866 		// most likely case
  3925 		// Most likely case.
  3867 		if ( 'posts' == get_option( 'show_on_front' ) && $this->is_home() ) {
  3926 		if ( 'posts' === get_option( 'show_on_front' ) && $this->is_home() ) {
  3868 			return true;
  3927 			return true;
  3869 		} elseif ( 'page' == get_option( 'show_on_front' ) && get_option( 'page_on_front' ) && $this->is_page( get_option( 'page_on_front' ) ) ) {
  3928 		} elseif ( 'page' === get_option( 'show_on_front' ) && get_option( 'page_on_front' )
       
  3929 			&& $this->is_page( get_option( 'page_on_front' ) )
       
  3930 		) {
  3870 			return true;
  3931 			return true;
  3871 		} else {
  3932 		} else {
  3872 			return false;
  3933 			return false;
  3873 		}
  3934 		}
  3874 	}
  3935 	}
  3885 	 *
  3946 	 *
  3886 	 * @see WP_Query::is_front_page()
  3947 	 * @see WP_Query::is_front_page()
  3887 	 *
  3948 	 *
  3888 	 * @since 3.1.0
  3949 	 * @since 3.1.0
  3889 	 *
  3950 	 *
  3890 	 * @return bool True if blog view homepage.
  3951 	 * @return bool Whether the query is for the blog homepage.
  3891 	 */
  3952 	 */
  3892 	public function is_home() {
  3953 	public function is_home() {
  3893 		return (bool) $this->is_home;
  3954 		return (bool) $this->is_home;
  3894 	}
  3955 	}
  3895 
  3956 
  3902 	 *
  3963 	 *
  3903 	 * This function will return true only on the page you set as the "Privacy Policy page".
  3964 	 * This function will return true only on the page you set as the "Privacy Policy page".
  3904 	 *
  3965 	 *
  3905 	 * @since 5.2.0
  3966 	 * @since 5.2.0
  3906 	 *
  3967 	 *
  3907 	 * @return bool True, if Privacy Policy page.
  3968 	 * @return bool Whether the query is for the Privacy Policy page.
  3908 	 */
  3969 	 */
  3909 	public function is_privacy_policy() {
  3970 	public function is_privacy_policy() {
  3910 		if ( get_option( 'wp_page_for_privacy_policy' ) && $this->is_page( get_option( 'wp_page_for_privacy_policy' ) ) ) {
  3971 		if ( get_option( 'wp_page_for_privacy_policy' )
       
  3972 			&& $this->is_page( get_option( 'wp_page_for_privacy_policy' ) )
       
  3973 		) {
  3911 			return true;
  3974 			return true;
  3912 		} else {
  3975 		} else {
  3913 			return false;
  3976 			return false;
  3914 		}
  3977 		}
  3915 	}
  3978 	}
  3917 	/**
  3980 	/**
  3918 	 * Is the query for an existing month archive?
  3981 	 * Is the query for an existing month archive?
  3919 	 *
  3982 	 *
  3920 	 * @since 3.1.0
  3983 	 * @since 3.1.0
  3921 	 *
  3984 	 *
  3922 	 * @return bool
  3985 	 * @return bool Whether the query is for an existing month archive.
  3923 	 */
  3986 	 */
  3924 	public function is_month() {
  3987 	public function is_month() {
  3925 		return (bool) $this->is_month;
  3988 		return (bool) $this->is_month;
  3926 	}
  3989 	}
  3927 
  3990 
  3934 	 * @see WP_Query::is_single()
  3997 	 * @see WP_Query::is_single()
  3935 	 * @see WP_Query::is_singular()
  3998 	 * @see WP_Query::is_singular()
  3936 	 *
  3999 	 *
  3937 	 * @since 3.1.0
  4000 	 * @since 3.1.0
  3938 	 *
  4001 	 *
  3939 	 * @param int|string|array $page Optional. Page ID, title, slug, path, or array of such. Default empty.
  4002 	 * @param int|string|int[]|string[] $page Optional. Page ID, title, slug, path, or array of such
       
  4003 	 *                                        to check against. Default empty.
  3940 	 * @return bool Whether the query is for an existing single page.
  4004 	 * @return bool Whether the query is for an existing single page.
  3941 	 */
  4005 	 */
  3942 	public function is_page( $page = '' ) {
  4006 	public function is_page( $page = '' ) {
  3943 		if ( ! $this->is_page ) {
  4007 		if ( ! $this->is_page ) {
  3944 			return false;
  4008 			return false;
  3950 
  4014 
  3951 		$page_obj = $this->get_queried_object();
  4015 		$page_obj = $this->get_queried_object();
  3952 
  4016 
  3953 		$page = array_map( 'strval', (array) $page );
  4017 		$page = array_map( 'strval', (array) $page );
  3954 
  4018 
  3955 		if ( in_array( (string) $page_obj->ID, $page ) ) {
  4019 		if ( in_array( (string) $page_obj->ID, $page, true ) ) {
  3956 			return true;
  4020 			return true;
  3957 		} elseif ( in_array( $page_obj->post_title, $page ) ) {
  4021 		} elseif ( in_array( $page_obj->post_title, $page, true ) ) {
  3958 			return true;
  4022 			return true;
  3959 		} elseif ( in_array( $page_obj->post_name, $page ) ) {
  4023 		} elseif ( in_array( $page_obj->post_name, $page, true ) ) {
  3960 			return true;
  4024 			return true;
  3961 		} else {
  4025 		} else {
  3962 			foreach ( $page as $pagepath ) {
  4026 			foreach ( $page as $pagepath ) {
  3963 				if ( ! strpos( $pagepath, '/' ) ) {
  4027 				if ( ! strpos( $pagepath, '/' ) ) {
  3964 					continue;
  4028 					continue;
  3973 
  4037 
  3974 		return false;
  4038 		return false;
  3975 	}
  4039 	}
  3976 
  4040 
  3977 	/**
  4041 	/**
  3978 	 * Is the query for paged result and not for the first page?
  4042 	 * Is the query for a paged result and not for the first page?
  3979 	 *
  4043 	 *
  3980 	 * @since 3.1.0
  4044 	 * @since 3.1.0
  3981 	 *
  4045 	 *
  3982 	 * @return bool
  4046 	 * @return bool Whether the query is for a paged result.
  3983 	 */
  4047 	 */
  3984 	public function is_paged() {
  4048 	public function is_paged() {
  3985 		return (bool) $this->is_paged;
  4049 		return (bool) $this->is_paged;
  3986 	}
  4050 	}
  3987 
  4051 
  3988 	/**
  4052 	/**
  3989 	 * Is the query for a post or page preview?
  4053 	 * Is the query for a post or page preview?
  3990 	 *
  4054 	 *
  3991 	 * @since 3.1.0
  4055 	 * @since 3.1.0
  3992 	 *
  4056 	 *
  3993 	 * @return bool
  4057 	 * @return bool Whether the query is for a post or page preview.
  3994 	 */
  4058 	 */
  3995 	public function is_preview() {
  4059 	public function is_preview() {
  3996 		return (bool) $this->is_preview;
  4060 		return (bool) $this->is_preview;
  3997 	}
  4061 	}
  3998 
  4062 
  3999 	/**
  4063 	/**
  4000 	 * Is the query for the robots file?
  4064 	 * Is the query for the robots.txt file?
  4001 	 *
  4065 	 *
  4002 	 * @since 3.1.0
  4066 	 * @since 3.1.0
  4003 	 *
  4067 	 *
  4004 	 * @return bool
  4068 	 * @return bool Whether the query is for the robots.txt file.
  4005 	 */
  4069 	 */
  4006 	public function is_robots() {
  4070 	public function is_robots() {
  4007 		return (bool) $this->is_robots;
  4071 		return (bool) $this->is_robots;
  4008 	}
  4072 	}
  4009 
  4073 
  4010 	/**
  4074 	/**
       
  4075 	 * Is the query for the favicon.ico file?
       
  4076 	 *
       
  4077 	 * @since 5.4.0
       
  4078 	 *
       
  4079 	 * @return bool Whether the query is for the favicon.ico file.
       
  4080 	 */
       
  4081 	public function is_favicon() {
       
  4082 		return (bool) $this->is_favicon;
       
  4083 	}
       
  4084 
       
  4085 	/**
  4011 	 * Is the query for a search?
  4086 	 * Is the query for a search?
  4012 	 *
  4087 	 *
  4013 	 * @since 3.1.0
  4088 	 * @since 3.1.0
  4014 	 *
  4089 	 *
  4015 	 * @return bool
  4090 	 * @return bool Whether the query is for a search.
  4016 	 */
  4091 	 */
  4017 	public function is_search() {
  4092 	public function is_search() {
  4018 		return (bool) $this->is_search;
  4093 		return (bool) $this->is_search;
  4019 	}
  4094 	}
  4020 
  4095 
  4029 	 * @see WP_Query::is_page()
  4104 	 * @see WP_Query::is_page()
  4030 	 * @see WP_Query::is_singular()
  4105 	 * @see WP_Query::is_singular()
  4031 	 *
  4106 	 *
  4032 	 * @since 3.1.0
  4107 	 * @since 3.1.0
  4033 	 *
  4108 	 *
  4034 	 * @param int|string|array $post Optional. Post ID, title, slug, path, or array of such. Default empty.
  4109 	 * @param int|string|int[]|string[] $post Optional. Post ID, title, slug, path, or array of such
       
  4110 	 *                                        to check against. Default empty.
  4035 	 * @return bool Whether the query is for an existing single post.
  4111 	 * @return bool Whether the query is for an existing single post.
  4036 	 */
  4112 	 */
  4037 	public function is_single( $post = '' ) {
  4113 	public function is_single( $post = '' ) {
  4038 		if ( ! $this->is_single ) {
  4114 		if ( ! $this->is_single ) {
  4039 			return false;
  4115 			return false;
  4045 
  4121 
  4046 		$post_obj = $this->get_queried_object();
  4122 		$post_obj = $this->get_queried_object();
  4047 
  4123 
  4048 		$post = array_map( 'strval', (array) $post );
  4124 		$post = array_map( 'strval', (array) $post );
  4049 
  4125 
  4050 		if ( in_array( (string) $post_obj->ID, $post ) ) {
  4126 		if ( in_array( (string) $post_obj->ID, $post, true ) ) {
  4051 			return true;
  4127 			return true;
  4052 		} elseif ( in_array( $post_obj->post_title, $post ) ) {
  4128 		} elseif ( in_array( $post_obj->post_title, $post, true ) ) {
  4053 			return true;
  4129 			return true;
  4054 		} elseif ( in_array( $post_obj->post_name, $post ) ) {
  4130 		} elseif ( in_array( $post_obj->post_name, $post, true ) ) {
  4055 			return true;
  4131 			return true;
  4056 		} else {
  4132 		} else {
  4057 			foreach ( $post as $postpath ) {
  4133 			foreach ( $post as $postpath ) {
  4058 				if ( ! strpos( $postpath, '/' ) ) {
  4134 				if ( ! strpos( $postpath, '/' ) ) {
  4059 					continue;
  4135 					continue;
  4078 	 * @see WP_Query::is_page()
  4154 	 * @see WP_Query::is_page()
  4079 	 * @see WP_Query::is_single()
  4155 	 * @see WP_Query::is_single()
  4080 	 *
  4156 	 *
  4081 	 * @since 3.1.0
  4157 	 * @since 3.1.0
  4082 	 *
  4158 	 *
  4083 	 * @param string|array $post_types Optional. Post type or array of post types. Default empty.
  4159 	 * @param string|string[] $post_types Optional. Post type or array of post types
  4084 	 * @return bool Whether the query is for an existing single post of any of the given post types.
  4160 	 *                                    to check against. Default empty.
       
  4161 	 * @return bool Whether the query is for an existing single post
       
  4162 	 *              or any of the given post types.
  4085 	 */
  4163 	 */
  4086 	public function is_singular( $post_types = '' ) {
  4164 	public function is_singular( $post_types = '' ) {
  4087 		if ( empty( $post_types ) || ! $this->is_singular ) {
  4165 		if ( empty( $post_types ) || ! $this->is_singular ) {
  4088 			return (bool) $this->is_singular;
  4166 			return (bool) $this->is_singular;
  4089 		}
  4167 		}
  4090 
  4168 
  4091 		$post_obj = $this->get_queried_object();
  4169 		$post_obj = $this->get_queried_object();
  4092 
  4170 
  4093 		return in_array( $post_obj->post_type, (array) $post_types );
  4171 		return in_array( $post_obj->post_type, (array) $post_types, true );
  4094 	}
  4172 	}
  4095 
  4173 
  4096 	/**
  4174 	/**
  4097 	 * Is the query for a specific time?
  4175 	 * Is the query for a specific time?
  4098 	 *
  4176 	 *
  4099 	 * @since 3.1.0
  4177 	 * @since 3.1.0
  4100 	 *
  4178 	 *
  4101 	 * @return bool
  4179 	 * @return bool Whether the query is for a specific time.
  4102 	 */
  4180 	 */
  4103 	public function is_time() {
  4181 	public function is_time() {
  4104 		return (bool) $this->is_time;
  4182 		return (bool) $this->is_time;
  4105 	}
  4183 	}
  4106 
  4184 
  4107 	/**
  4185 	/**
  4108 	 * Is the query for a trackback endpoint call?
  4186 	 * Is the query for a trackback endpoint call?
  4109 	 *
  4187 	 *
  4110 	 * @since 3.1.0
  4188 	 * @since 3.1.0
  4111 	 *
  4189 	 *
  4112 	 * @return bool
  4190 	 * @return bool Whether the query is for a trackback endpoint call.
  4113 	 */
  4191 	 */
  4114 	public function is_trackback() {
  4192 	public function is_trackback() {
  4115 		return (bool) $this->is_trackback;
  4193 		return (bool) $this->is_trackback;
  4116 	}
  4194 	}
  4117 
  4195 
  4118 	/**
  4196 	/**
  4119 	 * Is the query for an existing year archive?
  4197 	 * Is the query for an existing year archive?
  4120 	 *
  4198 	 *
  4121 	 * @since 3.1.0
  4199 	 * @since 3.1.0
  4122 	 *
  4200 	 *
  4123 	 * @return bool
  4201 	 * @return bool Whether the query is for an existing year archive.
  4124 	 */
  4202 	 */
  4125 	public function is_year() {
  4203 	public function is_year() {
  4126 		return (bool) $this->is_year;
  4204 		return (bool) $this->is_year;
  4127 	}
  4205 	}
  4128 
  4206 
  4129 	/**
  4207 	/**
  4130 	 * Is the query a 404 (returns no results)?
  4208 	 * Is the query a 404 (returns no results)?
  4131 	 *
  4209 	 *
  4132 	 * @since 3.1.0
  4210 	 * @since 3.1.0
  4133 	 *
  4211 	 *
  4134 	 * @return bool
  4212 	 * @return bool Whether the query is a 404 error.
  4135 	 */
  4213 	 */
  4136 	public function is_404() {
  4214 	public function is_404() {
  4137 		return (bool) $this->is_404;
  4215 		return (bool) $this->is_404;
  4138 	}
  4216 	}
  4139 
  4217 
  4140 	/**
  4218 	/**
  4141 	 * Is the query for an embedded post?
  4219 	 * Is the query for an embedded post?
  4142 	 *
  4220 	 *
  4143 	 * @since 4.4.0
  4221 	 * @since 4.4.0
  4144 	 *
  4222 	 *
  4145 	 * @return bool
  4223 	 * @return bool Whether the query is for an embedded post.
  4146 	 */
  4224 	 */
  4147 	public function is_embed() {
  4225 	public function is_embed() {
  4148 		return (bool) $this->is_embed;
  4226 		return (bool) $this->is_embed;
  4149 	}
  4227 	}
  4150 
  4228 
  4151 	/**
  4229 	/**
  4152 	 * Is the query the main query?
  4230 	 * Is the query the main query?
  4153 	 *
  4231 	 *
  4154 	 * @since 3.3.0
  4232 	 * @since 3.3.0
  4155 	 *
  4233 	 *
  4156 	 * @global WP_Query $wp_query Global WP_Query instance.
  4234 	 * @global WP_Query $wp_query WordPress Query object.
  4157 	 *
  4235 	 *
  4158 	 * @return bool
  4236 	 * @return bool Whether the query is the main query.
  4159 	 */
  4237 	 */
  4160 	public function is_main_query() {
  4238 	public function is_main_query() {
  4161 		global $wp_the_query;
  4239 		global $wp_the_query;
  4162 		return $wp_the_query === $this;
  4240 		return $wp_the_query === $this;
  4163 	}
  4241 	}
  4166 	 * Set up global post data.
  4244 	 * Set up global post data.
  4167 	 *
  4245 	 *
  4168 	 * @since 4.1.0
  4246 	 * @since 4.1.0
  4169 	 * @since 4.4.0 Added the ability to pass a post ID to `$post`.
  4247 	 * @since 4.4.0 Added the ability to pass a post ID to `$post`.
  4170 	 *
  4248 	 *
  4171 	 * @global int             $id
  4249 	 * @global int     $id
  4172 	 * @global WP_User         $authordata
  4250 	 * @global WP_User $authordata
  4173 	 * @global string|int|bool $currentday
  4251 	 * @global string  $currentday
  4174 	 * @global string|int|bool $currentmonth
  4252 	 * @global string  $currentmonth
  4175 	 * @global int             $page
  4253 	 * @global int     $page
  4176 	 * @global array           $pages
  4254 	 * @global array   $pages
  4177 	 * @global int             $multipage
  4255 	 * @global int     $multipage
  4178 	 * @global int             $more
  4256 	 * @global int     $more
  4179 	 * @global int             $numpages
  4257 	 * @global int     $numpages
  4180 	 *
  4258 	 *
  4181 	 * @param WP_Post|object|int $post WP_Post instance or Post ID/object.
  4259 	 * @param WP_Post|object|int $post WP_Post instance or Post ID/object.
  4182 	 * @return true True when finished.
  4260 	 * @return true True when finished.
  4183 	 */
  4261 	 */
  4184 	public function setup_postdata( $post ) {
  4262 	public function setup_postdata( $post ) {
  4206 		$multipage    = $elements['multipage'];
  4284 		$multipage    = $elements['multipage'];
  4207 		$more         = $elements['more'];
  4285 		$more         = $elements['more'];
  4208 		$numpages     = $elements['numpages'];
  4286 		$numpages     = $elements['numpages'];
  4209 
  4287 
  4210 		/**
  4288 		/**
  4211 		 * Fires once the post data has been setup.
  4289 		 * Fires once the post data has been set up.
  4212 		 *
  4290 		 *
  4213 		 * @since 2.8.0
  4291 		 * @since 2.8.0
  4214 		 * @since 4.1.0 Introduced `$this` parameter.
  4292 		 * @since 4.1.0 Introduced `$this` parameter.
  4215 		 *
  4293 		 *
  4216 		 * @param WP_Post  $post The Post object (passed by reference).
  4294 		 * @param WP_Post  $post The Post object (passed by reference).
  4225 	 * Generate post data.
  4303 	 * Generate post data.
  4226 	 *
  4304 	 *
  4227 	 * @since 5.2.0
  4305 	 * @since 5.2.0
  4228 	 *
  4306 	 *
  4229 	 * @param WP_Post|object|int $post WP_Post instance or Post ID/object.
  4307 	 * @param WP_Post|object|int $post WP_Post instance or Post ID/object.
  4230 	 * @return array|bool $elements Elements of post or false on failure.
  4308 	 * @return array|bool Elements of post or false on failure.
  4231 	 */
  4309 	 */
  4232 	public function generate_postdata( $post ) {
  4310 	public function generate_postdata( $post ) {
  4233 
  4311 
  4234 		if ( ! ( $post instanceof WP_Post ) ) {
  4312 		if ( ! ( $post instanceof WP_Post ) ) {
  4235 			$post = get_post( $post );
  4313 			$post = get_post( $post );
  4254 
  4332 
  4255 		/*
  4333 		/*
  4256 		 * Force full post content when viewing the permalink for the $post,
  4334 		 * Force full post content when viewing the permalink for the $post,
  4257 		 * or when on an RSS feed. Otherwise respect the 'more' tag.
  4335 		 * or when on an RSS feed. Otherwise respect the 'more' tag.
  4258 		 */
  4336 		 */
  4259 		if ( $post->ID === get_queried_object_id() && ( $this->is_page() || $this->is_single() ) ) {
  4337 		if ( get_queried_object_id() === $post->ID && ( $this->is_page() || $this->is_single() ) ) {
  4260 			$more = 1;
  4338 			$more = 1;
  4261 		} elseif ( $this->is_feed() ) {
  4339 		} elseif ( $this->is_feed() ) {
  4262 			$more = 1;
  4340 			$more = 1;
  4263 		} else {
  4341 		} else {
  4264 			$more = 0;
  4342 			$more = 0;
  4316 	 * After looping through a nested query, this function
  4394 	 * After looping through a nested query, this function
  4317 	 * restores the $post global to the current post in this query.
  4395 	 * restores the $post global to the current post in this query.
  4318 	 *
  4396 	 *
  4319 	 * @since 3.7.0
  4397 	 * @since 3.7.0
  4320 	 *
  4398 	 *
  4321 	 * @global WP_Post $post
  4399 	 * @global WP_Post $post Global post object.
  4322 	 */
  4400 	 */
  4323 	public function reset_postdata() {
  4401 	public function reset_postdata() {
  4324 		if ( ! empty( $this->post ) ) {
  4402 		if ( ! empty( $this->post ) ) {
  4325 			$GLOBALS['post'] = $this->post;
  4403 			$GLOBALS['post'] = $this->post;
  4326 			$this->setup_postdata( $this->post );
  4404 			$this->setup_postdata( $this->post );