<?php
/**
* Query API: WP_Query class
*
* @package WordPress
* @subpackage Query
* @since 4.7.0
*/
/**
* The WordPress Query class.
*
* @link https://developer.wordpress.org/reference/classes/wp_query/
*
* @since 1.5.0
* @since 4.5.0 Removed the `$comments_popup` property.
*/
#[AllowDynamicProperties]
class WP_Query {
/**
* Query vars set by the user.
*
* @since 1.5.0
* @var array
*/
public $query;
/**
* Query vars, after parsing.
*
* @since 1.5.0
* @var array
*/
public $query_vars = array();
/**
* Taxonomy query, as passed to get_tax_sql().
*
* @since 3.1.0
* @var WP_Tax_Query|null A taxonomy query instance.
*/
public $tax_query;
/**
* Metadata query container.
*
* @since 3.2.0
* @var WP_Meta_Query A meta query instance.
*/
public $meta_query = false;
/**
* Date query container.
*
* @since 3.7.0
* @var WP_Date_Query A date query instance.
*/
public $date_query = false;
/**
* Holds the data for a single object that is queried.
*
* Holds the contents of a post, page, category, attachment.
*
* @since 1.5.0
* @var WP_Term|WP_Post_Type|WP_Post|WP_User|null
*/
public $queried_object;
/**
* The ID of the queried object.
*
* @since 1.5.0
* @var int
*/
public $queried_object_id;
/**
* SQL for the database query.
*
* @since 2.0.1
* @var string
*/
public $request;
/**
* Array of post objects or post IDs.
*
* @since 1.5.0
* @var WP_Post[]|int[]
*/
public $posts;
/**
* The number of posts for the current query.
*
* @since 1.5.0
* @var int
*/
public $post_count = 0;
/**
* Index of the current item in the loop.
*
* @since 1.5.0
* @var int
*/
public $current_post = -1;
/**
* Whether the caller is before the loop.
*
* @since 6.3.0
* @var bool
*/
public $before_loop = true;
/**
* Whether the loop has started and the caller is in the loop.
*
* @since 2.0.0
* @var bool
*/
public $in_the_loop = false;
/**
* The current post.
*
* This property does not get populated when the `fields` argument is set to
* `ids` or `id=>parent`.
*
* @since 1.5.0
* @var WP_Post|null
*/
public $post;
/**
* The list of comments for current post.
*
* @since 2.2.0
* @var WP_Comment[]
*/
public $comments;
/**
* The number of comments for the posts.
*
* @since 2.2.0
* @var int
*/
public $comment_count = 0;
/**
* The index of the comment in the comment loop.
*
* @since 2.2.0
* @var int
*/
public $current_comment = -1;
/**
* Current comment object.
*
* @since 2.2.0
* @var WP_Comment
*/
public $comment;
/**
* The number of found posts for the current query.
*
* If limit clause was not used, equals $post_count.
*
* @since 2.1.0
* @var int
*/
public $found_posts = 0;
/**
* The number of pages.
*
* @since 2.1.0
* @var int
*/
public $max_num_pages = 0;
/**
* The number of comment pages.
*
* @since 2.7.0
* @var int
*/
public $max_num_comment_pages = 0;
/**
* Signifies whether the current query is for a single post.
*
* @since 1.5.0
* @var bool
*/
public $is_single = false;
/**
* Signifies whether the current query is for a preview.
*
* @since 2.0.0
* @var bool
*/
public $is_preview = false;
/**
* Signifies whether the current query is for a page.
*
* @since 1.5.0
* @var bool
*/
public $is_page = false;
/**
* Signifies whether the current query is for an archive.
*
* @since 1.5.0
* @var bool
*/
public $is_archive = false;
/**
* Signifies whether the current query is for a date archive.
*
* @since 1.5.0
* @var bool
*/
public $is_date = false;
/**
* Signifies whether the current query is for a year archive.
*
* @since 1.5.0
* @var bool
*/
public $is_year = false;
/**
* Signifies whether the current query is for a month archive.
*
* @since 1.5.0
* @var bool
*/
public $is_month = false;
/**
* Signifies whether the current query is for a day archive.
*
* @since 1.5.0
* @var bool
*/
public $is_day = false;
/**
* Signifies whether the current query is for a specific time.
*
* @since 1.5.0
* @var bool
*/
public $is_time = false;
/**
* Signifies whether the current query is for an author archive.
*
* @since 1.5.0
* @var bool
*/
public $is_author = false;
/**
* Signifies whether the current query is for a category archive.
*
* @since 1.5.0
* @var bool
*/
public $is_category = false;
/**
* Signifies whether the current query is for a tag archive.
*
* @since 2.3.0
* @var bool
*/
public $is_tag = false;
/**
* Signifies whether the current query is for a taxonomy archive.
*
* @since 2.5.0
* @var bool
*/
public $is_tax = false;
/**
* Signifies whether the current query is for a search.
*
* @since 1.5.0
* @var bool
*/
public $is_search = false;
/**
* Signifies whether the current query is for a feed.
*
* @since 1.5.0
* @var bool
*/
public $is_feed = false;
/**
* Signifies whether the current query is for a comment feed.
*
* @since 2.2.0
* @var bool
*/
public $is_comment_feed = false;
/**
* Signifies whether the current query is for trackback endpoint call.
*
* @since 1.5.0
* @var bool
*/
public $is_trackback = false;
/**
* Signifies whether the current query is for the site homepage.
*
* @since 1.5.0
* @var bool
*/
public $is_home = false;
/**
* Signifies whether the current query is for the Privacy Policy page.
*
* @since 5.2.0
* @var bool
*/
public $is_privacy_policy = false;
/**
* Signifies whether the current query couldn't find anything.
*
* @since 1.5.0
* @var bool
*/
public $is_404 = false;
/**
* Signifies whether the current query is for an embed.
*
* @since 4.4.0
* @var bool
*/
public $is_embed = false;
/**
* Signifies whether the current query is for a paged result and not for the first page.
*
* @since 1.5.0
* @var bool
*/
public $is_paged = false;
/**
* Signifies whether the current query is for an administrative interface page.
*
* @since 1.5.0
* @var bool
*/
public $is_admin = false;
/**
* Signifies whether the current query is for an attachment page.
*
* @since 2.0.0
* @var bool
*/
public $is_attachment = false;
/**
* Signifies whether the current query is for an existing single post of any post type
* (post, attachment, page, custom post types).
*
* @since 2.1.0
* @var bool
*/
public $is_singular = false;
/**
* Signifies whether the current query is for the robots.txt file.
*
* @since 2.1.0
* @var bool
*/
public $is_robots = false;
/**
* Signifies whether the current query is for the favicon.ico file.
*
* @since 5.4.0
* @var bool
*/
public $is_favicon = false;
/**
* Signifies whether the current query is for the page_for_posts page.
*
* Basically, the homepage if the option isn't set for the static homepage.
*
* @since 2.1.0
* @var bool
*/
public $is_posts_page = false;
/**
* Signifies whether the current query is for a post type archive.
*
* @since 3.1.0
* @var bool
*/
public $is_post_type_archive = false;
/**
* Stores the ->query_vars state like md5(serialize( $this->query_vars ) ) so we know
* whether we have to re-parse because something has changed
*
* @since 3.1.0
* @var bool|string
*/
private $query_vars_hash = false;
/**
* Whether query vars have changed since the initial parse_query() call. Used to catch modifications to query vars made
* via pre_get_posts hooks.
*
* @since 3.1.1
*/
private $query_vars_changed = true;
/**
* Set if post thumbnails are cached
*
* @since 3.2.0
* @var bool
*/
public $thumbnails_cached = false;
/**
* Controls whether an attachment query should include filenames or not.
*
* @since 6.0.3
* @var bool
*/
protected $allow_query_attachment_by_filename = false;
/**
* Cached list of search stopwords.
*
* @since 3.7.0
* @var array
*/
private $stopwords;
private $compat_fields = array( 'query_vars_hash', 'query_vars_changed' );
private $compat_methods = array( 'init_query_flags', 'parse_tax_query' );
/**
* Resets query flags to false.
*
* The query flags are what page info WordPress was able to figure out.
*
* @since 2.0.0
*/
private function init_query_flags() {
$this->is_single = false;
$this->is_preview = false;
$this->is_page = false;
$this->is_archive = false;
$this->is_date = false;
$this->is_year = false;
$this->is_month = false;
$this->is_day = false;
$this->is_time = false;
$this->is_author = false;
$this->is_category = false;
$this->is_tag = false;
$this->is_tax = false;
$this->is_search = false;
$this->is_feed = false;
$this->is_comment_feed = false;
$this->is_trackback = false;
$this->is_home = false;
$this->is_privacy_policy = false;
$this->is_404 = false;
$this->is_paged = false;
$this->is_admin = false;
$this->is_attachment = false;
$this->is_singular = false;
$this->is_robots = false;
$this->is_favicon = false;
$this->is_posts_page = false;
$this->is_post_type_archive = false;
}
/**
* Initiates object properties and sets default values.
*
* @since 1.5.0
*/
public function init() {
unset( $this->posts );
unset( $this->query );
$this->query_vars = array();
unset( $this->queried_object );
unset( $this->queried_object_id );
$this->post_count = 0;
$this->current_post = -1;
$this->in_the_loop = false;
$this->before_loop = true;
unset( $this->request );
unset( $this->post );
unset( $this->comments );
unset( $this->comment );
$this->comment_count = 0;
$this->current_comment = -1;
$this->found_posts = 0;
$this->max_num_pages = 0;
$this->max_num_comment_pages = 0;
$this->init_query_flags();
}
/**
* Reparses the query vars.
*
* @since 1.5.0
*/
public function parse_query_vars() {
$this->parse_query();
}
/**
* Fills in the query variables, which do not exist within the parameter.
*
* @since 2.1.0
* @since 4.5.0 Removed the `comments_popup` public query variable.
*
* @param array $query_vars Defined query variables.
* @return array Complete query variables with undefined ones filled in empty.
*/
public function fill_query_vars( $query_vars ) {
$keys = array(
'error',
'm',
'p',
'post_parent',
'subpost',
'subpost_id',
'attachment',
'attachment_id',
'name',
'pagename',
'page_id',
'second',
'minute',
'hour',
'day',
'monthnum',
'year',
'w',
'category_name',
'tag',
'cat',
'tag_id',
'author',
'author_name',
'feed',
'tb',
'paged',
'meta_key',
'meta_value',
'preview',
's',
'sentence',
'title',
'fields',
'menu_order',
'embed',
);
foreach ( $keys as $key ) {
if ( ! isset( $query_vars[ $key ] ) ) {
$query_vars[ $key ] = '';
}
}
$array_keys = array(
'category__in',
'category__not_in',
'category__and',
'post__in',
'post__not_in',
'post_name__in',
'tag__in',
'tag__not_in',
'tag__and',
'tag_slug__in',
'tag_slug__and',
'post_parent__in',
'post_parent__not_in',
'author__in',
'author__not_in',
'search_columns',
);
foreach ( $array_keys as $key ) {
if ( ! isset( $query_vars[ $key ] ) ) {
$query_vars[ $key ] = array();
}
}
return $query_vars;
}
/**
* Parses a query string and sets query type booleans.
*
* @since 1.5.0
* @since 4.2.0 Introduced the ability to order by specific clauses of a `$meta_query`, by passing the clause's
* array key to `$orderby`.
* @since 4.4.0 Introduced `$post_name__in` and `$title` parameters. `$s` was updated to support excluded
* search terms, by prepending a hyphen.
* @since 4.5.0 Removed the `$comments_popup` parameter.
* Introduced the `$comment_status` and `$ping_status` parameters.
* Introduced `RAND(x)` syntax for `$orderby`, which allows an integer seed value to random sorts.
* @since 4.6.0 Added 'post_name__in' support for `$orderby`. Introduced the `$lazy_load_term_meta` argument.
* @since 4.9.0 Introduced the `$comment_count` parameter.
* @since 5.1.0 Introduced the `$meta_compare_key` parameter.
* @since 5.3.0 Introduced the `$meta_type_key` parameter.
* @since 6.1.0 Introduced the `$update_menu_item_cache` parameter.
* @since 6.2.0 Introduced the `$search_columns` parameter.
*
* @param string|array $query {
* Optional. Array or string of Query parameters.
*
* @type int $attachment_id Attachment post ID. Used for 'attachment' post_type.
* @type int|string $author Author ID, or comma-separated list of IDs.
* @type string $author_name User 'user_nicename'.
* @type int[] $author__in An array of author IDs to query from.
* @type int[] $author__not_in An array of author IDs not to query from.
* @type bool $cache_results Whether to cache post information. Default true.
* @type int|string $cat Category ID or comma-separated list of IDs (this or any children).
* @type int[] $category__and An array of category IDs (AND in).
* @type int[] $category__in An array of category IDs (OR in, no children).
* @type int[] $category__not_in An array of category IDs (NOT in).
* @type string $category_name Use category slug (not name, this or any children).
* @type array|int $comment_count Filter results by comment count. Provide an integer to match
* comment count exactly. Provide an array with integer 'value'
* and 'compare' operator ('=', '!=', '>', '>=', '<', '<=' ) to
* compare against comment_count in a specific way.
* @type string $comment_status Comment status.
* @type int $comments_per_page The number of comments to return per page.
* Default 'comments_per_page' option.
* @type array $date_query An associative array of WP_Date_Query arguments.
* See WP_Date_Query::__construct().
* @type int $day Day of the month. Default empty. Accepts numbers 1-31.
* @type bool $exact Whether to search by exact keyword. Default false.
* @type string $fields Post fields to query for. Accepts:
* - '' Returns an array of complete post objects (`WP_Post[]`).
* - 'ids' Returns an array of post IDs (`int[]`).
* - 'id=>parent' Returns an associative array of parent post IDs,
* keyed by post ID (`int[]`).
* Default ''.
* @type int $hour Hour of the day. Default empty. Accepts numbers 0-23.
* @type int|bool $ignore_sticky_posts Whether to ignore sticky posts or not. Setting this to false
* excludes stickies from 'post__in'. Accepts 1|true, 0|false.
* Default false.
* @type int $m Combination YearMonth. Accepts any four-digit year and month
* numbers 01-12. Default empty.
*