wp/wp-includes/class-wp-query.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
    13  * @link https://developer.wordpress.org/reference/classes/wp_query/
    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 #[AllowDynamicProperties]
    18 class WP_Query {
    19 class WP_Query {
    19 
    20 
    20 	/**
    21 	/**
    21 	 * Query vars set by the user.
    22 	 * Query vars set by the user.
    22 	 *
    23 	 *
    35 
    36 
    36 	/**
    37 	/**
    37 	 * Taxonomy query, as passed to get_tax_sql().
    38 	 * Taxonomy query, as passed to get_tax_sql().
    38 	 *
    39 	 *
    39 	 * @since 3.1.0
    40 	 * @since 3.1.0
    40 	 * @var WP_Tax_Query A taxonomy query instance.
    41 	 * @var WP_Tax_Query|null A taxonomy query instance.
    41 	 */
    42 	 */
    42 	public $tax_query;
    43 	public $tax_query;
    43 
    44 
    44 	/**
    45 	/**
    45 	 * Metadata query container.
    46 	 * Metadata query container.
   106 	 * @var int
   107 	 * @var int
   107 	 */
   108 	 */
   108 	public $current_post = -1;
   109 	public $current_post = -1;
   109 
   110 
   110 	/**
   111 	/**
       
   112 	 * Whether the caller is before the loop.
       
   113 	 *
       
   114 	 * @since 6.3.0
       
   115 	 * @var bool
       
   116 	 */
       
   117 	public $before_loop = true;
       
   118 
       
   119 	/**
   111 	 * Whether the loop has started and the caller is in the loop.
   120 	 * Whether the loop has started and the caller is in the loop.
   112 	 *
   121 	 *
   113 	 * @since 2.0.0
   122 	 * @since 2.0.0
   114 	 * @var bool
   123 	 * @var bool
   115 	 */
   124 	 */
   441 	 *
   450 	 *
   442 	 * @since 3.2.0
   451 	 * @since 3.2.0
   443 	 * @var bool
   452 	 * @var bool
   444 	 */
   453 	 */
   445 	public $thumbnails_cached = false;
   454 	public $thumbnails_cached = false;
       
   455 
       
   456 	/**
       
   457 	 * Controls whether an attachment query should include filenames or not.
       
   458 	 *
       
   459 	 * @since 6.0.3
       
   460 	 * @var bool
       
   461 	 */
       
   462 	protected $allow_query_attachment_by_filename = false;
   446 
   463 
   447 	/**
   464 	/**
   448 	 * Cached list of search stopwords.
   465 	 * Cached list of search stopwords.
   449 	 *
   466 	 *
   450 	 * @since 3.7.0
   467 	 * @since 3.7.0
   506 		unset( $this->queried_object );
   523 		unset( $this->queried_object );
   507 		unset( $this->queried_object_id );
   524 		unset( $this->queried_object_id );
   508 		$this->post_count   = 0;
   525 		$this->post_count   = 0;
   509 		$this->current_post = -1;
   526 		$this->current_post = -1;
   510 		$this->in_the_loop  = false;
   527 		$this->in_the_loop  = false;
       
   528 		$this->before_loop  = true;
   511 		unset( $this->request );
   529 		unset( $this->request );
   512 		unset( $this->post );
   530 		unset( $this->post );
   513 		unset( $this->comments );
   531 		unset( $this->comments );
   514 		unset( $this->comment );
   532 		unset( $this->comment );
   515 		$this->comment_count         = 0;
   533 		$this->comment_count         = 0;
   520 
   538 
   521 		$this->init_query_flags();
   539 		$this->init_query_flags();
   522 	}
   540 	}
   523 
   541 
   524 	/**
   542 	/**
   525 	 * Reparse the query vars.
   543 	 * Reparses the query vars.
   526 	 *
   544 	 *
   527 	 * @since 1.5.0
   545 	 * @since 1.5.0
   528 	 */
   546 	 */
   529 	public function parse_query_vars() {
   547 	public function parse_query_vars() {
   530 		$this->parse_query();
   548 		$this->parse_query();
   599 			'tag_slug__and',
   617 			'tag_slug__and',
   600 			'post_parent__in',
   618 			'post_parent__in',
   601 			'post_parent__not_in',
   619 			'post_parent__not_in',
   602 			'author__in',
   620 			'author__in',
   603 			'author__not_in',
   621 			'author__not_in',
       
   622 			'search_columns',
   604 		);
   623 		);
   605 
   624 
   606 		foreach ( $array_keys as $key ) {
   625 		foreach ( $array_keys as $key ) {
   607 			if ( ! isset( $query_vars[ $key ] ) ) {
   626 			if ( ! isset( $query_vars[ $key ] ) ) {
   608 				$query_vars[ $key ] = array();
   627 				$query_vars[ $key ] = array();
   611 
   630 
   612 		return $query_vars;
   631 		return $query_vars;
   613 	}
   632 	}
   614 
   633 
   615 	/**
   634 	/**
   616 	 * Parse a query string and set query type booleans.
   635 	 * Parses a query string and sets query type booleans.
   617 	 *
   636 	 *
   618 	 * @since 1.5.0
   637 	 * @since 1.5.0
   619 	 * @since 4.2.0 Introduced the ability to order by specific clauses of a `$meta_query`, by passing the clause's
   638 	 * @since 4.2.0 Introduced the ability to order by specific clauses of a `$meta_query`, by passing the clause's
   620 	 *              array key to `$orderby`.
   639 	 *              array key to `$orderby`.
   621 	 * @since 4.4.0 Introduced `$post_name__in` and `$title` parameters. `$s` was updated to support excluded
   640 	 * @since 4.4.0 Introduced `$post_name__in` and `$title` parameters. `$s` was updated to support excluded
   625 	 *              Introduced `RAND(x)` syntax for `$orderby`, which allows an integer seed value to random sorts.
   644 	 *              Introduced `RAND(x)` syntax for `$orderby`, which allows an integer seed value to random sorts.
   626 	 * @since 4.6.0 Added 'post_name__in' support for `$orderby`. Introduced the `$lazy_load_term_meta` argument.
   645 	 * @since 4.6.0 Added 'post_name__in' support for `$orderby`. Introduced the `$lazy_load_term_meta` argument.
   627 	 * @since 4.9.0 Introduced the `$comment_count` parameter.
   646 	 * @since 4.9.0 Introduced the `$comment_count` parameter.
   628 	 * @since 5.1.0 Introduced the `$meta_compare_key` parameter.
   647 	 * @since 5.1.0 Introduced the `$meta_compare_key` parameter.
   629 	 * @since 5.3.0 Introduced the `$meta_type_key` parameter.
   648 	 * @since 5.3.0 Introduced the `$meta_type_key` parameter.
       
   649 	 * @since 6.1.0 Introduced the `$update_menu_item_cache` parameter.
       
   650 	 * @since 6.2.0 Introduced the `$search_columns` parameter.
   630 	 *
   651 	 *
   631 	 * @param string|array $query {
   652 	 * @param string|array $query {
   632 	 *     Optional. Array or string of Query parameters.
   653 	 *     Optional. Array or string of Query parameters.
   633 	 *
   654 	 *
   634 	 *     @type int             $attachment_id           Attachment post ID. Used for 'attachment' post_type.
   655 	 *     @type int             $attachment_id          Attachment post ID. Used for 'attachment' post_type.
   635 	 *     @type int|string      $author                  Author ID, or comma-separated list of IDs.
   656 	 *     @type int|string      $author                 Author ID, or comma-separated list of IDs.
   636 	 *     @type string          $author_name             User 'user_nicename'.
   657 	 *     @type string          $author_name            User 'user_nicename'.
   637 	 *     @type int[]           $author__in              An array of author IDs to query from.
   658 	 *     @type int[]           $author__in             An array of author IDs to query from.
   638 	 *     @type int[]           $author__not_in          An array of author IDs not to query from.
   659 	 *     @type int[]           $author__not_in         An array of author IDs not to query from.
   639 	 *     @type bool            $cache_results           Whether to cache post information. Default true.
   660 	 *     @type bool            $cache_results          Whether to cache post information. Default true.
   640 	 *     @type int|string      $cat                     Category ID or comma-separated list of IDs (this or any children).
   661 	 *     @type int|string      $cat                    Category ID or comma-separated list of IDs (this or any children).
   641 	 *     @type int[]           $category__and           An array of category IDs (AND in).
   662 	 *     @type int[]           $category__and          An array of category IDs (AND in).
   642 	 *     @type int[]           $category__in            An array of category IDs (OR in, no children).
   663 	 *     @type int[]           $category__in           An array of category IDs (OR in, no children).
   643 	 *     @type int[]           $category__not_in        An array of category IDs (NOT in).
   664 	 *     @type int[]           $category__not_in       An array of category IDs (NOT in).
   644 	 *     @type string          $category_name           Use category slug (not name, this or any children).
   665 	 *     @type string          $category_name          Use category slug (not name, this or any children).
   645 	 *     @type array|int       $comment_count           Filter results by comment count. Provide an integer to match
   666 	 *     @type array|int       $comment_count          Filter results by comment count. Provide an integer to match
   646 	 *                                                    comment count exactly. Provide an array with integer 'value'
   667 	 *                                                   comment count exactly. Provide an array with integer 'value'
   647 	 *                                                    and 'compare' operator ('=', '!=', '>', '>=', '<', '<=' ) to
   668 	 *                                                   and 'compare' operator ('=', '!=', '>', '>=', '<', '<=' ) to
   648 	 *                                                    compare against comment_count in a specific way.
   669 	 *                                                   compare against comment_count in a specific way.
   649 	 *     @type string          $comment_status          Comment status.
   670 	 *     @type string          $comment_status         Comment status.
   650 	 *     @type int             $comments_per_page       The number of comments to return per page.
   671 	 *     @type int             $comments_per_page      The number of comments to return per page.
   651 	 *                                                    Default 'comments_per_page' option.
   672 	 *                                                   Default 'comments_per_page' option.
   652 	 *     @type array           $date_query              An associative array of WP_Date_Query arguments.
   673 	 *     @type array           $date_query             An associative array of WP_Date_Query arguments.
   653 	 *                                                    See WP_Date_Query::__construct().
   674 	 *                                                   See WP_Date_Query::__construct().
   654 	 *     @type int             $day                     Day of the month. Default empty. Accepts numbers 1-31.
   675 	 *     @type int             $day                    Day of the month. Default empty. Accepts numbers 1-31.
   655 	 *     @type bool            $exact                   Whether to search by exact keyword. Default false.
   676 	 *     @type bool            $exact                  Whether to search by exact keyword. Default false.
   656 	 *     @type string          $fields                  Post fields to query for. Accepts:
   677 	 *     @type string          $fields                 Post fields to query for. Accepts:
   657 	 *                                                    - '' Returns an array of complete post objects (`WP_Post[]`).
   678 	 *                                                   - '' Returns an array of complete post objects (`WP_Post[]`).
   658 	 *                                                    - 'ids' Returns an array of post IDs (`int[]`).
   679 	 *                                                   - 'ids' Returns an array of post IDs (`int[]`).
   659 	 *                                                    - 'id=>parent' Returns an associative array of parent post IDs,
   680 	 *                                                   - 'id=>parent' Returns an associative array of parent post IDs,
   660 	 *                                                      keyed by post ID (`int[]`).
   681 	 *                                                     keyed by post ID (`int[]`).
   661 	 *                                                    Default ''.
   682 	 *                                                   Default ''.
   662 	 *     @type int             $hour                    Hour of the day. Default empty. Accepts numbers 0-23.
   683 	 *     @type int             $hour                   Hour of the day. Default empty. Accepts numbers 0-23.
   663 	 *     @type int|bool        $ignore_sticky_posts     Whether to ignore sticky posts or not. Setting this to false
   684 	 *     @type int|bool        $ignore_sticky_posts    Whether to ignore sticky posts or not. Setting this to false
   664 	 *                                                    excludes stickies from 'post__in'. Accepts 1|true, 0|false.
   685 	 *                                                   excludes stickies from 'post__in'. Accepts 1|true, 0|false.
   665 	 *                                                    Default false.
   686 	 *                                                   Default false.
   666 	 *     @type int             $m                       Combination YearMonth. Accepts any four-digit year and month
   687 	 *     @type int             $m                      Combination YearMonth. Accepts any four-digit year and month
   667 	 *                                                    numbers 1-12. Default empty.
   688 	 *                                                   numbers 01-12. Default empty.
   668 	 *     @type string|string[] $meta_key                Meta key or keys to filter by.
   689 	 *     @type string|string[] $meta_key               Meta key or keys to filter by.
   669 	 *     @type string|string[] $meta_value              Meta value or values to filter by.
   690 	 *     @type string|string[] $meta_value             Meta value or values to filter by.
   670 	 *     @type string          $meta_compare            MySQL operator used for comparing the meta value.
   691 	 *     @type string          $meta_compare           MySQL operator used for comparing the meta value.
   671 	 *                                                    See WP_Meta_Query::__construct for accepted values and default value.
   692 	 *                                                   See WP_Meta_Query::__construct() for accepted values and default value.
   672 	 *     @type string          $meta_compare_key        MySQL operator used for comparing the meta key.
   693 	 *     @type string          $meta_compare_key       MySQL operator used for comparing the meta key.
   673 	 *                                                    See WP_Meta_Query::__construct for accepted values and default value.
   694 	 *                                                   See WP_Meta_Query::__construct() for accepted values and default value.
   674 	 *     @type string          $meta_type               MySQL data type that the meta_value column will be CAST to for comparisons.
   695 	 *     @type string          $meta_type              MySQL data type that the meta_value column will be CAST to for comparisons.
   675 	 *                                                    See WP_Meta_Query::__construct for accepted values and default value.
   696 	 *                                                   See WP_Meta_Query::__construct() for accepted values and default value.
   676 	 *     @type string          $meta_type_key           MySQL data type that the meta_key column will be CAST to for comparisons.
   697 	 *     @type string          $meta_type_key          MySQL data type that the meta_key column will be CAST to for comparisons.
   677 	 *                                                    See WP_Meta_Query::__construct for accepted values and default value.
   698 	 *                                                   See WP_Meta_Query::__construct() for accepted values and default value.
   678 	 *     @type array           $meta_query              An associative array of WP_Meta_Query arguments.
   699 	 *     @type array           $meta_query             An associative array of WP_Meta_Query arguments.
   679 	 *                                                    See WP_Meta_Query::__construct for accepted values.
   700 	 *                                                   See WP_Meta_Query::__construct() for accepted values.
   680 	 *     @type int             $menu_order              The menu order of the posts.
   701 	 *     @type int             $menu_order             The menu order of the posts.
   681 	 *     @type int             $minute                  Minute of the hour. Default empty. Accepts numbers 0-59.
   702 	 *     @type int             $minute                 Minute of the hour. Default empty. Accepts numbers 0-59.
   682 	 *     @type int             $monthnum                The two-digit month. Default empty. Accepts numbers 1-12.
   703 	 *     @type int             $monthnum               The two-digit month. Default empty. Accepts numbers 1-12.
   683 	 *     @type string          $name                    Post slug.
   704 	 *     @type string          $name                   Post slug.
   684 	 *     @type bool            $nopaging                Show all posts (true) or paginate (false). Default false.
   705 	 *     @type bool            $nopaging               Show all posts (true) or paginate (false). Default false.
   685 	 *     @type bool            $no_found_rows           Whether to skip counting the total rows found. Enabling can improve
   706 	 *     @type bool            $no_found_rows          Whether to skip counting the total rows found. Enabling can improve
   686 	 *                                                    performance. Default false.
   707 	 *                                                   performance. Default false.
   687 	 *     @type int             $offset                  The number of posts to offset before retrieval.
   708 	 *     @type int             $offset                 The number of posts to offset before retrieval.
   688 	 *     @type string          $order                   Designates ascending or descending order of posts. Default 'DESC'.
   709 	 *     @type string          $order                  Designates ascending or descending order of posts. Default 'DESC'.
   689 	 *                                                    Accepts 'ASC', 'DESC'.
   710 	 *                                                   Accepts 'ASC', 'DESC'.
   690 	 *     @type string|array    $orderby                 Sort retrieved posts by parameter. One or more options may be passed.
   711 	 *     @type string|array    $orderby                Sort retrieved posts by parameter. One or more options may be passed.
   691 	 *                                                    To use 'meta_value', or 'meta_value_num', 'meta_key=keyname' must be
   712 	 *                                                   To use 'meta_value', or 'meta_value_num', 'meta_key=keyname' must be
   692 	 *                                                    also be defined. To sort by a specific `$meta_query` clause, use that
   713 	 *                                                   also be defined. To sort by a specific `$meta_query` clause, use that
   693 	 *                                                    clause's array key. Accepts:
   714 	 *                                                   clause's array key. Accepts:
   694 	 *                                                    - 'none'
   715 	 *                                                   - 'none'
   695 	 *                                                    - 'name'
   716 	 *                                                   - 'name'
   696 	 *                                                    - 'author'
   717 	 *                                                   - 'author'
   697 	 *                                                    - 'date'
   718 	 *                                                   - 'date'
   698 	 *                                                    - 'title'
   719 	 *                                                   - 'title'
   699 	 *                                                    - 'modified'
   720 	 *                                                   - 'modified'
   700 	 *                                                    - 'menu_order'
   721 	 *                                                   - 'menu_order'
   701 	 *                                                    - 'parent'
   722 	 *                                                   - 'parent'
   702 	 *                                                    - 'ID'
   723 	 *                                                   - 'ID'
   703 	 *                                                    - 'rand'
   724 	 *                                                   - 'rand'
   704 	 *                                                    - 'relevance'
   725 	 *                                                   - 'relevance'
   705 	 *                                                    - 'RAND(x)' (where 'x' is an integer seed value)
   726 	 *                                                   - 'RAND(x)' (where 'x' is an integer seed value)
   706 	 *                                                    - 'comment_count'
   727 	 *                                                   - 'comment_count'
   707 	 *                                                    - 'meta_value'
   728 	 *                                                   - 'meta_value'
   708 	 *                                                    - 'meta_value_num'
   729 	 *                                                   - 'meta_value_num'
   709 	 *                                                    - 'post__in'
   730 	 *                                                   - 'post__in'
   710 	 *                                                    - 'post_name__in'
   731 	 *                                                   - 'post_name__in'
   711 	 *                                                    - 'post_parent__in'
   732 	 *                                                   - 'post_parent__in'
   712 	 *                                                    - The array keys of `$meta_query`.
   733 	 *                                                   - The array keys of `$meta_query`.
   713 	 *                                                    Default is 'date', except when a search is being performed, when
   734 	 *                                                   Default is 'date', except when a search is being performed, when
   714 	 *                                                    the default is 'relevance'.
   735 	 *                                                   the default is 'relevance'.
   715 	 *     @type int             $p                       Post ID.
   736 	 *     @type int             $p                      Post ID.
   716 	 *     @type int             $page                    Show the number of posts that would show up on page X of a
   737 	 *     @type int             $page                   Show the number of posts that would show up on page X of a
   717 	 *                                                    static front page.
   738 	 *                                                   static front page.
   718 	 *     @type int             $paged                   The number of the current page.
   739 	 *     @type int             $paged                  The number of the current page.
   719 	 *     @type int             $page_id                 Page ID.
   740 	 *     @type int             $page_id                Page ID.
   720 	 *     @type string          $pagename                Page slug.
   741 	 *     @type string          $pagename               Page slug.
   721 	 *     @type string          $perm                    Show posts if user has the appropriate capability.
   742 	 *     @type string          $perm                   Show posts if user has the appropriate capability.
   722 	 *     @type string          $ping_status             Ping status.
   743 	 *     @type string          $ping_status            Ping status.
   723 	 *     @type int[]           $post__in                An array of post IDs to retrieve, sticky posts will be included.
   744 	 *     @type int[]           $post__in               An array of post IDs to retrieve, sticky posts will be included.
   724 	 *     @type int[]           $post__not_in            An array of post IDs not to retrieve. Note: a string of comma-
   745 	 *     @type int[]           $post__not_in           An array of post IDs not to retrieve. Note: a string of comma-
   725 	 *                                                    separated IDs will NOT work.
   746 	 *                                                   separated IDs will NOT work.
   726 	 *     @type string          $post_mime_type          The mime type of the post. Used for 'attachment' post_type.
   747 	 *     @type string          $post_mime_type         The mime type of the post. Used for 'attachment' post_type.
   727 	 *     @type string[]        $post_name__in           An array of post slugs that results must match.
   748 	 *     @type string[]        $post_name__in          An array of post slugs that results must match.
   728 	 *     @type int             $post_parent             Page ID to retrieve child pages for. Use 0 to only retrieve
   749 	 *     @type int             $post_parent            Page ID to retrieve child pages for. Use 0 to only retrieve
   729 	 *                                                    top-level pages.
   750 	 *                                                   top-level pages.
   730 	 *     @type int[]           $post_parent__in         An array containing parent page IDs to query child pages from.
   751 	 *     @type int[]           $post_parent__in        An array containing parent page IDs to query child pages from.
   731 	 *     @type int[]           $post_parent__not_in     An array containing parent page IDs not to query child pages from.
   752 	 *     @type int[]           $post_parent__not_in    An array containing parent page IDs not to query child pages from.
   732 	 *     @type string|string[] $post_type               A post type slug (string) or array of post type slugs.
   753 	 *     @type string|string[] $post_type              A post type slug (string) or array of post type slugs.
   733 	 *                                                    Default 'any' if using 'tax_query'.
   754 	 *                                                   Default 'any' if using 'tax_query'.
   734 	 *     @type string|string[] $post_status             A post status (string) or array of post statuses.
   755 	 *     @type string|string[] $post_status            A post status (string) or array of post statuses.
   735 	 *     @type int             $posts_per_page          The number of posts to query for. Use -1 to request all posts.
   756 	 *     @type int             $posts_per_page         The number of posts to query for. Use -1 to request all posts.
   736 	 *     @type int             $posts_per_archive_page  The number of posts to query for by archive page. Overrides
   757 	 *     @type int             $posts_per_archive_page The number of posts to query for by archive page. Overrides
   737 	 *                                                    'posts_per_page' when is_archive(), or is_search() are true.
   758 	 *                                                   'posts_per_page' when is_archive(), or is_search() are true.
   738 	 *     @type string          $s                       Search keyword(s). Prepending a term with a hyphen will
   759 	 *     @type string          $s                      Search keyword(s). Prepending a term with a hyphen will
   739 	 *                                                    exclude posts matching that term. Eg, 'pillow -sofa' will
   760 	 *                                                   exclude posts matching that term. Eg, 'pillow -sofa' will
   740 	 *                                                    return posts containing 'pillow' but not 'sofa'. The
   761 	 *                                                   return posts containing 'pillow' but not 'sofa'. The
   741 	 *                                                    character used for exclusion can be modified using the
   762 	 *                                                   character used for exclusion can be modified using the
   742 	 *                                                    the 'wp_query_search_exclusion_prefix' filter.
   763 	 *                                                   the 'wp_query_search_exclusion_prefix' filter.
   743 	 *     @type int             $second                  Second of the minute. Default empty. Accepts numbers 0-59.
   764 	 *     @type string[]        $search_columns         Array of column names to be searched. Accepts 'post_title',
   744 	 *     @type bool            $sentence                Whether to search by phrase. Default false.
   765 	 *                                                   'post_excerpt' and 'post_content'. Default empty array.
   745 	 *     @type bool            $suppress_filters        Whether to suppress filters. Default false.
   766 	 *     @type int             $second                 Second of the minute. Default empty. Accepts numbers 0-59.
   746 	 *     @type string          $tag                     Tag slug. Comma-separated (either), Plus-separated (all).
   767 	 *     @type bool            $sentence               Whether to search by phrase. Default false.
   747 	 *     @type int[]           $tag__and                An array of tag IDs (AND in).
   768 	 *     @type bool            $suppress_filters       Whether to suppress filters. Default false.
   748 	 *     @type int[]           $tag__in                 An array of tag IDs (OR in).
   769 	 *     @type string          $tag                    Tag slug. Comma-separated (either), Plus-separated (all).
   749 	 *     @type int[]           $tag__not_in             An array of tag IDs (NOT in).
   770 	 *     @type int[]           $tag__and               An array of tag IDs (AND in).
   750 	 *     @type int             $tag_id                  Tag id or comma-separated list of IDs.
   771 	 *     @type int[]           $tag__in                An array of tag IDs (OR in).
   751 	 *     @type string[]        $tag_slug__and           An array of tag slugs (AND in).
   772 	 *     @type int[]           $tag__not_in            An array of tag IDs (NOT in).
   752 	 *     @type string[]        $tag_slug__in            An array of tag slugs (OR in). unless 'ignore_sticky_posts' is
   773 	 *     @type int             $tag_id                 Tag id or comma-separated list of IDs.
   753 	 *                                                    true. Note: a string of comma-separated IDs will NOT work.
   774 	 *     @type string[]        $tag_slug__and          An array of tag slugs (AND in).
   754 	 *     @type array           $tax_query               An associative array of WP_Tax_Query arguments.
   775 	 *     @type string[]        $tag_slug__in           An array of tag slugs (OR in). unless 'ignore_sticky_posts' is
   755 	 *                                                    See WP_Tax_Query->__construct().
   776 	 *                                                   true. Note: a string of comma-separated IDs will NOT work.
   756 	 *     @type string          $title                   Post title.
   777 	 *     @type array           $tax_query              An associative array of WP_Tax_Query arguments.
   757 	 *     @type bool            $update_post_meta_cache  Whether to update the post meta cache. Default true.
   778 	 *                                                   See WP_Tax_Query::__construct().
   758 	 *     @type bool            $update_post_term_cache  Whether to update the post term cache. Default true.
   779 	 *     @type string          $title                  Post title.
   759 	 *     @type bool            $lazy_load_term_meta     Whether to lazy-load term meta. Setting to false will
   780 	 *     @type bool            $update_post_meta_cache Whether to update the post meta cache. Default true.
   760 	 *                                                    disable cache priming for term meta, so that each
   781 	 *     @type bool            $update_post_term_cache Whether to update the post term cache. Default true.
   761 	 *                                                    get_term_meta() call will hit the database.
   782 	 *     @type bool            $update_menu_item_cache Whether to update the menu item cache. Default false.
   762 	 *                                                    Defaults to the value of `$update_post_term_cache`.
   783 	 *     @type bool            $lazy_load_term_meta    Whether to lazy-load term meta. Setting to false will
   763 	 *     @type int             $w                       The week number of the year. Default empty. Accepts numbers 0-53.
   784 	 *                                                   disable cache priming for term meta, so that each
   764 	 *     @type int             $year                    The four-digit year. Default empty. Accepts any four-digit year.
   785 	 *                                                   get_term_meta() call will hit the database.
       
   786 	 *                                                   Defaults to the value of `$update_post_term_cache`.
       
   787 	 *     @type int             $w                      The week number of the year. Default empty. Accepts numbers 0-53.
       
   788 	 *     @type int             $year                   The four-digit year. Default empty. Accepts any four-digit year.
   765 	 * }
   789 	 * }
   766 	 */
   790 	 */
   767 	public function parse_query( $query = '' ) {
   791 	public function parse_query( $query = '' ) {
   768 		if ( ! empty( $query ) ) {
   792 		if ( ! empty( $query ) ) {
   769 			$this->init();
   793 			$this->init();
   788 			$qv['error'] = '404';
   812 			$qv['error'] = '404';
   789 		} else {
   813 		} else {
   790 			$qv['p'] = (int) $qv['p'];
   814 			$qv['p'] = (int) $qv['p'];
   791 		}
   815 		}
   792 
   816 
   793 		$qv['page_id']  = absint( $qv['page_id'] );
   817 		$qv['page_id']  = is_scalar( $qv['page_id'] ) ? absint( $qv['page_id'] ) : 0;
   794 		$qv['year']     = absint( $qv['year'] );
   818 		$qv['year']     = is_scalar( $qv['year'] ) ? absint( $qv['year'] ) : 0;
   795 		$qv['monthnum'] = absint( $qv['monthnum'] );
   819 		$qv['monthnum'] = is_scalar( $qv['monthnum'] ) ? absint( $qv['monthnum'] ) : 0;
   796 		$qv['day']      = absint( $qv['day'] );
   820 		$qv['day']      = is_scalar( $qv['day'] ) ? absint( $qv['day'] ) : 0;
   797 		$qv['w']        = absint( $qv['w'] );
   821 		$qv['w']        = is_scalar( $qv['w'] ) ? absint( $qv['w'] ) : 0;
   798 		$qv['m']        = is_scalar( $qv['m'] ) ? preg_replace( '|[^0-9]|', '', $qv['m'] ) : '';
   822 		$qv['m']        = is_scalar( $qv['m'] ) ? preg_replace( '|[^0-9]|', '', $qv['m'] ) : '';
   799 		$qv['paged']    = absint( $qv['paged'] );
   823 		$qv['paged']    = is_scalar( $qv['paged'] ) ? absint( $qv['paged'] ) : 0;
   800 		$qv['cat']      = preg_replace( '|[^0-9,-]|', '', $qv['cat'] );    // Comma-separated list of positive or negative integers.
   824 		$qv['cat']      = preg_replace( '|[^0-9,-]|', '', $qv['cat'] ); // Array or comma-separated list of positive or negative integers.
   801 		$qv['author']   = preg_replace( '|[^0-9,-]|', '', $qv['author'] ); // Comma-separated list of positive or negative integers.
   825 		$qv['author']   = is_scalar( $qv['author'] ) ? preg_replace( '|[^0-9,-]|', '', $qv['author'] ) : ''; // Comma-separated list of positive or negative integers.
   802 		$qv['pagename'] = trim( $qv['pagename'] );
   826 		$qv['pagename'] = is_scalar( $qv['pagename'] ) ? trim( $qv['pagename'] ) : '';
   803 		$qv['name']     = trim( $qv['name'] );
   827 		$qv['name']     = is_scalar( $qv['name'] ) ? trim( $qv['name'] ) : '';
   804 		$qv['title']    = trim( $qv['title'] );
   828 		$qv['title']    = is_scalar( $qv['title'] ) ? trim( $qv['title'] ) : '';
   805 		if ( '' !== $qv['hour'] ) {
   829 
       
   830 		if ( is_scalar( $qv['hour'] ) && '' !== $qv['hour'] ) {
   806 			$qv['hour'] = absint( $qv['hour'] );
   831 			$qv['hour'] = absint( $qv['hour'] );
   807 		}
   832 		} else {
   808 		if ( '' !== $qv['minute'] ) {
   833 			$qv['hour'] = '';
       
   834 		}
       
   835 
       
   836 		if ( is_scalar( $qv['minute'] ) && '' !== $qv['minute'] ) {
   809 			$qv['minute'] = absint( $qv['minute'] );
   837 			$qv['minute'] = absint( $qv['minute'] );
   810 		}
   838 		} else {
   811 		if ( '' !== $qv['second'] ) {
   839 			$qv['minute'] = '';
       
   840 		}
       
   841 
       
   842 		if ( is_scalar( $qv['second'] ) && '' !== $qv['second'] ) {
   812 			$qv['second'] = absint( $qv['second'] );
   843 			$qv['second'] = absint( $qv['second'] );
   813 		}
   844 		} else {
   814 		if ( '' !== $qv['menu_order'] ) {
   845 			$qv['second'] = '';
       
   846 		}
       
   847 
       
   848 		if ( is_scalar( $qv['menu_order'] ) && '' !== $qv['menu_order'] ) {
   815 			$qv['menu_order'] = absint( $qv['menu_order'] );
   849 			$qv['menu_order'] = absint( $qv['menu_order'] );
       
   850 		} else {
       
   851 			$qv['menu_order'] = '';
   816 		}
   852 		}
   817 
   853 
   818 		// Fairly large, potentially too large, upper bound for search string lengths.
   854 		// Fairly large, potentially too large, upper bound for search string lengths.
   819 		if ( ! is_scalar( $qv['s'] ) || ( ! empty( $qv['s'] ) && strlen( $qv['s'] ) > 1600 ) ) {
   855 		if ( ! is_scalar( $qv['s'] ) || ( ! empty( $qv['s'] ) && strlen( $qv['s'] ) > 1600 ) ) {
   820 			$qv['s'] = '';
   856 			$qv['s'] = '';
   821 		}
   857 		}
   822 
   858 
   823 		// Compat. Map subpost to attachment.
   859 		// Compat. Map subpost to attachment.
   824 		if ( '' != $qv['subpost'] ) {
   860 		if ( is_scalar( $qv['subpost'] ) && '' != $qv['subpost'] ) {
   825 			$qv['attachment'] = $qv['subpost'];
   861 			$qv['attachment'] = $qv['subpost'];
   826 		}
   862 		}
   827 		if ( '' != $qv['subpost_id'] ) {
   863 		if ( is_scalar( $qv['subpost_id'] ) && '' != $qv['subpost_id'] ) {
   828 			$qv['attachment_id'] = $qv['subpost_id'];
   864 			$qv['attachment_id'] = $qv['subpost_id'];
   829 		}
   865 		}
   830 
   866 
   831 		$qv['attachment_id'] = absint( $qv['attachment_id'] );
   867 		$qv['attachment_id'] = is_scalar( $qv['attachment_id'] ) ? absint( $qv['attachment_id'] ) : 0;
   832 
   868 
   833 		if ( ( '' !== $qv['attachment'] ) || ! empty( $qv['attachment_id'] ) ) {
   869 		if ( ( '' !== $qv['attachment'] ) || ! empty( $qv['attachment_id'] ) ) {
   834 			$this->is_single     = true;
   870 			$this->is_single     = true;
   835 			$this->is_attachment = true;
   871 			$this->is_attachment = true;
   836 		} elseif ( '' !== $qv['name'] ) {
   872 		} elseif ( '' !== $qv['name'] ) {
   977 
  1013 
   978 		if ( is_admin() ) {
  1014 		if ( is_admin() ) {
   979 			$this->is_admin = true;
  1015 			$this->is_admin = true;
   980 		}
  1016 		}
   981 
  1017 
   982 		if ( false !== strpos( $qv['feed'], 'comments-' ) ) {
  1018 		if ( str_contains( $qv['feed'], 'comments-' ) ) {
   983 			$qv['feed']         = str_replace( 'comments-', '', $qv['feed'] );
  1019 			$qv['feed']         = str_replace( 'comments-', '', $qv['feed'] );
   984 			$qv['withcomments'] = 1;
  1020 			$qv['withcomments'] = 1;
   985 		}
  1021 		}
   986 
  1022 
   987 		$this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
  1023 		$this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
   989 		if ( $this->is_feed && ( ! empty( $qv['withcomments'] ) || ( empty( $qv['withoutcomments'] ) && $this->is_singular ) ) ) {
  1025 		if ( $this->is_feed && ( ! empty( $qv['withcomments'] ) || ( empty( $qv['withoutcomments'] ) && $this->is_singular ) ) ) {
   990 			$this->is_comment_feed = true;
  1026 			$this->is_comment_feed = true;
   991 		}
  1027 		}
   992 
  1028 
   993 		if ( ! ( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed
  1029 		if ( ! ( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed
   994 				|| ( defined( 'REST_REQUEST' ) && REST_REQUEST && $this->is_main_query() )
  1030 				|| ( wp_is_serving_rest_request() && $this->is_main_query() )
   995 				|| $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_robots || $this->is_favicon ) ) {
  1031 				|| $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_robots || $this->is_favicon ) ) {
   996 			$this->is_home = true;
  1032 			$this->is_home = true;
   997 		}
  1033 		}
   998 
  1034 
   999 		// Correct `is_*` for 'page_on_front' and 'page_for_posts'.
  1035 		// Correct `is_*` for 'page_on_front' and 'page_for_posts'.
  1147 
  1183 
  1148 				if ( is_array( $term ) ) {
  1184 				if ( is_array( $term ) ) {
  1149 					$term = implode( ',', $term );
  1185 					$term = implode( ',', $term );
  1150 				}
  1186 				}
  1151 
  1187 
  1152 				if ( strpos( $term, '+' ) !== false ) {
  1188 				if ( str_contains( $term, '+' ) ) {
  1153 					$terms = preg_split( '/[+]+/', $term );
  1189 					$terms = preg_split( '/[+]+/', $term );
  1154 					foreach ( $terms as $term ) {
  1190 					foreach ( $terms as $term ) {
  1155 						$tax_query[] = array_merge(
  1191 						$tax_query[] = array_merge(
  1156 							$tax_query_defaults,
  1192 							$tax_query_defaults,
  1157 							array(
  1193 							array(
  1260 		}
  1296 		}
  1261 
  1297 
  1262 		// Tag stuff.
  1298 		// Tag stuff.
  1263 
  1299 
  1264 		if ( '' !== $q['tag'] && ! $this->is_singular && $this->query_vars_changed ) {
  1300 		if ( '' !== $q['tag'] && ! $this->is_singular && $this->query_vars_changed ) {
  1265 			if ( strpos( $q['tag'], ',' ) !== false ) {
  1301 			if ( str_contains( $q['tag'], ',' ) ) {
  1266 				$tags = preg_split( '/[,\r\n\t ]+/', $q['tag'] );
  1302 				$tags = preg_split( '/[,\r\n\t ]+/', $q['tag'] );
  1267 				foreach ( (array) $tags as $tag ) {
  1303 				foreach ( (array) $tags as $tag ) {
  1268 					$tag                 = sanitize_term_field( 'slug', $tag, 0, 'post_tag', 'db' );
  1304 					$tag                 = sanitize_term_field( 'slug', $tag, 0, 'post_tag', 'db' );
  1269 					$q['tag_slug__in'][] = $tag;
  1305 					$q['tag_slug__in'][] = $tag;
  1270 				}
  1306 				}
  1385 
  1421 
  1386 		$n                         = ! empty( $q['exact'] ) ? '' : '%';
  1422 		$n                         = ! empty( $q['exact'] ) ? '' : '%';
  1387 		$searchand                 = '';
  1423 		$searchand                 = '';
  1388 		$q['search_orderby_title'] = array();
  1424 		$q['search_orderby_title'] = array();
  1389 
  1425 
       
  1426 		$default_search_columns = array( 'post_title', 'post_excerpt', 'post_content' );
       
  1427 		$search_columns         = ! empty( $q['search_columns'] ) ? $q['search_columns'] : $default_search_columns;
       
  1428 		if ( ! is_array( $search_columns ) ) {
       
  1429 			$search_columns = array( $search_columns );
       
  1430 		}
       
  1431 
       
  1432 		/**
       
  1433 		 * Filters the columns to search in a WP_Query search.
       
  1434 		 *
       
  1435 		 * The supported columns are `post_title`, `post_excerpt` and `post_content`.
       
  1436 		 * They are all included by default.
       
  1437 		 *
       
  1438 		 * @since 6.2.0
       
  1439 		 *
       
  1440 		 * @param string[] $search_columns Array of column names to be searched.
       
  1441 		 * @param string   $search         Text being searched.
       
  1442 		 * @param WP_Query $query          The current WP_Query instance.
       
  1443 		 */
       
  1444 		$search_columns = (array) apply_filters( 'post_search_columns', $search_columns, $q['s'], $this );
       
  1445 
       
  1446 		// Use only supported search columns.
       
  1447 		$search_columns = array_intersect( $search_columns, $default_search_columns );
       
  1448 		if ( empty( $search_columns ) ) {
       
  1449 			$search_columns = $default_search_columns;
       
  1450 		}
       
  1451 
  1390 		/**
  1452 		/**
  1391 		 * Filters the prefix that indicates that a search term should be excluded from results.
  1453 		 * Filters the prefix that indicates that a search term should be excluded from results.
  1392 		 *
  1454 		 *
  1393 		 * @since 4.7.0
  1455 		 * @since 4.7.0
  1394 		 *
  1456 		 *
  1397 		 */
  1459 		 */
  1398 		$exclusion_prefix = apply_filters( 'wp_query_search_exclusion_prefix', '-' );
  1460 		$exclusion_prefix = apply_filters( 'wp_query_search_exclusion_prefix', '-' );
  1399 
  1461 
  1400 		foreach ( $q['search_terms'] as $term ) {
  1462 		foreach ( $q['search_terms'] as $term ) {
  1401 			// If there is an $exclusion_prefix, terms prefixed with it should be excluded.
  1463 			// If there is an $exclusion_prefix, terms prefixed with it should be excluded.
  1402 			$exclude = $exclusion_prefix && ( substr( $term, 0, 1 ) === $exclusion_prefix );
  1464 			$exclude = $exclusion_prefix && str_starts_with( $term, $exclusion_prefix );
  1403 			if ( $exclude ) {
  1465 			if ( $exclude ) {
  1404 				$like_op  = 'NOT LIKE';
  1466 				$like_op  = 'NOT LIKE';
  1405 				$andor_op = 'AND';
  1467 				$andor_op = 'AND';
  1406 				$term     = substr( $term, 1 );
  1468 				$term     = substr( $term, 1 );
  1407 			} else {
  1469 			} else {
  1412 			if ( $n && ! $exclude ) {
  1474 			if ( $n && ! $exclude ) {
  1413 				$like                        = '%' . $wpdb->esc_like( $term ) . '%';
  1475 				$like                        = '%' . $wpdb->esc_like( $term ) . '%';
  1414 				$q['search_orderby_title'][] = $wpdb->prepare( "{$wpdb->posts}.post_title LIKE %s", $like );
  1476 				$q['search_orderby_title'][] = $wpdb->prepare( "{$wpdb->posts}.post_title LIKE %s", $like );
  1415 			}
  1477 			}
  1416 
  1478 
  1417 			$like      = $n . $wpdb->esc_like( $term ) . $n;
  1479 			$like = $n . $wpdb->esc_like( $term ) . $n;
  1418 			$search   .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s))", $like, $like, $like );
  1480 
       
  1481 			$search_columns_parts = array();
       
  1482 			foreach ( $search_columns as $search_column ) {
       
  1483 				$search_columns_parts[ $search_column ] = $wpdb->prepare( "({$wpdb->posts}.$search_column $like_op %s)", $like );
       
  1484 			}
       
  1485 
       
  1486 			if ( ! empty( $this->allow_query_attachment_by_filename ) ) {
       
  1487 				$search_columns_parts['attachment'] = $wpdb->prepare( "(sq1.meta_value $like_op %s)", $like );
       
  1488 			}
       
  1489 
       
  1490 			$search .= "$searchand(" . implode( " $andor_op ", $search_columns_parts ) . ')';
       
  1491 
  1419 			$searchand = ' AND ';
  1492 			$searchand = ' AND ';
  1420 		}
  1493 		}
  1421 
  1494 
  1422 		if ( ! empty( $search ) ) {
  1495 		if ( ! empty( $search ) ) {
  1423 			$search = " AND ({$search}) ";
  1496 			$search = " AND ({$search}) ";
  1428 
  1501 
  1429 		return $search;
  1502 		return $search;
  1430 	}
  1503 	}
  1431 
  1504 
  1432 	/**
  1505 	/**
  1433 	 * Check if the terms are suitable for searching.
  1506 	 * Checks if the terms are suitable for searching.
  1434 	 *
  1507 	 *
  1435 	 * Uses an array of stopwords (terms) that are excluded from the separate
  1508 	 * Uses an array of stopwords (terms) that are excluded from the separate
  1436 	 * term matching when searching for posts. The list of English stopwords is
  1509 	 * term matching when searching for posts. The list of English stopwords is
  1437 	 * the approximate search engines list, and is translatable.
  1510 	 * the approximate search engines list, and is translatable.
  1438 	 *
  1511 	 *
  1469 
  1542 
  1470 		return $checked;
  1543 		return $checked;
  1471 	}
  1544 	}
  1472 
  1545 
  1473 	/**
  1546 	/**
  1474 	 * Retrieve stopwords used when parsing search terms.
  1547 	 * Retrieves stopwords used when parsing search terms.
  1475 	 *
  1548 	 *
  1476 	 * @since 3.7.0
  1549 	 * @since 3.7.0
  1477 	 *
  1550 	 *
  1478 	 * @return string[] Stopwords.
  1551 	 * @return string[] Stopwords.
  1479 	 */
  1552 	 */
  1541 			// Sentence match in 'post_title'.
  1614 			// Sentence match in 'post_title'.
  1542 			if ( $like ) {
  1615 			if ( $like ) {
  1543 				$search_orderby .= $wpdb->prepare( "WHEN {$wpdb->posts}.post_title LIKE %s THEN 1 ", $like );
  1616 				$search_orderby .= $wpdb->prepare( "WHEN {$wpdb->posts}.post_title LIKE %s THEN 1 ", $like );
  1544 			}
  1617 			}
  1545 
  1618 
  1546 			// Sanity limit, sort as sentence when more than 6 terms
  1619 			/*
  1547 			// (few searches are longer than 6 terms and most titles are not).
  1620 			 * Sanity limit, sort as sentence when more than 6 terms
       
  1621 			 * (few searches are longer than 6 terms and most titles are not).
       
  1622 			 */
  1548 			if ( $num_terms < 7 ) {
  1623 			if ( $num_terms < 7 ) {
  1549 				// All words in title.
  1624 				// All words in title.
  1550 				$search_orderby .= 'WHEN ' . implode( ' AND ', $q['search_orderby_title'] ) . ' THEN 2 ';
  1625 				$search_orderby .= 'WHEN ' . implode( ' AND ', $q['search_orderby_title'] ) . ' THEN 2 ';
  1551 				// Any word in title, not needed when $num_terms == 1.
  1626 				// Any word in title, not needed when $num_terms == 1.
  1552 				if ( $num_terms > 1 ) {
  1627 				if ( $num_terms > 1 ) {
  1749 	 *
  1824 	 *
  1750 	 * @since 1.5.0
  1825 	 * @since 1.5.0
  1751 	 * @since 3.9.0 The `$default_value` argument was introduced.
  1826 	 * @since 3.9.0 The `$default_value` argument was introduced.
  1752 	 *
  1827 	 *
  1753 	 * @param string $query_var     Query variable key.
  1828 	 * @param string $query_var     Query variable key.
  1754 	 * @param mixed  $default_value Optional. Value to return if the query variable is not set. Default empty string.
  1829 	 * @param mixed  $default_value Optional. Value to return if the query variable is not set.
       
  1830 	 *                              Default empty string.
  1755 	 * @return mixed Contents of the query variable.
  1831 	 * @return mixed Contents of the query variable.
  1756 	 */
  1832 	 */
  1757 	public function get( $query_var, $default_value = '' ) {
  1833 	public function get( $query_var, $default_value = '' ) {
  1758 		if ( isset( $this->query_vars[ $query_var ] ) ) {
  1834 		if ( isset( $this->query_vars[ $query_var ] ) ) {
  1759 			return $this->query_vars[ $query_var ];
  1835 			return $this->query_vars[ $query_var ];
  1808 		$q = &$this->query_vars;
  1884 		$q = &$this->query_vars;
  1809 
  1885 
  1810 		// Fill again in case 'pre_get_posts' unset some vars.
  1886 		// Fill again in case 'pre_get_posts' unset some vars.
  1811 		$q = $this->fill_query_vars( $q );
  1887 		$q = $this->fill_query_vars( $q );
  1812 
  1888 
       
  1889 		/**
       
  1890 		 * Filters whether an attachment query should include filenames or not.
       
  1891 		 *
       
  1892 		 * @since 6.0.3
       
  1893 		 *
       
  1894 		 * @param bool $allow_query_attachment_by_filename Whether or not to include filenames.
       
  1895 		 */
       
  1896 		$this->allow_query_attachment_by_filename = apply_filters( 'wp_allow_query_attachment_by_filename', false );
       
  1897 		remove_all_filters( 'wp_allow_query_attachment_by_filename' );
       
  1898 
  1813 		// Parse meta query.
  1899 		// Parse meta query.
  1814 		$this->meta_query = new WP_Meta_Query();
  1900 		$this->meta_query = new WP_Meta_Query();
  1815 		$this->meta_query->parse_query_vars( $q );
  1901 		$this->meta_query->parse_query_vars( $q );
  1816 
  1902 
  1817 		// Set a flag if a 'pre_get_posts' hook changed the query vars.
  1903 		// Set a flag if a 'pre_get_posts' hook changed the query vars.
  1858 		if ( ! isset( $q['suppress_filters'] ) ) {
  1944 		if ( ! isset( $q['suppress_filters'] ) ) {
  1859 			$q['suppress_filters'] = false;
  1945 			$q['suppress_filters'] = false;
  1860 		}
  1946 		}
  1861 
  1947 
  1862 		if ( ! isset( $q['cache_results'] ) ) {
  1948 		if ( ! isset( $q['cache_results'] ) ) {
  1863 			if ( wp_using_ext_object_cache() ) {
  1949 			$q['cache_results'] = true;
  1864 				$q['cache_results'] = false;
       
  1865 			} else {
       
  1866 				$q['cache_results'] = true;
       
  1867 			}
       
  1868 		}
  1950 		}
  1869 
  1951 
  1870 		if ( ! isset( $q['update_post_term_cache'] ) ) {
  1952 		if ( ! isset( $q['update_post_term_cache'] ) ) {
  1871 			$q['update_post_term_cache'] = true;
  1953 			$q['update_post_term_cache'] = true;
  1872 		}
  1954 		}
  1873 
  1955 
       
  1956 		if ( ! isset( $q['update_menu_item_cache'] ) ) {
       
  1957 			$q['update_menu_item_cache'] = false;
       
  1958 		}
       
  1959 
  1874 		if ( ! isset( $q['lazy_load_term_meta'] ) ) {
  1960 		if ( ! isset( $q['lazy_load_term_meta'] ) ) {
  1875 			$q['lazy_load_term_meta'] = $q['update_post_term_cache'];
  1961 			$q['lazy_load_term_meta'] = $q['update_post_term_cache'];
       
  1962 		} elseif ( $q['lazy_load_term_meta'] ) { // Lazy loading term meta only works if term caches are primed.
       
  1963 			$q['update_post_term_cache'] = true;
  1876 		}
  1964 		}
  1877 
  1965 
  1878 		if ( ! isset( $q['update_post_meta_cache'] ) ) {
  1966 		if ( ! isset( $q['update_post_meta_cache'] ) ) {
  1879 			$q['update_post_meta_cache'] = true;
  1967 			$q['update_post_meta_cache'] = true;
  1880 		}
  1968 		}
  1930 			$this->is_home = false;
  2018 			$this->is_home = false;
  1931 			$q['page_id']  = get_option( 'page_on_front' );
  2019 			$q['page_id']  = get_option( 'page_on_front' );
  1932 		}
  2020 		}
  1933 
  2021 
  1934 		if ( isset( $q['page'] ) ) {
  2022 		if ( isset( $q['page'] ) ) {
  1935 			$q['page'] = trim( $q['page'], '/' );
  2023 			$q['page'] = is_scalar( $q['page'] ) ? absint( trim( $q['page'], '/' ) ) : 0;
  1936 			$q['page'] = absint( $q['page'] );
       
  1937 		}
  2024 		}
  1938 
  2025 
  1939 		// If true, forcibly turns off SQL_CALC_FOUND_ROWS even when limits are present.
  2026 		// If true, forcibly turns off SQL_CALC_FOUND_ROWS even when limits are present.
  1940 		if ( isset( $q['no_found_rows'] ) ) {
  2027 		if ( isset( $q['no_found_rows'] ) ) {
  1941 			$q['no_found_rows'] = (bool) $q['no_found_rows'];
  2028 			$q['no_found_rows'] = (bool) $q['no_found_rows'];
  2173 						$post_type[] = $pt;
  2260 						$post_type[] = $pt;
  2174 					}
  2261 					}
  2175 				}
  2262 				}
  2176 				if ( ! $post_type ) {
  2263 				if ( ! $post_type ) {
  2177 					$post_type = 'any';
  2264 					$post_type = 'any';
  2178 				} elseif ( count( $post_type ) == 1 ) {
  2265 				} elseif ( count( $post_type ) === 1 ) {
  2179 					$post_type = $post_type[0];
  2266 					$post_type = $post_type[0];
       
  2267 				} else {
       
  2268 					// Sort post types to ensure same cache key generation.
       
  2269 					sort( $post_type );
  2180 				}
  2270 				}
  2181 
  2271 
  2182 				$post_status_join = true;
  2272 				$post_status_join = true;
  2183 			} elseif ( in_array( 'attachment', (array) $post_type, true ) ) {
  2273 			} elseif ( in_array( 'attachment', (array) $post_type, true ) ) {
  2184 				$post_status_join = true;
  2274 				$post_status_join = true;
  2239 					unset( $the_tag );
  2329 					unset( $the_tag );
  2240 				}
  2330 				}
  2241 			}
  2331 			}
  2242 		}
  2332 		}
  2243 
  2333 
  2244 		if ( ! empty( $this->tax_query->queries ) || ! empty( $this->meta_query->queries ) ) {
  2334 		if ( ! empty( $this->tax_query->queries ) || ! empty( $this->meta_query->queries ) || ! empty( $this->allow_query_attachment_by_filename ) ) {
  2245 			$groupby = "{$wpdb->posts}.ID";
  2335 			$groupby = "{$wpdb->posts}.ID";
  2246 		}
  2336 		}
  2247 
  2337 
  2248 		// Author/user stuff.
  2338 		// Author/user stuff.
  2249 
  2339 
  2266 		}
  2356 		}
  2267 
  2357 
  2268 		// Author stuff for nice URLs.
  2358 		// Author stuff for nice URLs.
  2269 
  2359 
  2270 		if ( '' !== $q['author_name'] ) {
  2360 		if ( '' !== $q['author_name'] ) {
  2271 			if ( strpos( $q['author_name'], '/' ) !== false ) {
  2361 			if ( str_contains( $q['author_name'], '/' ) ) {
  2272 				$q['author_name'] = explode( '/', $q['author_name'] );
  2362 				$q['author_name'] = explode( '/', $q['author_name'] );
  2273 				if ( $q['author_name'][ count( $q['author_name'] ) - 1 ] ) {
  2363 				if ( $q['author_name'][ count( $q['author_name'] ) - 1 ] ) {
  2274 					$q['author_name'] = $q['author_name'][ count( $q['author_name'] ) - 1 ]; // No trailing slash.
  2364 					$q['author_name'] = $q['author_name'][ count( $q['author_name'] ) - 1 ]; // No trailing slash.
  2275 				} else {
  2365 				} else {
  2276 					$q['author_name'] = $q['author_name'][ count( $q['author_name'] ) - 2 ]; // There was a trailing slash.
  2366 					$q['author_name'] = $q['author_name'][ count( $q['author_name'] ) - 2 ]; // There was a trailing slash.
  2315 
  2405 
  2316 		if ( isset( $q['post_mime_type'] ) && '' !== $q['post_mime_type'] ) {
  2406 		if ( isset( $q['post_mime_type'] ) && '' !== $q['post_mime_type'] ) {
  2317 			$whichmimetype = wp_post_mime_type_where( $q['post_mime_type'], $wpdb->posts );
  2407 			$whichmimetype = wp_post_mime_type_where( $q['post_mime_type'], $wpdb->posts );
  2318 		}
  2408 		}
  2319 		$where .= $search . $whichauthor . $whichmimetype;
  2409 		$where .= $search . $whichauthor . $whichmimetype;
       
  2410 
       
  2411 		if ( ! empty( $this->allow_query_attachment_by_filename ) ) {
       
  2412 			$join .= " LEFT JOIN {$wpdb->postmeta} AS sq1 ON ( {$wpdb->posts}.ID = sq1.post_id AND sq1.meta_key = '_wp_attached_file' )";
       
  2413 		}
  2320 
  2414 
  2321 		if ( ! empty( $this->meta_query->queries ) ) {
  2415 		if ( ! empty( $this->meta_query->queries ) ) {
  2322 			$clauses = $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this );
  2416 			$clauses = $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this );
  2323 			$join   .= $clauses['join'];
  2417 			$join   .= $clauses['join'];
  2324 			$where  .= $clauses['where'];
  2418 			$where  .= $clauses['where'];
  2449 				$skip_post_status = true;
  2543 				$skip_post_status = true;
  2450 			} else {
  2544 			} else {
  2451 				$post_type_where = " AND {$wpdb->posts}.post_type IN ('" . implode( "', '", array_map( 'esc_sql', $in_search_post_types ) ) . "')";
  2545 				$post_type_where = " AND {$wpdb->posts}.post_type IN ('" . implode( "', '", array_map( 'esc_sql', $in_search_post_types ) ) . "')";
  2452 			}
  2546 			}
  2453 		} elseif ( ! empty( $post_type ) && is_array( $post_type ) ) {
  2547 		} elseif ( ! empty( $post_type ) && is_array( $post_type ) ) {
       
  2548 			// Sort post types to ensure same cache key generation.
       
  2549 			sort( $post_type );
  2454 			$post_type_where = " AND {$wpdb->posts}.post_type IN ('" . implode( "', '", esc_sql( $post_type ) ) . "')";
  2550 			$post_type_where = " AND {$wpdb->posts}.post_type IN ('" . implode( "', '", esc_sql( $post_type ) ) . "')";
  2455 		} elseif ( ! empty( $post_type ) ) {
  2551 		} elseif ( ! empty( $post_type ) ) {
  2456 			$post_type_where  = $wpdb->prepare( " AND {$wpdb->posts}.post_type = %s", $post_type );
  2552 			$post_type_where  = $wpdb->prepare( " AND {$wpdb->posts}.post_type = %s", $post_type );
  2457 			$post_type_object = get_post_type_object( $post_type );
  2553 			$post_type_object = get_post_type_object( $post_type );
  2458 		} elseif ( $this->is_attachment ) {
  2554 		} elseif ( $this->is_attachment ) {
  2554 			} else {
  2650 			} else {
  2555 				$queried_post_types = array( 'post' );
  2651 				$queried_post_types = array( 'post' );
  2556 			}
  2652 			}
  2557 
  2653 
  2558 			if ( ! empty( $queried_post_types ) ) {
  2654 			if ( ! empty( $queried_post_types ) ) {
  2559 
  2655 				sort( $queried_post_types );
  2560 				$status_type_clauses = array();
  2656 				$status_type_clauses = array();
  2561 
  2657 
  2562 				foreach ( $queried_post_types as $queried_post_type ) {
  2658 				foreach ( $queried_post_types as $queried_post_type ) {
  2563 
  2659 
  2564 					$queried_post_type_object = get_post_type_object( $queried_post_type );
  2660 					$queried_post_type_object = get_post_type_object( $queried_post_type );
  2725 
  2821 
  2726 			$key          = md5( $comments_request );
  2822 			$key          = md5( $comments_request );
  2727 			$last_changed = wp_cache_get_last_changed( 'comment' ) . ':' . wp_cache_get_last_changed( 'posts' );
  2823 			$last_changed = wp_cache_get_last_changed( 'comment' ) . ':' . wp_cache_get_last_changed( 'posts' );
  2728 
  2824 
  2729 			$cache_key   = "comment_feed:$key:$last_changed";
  2825 			$cache_key   = "comment_feed:$key:$last_changed";
  2730 			$comment_ids = wp_cache_get( $cache_key, 'comment' );
  2826 			$comment_ids = wp_cache_get( $cache_key, 'comment-queries' );
  2731 			if ( false === $comment_ids ) {
  2827 			if ( false === $comment_ids ) {
  2732 				$comment_ids = $wpdb->get_col( $comments_request );
  2828 				$comment_ids = $wpdb->get_col( $comments_request );
  2733 				wp_cache_add( $cache_key, $comment_ids, 'comment' );
  2829 				wp_cache_add( $cache_key, $comment_ids, 'comment-queries' );
  2734 			}
  2830 			}
  2735 			_prime_comment_caches( $comment_ids, false );
  2831 			_prime_comment_caches( $comment_ids );
  2736 
  2832 
  2737 			// Convert to WP_Comment.
  2833 			// Convert to WP_Comment.
  2738 			/** @var WP_Comment[] */
  2834 			/** @var WP_Comment[] */
  2739 			$this->comments      = array_map( 'get_comment', $comment_ids );
  2835 			$this->comments      = array_map( 'get_comment', $comment_ids );
  2740 			$this->comment_count = count( $this->comments );
  2836 			$this->comment_count = count( $this->comments );
  3011 		$found_rows = '';
  3107 		$found_rows = '';
  3012 		if ( ! $q['no_found_rows'] && ! empty( $limits ) ) {
  3108 		if ( ! $q['no_found_rows'] && ! empty( $limits ) ) {
  3013 			$found_rows = 'SQL_CALC_FOUND_ROWS';
  3109 			$found_rows = 'SQL_CALC_FOUND_ROWS';
  3014 		}
  3110 		}
  3015 
  3111 
  3016 		$old_request = "
  3112 		/*
  3017 			SELECT $found_rows $distinct $fields
  3113 		 * Beginning of the string is on a new line to prevent leading whitespace.
  3018 			FROM {$wpdb->posts} $join
  3114 		 *
  3019 			WHERE 1=1 $where
  3115 		 * The additional indentation of subsequent lines is to ensure the SQL
  3020 			$groupby
  3116 		 * queries are identical to those generated when splitting queries. This
  3021 			$orderby
  3117 		 * improves caching of the query by ensuring the same cache key is
  3022 			$limits
  3118 		 * generated for the same database queries functionally.
  3023 		";
  3119 		 *
       
  3120 		 * See https://core.trac.wordpress.org/ticket/56841.
       
  3121 		 * See https://github.com/WordPress/wordpress-develop/pull/6393#issuecomment-2088217429
       
  3122 		 */
       
  3123 		$old_request =
       
  3124 			"SELECT $found_rows $distinct $fields
       
  3125 					 FROM {$wpdb->posts} $join
       
  3126 					 WHERE 1=1 $where
       
  3127 					 $groupby
       
  3128 					 $orderby
       
  3129 					 $limits";
  3024 
  3130 
  3025 		$this->request = $old_request;
  3131 		$this->request = $old_request;
  3026 
  3132 
  3027 		if ( ! $q['suppress_filters'] ) {
  3133 		if ( ! $q['suppress_filters'] ) {
  3028 			/**
  3134 			/**
  3052 		 *                                    or null to allow WP to run its normal queries.
  3158 		 *                                    or null to allow WP to run its normal queries.
  3053 		 * @param WP_Query             $query The WP_Query instance (passed by reference).
  3159 		 * @param WP_Query             $query The WP_Query instance (passed by reference).
  3054 		 */
  3160 		 */
  3055 		$this->posts = apply_filters_ref_array( 'posts_pre_query', array( null, &$this ) );
  3161 		$this->posts = apply_filters_ref_array( 'posts_pre_query', array( null, &$this ) );
  3056 
  3162 
       
  3163 		/*
       
  3164 		 * Ensure the ID database query is able to be cached.
       
  3165 		 *
       
  3166 		 * Random queries are expected to have unpredictable results and
       
  3167 		 * cannot be cached. Note the space before `RAND` in the string
       
  3168 		 * search, that to ensure against a collision with another
       
  3169 		 * function.
       
  3170 		 *
       
  3171 		 * If `$fields` has been modified by the `posts_fields`,
       
  3172 		 * `posts_fields_request`, `post_clauses` or `posts_clauses_request`
       
  3173 		 * filters, then caching is disabled to prevent caching collisions.
       
  3174 		 */
       
  3175 		$id_query_is_cacheable = ! str_contains( strtoupper( $orderby ), ' RAND(' );
       
  3176 
       
  3177 		$cacheable_field_values = array(
       
  3178 			"{$wpdb->posts}.*",
       
  3179 			"{$wpdb->posts}.ID, {$wpdb->posts}.post_parent",
       
  3180 			"{$wpdb->posts}.ID",
       
  3181 		);
       
  3182 
       
  3183 		if ( ! in_array( $fields, $cacheable_field_values, true ) ) {
       
  3184 			$id_query_is_cacheable = false;
       
  3185 		}
       
  3186 
       
  3187 		if ( $q['cache_results'] && $id_query_is_cacheable ) {
       
  3188 			$new_request = str_replace( $fields, "{$wpdb->posts}.*", $this->request );
       
  3189 			$cache_key   = $this->generate_cache_key( $q, $new_request );
       
  3190 
       
  3191 			$cache_found = false;
       
  3192 			if ( null === $this->posts ) {
       
  3193 				$cached_results = wp_cache_get( $cache_key, 'post-queries', false, $cache_found );
       
  3194 
       
  3195 				if ( $cached_results ) {
       
  3196 					/** @var int[] */
       
  3197 					$post_ids = array_map( 'intval', $cached_results['posts'] );
       
  3198 
       
  3199 					$this->post_count    = count( $post_ids );
       
  3200 					$this->found_posts   = $cached_results['found_posts'];
       
  3201 					$this->max_num_pages = $cached_results['max_num_pages'];
       
  3202 
       
  3203 					if ( 'ids' === $q['fields'] ) {
       
  3204 						$this->posts = $post_ids;
       
  3205 
       
  3206 						return $this->posts;
       
  3207 					} elseif ( 'id=>parent' === $q['fields'] ) {
       
  3208 						_prime_post_parent_id_caches( $post_ids );
       
  3209 
       
  3210 						$post_parent_cache_keys = array();
       
  3211 						foreach ( $post_ids as $post_id ) {
       
  3212 							$post_parent_cache_keys[] = 'post_parent:' . (string) $post_id;
       
  3213 						}
       
  3214 
       
  3215 						/** @var int[] */
       
  3216 						$post_parents = wp_cache_get_multiple( $post_parent_cache_keys, 'posts' );
       
  3217 
       
  3218 						foreach ( $post_parents as $cache_key => $post_parent ) {
       
  3219 							$obj              = new stdClass();
       
  3220 							$obj->ID          = (int) str_replace( 'post_parent:', '', $cache_key );
       
  3221 							$obj->post_parent = (int) $post_parent;
       
  3222 
       
  3223 							$this->posts[] = $obj;
       
  3224 						}
       
  3225 
       
  3226 						return $post_parents;
       
  3227 					} else {
       
  3228 						_prime_post_caches( $post_ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
       
  3229 						/** @var WP_Post[] */
       
  3230 						$this->posts = array_map( 'get_post', $post_ids );
       
  3231 					}
       
  3232 				}
       
  3233 			}
       
  3234 		}
       
  3235 
  3057 		if ( 'ids' === $q['fields'] ) {
  3236 		if ( 'ids' === $q['fields'] ) {
  3058 			if ( null === $this->posts ) {
  3237 			if ( null === $this->posts ) {
  3059 				$this->posts = $wpdb->get_col( $this->request );
  3238 				$this->posts = $wpdb->get_col( $this->request );
  3060 			}
  3239 			}
  3061 
  3240 
  3062 			/** @var int[] */
  3241 			/** @var int[] */
  3063 			$this->posts      = array_map( 'intval', $this->posts );
  3242 			$this->posts      = array_map( 'intval', $this->posts );
  3064 			$this->post_count = count( $this->posts );
  3243 			$this->post_count = count( $this->posts );
  3065 			$this->set_found_posts( $q, $limits );
  3244 			$this->set_found_posts( $q, $limits );
  3066 
  3245 
       
  3246 			if ( $q['cache_results'] && $id_query_is_cacheable ) {
       
  3247 				$cache_value = array(
       
  3248 					'posts'         => $this->posts,
       
  3249 					'found_posts'   => $this->found_posts,
       
  3250 					'max_num_pages' => $this->max_num_pages,
       
  3251 				);
       
  3252 
       
  3253 				wp_cache_set( $cache_key, $cache_value, 'post-queries' );
       
  3254 			}
       
  3255 
  3067 			return $this->posts;
  3256 			return $this->posts;
  3068 		}
  3257 		}
  3069 
  3258 
  3070 		if ( 'id=>parent' === $q['fields'] ) {
  3259 		if ( 'id=>parent' === $q['fields'] ) {
  3071 			if ( null === $this->posts ) {
  3260 			if ( null === $this->posts ) {
  3074 
  3263 
  3075 			$this->post_count = count( $this->posts );
  3264 			$this->post_count = count( $this->posts );
  3076 			$this->set_found_posts( $q, $limits );
  3265 			$this->set_found_posts( $q, $limits );
  3077 
  3266 
  3078 			/** @var int[] */
  3267 			/** @var int[] */
  3079 			$r = array();
  3268 			$post_parents       = array();
       
  3269 			$post_ids           = array();
       
  3270 			$post_parents_cache = array();
       
  3271 
  3080 			foreach ( $this->posts as $key => $post ) {
  3272 			foreach ( $this->posts as $key => $post ) {
  3081 				$this->posts[ $key ]->ID          = (int) $post->ID;
  3273 				$this->posts[ $key ]->ID          = (int) $post->ID;
  3082 				$this->posts[ $key ]->post_parent = (int) $post->post_parent;
  3274 				$this->posts[ $key ]->post_parent = (int) $post->post_parent;
  3083 
  3275 
  3084 				$r[ (int) $post->ID ] = (int) $post->post_parent;
  3276 				$post_parents[ (int) $post->ID ] = (int) $post->post_parent;
  3085 			}
  3277 				$post_ids[]                      = (int) $post->ID;
  3086 
  3278 
  3087 			return $r;
  3279 				$post_parents_cache[ 'post_parent:' . (string) $post->ID ] = (int) $post->post_parent;
  3088 		}
  3280 			}
       
  3281 			// Prime post parent caches, so that on second run, there is not another database query.
       
  3282 			wp_cache_add_multiple( $post_parents_cache, 'posts' );
       
  3283 
       
  3284 			if ( $q['cache_results'] && $id_query_is_cacheable ) {
       
  3285 				$cache_value = array(
       
  3286 					'posts'         => $post_ids,
       
  3287 					'found_posts'   => $this->found_posts,
       
  3288 					'max_num_pages' => $this->max_num_pages,
       
  3289 				);
       
  3290 
       
  3291 				wp_cache_set( $cache_key, $cache_value, 'post-queries' );
       
  3292 			}
       
  3293 
       
  3294 			return $post_parents;
       
  3295 		}
       
  3296 
       
  3297 		$is_unfiltered_query = $old_request == $this->request && "{$wpdb->posts}.*" === $fields;
  3089 
  3298 
  3090 		if ( null === $this->posts ) {
  3299 		if ( null === $this->posts ) {
  3091 			$split_the_query = ( $old_request == $this->request && "{$wpdb->posts}.*" === $fields && ! empty( $limits ) && $q['posts_per_page'] < 500 );
  3300 			$split_the_query = (
       
  3301 				$is_unfiltered_query
       
  3302 				&& (
       
  3303 					wp_using_ext_object_cache()
       
  3304 					|| ( ! empty( $limits ) && $q['posts_per_page'] < 500 )
       
  3305 				)
       
  3306 			);
  3092 
  3307 
  3093 			/**
  3308 			/**
  3094 			 * Filters whether to split the query.
  3309 			 * Filters whether to split the query.
  3095 			 *
  3310 			 *
  3096 			 * Splitting the query will cause it to fetch just the IDs of the found posts
  3311 			 * Splitting the query will cause it to fetch just the IDs of the found posts
  3097 			 * (and then individually fetch each post by ID), rather than fetching every
  3312 			 * (and then individually fetch each post by ID), rather than fetching every
  3098 			 * complete row at once. One massive result vs. many small results.
  3313 			 * complete row at once. One massive result vs. many small results.
  3099 			 *
  3314 			 *
  3100 			 * @since 3.4.0
  3315 			 * @since 3.4.0
       
  3316 			 * @since 6.6.0 Added the `$old_request` and `$clauses` parameters.
  3101 			 *
  3317 			 *
  3102 			 * @param bool     $split_the_query Whether or not to split the query.
  3318 			 * @param bool     $split_the_query Whether or not to split the query.
  3103 			 * @param WP_Query $query           The WP_Query instance.
  3319 			 * @param WP_Query $query           The WP_Query instance.
       
  3320 			 * @param string   $old_request     The complete SQL query before filtering.
       
  3321 			 * @param string[] $clauses {
       
  3322 			 *     Associative array of the clauses for the query.
       
  3323 			 *
       
  3324 			 *     @type string $where    The WHERE clause of the query.
       
  3325 			 *     @type string $groupby  The GROUP BY clause of the query.
       
  3326 			 *     @type string $join     The JOIN clause of the query.
       
  3327 			 *     @type string $orderby  The ORDER BY clause of the query.
       
  3328 			 *     @type string $distinct The DISTINCT clause of the query.
       
  3329 			 *     @type string $fields   The SELECT clause of the query.
       
  3330 			 *     @type string $limits   The LIMIT clause of the query.
       
  3331 			 * }
  3104 			 */
  3332 			 */
  3105 			$split_the_query = apply_filters( 'split_the_query', $split_the_query, $this );
  3333 			$split_the_query = apply_filters( 'split_the_query', $split_the_query, $this, $old_request, compact( $pieces ) );
  3106 
  3334 
  3107 			if ( $split_the_query ) {
  3335 			if ( $split_the_query ) {
  3108 				// First get the IDs and then fill in the objects.
  3336 				// First get the IDs and then fill in the objects.
  3109 
  3337 
  3110 				$this->request = "
  3338 				// Beginning of the string is on a new line to prevent leading whitespace. See https://core.trac.wordpress.org/ticket/56841.
  3111 					SELECT $found_rows $distinct {$wpdb->posts}.ID
  3339 				$this->request =
  3112 					FROM {$wpdb->posts} $join
  3340 					"SELECT $found_rows $distinct {$wpdb->posts}.ID
  3113 					WHERE 1=1 $where
  3341 					 FROM {$wpdb->posts} $join
  3114 					$groupby
  3342 					 WHERE 1=1 $where
  3115 					$orderby
  3343 					 $groupby
  3116 					$limits
  3344 					 $orderby
  3117 				";
  3345 					 $limits";
  3118 
  3346 
  3119 				/**
  3347 				/**
  3120 				 * Filters the Post IDs SQL request before sending.
  3348 				 * Filters the Post IDs SQL request before sending.
  3121 				 *
  3349 				 *
  3122 				 * @since 3.4.0
  3350 				 * @since 3.4.0
  3124 				 * @param string   $request The post ID request.
  3352 				 * @param string   $request The post ID request.
  3125 				 * @param WP_Query $query   The WP_Query instance.
  3353 				 * @param WP_Query $query   The WP_Query instance.
  3126 				 */
  3354 				 */
  3127 				$this->request = apply_filters( 'posts_request_ids', $this->request, $this );
  3355 				$this->request = apply_filters( 'posts_request_ids', $this->request, $this );
  3128 
  3356 
  3129 				$ids = $wpdb->get_col( $this->request );
  3357 				$post_ids = $wpdb->get_col( $this->request );
  3130 
  3358 
  3131 				if ( $ids ) {
  3359 				if ( $post_ids ) {
  3132 					$this->posts = $ids;
  3360 					$this->posts = $post_ids;
  3133 					$this->set_found_posts( $q, $limits );
  3361 					$this->set_found_posts( $q, $limits );
  3134 					_prime_post_caches( $ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
  3362 					_prime_post_caches( $post_ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
  3135 				} else {
  3363 				} else {
  3136 					$this->posts = array();
  3364 					$this->posts = array();
  3137 				}
  3365 				}
  3138 			} else {
  3366 			} else {
  3139 				$this->posts = $wpdb->get_results( $this->request );
  3367 				$this->posts = $wpdb->get_results( $this->request );
  3145 		if ( $this->posts ) {
  3373 		if ( $this->posts ) {
  3146 			/** @var WP_Post[] */
  3374 			/** @var WP_Post[] */
  3147 			$this->posts = array_map( 'get_post', $this->posts );
  3375 			$this->posts = array_map( 'get_post', $this->posts );
  3148 		}
  3376 		}
  3149 
  3377 
       
  3378 		$unfiltered_posts = $this->posts;
       
  3379 
       
  3380 		if ( $q['cache_results'] && $id_query_is_cacheable && ! $cache_found ) {
       
  3381 			$post_ids = wp_list_pluck( $this->posts, 'ID' );
       
  3382 
       
  3383 			$cache_value = array(
       
  3384 				'posts'         => $post_ids,
       
  3385 				'found_posts'   => $this->found_posts,
       
  3386 				'max_num_pages' => $this->max_num_pages,
       
  3387 			);
       
  3388 
       
  3389 			wp_cache_set( $cache_key, $cache_value, 'post-queries' );
       
  3390 		}
       
  3391 
  3150 		if ( ! $q['suppress_filters'] ) {
  3392 		if ( ! $q['suppress_filters'] ) {
  3151 			/**
  3393 			/**
  3152 			 * Filters the raw post results array, prior to status checks.
  3394 			 * Filters the raw post results array, prior to status checks.
  3153 			 *
  3395 			 *
  3154 			 * @since 2.3.0
  3396 			 * @since 2.3.0
  3177 			/** This filter is documented in wp-includes/query.php */
  3419 			/** This filter is documented in wp-includes/query.php */
  3178 			$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option( 'posts_per_rss' ), &$this ) );
  3420 			$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option( 'posts_per_rss' ), &$this ) );
  3179 
  3421 
  3180 			$comments_request = "SELECT {$wpdb->comments}.comment_ID FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits";
  3422 			$comments_request = "SELECT {$wpdb->comments}.comment_ID FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits";
  3181 
  3423 
  3182 			$key          = md5( $comments_request );
  3424 			$comment_key          = md5( $comments_request );
  3183 			$last_changed = wp_cache_get_last_changed( 'comment' );
  3425 			$comment_last_changed = wp_cache_get_last_changed( 'comment' );
  3184 
  3426 
  3185 			$cache_key   = "comment_feed:$key:$last_changed";
  3427 			$comment_cache_key = "comment_feed:$comment_key:$comment_last_changed";
  3186 			$comment_ids = wp_cache_get( $cache_key, 'comment' );
  3428 			$comment_ids       = wp_cache_get( $comment_cache_key, 'comment-queries' );
  3187 			if ( false === $comment_ids ) {
  3429 			if ( false === $comment_ids ) {
  3188 				$comment_ids = $wpdb->get_col( $comments_request );
  3430 				$comment_ids = $wpdb->get_col( $comments_request );
  3189 				wp_cache_add( $cache_key, $comment_ids, 'comment' );
  3431 				wp_cache_add( $comment_cache_key, $comment_ids, 'comment-queries' );
  3190 			}
  3432 			}
  3191 			_prime_comment_caches( $comment_ids, false );
  3433 			_prime_comment_caches( $comment_ids );
  3192 
  3434 
  3193 			// Convert to WP_Comment.
  3435 			// Convert to WP_Comment.
  3194 			/** @var WP_Comment[] */
  3436 			/** @var WP_Comment[] */
  3195 			$this->comments      = array_map( 'get_comment', $comment_ids );
  3437 			$this->comments      = array_map( 'get_comment', $comment_ids );
  3196 			$this->comment_count = count( $this->comments );
  3438 			$this->comment_count = count( $this->comments );
  3266 					// Remove sticky from current position.
  3508 					// Remove sticky from current position.
  3267 					array_splice( $this->posts, $i, 1 );
  3509 					array_splice( $this->posts, $i, 1 );
  3268 					// Move to front, after other stickies.
  3510 					// Move to front, after other stickies.
  3269 					array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) );
  3511 					array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) );
  3270 					// Increment the sticky offset. The next sticky will be placed at this offset.
  3512 					// Increment the sticky offset. The next sticky will be placed at this offset.
  3271 					$sticky_offset++;
  3513 					++$sticky_offset;
  3272 					// Remove post from sticky posts array.
  3514 					// Remove post from sticky posts array.
  3273 					$offset = array_search( $sticky_post->ID, $sticky_posts, true );
  3515 					$offset = array_search( $sticky_post->ID, $sticky_posts, true );
  3274 					unset( $sticky_posts[ $offset ] );
  3516 					unset( $sticky_posts[ $offset ] );
  3275 				}
  3517 				}
  3276 			}
  3518 			}
  3296 					)
  3538 					)
  3297 				);
  3539 				);
  3298 
  3540 
  3299 				foreach ( $stickies as $sticky_post ) {
  3541 				foreach ( $stickies as $sticky_post ) {
  3300 					array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) );
  3542 					array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) );
  3301 					$sticky_offset++;
  3543 					++$sticky_offset;
  3302 				}
  3544 				}
  3303 			}
  3545 			}
  3304 		}
       
  3305 
       
  3306 		// If comments have been fetched as part of the query, make sure comment meta lazy-loading is set up.
       
  3307 		if ( ! empty( $this->comments ) ) {
       
  3308 			wp_queue_comments_for_comment_meta_lazyload( $this->comments );
       
  3309 		}
  3546 		}
  3310 
  3547 
  3311 		if ( ! $q['suppress_filters'] ) {
  3548 		if ( ! $q['suppress_filters'] ) {
  3312 			/**
  3549 			/**
  3313 			 * Filters the array of retrieved posts after they've been fetched and
  3550 			 * Filters the array of retrieved posts after they've been fetched and
  3319 			 * @param WP_Query  $query The WP_Query instance (passed by reference).
  3556 			 * @param WP_Query  $query The WP_Query instance (passed by reference).
  3320 			 */
  3557 			 */
  3321 			$this->posts = apply_filters_ref_array( 'the_posts', array( $this->posts, &$this ) );
  3558 			$this->posts = apply_filters_ref_array( 'the_posts', array( $this->posts, &$this ) );
  3322 		}
  3559 		}
  3323 
  3560 
  3324 		// Ensure that any posts added/modified via one of the filters above are
  3561 		/*
  3325 		// of the type WP_Post and are filtered.
  3562 		 * Ensure that any posts added/modified via one of the filters above are
       
  3563 		 * of the type WP_Post and are filtered.
       
  3564 		 */
  3326 		if ( $this->posts ) {
  3565 		if ( $this->posts ) {
  3327 			$this->post_count = count( $this->posts );
  3566 			$this->post_count = count( $this->posts );
  3328 
  3567 
  3329 			/** @var WP_Post[] */
  3568 			/** @var WP_Post[] */
  3330 			$this->posts = array_map( 'get_post', $this->posts );
  3569 			$this->posts = array_map( 'get_post', $this->posts );
  3331 
  3570 
  3332 			if ( $q['cache_results'] ) {
  3571 			if ( $q['cache_results'] ) {
  3333 				update_post_caches( $this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
  3572 				if ( $is_unfiltered_query && $unfiltered_posts === $this->posts ) {
       
  3573 					update_post_caches( $this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
       
  3574 				} else {
       
  3575 					$post_ids = wp_list_pluck( $this->posts, 'ID' );
       
  3576 					_prime_post_caches( $post_ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
       
  3577 				}
  3334 			}
  3578 			}
  3335 
  3579 
  3336 			/** @var WP_Post */
  3580 			/** @var WP_Post */
  3337 			$this->post = reset( $this->posts );
  3581 			$this->post = reset( $this->posts );
  3338 		} else {
  3582 		} else {
  3339 			$this->post_count = 0;
  3583 			$this->post_count = 0;
  3340 			$this->posts      = array();
  3584 			$this->posts      = array();
  3341 		}
  3585 		}
  3342 
  3586 
       
  3587 		if ( ! empty( $this->posts ) && $q['update_menu_item_cache'] ) {
       
  3588 			update_menu_item_cache( $this->posts );
       
  3589 		}
       
  3590 
  3343 		if ( $q['lazy_load_term_meta'] ) {
  3591 		if ( $q['lazy_load_term_meta'] ) {
  3344 			wp_queue_posts_for_term_meta_lazyload( $this->posts );
  3592 			wp_queue_posts_for_term_meta_lazyload( $this->posts );
  3345 		}
  3593 		}
  3346 
  3594 
  3347 		return $this->posts;
  3595 		return $this->posts;
  3348 	}
  3596 	}
  3349 
  3597 
  3350 	/**
  3598 	/**
  3351 	 * Set up the amount of found posts and the number of pages (if limit clause was used)
  3599 	 * Sets up the amount of found posts and the number of pages (if limit clause was used)
  3352 	 * for the current query.
  3600 	 * for the current query.
  3353 	 *
  3601 	 *
  3354 	 * @since 3.5.0
  3602 	 * @since 3.5.0
  3355 	 *
  3603 	 *
  3356 	 * @global wpdb $wpdb WordPress database abstraction object.
  3604 	 * @global wpdb $wpdb WordPress database abstraction object.
  3359 	 * @param string $limits LIMIT clauses of the query.
  3607 	 * @param string $limits LIMIT clauses of the query.
  3360 	 */
  3608 	 */
  3361 	private function set_found_posts( $q, $limits ) {
  3609 	private function set_found_posts( $q, $limits ) {
  3362 		global $wpdb;
  3610 		global $wpdb;
  3363 
  3611 
  3364 		// Bail if posts is an empty array. Continue if posts is an empty string,
  3612 		/*
  3365 		// null, or false to accommodate caching plugins that fill posts later.
  3613 		 * Bail if posts is an empty array. Continue if posts is an empty string,
       
  3614 		 * null, or false to accommodate caching plugins that fill posts later.
       
  3615 		 */
  3366 		if ( $q['no_found_rows'] || ( is_array( $this->posts ) && ! $this->posts ) ) {
  3616 		if ( $q['no_found_rows'] || ( is_array( $this->posts ) && ! $this->posts ) ) {
  3367 			return;
  3617 			return;
  3368 		}
  3618 		}
  3369 
  3619 
  3370 		if ( ! empty( $limits ) ) {
  3620 		if ( ! empty( $limits ) ) {
  3400 		 * @param WP_Query $query       The WP_Query instance (passed by reference).
  3650 		 * @param WP_Query $query       The WP_Query instance (passed by reference).
  3401 		 */
  3651 		 */
  3402 		$this->found_posts = (int) apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
  3652 		$this->found_posts = (int) apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
  3403 
  3653 
  3404 		if ( ! empty( $limits ) ) {
  3654 		if ( ! empty( $limits ) ) {
  3405 			$this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] );
  3655 			$this->max_num_pages = (int) ceil( $this->found_posts / $q['posts_per_page'] );
  3406 		}
  3656 		}
  3407 	}
  3657 	}
  3408 
  3658 
  3409 	/**
  3659 	/**
  3410 	 * Set up the next post and iterate current post index.
  3660 	 * Sets up the next post and iterate current post index.
  3411 	 *
  3661 	 *
  3412 	 * @since 1.5.0
  3662 	 * @since 1.5.0
  3413 	 *
  3663 	 *
  3414 	 * @return WP_Post Next post.
  3664 	 * @return WP_Post Next post.
  3415 	 */
  3665 	 */
  3416 	public function next_post() {
  3666 	public function next_post() {
  3417 
  3667 
  3418 		$this->current_post++;
  3668 		++$this->current_post;
  3419 
  3669 
  3420 		/** @var WP_Post */
  3670 		/** @var WP_Post */
  3421 		$this->post = $this->posts[ $this->current_post ];
  3671 		$this->post = $this->posts[ $this->current_post ];
  3422 		return $this->post;
  3672 		return $this->post;
  3423 	}
  3673 	}
  3432 	 *
  3682 	 *
  3433 	 * @global WP_Post $post Global post object.
  3683 	 * @global WP_Post $post Global post object.
  3434 	 */
  3684 	 */
  3435 	public function the_post() {
  3685 	public function the_post() {
  3436 		global $post;
  3686 		global $post;
       
  3687 
       
  3688 		if ( ! $this->in_the_loop ) {
       
  3689 			// Only prime the post cache for queries limited to the ID field.
       
  3690 			$post_ids = array_filter( $this->posts, 'is_numeric' );
       
  3691 			// Exclude any falsey values, such as 0.
       
  3692 			$post_ids = array_filter( $post_ids );
       
  3693 			if ( $post_ids ) {
       
  3694 				_prime_post_caches( $post_ids, $this->query_vars['update_post_term_cache'], $this->query_vars['update_post_meta_cache'] );
       
  3695 			}
       
  3696 			$post_objects = array_map( 'get_post', $this->posts );
       
  3697 			update_post_author_caches( $post_objects );
       
  3698 		}
       
  3699 
  3437 		$this->in_the_loop = true;
  3700 		$this->in_the_loop = true;
       
  3701 		$this->before_loop = false;
  3438 
  3702 
  3439 		if ( -1 == $this->current_post ) { // Loop has just started.
  3703 		if ( -1 == $this->current_post ) { // Loop has just started.
  3440 			/**
  3704 			/**
  3441 			 * Fires once the loop is started.
  3705 			 * Fires once the loop is started.
  3442 			 *
  3706 			 *
  3473 			 */
  3737 			 */
  3474 			do_action_ref_array( 'loop_end', array( &$this ) );
  3738 			do_action_ref_array( 'loop_end', array( &$this ) );
  3475 			// Do some cleaning up after the loop.
  3739 			// Do some cleaning up after the loop.
  3476 			$this->rewind_posts();
  3740 			$this->rewind_posts();
  3477 		} elseif ( 0 === $this->post_count ) {
  3741 		} elseif ( 0 === $this->post_count ) {
       
  3742 			$this->before_loop = false;
       
  3743 
  3478 			/**
  3744 			/**
  3479 			 * Fires if no results are found in a post query.
  3745 			 * Fires if no results are found in a post query.
  3480 			 *
  3746 			 *
  3481 			 * @since 4.9.0
  3747 			 * @since 4.9.0
  3482 			 *
  3748 			 *
  3488 		$this->in_the_loop = false;
  3754 		$this->in_the_loop = false;
  3489 		return false;
  3755 		return false;
  3490 	}
  3756 	}
  3491 
  3757 
  3492 	/**
  3758 	/**
  3493 	 * Rewind the posts and reset post index.
  3759 	 * Rewinds the posts and resets post index.
  3494 	 *
  3760 	 *
  3495 	 * @since 1.5.0
  3761 	 * @since 1.5.0
  3496 	 */
  3762 	 */
  3497 	public function rewind_posts() {
  3763 	public function rewind_posts() {
  3498 		$this->current_post = -1;
  3764 		$this->current_post = -1;
  3500 			$this->post = $this->posts[0];
  3766 			$this->post = $this->posts[0];
  3501 		}
  3767 		}
  3502 	}
  3768 	}
  3503 
  3769 
  3504 	/**
  3770 	/**
  3505 	 * Iterate current comment index and return WP_Comment object.
  3771 	 * Iterates current comment index and returns WP_Comment object.
  3506 	 *
  3772 	 *
  3507 	 * @since 2.2.0
  3773 	 * @since 2.2.0
  3508 	 *
  3774 	 *
  3509 	 * @return WP_Comment Comment object.
  3775 	 * @return WP_Comment Comment object.
  3510 	 */
  3776 	 */
  3511 	public function next_comment() {
  3777 	public function next_comment() {
  3512 		$this->current_comment++;
  3778 		++$this->current_comment;
  3513 
  3779 
  3514 		/** @var WP_Comment */
  3780 		/** @var WP_Comment */
  3515 		$this->comment = $this->comments[ $this->current_comment ];
  3781 		$this->comment = $this->comments[ $this->current_comment ];
  3516 		return $this->comment;
  3782 		return $this->comment;
  3517 	}
  3783 	}
  3537 			do_action( 'comment_loop_start' );
  3803 			do_action( 'comment_loop_start' );
  3538 		}
  3804 		}
  3539 	}
  3805 	}
  3540 
  3806 
  3541 	/**
  3807 	/**
  3542 	 * Whether there are more comments available.
  3808 	 * Determines whether there are more comments available.
  3543 	 *
  3809 	 *
  3544 	 * Automatically rewinds comments when finished.
  3810 	 * Automatically rewinds comments when finished.
  3545 	 *
  3811 	 *
  3546 	 * @since 2.2.0
  3812 	 * @since 2.2.0
  3547 	 *
  3813 	 *
  3556 
  3822 
  3557 		return false;
  3823 		return false;
  3558 	}
  3824 	}
  3559 
  3825 
  3560 	/**
  3826 	/**
  3561 	 * Rewind the comments, resets the comment index and comment to first.
  3827 	 * Rewinds the comments, resets the comment index and comment to first.
  3562 	 *
  3828 	 *
  3563 	 * @since 2.2.0
  3829 	 * @since 2.2.0
  3564 	 */
  3830 	 */
  3565 	public function rewind_comments() {
  3831 	public function rewind_comments() {
  3566 		$this->current_comment = -1;
  3832 		$this->current_comment = -1;
  3718 			$this->query( $query );
  3984 			$this->query( $query );
  3719 		}
  3985 		}
  3720 	}
  3986 	}
  3721 
  3987 
  3722 	/**
  3988 	/**
  3723 	 * Make private properties readable for backward compatibility.
  3989 	 * Makes private properties readable for backward compatibility.
  3724 	 *
  3990 	 *
  3725 	 * @since 4.0.0
  3991 	 * @since 4.0.0
  3726 	 *
  3992 	 *
  3727 	 * @param string $name Property to get.
  3993 	 * @param string $name Property to get.
  3728 	 * @return mixed Property.
  3994 	 * @return mixed Property.
  3732 			return $this->$name;
  3998 			return $this->$name;
  3733 		}
  3999 		}
  3734 	}
  4000 	}
  3735 
  4001 
  3736 	/**
  4002 	/**
  3737 	 * Make private properties checkable for backward compatibility.
  4003 	 * Makes private properties checkable for backward compatibility.
  3738 	 *
  4004 	 *
  3739 	 * @since 4.0.0
  4005 	 * @since 4.0.0
  3740 	 *
  4006 	 *
  3741 	 * @param string $name Property to check if set.
  4007 	 * @param string $name Property to check if set.
  3742 	 * @return bool Whether the property is set.
  4008 	 * @return bool Whether the property is set.
  3746 			return isset( $this->$name );
  4012 			return isset( $this->$name );
  3747 		}
  4013 		}
  3748 	}
  4014 	}
  3749 
  4015 
  3750 	/**
  4016 	/**
  3751 	 * Make private/protected methods readable for backward compatibility.
  4017 	 * Makes private/protected methods readable for backward compatibility.
  3752 	 *
  4018 	 *
  3753 	 * @since 4.0.0
  4019 	 * @since 4.0.0
  3754 	 *
  4020 	 *
  3755 	 * @param string $name      Method to call.
  4021 	 * @param string $name      Method to call.
  3756 	 * @param array  $arguments Arguments to pass when calling.
  4022 	 * @param array  $arguments Arguments to pass when calling.
  3762 		}
  4028 		}
  3763 		return false;
  4029 		return false;
  3764 	}
  4030 	}
  3765 
  4031 
  3766 	/**
  4032 	/**
  3767 	 * Is the query for an existing archive page?
  4033 	 * Determines whether the query is for an existing archive page.
  3768 	 *
  4034 	 *
  3769 	 * Archive pages include category, tag, author, date, custom post type,
  4035 	 * Archive pages include category, tag, author, date, custom post type,
  3770 	 * and custom taxonomy based archives.
  4036 	 * and custom taxonomy based archives.
  3771 	 *
  4037 	 *
  3772 	 * @since 3.1.0
  4038 	 * @since 3.1.0
  3783 	public function is_archive() {
  4049 	public function is_archive() {
  3784 		return (bool) $this->is_archive;
  4050 		return (bool) $this->is_archive;
  3785 	}
  4051 	}
  3786 
  4052 
  3787 	/**
  4053 	/**
  3788 	 * Is the query for an existing post type archive page?
  4054 	 * Determines whether the query is for an existing post type archive page.
  3789 	 *
  4055 	 *
  3790 	 * @since 3.1.0
  4056 	 * @since 3.1.0
  3791 	 *
  4057 	 *
  3792 	 * @param string|string[] $post_types Optional. Post type or array of posts types
  4058 	 * @param string|string[] $post_types Optional. Post type or array of posts types
  3793 	 *                                    to check against. Default empty.
  4059 	 *                                    to check against. Default empty.
  3802 		if ( is_array( $post_type ) ) {
  4068 		if ( is_array( $post_type ) ) {
  3803 			$post_type = reset( $post_type );
  4069 			$post_type = reset( $post_type );
  3804 		}
  4070 		}
  3805 		$post_type_object = get_post_type_object( $post_type );
  4071 		$post_type_object = get_post_type_object( $post_type );
  3806 
  4072 
       
  4073 		if ( ! $post_type_object ) {
       
  4074 			return false;
       
  4075 		}
       
  4076 
  3807 		return in_array( $post_type_object->name, (array) $post_types, true );
  4077 		return in_array( $post_type_object->name, (array) $post_types, true );
  3808 	}
  4078 	}
  3809 
  4079 
  3810 	/**
  4080 	/**
  3811 	 * Is the query for an existing attachment page?
  4081 	 * Determines whether the query is for an existing attachment page.
  3812 	 *
  4082 	 *
  3813 	 * @since 3.1.0
  4083 	 * @since 3.1.0
  3814 	 *
  4084 	 *
  3815 	 * @param int|string|int[]|string[] $attachment Optional. Attachment ID, title, slug, or array of such
  4085 	 * @param int|string|int[]|string[] $attachment Optional. Attachment ID, title, slug, or array of such
  3816 	 *                                              to check against. Default empty.
  4086 	 *                                              to check against. Default empty.
  3826 		}
  4096 		}
  3827 
  4097 
  3828 		$attachment = array_map( 'strval', (array) $attachment );
  4098 		$attachment = array_map( 'strval', (array) $attachment );
  3829 
  4099 
  3830 		$post_obj = $this->get_queried_object();
  4100 		$post_obj = $this->get_queried_object();
       
  4101 		if ( ! $post_obj ) {
       
  4102 			return false;
       
  4103 		}
  3831 
  4104 
  3832 		if ( in_array( (string) $post_obj->ID, $attachment, true ) ) {
  4105 		if ( in_array( (string) $post_obj->ID, $attachment, true ) ) {
  3833 			return true;
  4106 			return true;
  3834 		} elseif ( in_array( $post_obj->post_title, $attachment, true ) ) {
  4107 		} elseif ( in_array( $post_obj->post_title, $attachment, true ) ) {
  3835 			return true;
  4108 			return true;
  3838 		}
  4111 		}
  3839 		return false;
  4112 		return false;
  3840 	}
  4113 	}
  3841 
  4114 
  3842 	/**
  4115 	/**
  3843 	 * Is the query for an existing author archive page?
  4116 	 * Determines whether the query is for an existing author archive page.
  3844 	 *
  4117 	 *
  3845 	 * If the $author parameter is specified, this function will additionally
  4118 	 * If the $author parameter is specified, this function will additionally
  3846 	 * check if the query is for one of the authors specified.
  4119 	 * check if the query is for one of the authors specified.
  3847 	 *
  4120 	 *
  3848 	 * @since 3.1.0
  4121 	 * @since 3.1.0
  3859 		if ( empty( $author ) ) {
  4132 		if ( empty( $author ) ) {
  3860 			return true;
  4133 			return true;
  3861 		}
  4134 		}
  3862 
  4135 
  3863 		$author_obj = $this->get_queried_object();
  4136 		$author_obj = $this->get_queried_object();
       
  4137 		if ( ! $author_obj ) {
       
  4138 			return false;
       
  4139 		}
  3864 
  4140 
  3865 		$author = array_map( 'strval', (array) $author );
  4141 		$author = array_map( 'strval', (array) $author );
  3866 
  4142 
  3867 		if ( in_array( (string) $author_obj->ID, $author, true ) ) {
  4143 		if ( in_array( (string) $author_obj->ID, $author, true ) ) {
  3868 			return true;
  4144 			return true;
  3874 
  4150 
  3875 		return false;
  4151 		return false;
  3876 	}
  4152 	}
  3877 
  4153 
  3878 	/**
  4154 	/**
  3879 	 * Is the query for an existing category archive page?
  4155 	 * Determines whether the query is for an existing category archive page.
  3880 	 *
  4156 	 *
  3881 	 * If the $category parameter is specified, this function will additionally
  4157 	 * If the $category parameter is specified, this function will additionally
  3882 	 * check if the query is for one of the categories specified.
  4158 	 * check if the query is for one of the categories specified.
  3883 	 *
  4159 	 *
  3884 	 * @since 3.1.0
  4160 	 * @since 3.1.0
  3895 		if ( empty( $category ) ) {
  4171 		if ( empty( $category ) ) {
  3896 			return true;
  4172 			return true;
  3897 		}
  4173 		}
  3898 
  4174 
  3899 		$cat_obj = $this->get_queried_object();
  4175 		$cat_obj = $this->get_queried_object();
       
  4176 		if ( ! $cat_obj ) {
       
  4177 			return false;
       
  4178 		}
  3900 
  4179 
  3901 		$category = array_map( 'strval', (array) $category );
  4180 		$category = array_map( 'strval', (array) $category );
  3902 
  4181 
  3903 		if ( in_array( (string) $cat_obj->term_id, $category, true ) ) {
  4182 		if ( in_array( (string) $cat_obj->term_id, $category, true ) ) {
  3904 			return true;
  4183 			return true;
  3910 
  4189 
  3911 		return false;
  4190 		return false;
  3912 	}
  4191 	}
  3913 
  4192 
  3914 	/**
  4193 	/**
  3915 	 * Is the query for an existing tag archive page?
  4194 	 * Determines whether the query is for an existing tag archive page.
  3916 	 *
  4195 	 *
  3917 	 * If the $tag parameter is specified, this function will additionally
  4196 	 * If the $tag parameter is specified, this function will additionally
  3918 	 * check if the query is for one of the tags specified.
  4197 	 * check if the query is for one of the tags specified.
  3919 	 *
  4198 	 *
  3920 	 * @since 3.1.0
  4199 	 * @since 3.1.0
  3931 		if ( empty( $tag ) ) {
  4210 		if ( empty( $tag ) ) {
  3932 			return true;
  4211 			return true;
  3933 		}
  4212 		}
  3934 
  4213 
  3935 		$tag_obj = $this->get_queried_object();
  4214 		$tag_obj = $this->get_queried_object();
       
  4215 		if ( ! $tag_obj ) {
       
  4216 			return false;
       
  4217 		}
  3936 
  4218 
  3937 		$tag = array_map( 'strval', (array) $tag );
  4219 		$tag = array_map( 'strval', (array) $tag );
  3938 
  4220 
  3939 		if ( in_array( (string) $tag_obj->term_id, $tag, true ) ) {
  4221 		if ( in_array( (string) $tag_obj->term_id, $tag, true ) ) {
  3940 			return true;
  4222 			return true;
  3946 
  4228 
  3947 		return false;
  4229 		return false;
  3948 	}
  4230 	}
  3949 
  4231 
  3950 	/**
  4232 	/**
  3951 	 * Is the query for an existing custom taxonomy archive page?
  4233 	 * Determines whether the query is for an existing custom taxonomy archive page.
  3952 	 *
  4234 	 *
  3953 	 * If the $taxonomy parameter is specified, this function will additionally
  4235 	 * If the $taxonomy parameter is specified, this function will additionally
  3954 	 * check if the query is for that specific $taxonomy.
  4236 	 * check if the query is for that specific $taxonomy.
  3955 	 *
  4237 	 *
  3956 	 * If the $term parameter is specified in addition to the $taxonomy parameter,
  4238 	 * If the $term parameter is specified in addition to the $taxonomy parameter,
  4002 				)
  4284 				)
  4003 			);
  4285 			);
  4004 	}
  4286 	}
  4005 
  4287 
  4006 	/**
  4288 	/**
  4007 	 * Whether the current URL is within the comments popup window.
  4289 	 * Determines whether the current URL is within the comments popup window.
  4008 	 *
  4290 	 *
  4009 	 * @since 3.1.0
  4291 	 * @since 3.1.0
  4010 	 * @deprecated 4.5.0
  4292 	 * @deprecated 4.5.0
  4011 	 *
  4293 	 *
  4012 	 * @return false Always returns false.
  4294 	 * @return false Always returns false.
  4016 
  4298 
  4017 		return false;
  4299 		return false;
  4018 	}
  4300 	}
  4019 
  4301 
  4020 	/**
  4302 	/**
  4021 	 * Is the query for an existing date archive?
  4303 	 * Determines whether the query is for an existing date archive.
  4022 	 *
  4304 	 *
  4023 	 * @since 3.1.0
  4305 	 * @since 3.1.0
  4024 	 *
  4306 	 *
  4025 	 * @return bool Whether the query is for an existing date archive.
  4307 	 * @return bool Whether the query is for an existing date archive.
  4026 	 */
  4308 	 */
  4027 	public function is_date() {
  4309 	public function is_date() {
  4028 		return (bool) $this->is_date;
  4310 		return (bool) $this->is_date;
  4029 	}
  4311 	}
  4030 
  4312 
  4031 	/**
  4313 	/**
  4032 	 * Is the query for an existing day archive?
  4314 	 * Determines whether the query is for an existing day archive.
  4033 	 *
  4315 	 *
  4034 	 * @since 3.1.0
  4316 	 * @since 3.1.0
  4035 	 *
  4317 	 *
  4036 	 * @return bool Whether the query is for an existing day archive.
  4318 	 * @return bool Whether the query is for an existing day archive.
  4037 	 */
  4319 	 */
  4038 	public function is_day() {
  4320 	public function is_day() {
  4039 		return (bool) $this->is_day;
  4321 		return (bool) $this->is_day;
  4040 	}
  4322 	}
  4041 
  4323 
  4042 	/**
  4324 	/**
  4043 	 * Is the query for a feed?
  4325 	 * Determines whether the query is for a feed.
  4044 	 *
  4326 	 *
  4045 	 * @since 3.1.0
  4327 	 * @since 3.1.0
  4046 	 *
  4328 	 *
  4047 	 * @param string|string[] $feeds Optional. Feed type or array of feed types
  4329 	 * @param string|string[] $feeds Optional. Feed type or array of feed types
  4048 	 *                                         to check against. Default empty.
  4330 	 *                                         to check against. Default empty.
  4060 
  4342 
  4061 		return in_array( $qv, (array) $feeds, true );
  4343 		return in_array( $qv, (array) $feeds, true );
  4062 	}
  4344 	}
  4063 
  4345 
  4064 	/**
  4346 	/**
  4065 	 * Is the query for a comments feed?
  4347 	 * Determines whether the query is for a comments feed.
  4066 	 *
  4348 	 *
  4067 	 * @since 3.1.0
  4349 	 * @since 3.1.0
  4068 	 *
  4350 	 *
  4069 	 * @return bool Whether the query is for a comments feed.
  4351 	 * @return bool Whether the query is for a comments feed.
  4070 	 */
  4352 	 */
  4071 	public function is_comment_feed() {
  4353 	public function is_comment_feed() {
  4072 		return (bool) $this->is_comment_feed;
  4354 		return (bool) $this->is_comment_feed;
  4073 	}
  4355 	}
  4074 
  4356 
  4075 	/**
  4357 	/**
  4076 	 * Is the query for the front page of the site?
  4358 	 * Determines whether the query is for the front page of the site.
  4077 	 *
  4359 	 *
  4078 	 * This is for what is displayed at your site's main URL.
  4360 	 * This is for what is displayed at your site's main URL.
  4079 	 *
  4361 	 *
  4080 	 * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_on_front'.
  4362 	 * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_on_front'.
  4081 	 *
  4363 	 *
  4082 	 * If you set a static page for the front page of your site, this function will return
  4364 	 * If you set a static page for the front page of your site, this function will return
  4083 	 * true when viewing that page.
  4365 	 * true when viewing that page.
  4084 	 *
  4366 	 *
  4085 	 * Otherwise the same as @see WP_Query::is_home()
  4367 	 * Otherwise the same as {@see WP_Query::is_home()}.
  4086 	 *
  4368 	 *
  4087 	 * @since 3.1.0
  4369 	 * @since 3.1.0
  4088 	 *
  4370 	 *
  4089 	 * @return bool Whether the query is for the front page of the site.
  4371 	 * @return bool Whether the query is for the front page of the site.
  4090 	 */
  4372 	 */
  4100 			return false;
  4382 			return false;
  4101 		}
  4383 		}
  4102 	}
  4384 	}
  4103 
  4385 
  4104 	/**
  4386 	/**
  4105 	 * Is the query for the blog homepage?
  4387 	 * Determines whether the query is for the blog homepage.
  4106 	 *
  4388 	 *
  4107 	 * This is the page which shows the time based blog content of your site.
  4389 	 * This is the page which shows the time based blog content of your site.
  4108 	 *
  4390 	 *
  4109 	 * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_for_posts'.
  4391 	 * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_for_posts'.
  4110 	 *
  4392 	 *
  4120 	public function is_home() {
  4402 	public function is_home() {
  4121 		return (bool) $this->is_home;
  4403 		return (bool) $this->is_home;
  4122 	}
  4404 	}
  4123 
  4405 
  4124 	/**
  4406 	/**
  4125 	 * Is the query for the Privacy Policy page?
  4407 	 * Determines whether the query is for the Privacy Policy page.
  4126 	 *
  4408 	 *
  4127 	 * This is the page which shows the Privacy Policy content of your site.
  4409 	 * This is the page which shows the Privacy Policy content of your site.
  4128 	 *
  4410 	 *
  4129 	 * Depends on the site's "Change your Privacy Policy page" Privacy Settings 'wp_page_for_privacy_policy'.
  4411 	 * Depends on the site's "Change your Privacy Policy page" Privacy Settings 'wp_page_for_privacy_policy'.
  4130 	 *
  4412 	 *
  4143 			return false;
  4425 			return false;
  4144 		}
  4426 		}
  4145 	}
  4427 	}
  4146 
  4428 
  4147 	/**
  4429 	/**
  4148 	 * Is the query for an existing month archive?
  4430 	 * Determines whether the query is for an existing month archive.
  4149 	 *
  4431 	 *
  4150 	 * @since 3.1.0
  4432 	 * @since 3.1.0
  4151 	 *
  4433 	 *
  4152 	 * @return bool Whether the query is for an existing month archive.
  4434 	 * @return bool Whether the query is for an existing month archive.
  4153 	 */
  4435 	 */
  4154 	public function is_month() {
  4436 	public function is_month() {
  4155 		return (bool) $this->is_month;
  4437 		return (bool) $this->is_month;
  4156 	}
  4438 	}
  4157 
  4439 
  4158 	/**
  4440 	/**
  4159 	 * Is the query for an existing single page?
  4441 	 * Determines whether the query is for an existing single page.
  4160 	 *
  4442 	 *
  4161 	 * If the $page parameter is specified, this function will additionally
  4443 	 * If the $page parameter is specified, this function will additionally
  4162 	 * check if the query is for one of the pages specified.
  4444 	 * check if the query is for one of the pages specified.
  4163 	 *
  4445 	 *
  4164 	 * @since 3.1.0
  4446 	 * @since 3.1.0
  4178 		if ( empty( $page ) ) {
  4460 		if ( empty( $page ) ) {
  4179 			return true;
  4461 			return true;
  4180 		}
  4462 		}
  4181 
  4463 
  4182 		$page_obj = $this->get_queried_object();
  4464 		$page_obj = $this->get_queried_object();
       
  4465 		if ( ! $page_obj ) {
       
  4466 			return false;
       
  4467 		}
  4183 
  4468 
  4184 		$page = array_map( 'strval', (array) $page );
  4469 		$page = array_map( 'strval', (array) $page );
  4185 
  4470 
  4186 		if ( in_array( (string) $page_obj->ID, $page, true ) ) {
  4471 		if ( in_array( (string) $page_obj->ID, $page, true ) ) {
  4187 			return true;
  4472 			return true;
  4204 
  4489 
  4205 		return false;
  4490 		return false;
  4206 	}
  4491 	}
  4207 
  4492 
  4208 	/**
  4493 	/**
  4209 	 * Is the query for a paged result and not for the first page?
  4494 	 * Determines whether the query is for a paged result and not for the first page.
  4210 	 *
  4495 	 *
  4211 	 * @since 3.1.0
  4496 	 * @since 3.1.0
  4212 	 *
  4497 	 *
  4213 	 * @return bool Whether the query is for a paged result.
  4498 	 * @return bool Whether the query is for a paged result.
  4214 	 */
  4499 	 */
  4215 	public function is_paged() {
  4500 	public function is_paged() {
  4216 		return (bool) $this->is_paged;
  4501 		return (bool) $this->is_paged;
  4217 	}
  4502 	}
  4218 
  4503 
  4219 	/**
  4504 	/**
  4220 	 * Is the query for a post or page preview?
  4505 	 * Determines whether the query is for a post or page preview.
  4221 	 *
  4506 	 *
  4222 	 * @since 3.1.0
  4507 	 * @since 3.1.0
  4223 	 *
  4508 	 *
  4224 	 * @return bool Whether the query is for a post or page preview.
  4509 	 * @return bool Whether the query is for a post or page preview.
  4225 	 */
  4510 	 */
  4226 	public function is_preview() {
  4511 	public function is_preview() {
  4227 		return (bool) $this->is_preview;
  4512 		return (bool) $this->is_preview;
  4228 	}
  4513 	}
  4229 
  4514 
  4230 	/**
  4515 	/**
  4231 	 * Is the query for the robots.txt file?
  4516 	 * Determines whether the query is for the robots.txt file.
  4232 	 *
  4517 	 *
  4233 	 * @since 3.1.0
  4518 	 * @since 3.1.0
  4234 	 *
  4519 	 *
  4235 	 * @return bool Whether the query is for the robots.txt file.
  4520 	 * @return bool Whether the query is for the robots.txt file.
  4236 	 */
  4521 	 */
  4237 	public function is_robots() {
  4522 	public function is_robots() {
  4238 		return (bool) $this->is_robots;
  4523 		return (bool) $this->is_robots;
  4239 	}
  4524 	}
  4240 
  4525 
  4241 	/**
  4526 	/**
  4242 	 * Is the query for the favicon.ico file?
  4527 	 * Determines whether the query is for the favicon.ico file.
  4243 	 *
  4528 	 *
  4244 	 * @since 5.4.0
  4529 	 * @since 5.4.0
  4245 	 *
  4530 	 *
  4246 	 * @return bool Whether the query is for the favicon.ico file.
  4531 	 * @return bool Whether the query is for the favicon.ico file.
  4247 	 */
  4532 	 */
  4248 	public function is_favicon() {
  4533 	public function is_favicon() {
  4249 		return (bool) $this->is_favicon;
  4534 		return (bool) $this->is_favicon;
  4250 	}
  4535 	}
  4251 
  4536 
  4252 	/**
  4537 	/**
  4253 	 * Is the query for a search?
  4538 	 * Determines whether the query is for a search.
  4254 	 *
  4539 	 *
  4255 	 * @since 3.1.0
  4540 	 * @since 3.1.0
  4256 	 *
  4541 	 *
  4257 	 * @return bool Whether the query is for a search.
  4542 	 * @return bool Whether the query is for a search.
  4258 	 */
  4543 	 */
  4259 	public function is_search() {
  4544 	public function is_search() {
  4260 		return (bool) $this->is_search;
  4545 		return (bool) $this->is_search;
  4261 	}
  4546 	}
  4262 
  4547 
  4263 	/**
  4548 	/**
  4264 	 * Is the query for an existing single post?
  4549 	 * Determines whether the query is for an existing single post.
  4265 	 *
  4550 	 *
  4266 	 * Works for any post type excluding pages.
  4551 	 * Works for any post type excluding pages.
  4267 	 *
  4552 	 *
  4268 	 * If the $post parameter is specified, this function will additionally
  4553 	 * If the $post parameter is specified, this function will additionally
  4269 	 * check if the query is for one of the Posts specified.
  4554 	 * check if the query is for one of the Posts specified.
  4285 		if ( empty( $post ) ) {
  4570 		if ( empty( $post ) ) {
  4286 			return true;
  4571 			return true;
  4287 		}
  4572 		}
  4288 
  4573 
  4289 		$post_obj = $this->get_queried_object();
  4574 		$post_obj = $this->get_queried_object();
       
  4575 		if ( ! $post_obj ) {
       
  4576 			return false;
       
  4577 		}
  4290 
  4578 
  4291 		$post = array_map( 'strval', (array) $post );
  4579 		$post = array_map( 'strval', (array) $post );
  4292 
  4580 
  4293 		if ( in_array( (string) $post_obj->ID, $post, true ) ) {
  4581 		if ( in_array( (string) $post_obj->ID, $post, true ) ) {
  4294 			return true;
  4582 			return true;
  4310 		}
  4598 		}
  4311 		return false;
  4599 		return false;
  4312 	}
  4600 	}
  4313 
  4601 
  4314 	/**
  4602 	/**
  4315 	 * Is the query for an existing single post of any post type (post, attachment, page,
  4603 	 * Determines whether the query is for an existing single post of any post type
  4316 	 * custom post types)?
  4604 	 * (post, attachment, page, custom post types).
  4317 	 *
  4605 	 *
  4318 	 * If the $post_types parameter is specified, this function will additionally
  4606 	 * If the $post_types parameter is specified, this function will additionally
  4319 	 * check if the query is for one of the Posts Types specified.
  4607 	 * check if the query is for one of the Posts Types specified.
  4320 	 *
  4608 	 *
  4321 	 * @since 3.1.0
  4609 	 * @since 3.1.0
  4332 		if ( empty( $post_types ) || ! $this->is_singular ) {
  4620 		if ( empty( $post_types ) || ! $this->is_singular ) {
  4333 			return (bool) $this->is_singular;
  4621 			return (bool) $this->is_singular;
  4334 		}
  4622 		}
  4335 
  4623 
  4336 		$post_obj = $this->get_queried_object();
  4624 		$post_obj = $this->get_queried_object();
       
  4625 		if ( ! $post_obj ) {
       
  4626 			return false;
       
  4627 		}
  4337 
  4628 
  4338 		return in_array( $post_obj->post_type, (array) $post_types, true );
  4629 		return in_array( $post_obj->post_type, (array) $post_types, true );
  4339 	}
  4630 	}
  4340 
  4631 
  4341 	/**
  4632 	/**
  4342 	 * Is the query for a specific time?
  4633 	 * Determines whether the query is for a specific time.
  4343 	 *
  4634 	 *
  4344 	 * @since 3.1.0
  4635 	 * @since 3.1.0
  4345 	 *
  4636 	 *
  4346 	 * @return bool Whether the query is for a specific time.
  4637 	 * @return bool Whether the query is for a specific time.
  4347 	 */
  4638 	 */
  4348 	public function is_time() {
  4639 	public function is_time() {
  4349 		return (bool) $this->is_time;
  4640 		return (bool) $this->is_time;
  4350 	}
  4641 	}
  4351 
  4642 
  4352 	/**
  4643 	/**
  4353 	 * Is the query for a trackback endpoint call?
  4644 	 * Determines whether the query is for a trackback endpoint call.
  4354 	 *
  4645 	 *
  4355 	 * @since 3.1.0
  4646 	 * @since 3.1.0
  4356 	 *
  4647 	 *
  4357 	 * @return bool Whether the query is for a trackback endpoint call.
  4648 	 * @return bool Whether the query is for a trackback endpoint call.
  4358 	 */
  4649 	 */
  4359 	public function is_trackback() {
  4650 	public function is_trackback() {
  4360 		return (bool) $this->is_trackback;
  4651 		return (bool) $this->is_trackback;
  4361 	}
  4652 	}
  4362 
  4653 
  4363 	/**
  4654 	/**
  4364 	 * Is the query for an existing year archive?
  4655 	 * Determines whether the query is for an existing year archive.
  4365 	 *
  4656 	 *
  4366 	 * @since 3.1.0
  4657 	 * @since 3.1.0
  4367 	 *
  4658 	 *
  4368 	 * @return bool Whether the query is for an existing year archive.
  4659 	 * @return bool Whether the query is for an existing year archive.
  4369 	 */
  4660 	 */
  4370 	public function is_year() {
  4661 	public function is_year() {
  4371 		return (bool) $this->is_year;
  4662 		return (bool) $this->is_year;
  4372 	}
  4663 	}
  4373 
  4664 
  4374 	/**
  4665 	/**
  4375 	 * Is the query a 404 (returns no results)?
  4666 	 * Determines whether the query is a 404 (returns no results).
  4376 	 *
  4667 	 *
  4377 	 * @since 3.1.0
  4668 	 * @since 3.1.0
  4378 	 *
  4669 	 *
  4379 	 * @return bool Whether the query is a 404 error.
  4670 	 * @return bool Whether the query is a 404 error.
  4380 	 */
  4671 	 */
  4381 	public function is_404() {
  4672 	public function is_404() {
  4382 		return (bool) $this->is_404;
  4673 		return (bool) $this->is_404;
  4383 	}
  4674 	}
  4384 
  4675 
  4385 	/**
  4676 	/**
  4386 	 * Is the query for an embedded post?
  4677 	 * Determines whether the query is for an embedded post.
  4387 	 *
  4678 	 *
  4388 	 * @since 4.4.0
  4679 	 * @since 4.4.0
  4389 	 *
  4680 	 *
  4390 	 * @return bool Whether the query is for an embedded post.
  4681 	 * @return bool Whether the query is for an embedded post.
  4391 	 */
  4682 	 */
  4392 	public function is_embed() {
  4683 	public function is_embed() {
  4393 		return (bool) $this->is_embed;
  4684 		return (bool) $this->is_embed;
  4394 	}
  4685 	}
  4395 
  4686 
  4396 	/**
  4687 	/**
  4397 	 * Is the query the main query?
  4688 	 * Determines whether the query is the main query.
  4398 	 *
  4689 	 *
  4399 	 * @since 3.3.0
  4690 	 * @since 3.3.0
  4400 	 *
  4691 	 *
  4401 	 * @global WP_Query $wp_query WordPress Query object.
  4692 	 * @global WP_Query $wp_the_query WordPress Query object.
  4402 	 *
  4693 	 *
  4403 	 * @return bool Whether the query is the main query.
  4694 	 * @return bool Whether the query is the main query.
  4404 	 */
  4695 	 */
  4405 	public function is_main_query() {
  4696 	public function is_main_query() {
  4406 		global $wp_the_query;
  4697 		global $wp_the_query;
  4407 		return $wp_the_query === $this;
  4698 		return $wp_the_query === $this;
  4408 	}
  4699 	}
  4409 
  4700 
  4410 	/**
  4701 	/**
  4411 	 * Set up global post data.
  4702 	 * Sets up global post data.
  4412 	 *
  4703 	 *
  4413 	 * @since 4.1.0
  4704 	 * @since 4.1.0
  4414 	 * @since 4.4.0 Added the ability to pass a post ID to `$post`.
  4705 	 * @since 4.4.0 Added the ability to pass a post ID to `$post`.
  4415 	 *
  4706 	 *
  4416 	 * @global int     $id
  4707 	 * @global int     $id
  4465 
  4756 
  4466 		return true;
  4757 		return true;
  4467 	}
  4758 	}
  4468 
  4759 
  4469 	/**
  4760 	/**
  4470 	 * Generate post data.
  4761 	 * Generates post data.
  4471 	 *
  4762 	 *
  4472 	 * @since 5.2.0
  4763 	 * @since 5.2.0
  4473 	 *
  4764 	 *
  4474 	 * @param WP_Post|object|int $post WP_Post instance or Post ID/object.
  4765 	 * @param WP_Post|object|int $post WP_Post instance or Post ID/object.
  4475 	 * @return array|false Elements of post or false on failure.
  4766 	 * @return array|false Elements of post or false on failure.
  4486 
  4777 
  4487 		$id = (int) $post->ID;
  4778 		$id = (int) $post->ID;
  4488 
  4779 
  4489 		$authordata = get_userdata( $post->post_author );
  4780 		$authordata = get_userdata( $post->post_author );
  4490 
  4781 
  4491 		$currentday   = mysql2date( 'd.m.y', $post->post_date, false );
  4782 		$currentday   = false;
  4492 		$currentmonth = mysql2date( 'm', $post->post_date, false );
  4783 		$currentmonth = false;
  4493 		$numpages     = 1;
  4784 
  4494 		$multipage    = 0;
  4785 		$post_date = $post->post_date;
  4495 		$page         = $this->get( 'page' );
  4786 		if ( ! empty( $post_date ) && '0000-00-00 00:00:00' !== $post_date ) {
       
  4787 			// Avoid using mysql2date for performance reasons.
       
  4788 			$currentmonth = substr( $post_date, 5, 2 );
       
  4789 			$day          = substr( $post_date, 8, 2 );
       
  4790 			$year         = substr( $post_date, 2, 2 );
       
  4791 
       
  4792 			$currentday = sprintf( '%s.%s.%s', $day, $currentmonth, $year );
       
  4793 		}
       
  4794 
       
  4795 		$numpages  = 1;
       
  4796 		$multipage = 0;
       
  4797 		$page      = $this->get( 'page' );
  4496 		if ( ! $page ) {
  4798 		if ( ! $page ) {
  4497 			$page = 1;
  4799 			$page = 1;
  4498 		}
  4800 		}
  4499 
  4801 
  4500 		/*
  4802 		/*
  4508 		} else {
  4810 		} else {
  4509 			$more = 0;
  4811 			$more = 0;
  4510 		}
  4812 		}
  4511 
  4813 
  4512 		$content = $post->post_content;
  4814 		$content = $post->post_content;
  4513 		if ( false !== strpos( $content, '<!--nextpage-->' ) ) {
  4815 		if ( str_contains( $content, '<!--nextpage-->' ) ) {
  4514 			$content = str_replace( "\n<!--nextpage-->\n", '<!--nextpage-->', $content );
  4816 			$content = str_replace( "\n<!--nextpage-->\n", '<!--nextpage-->', $content );
  4515 			$content = str_replace( "\n<!--nextpage-->", '<!--nextpage-->', $content );
  4817 			$content = str_replace( "\n<!--nextpage-->", '<!--nextpage-->', $content );
  4516 			$content = str_replace( "<!--nextpage-->\n", '<!--nextpage-->', $content );
  4818 			$content = str_replace( "<!--nextpage-->\n", '<!--nextpage-->', $content );
  4517 
  4819 
  4518 			// Remove the nextpage block delimiters, to avoid invalid block structures in the split content.
  4820 			// Remove the nextpage block delimiters, to avoid invalid block structures in the split content.
  4519 			$content = str_replace( '<!-- wp:nextpage -->', '', $content );
  4821 			$content = str_replace( '<!-- wp:nextpage -->', '', $content );
  4520 			$content = str_replace( '<!-- /wp:nextpage -->', '', $content );
  4822 			$content = str_replace( '<!-- /wp:nextpage -->', '', $content );
  4521 
  4823 
  4522 			// Ignore nextpage at the beginning of the content.
  4824 			// Ignore nextpage at the beginning of the content.
  4523 			if ( 0 === strpos( $content, '<!--nextpage-->' ) ) {
  4825 			if ( str_starts_with( $content, '<!--nextpage-->' ) ) {
  4524 				$content = substr( $content, 15 );
  4826 				$content = substr( $content, 15 );
  4525 			}
  4827 			}
  4526 
  4828 
  4527 			$pages = explode( '<!--nextpage-->', $content );
  4829 			$pages = explode( '<!--nextpage-->', $content );
  4528 		} else {
  4830 		} else {
  4555 
  4857 
  4556 		$elements = compact( 'id', 'authordata', 'currentday', 'currentmonth', 'page', 'pages', 'multipage', 'more', 'numpages' );
  4858 		$elements = compact( 'id', 'authordata', 'currentday', 'currentmonth', 'page', 'pages', 'multipage', 'more', 'numpages' );
  4557 
  4859 
  4558 		return $elements;
  4860 		return $elements;
  4559 	}
  4861 	}
       
  4862 
       
  4863 	/**
       
  4864 	 * Generates cache key.
       
  4865 	 *
       
  4866 	 * @since 6.1.0
       
  4867 	 *
       
  4868 	 * @global wpdb $wpdb WordPress database abstraction object.
       
  4869 	 *
       
  4870 	 * @param array  $args Query arguments.
       
  4871 	 * @param string $sql  SQL statement.
       
  4872 	 * @return string Cache key.
       
  4873 	 */
       
  4874 	protected function generate_cache_key( array $args, $sql ) {
       
  4875 		global $wpdb;
       
  4876 
       
  4877 		unset(
       
  4878 			$args['cache_results'],
       
  4879 			$args['fields'],
       
  4880 			$args['lazy_load_term_meta'],
       
  4881 			$args['update_post_meta_cache'],
       
  4882 			$args['update_post_term_cache'],
       
  4883 			$args['update_menu_item_cache'],
       
  4884 			$args['suppress_filters']
       
  4885 		);
       
  4886 
       
  4887 		if ( empty( $args['post_type'] ) ) {
       
  4888 			if ( $this->is_attachment ) {
       
  4889 				$args['post_type'] = 'attachment';
       
  4890 			} elseif ( $this->is_page ) {
       
  4891 				$args['post_type'] = 'page';
       
  4892 			} else {
       
  4893 				$args['post_type'] = 'post';
       
  4894 			}
       
  4895 		} elseif ( 'any' === $args['post_type'] ) {
       
  4896 			$args['post_type'] = array_values( get_post_types( array( 'exclude_from_search' => false ) ) );
       
  4897 		}
       
  4898 		$args['post_type'] = (array) $args['post_type'];
       
  4899 		// Sort post types to ensure same cache key generation.
       
  4900 		sort( $args['post_type'] );
       
  4901 
       
  4902 		if ( isset( $args['post_status'] ) ) {
       
  4903 			$args['post_status'] = (array) $args['post_status'];
       
  4904 			// Sort post status to ensure same cache key generation.
       
  4905 			sort( $args['post_status'] );
       
  4906 		}
       
  4907 
       
  4908 		// Add a default orderby value of date to ensure same cache key generation.
       
  4909 		if ( ! isset( $q['orderby'] ) ) {
       
  4910 			$args['orderby'] = 'date';
       
  4911 		}
       
  4912 
       
  4913 		$placeholder = $wpdb->placeholder_escape();
       
  4914 		array_walk_recursive(
       
  4915 			$args,
       
  4916 			/*
       
  4917 			 * Replace wpdb placeholders with the string used in the database
       
  4918 			 * query to avoid unreachable cache keys. This is necessary because
       
  4919 			 * the placeholder is randomly generated in each request.
       
  4920 			 *
       
  4921 			 * $value is passed by reference to allow it to be modified.
       
  4922 			 * array_walk_recursive() does not return an array.
       
  4923 			 */
       
  4924 			static function ( &$value ) use ( $wpdb, $placeholder ) {
       
  4925 				if ( is_string( $value ) && str_contains( $value, $placeholder ) ) {
       
  4926 					$value = $wpdb->remove_placeholder_escape( $value );
       
  4927 				}
       
  4928 			}
       
  4929 		);
       
  4930 
       
  4931 		ksort( $args );
       
  4932 
       
  4933 		// Replace wpdb placeholder in the SQL statement used by the cache key.
       
  4934 		$sql = $wpdb->remove_placeholder_escape( $sql );
       
  4935 		$key = md5( serialize( $args ) . $sql );
       
  4936 
       
  4937 		$last_changed = wp_cache_get_last_changed( 'posts' );
       
  4938 		if ( ! empty( $this->tax_query->queries ) ) {
       
  4939 			$last_changed .= wp_cache_get_last_changed( 'terms' );
       
  4940 		}
       
  4941 
       
  4942 		return "wp_query:$key:$last_changed";
       
  4943 	}
       
  4944 
  4560 	/**
  4945 	/**
  4561 	 * After looping through a nested query, this function
  4946 	 * After looping through a nested query, this function
  4562 	 * restores the $post global to the current post in this query.
  4947 	 * restores the $post global to the current post in this query.
  4563 	 *
  4948 	 *
  4564 	 * @since 3.7.0
  4949 	 * @since 3.7.0
  4571 			$this->setup_postdata( $this->post );
  4956 			$this->setup_postdata( $this->post );
  4572 		}
  4957 		}
  4573 	}
  4958 	}
  4574 
  4959 
  4575 	/**
  4960 	/**
  4576 	 * Lazyload term meta for posts in the loop.
  4961 	 * Lazyloads term meta for posts in the loop.
  4577 	 *
  4962 	 *
  4578 	 * @since 4.4.0
  4963 	 * @since 4.4.0
  4579 	 * @deprecated 4.5.0 See wp_queue_posts_for_term_meta_lazyload().
  4964 	 * @deprecated 4.5.0 See wp_queue_posts_for_term_meta_lazyload().
  4580 	 *
  4965 	 *
  4581 	 * @param mixed $check
  4966 	 * @param mixed $check
  4586 		_deprecated_function( __METHOD__, '4.5.0' );
  4971 		_deprecated_function( __METHOD__, '4.5.0' );
  4587 		return $check;
  4972 		return $check;
  4588 	}
  4973 	}
  4589 
  4974 
  4590 	/**
  4975 	/**
  4591 	 * Lazyload comment meta for comments in the loop.
  4976 	 * Lazyloads comment meta for comments in the loop.
  4592 	 *
  4977 	 *
  4593 	 * @since 4.4.0
  4978 	 * @since 4.4.0
  4594 	 * @deprecated 4.5.0 See wp_queue_comments_for_comment_meta_lazyload().
  4979 	 * @deprecated 4.5.0 See wp_lazyload_comment_meta().
  4595 	 *
  4980 	 *
  4596 	 * @param mixed $check
  4981 	 * @param mixed $check
  4597 	 * @param int   $comment_id
  4982 	 * @param int   $comment_id
  4598 	 * @return mixed
  4983 	 * @return mixed
  4599 	 */
  4984 	 */