run:R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
23.8 KB
2026-03-11 16:18:51
R W Run
7.8 KB
2026-03-11 16:18:52
R W Run
36.1 KB
2026-03-11 16:18:51
R W Run
11.9 KB
2026-03-11 16:18:52
R W Run
18.94 KB
2026-03-11 16:18:52
R W Run
7.35 KB
2026-03-11 16:18:52
R W Run
28.6 KB
2026-03-11 16:18:51
R W Run
316 By
2026-03-11 16:18:51
R W Run
12.9 KB
2026-03-11 16:18:51
R W Run
61.02 KB
2026-03-11 16:18:52
R W Run
15 KB
2026-03-11 16:18:51
R W Run
112.05 KB
2026-03-11 16:18:51
R W Run
12.47 KB
2026-03-11 16:18:51
R W Run
15.07 KB
2026-03-11 16:18:52
R W Run
9.84 KB
2026-03-11 16:18:52
R W Run
13.17 KB
2026-03-11 16:18:52
R W Run
33.83 KB
2026-03-11 16:18:51
R W Run
42.63 KB
2026-03-11 16:18:51
R W Run
55.71 KB
2026-03-11 16:18:52
R W Run
12.53 KB
2026-03-11 16:18:51
R W Run
2.55 KB
2026-03-11 16:18:52
R W Run
28.92 KB
2026-03-11 16:18:52
R W Run
539 By
2026-03-11 16:18:51
R W Run
367 By
2026-03-11 16:18:52
R W Run
42.65 KB
2026-03-11 16:18:51
R W Run
401 By
2026-03-11 16:18:51
R W Run
6.61 KB
2026-03-11 16:18:51
R W Run
664 By
2026-03-11 16:18:52
R W Run
20.63 KB
2026-03-11 16:18:51
R W Run
2.18 KB
2026-03-11 16:18:52
R W Run
453 By
2026-03-11 16:18:52
R W Run
457 By
2026-03-11 16:18:51
R W Run
36.83 KB
2026-03-11 16:18:52
R W Run
2.41 KB
2026-03-11 16:18:52
R W Run
8.28 KB
2026-03-11 16:18:51
R W Run
13.89 KB
2026-03-11 16:18:51
R W Run
11.76 KB
2026-03-11 16:18:51
R W Run
2.65 KB
2026-03-11 16:18:51
R W Run
7.43 KB
2026-03-11 16:18:51
R W Run
17.46 KB
2026-03-11 16:18:51
R W Run
5.14 KB
2026-03-11 16:18:52
R W Run
16.7 KB
2026-03-11 16:18:51
R W Run
8.28 KB
2026-03-11 16:18:52
R W Run
2.92 KB
2026-03-11 16:18:52
R W Run
1.32 KB
2026-03-11 16:18:51
R W Run
4.6 KB
2026-03-11 16:18:52
R W Run
11.62 KB
2026-03-11 16:18:52
R W Run
2.5 KB
2026-03-11 16:18:51
R W Run
1.97 KB
2026-03-11 16:18:51
R W Run
11.25 KB
2026-03-11 16:18:52
R W Run
5.32 KB
2026-03-11 16:18:51
R W Run
10.99 KB
2026-03-11 16:18:52
R W Run
68.32 KB
2026-03-11 16:18:51
R W Run
6.34 KB
2026-03-11 16:18:51
R W Run
5.49 KB
2026-03-11 16:18:51
R W Run
1.99 KB
2026-03-11 16:18:52
R W Run
7.02 KB
2026-03-11 16:18:51
R W Run
4.91 KB
2026-03-11 16:18:52
R W Run
16.86 KB
2026-03-11 16:18:51
R W Run
24.23 KB
2026-03-11 16:18:51
R W Run
3.97 KB
2026-03-11 16:18:51
R W Run
47.66 KB
2026-03-11 16:18:51
R W Run
9.22 KB
2026-03-11 16:18:51
R W Run
25.51 KB
2026-03-11 16:18:51
R W Run
198.38 KB
2026-03-11 16:18:52
R W Run
56.65 KB
2026-03-11 16:18:51
R W Run
10.46 KB
2026-03-11 16:18:51
R W Run
10.95 KB
2026-03-11 16:18:52
R W Run
29.26 KB
2026-03-11 16:18:51
R W Run
70.91 KB
2026-03-11 16:18:52
R W Run
35.3 KB
2026-03-11 16:18:52
R W Run
16.61 KB
2026-03-11 16:18:52
R W Run
2.57 KB
2026-03-11 16:18:52
R W Run
39.83 KB
2026-03-11 16:18:51
R W Run
70.64 KB
2026-03-11 16:18:51
R W Run
15.56 KB
2026-03-11 16:18:52
R W Run
7.33 KB
2026-03-11 16:18:52
R W Run
253 By
2026-03-11 16:18:51
R W Run
7.96 KB
2026-03-11 16:18:52
R W Run
3.23 KB
2026-03-11 16:18:52
R W Run
969 By
2026-03-11 16:18:52
R W Run
16.28 KB
2026-03-11 16:18:51
R W Run
7.22 KB
2026-03-11 16:18:51
R W Run
12.95 KB
2026-03-11 16:18:51
R W Run
6.53 KB
2026-03-11 16:18:51
R W Run
3.42 KB
2026-03-11 16:18:52
R W Run
5.84 KB
2026-03-11 16:18:51
R W Run
1.97 KB
2026-03-11 16:18:51
R W Run
4.3 KB
2026-03-11 16:18:52
R W Run
2.91 KB
2026-03-11 16:18:51
R W Run
16.46 KB
2026-03-11 16:18:52
R W Run
40.6 KB
2026-03-11 16:18:51
R W Run
20.22 KB
2026-03-11 16:18:51
R W Run
36.11 KB
2026-03-11 16:18:52
R W Run
17.01 KB
2026-03-11 16:18:51
R W Run
7.27 KB
2026-03-11 16:18:52
R W Run
6.62 KB
2026-03-11 16:18:52
R W Run
16.49 KB
2026-03-11 16:18:52
R W Run
1.79 KB
2026-03-11 16:18:52
R W Run
29.82 KB
2026-03-11 16:18:51
R W Run
6.67 KB
2026-03-11 16:18:52
R W Run
8.98 KB
2026-03-11 16:18:52
R W Run
19.42 KB
2026-03-11 16:18:51
R W Run
12.01 KB
2026-03-11 16:18:51
R W Run
17.11 KB
2026-03-11 16:18:51
R W Run
6.74 KB
2026-03-11 16:18:52
R W Run
30.93 KB
2026-03-11 16:18:51
R W Run
4.99 KB
2026-03-11 16:18:51
R W Run
4.25 KB
2026-03-11 16:18:51
R W Run
24.72 KB
2026-03-11 16:18:51
R W Run
29.96 KB
2026-03-11 16:18:52
R W Run
6.41 KB
2026-03-11 16:18:51
R W Run
160 KB
2026-03-11 16:18:51
R W Run
6.72 KB
2026-03-11 16:18:52
R W Run
10.92 KB
2026-03-11 16:18:51
R W Run
4.77 KB
2026-03-11 16:18:51
R W Run
3.38 KB
2026-03-11 16:18:51
R W Run
11.18 KB
2026-03-11 16:18:51
R W Run
62.19 KB
2026-03-11 16:18:51
R W Run
2.46 KB
2026-03-11 16:18:51
R W Run
9.17 KB
2026-03-11 16:18:51
R W Run
32.15 KB
2026-03-11 16:18:51
R W Run
34.05 KB
2026-03-11 16:18:52
R W Run
7.15 KB
2026-03-11 16:18:51
R W Run
3.47 KB
2026-03-11 16:18:52
R W Run
1.87 KB
2026-03-11 16:18:52
R W Run
30.91 KB
2026-03-11 16:18:51
R W Run
7.29 KB
2026-03-11 16:18:52
R W Run
7.35 KB
2026-03-11 16:18:51
R W Run
12.54 KB
2026-03-11 16:18:51
R W Run
19.12 KB
2026-03-11 16:18:51
R W Run
18.12 KB
2026-03-11 16:18:52
R W Run
39.99 KB
2026-03-11 16:18:52
R W Run
5.17 KB
2026-03-11 16:18:52
R W Run
979 By
2026-03-11 16:18:51
R W Run
18.44 KB
2026-03-11 16:18:52
R W Run
10.24 KB
2026-03-11 16:18:51
R W Run
1.77 KB
2026-03-11 16:18:52
R W Run
34.9 KB
2026-03-11 16:18:51
R W Run
7.19 KB
2026-03-11 16:18:52
R W Run
160.5 KB
2026-03-11 16:18:51
R W Run
64.27 KB
2026-03-11 16:18:51
R W Run
27.95 KB
2026-03-11 16:18:51
R W Run
4.69 KB
2026-03-11 16:18:51
R W Run
2.94 KB
2026-03-11 16:18:51
R W Run
43.13 KB
2026-03-11 16:18:52
R W Run
2.25 KB
2026-03-11 16:18:52
R W Run
22.5 KB
2026-03-11 16:18:51
R W Run
13.01 KB
2026-03-11 16:18:52
R W Run
3.27 KB
2026-03-11 16:18:51
R W Run
18 KB
2026-03-11 16:18:51
R W Run
210.4 KB
2026-03-11 16:18:52
R W Run
25.86 KB
2026-03-11 16:18:52
R W Run
115.85 KB
2026-03-11 16:18:51
R W Run
373 By
2026-03-11 16:18:52
R W Run
343 By
2026-03-11 16:18:52
R W Run
338 By
2026-03-11 16:18:51
R W Run
100.73 KB
2026-03-11 16:18:52
R W Run
130.93 KB
2026-03-11 16:18:51
R W Run
19.1 KB
2026-03-11 16:18:51
R W Run
17.41 KB
2026-03-11 16:18:52
R W Run
41.98 KB
2026-03-11 16:18:52
R W Run
400 By
2026-03-11 16:18:52
R W Run
11.1 KB
2026-03-11 16:18:52
R W Run
37.02 KB
2026-03-11 16:18:51
R W Run
2.24 KB
2026-03-11 16:18:51
R W Run
188.13 KB
2026-03-11 16:18:51
R W Run
338 By
2026-03-11 16:18:51
R W Run
38 KB
2026-03-11 16:18:51
R W Run
4.02 KB
2026-03-11 16:18:52
R W Run
5.38 KB
2026-03-11 16:18:51
R W Run
3.05 KB
2026-03-11 16:18:52
R W Run
2.61 KB
2026-03-11 16:18:51
R W Run
1.16 KB
2026-03-11 16:18:52
R W Run
4.04 KB
2026-03-11 16:18:51
R W Run
3.71 KB
2026-03-11 16:18:51
R W Run
24.6 KB
2026-03-11 16:18:51
R W Run
9.56 KB
2026-03-11 16:18:51
R W Run
346.43 KB
2026-03-11 16:18:52
R W Run
281.84 KB
2026-03-11 16:18:52
R W Run
14.95 KB
2026-03-11 16:18:51
R W Run
8.44 KB
2026-03-11 16:18:52
R W Run
168.95 KB
2026-03-11 16:18:52
R W Run
20.71 KB
2026-03-11 16:18:52
R W Run
25.27 KB
2026-03-11 16:18:51
R W Run
5.72 KB
2026-03-11 16:18:51
R W Run
4.63 KB
2026-03-11 16:18:52
R W Run
81.73 KB
2026-03-11 16:18:51
R W Run
67.18 KB
2026-03-11 16:18:51
R W Run
156.36 KB
2026-03-11 16:18:52
R W Run
55.19 KB
2026-03-11 16:18:51
R W Run
162 By
2026-03-11 16:18:51
R W Run
61.72 KB
2026-03-11 16:18:51
R W Run
216.06 KB
2026-03-11 16:18:52
R W Run
65.09 KB
2026-03-11 16:18:51
R W Run
25.24 KB
2026-03-11 16:18:52
R W Run
4.81 KB
2026-03-11 16:18:51
R W Run
6.48 KB
2026-03-11 16:18:52
R W Run
21.25 KB
2026-03-11 16:18:51
R W Run
2.79 KB
2026-03-11 16:18:52
R W Run
89.69 KB
2026-03-11 16:18:52
R W Run
19.42 KB
2026-03-11 16:18:52
R W Run
3.69 KB
2026-03-11 16:18:52
R W Run
4.11 KB
2026-03-11 16:18:51
R W Run
40.74 KB
2026-03-11 16:18:51
R W Run
25.38 KB
2026-03-11 16:18:51
R W Run
43.31 KB
2026-03-11 16:18:52
R W Run
102.57 KB
2026-03-11 16:18:52
R W Run
6.18 KB
2026-03-11 16:18:51
R W Run
124.47 KB
2026-03-11 16:18:52
R W Run
35.65 KB
2026-03-11 16:18:52
R W Run
6.94 KB
2026-03-11 16:18:52
R W Run
67.04 KB
2026-03-11 16:18:52
R W Run
10.62 KB
2026-03-11 16:18:51
R W Run
289.35 KB
2026-03-11 16:18:52
R W Run
36.23 KB
2026-03-11 16:18:51
R W Run
200 By
2026-03-11 16:18:52
R W Run
200 By
2026-03-11 16:18:52
R W Run
98.29 KB
2026-03-11 16:18:52
R W Run
30.02 KB
2026-03-11 16:18:52
R W Run
19.03 KB
2026-03-11 16:18:52
R W Run
5.06 KB
2026-03-11 16:18:52
R W Run
255 By
2026-03-11 16:18:51
R W Run
22.66 KB
2026-03-11 16:18:52
R W Run
154.63 KB
2026-03-11 16:18:51
R W Run
9.68 KB
2026-03-11 16:18:51
R W Run
258 By
2026-03-11 16:18:51
R W Run
23.49 KB
2026-03-11 16:18:51
R W Run
3.16 KB
2026-03-11 16:18:51
R W Run
8.4 KB
2026-03-11 16:18:52
R W Run
441 By
2026-03-11 16:18:51
R W Run
7.39 KB
2026-03-11 16:18:51
R W Run
173 KB
2026-03-11 16:18:52
R W Run
544 By
2026-03-11 16:18:52
R W Run
4.17 KB
2026-03-11 16:18:51
R W Run
35.97 KB
2026-03-11 16:18:52
R W Run
1.69 KB
2026-03-11 16:18:51
R W Run
2.84 KB
2026-03-11 16:18:52
R W Run
6.09 KB
2026-03-11 16:18:51
R W Run
8.71 KB
2026-03-11 16:18:51
R W Run
131.84 KB
2026-03-11 16:18:51
R W Run
37.45 KB
2026-03-11 16:18:51
R W Run
173.89 KB
2026-03-11 16:18:51
R W Run
7.09 KB
2026-03-11 16:18:51
R W Run
6.41 KB
2026-03-11 16:18:51
R W Run
1.08 KB
2026-03-11 16:18:51
R W Run
69.46 KB
2026-03-11 16:18:52
R W Run
445 By
2026-03-11 16:18:51
R W Run
799 By
2026-03-11 16:18:52
R W Run
error_log
📄class-wp-comment-query.php
1<?php
2/**
3 * Comment API: WP_Comment_Query class
4 *
5 * @package WordPress
6 * @subpackage Comments
7 * @since 4.4.0
8 */
9
10/**
11 * Core class used for querying comments.
12 *
13 * @since 3.1.0
14 *
15 * @see WP_Comment_Query::__construct() for accepted arguments.
16 */
17#[AllowDynamicProperties]
18class WP_Comment_Query {
19
20 /**
21 * SQL for database query.
22 *
23 * @since 4.0.1
24 * @var string
25 */
26 public $request;
27
28 /**
29 * Metadata query container
30 *
31 * @since 3.5.0
32 * @var WP_Meta_Query A meta query instance.
33 */
34 public $meta_query = false;
35
36 /**
37 * Metadata query clauses.
38 *
39 * @since 4.4.0
40 * @var array
41 */
42 protected $meta_query_clauses;
43
44 /**
45 * SQL query clauses.
46 *
47 * @since 4.4.0
48 * @var array
49 */
50 protected $sql_clauses = array(
51 'select' => '',
52 'from' => '',
53 'where' => array(),
54 'groupby' => '',
55 'orderby' => '',
56 'limits' => '',
57 );
58
59 /**
60 * SQL WHERE clause.
61 *
62 * Stored after the {@see 'comments_clauses'} filter is run on the compiled WHERE sub-clauses.
63 *
64 * @since 4.4.2
65 * @var string
66 */
67 protected $filtered_where_clause;
68
69 /**
70 * Date query container
71 *
72 * @since 3.7.0
73 * @var WP_Date_Query A date query instance.
74 */
75 public $date_query = false;
76
77 /**
78 * Query vars set by the user.
79 *
80 * @since 3.1.0
81 * @var array
82 */
83 public $query_vars;
84
85 /**
86 * Default values for query vars.
87 *
88 * @since 4.2.0
89 * @var array
90 */
91 public $query_var_defaults;
92
93 /**
94 * List of comments located by the query.
95 *
96 * @since 4.0.0
97 * @var int[]|WP_Comment[]
98 */
99 public $comments;
100
101 /**
102 * The amount of found comments for the current query.
103 *
104 * @since 4.4.0
105 * @var int
106 */
107 public $found_comments = 0;
108
109 /**
110 * The number of pages.
111 *
112 * @since 4.4.0
113 * @var int
114 */
115 public $max_num_pages = 0;
116
117 /**
118 * Make private/protected methods readable for backward compatibility.
119 *
120 * @since 4.0.0
121 *
122 * @param string $name Method to call.
123 * @param array $arguments Arguments to pass when calling.
124 * @return mixed|false Return value of the callback, false otherwise.
125 */
126 public function __call( $name, $arguments ) {
127 if ( 'get_search_sql' === $name ) {
128 return $this->get_search_sql( ...$arguments );
129 }
130 return false;
131 }
132
133 /**
134 * Constructor.
135 *
136 * Sets up the comment query, based on the query vars passed.
137 *
138 * @since 4.2.0
139 * @since 4.4.0 `$parent__in` and `$parent__not_in` were added.
140 * @since 4.4.0 Order by `comment__in` was added. `$update_comment_meta_cache`, `$no_found_rows`,
141 * `$hierarchical`, and `$update_comment_post_cache` were added.
142 * @since 4.5.0 Introduced the `$author_url` argument.
143 * @since 4.6.0 Introduced the `$cache_domain` argument.
144 * @since 4.9.0 Introduced the `$paged` argument.
145 * @since 5.1.0 Introduced the `$meta_compare_key` argument.
146 * @since 5.3.0 Introduced the `$meta_type_key` argument.
147 *
148 * @param string|array $query {
149 * Optional. Array or query string of comment query parameters. Default empty.
150 *
151 * @type string $author_email Comment author email address. Default empty.
152 * @type string $author_url Comment author URL. Default empty.
153 * @type int[] $author__in Array of author IDs to include comments for. Default empty.
154 * @type int[] $author__not_in Array of author IDs to exclude comments for. Default empty.
155 * @type int[] $comment__in Array of comment IDs to include. Default empty.
156 * @type int[] $comment__not_in Array of comment IDs to exclude. Default empty.
157 * @type bool $count Whether to return a comment count (true) or array of
158 * comment objects (false). Default false.
159 * @type array $date_query Date query clauses to limit comments by. See WP_Date_Query.
160 * Default null.
161 * @type string $fields Comment fields to return. Accepts 'ids' for comment IDs
162 * only or empty for all fields. Default empty.
163 * @type array $include_unapproved Array of IDs or email addresses of users whose unapproved
164 * comments will be returned by the query regardless of
165 * `$status`. Default empty.
166 * @type int $karma Karma score to retrieve matching comments for.
167 * Default empty.
168 * @type string|string[] $meta_key Meta key or keys to filter by.
169 * @type string|string[] $meta_value Meta value or values to filter by.
170 * @type string $meta_compare MySQL operator used for comparing the meta value.
171 * See WP_Meta_Query::__construct() for accepted values and default value.
172 * @type string $meta_compare_key MySQL operator used for comparing the meta key.
173 * See WP_Meta_Query::__construct() for accepted values and default value.
174 * @type string $meta_type MySQL data type that the meta_value column will be CAST to for comparisons.
175 * See WP_Meta_Query::__construct() for accepted values and default value.
176 * @type string $meta_type_key MySQL data type that the meta_key column will be CAST to for comparisons.
177 * See WP_Meta_Query::__construct() for accepted values and default value.
178 * @type array $meta_query An associative array of WP_Meta_Query arguments.
179 * See WP_Meta_Query::__construct() for accepted values.
180 * @type int $number Maximum number of comments to retrieve.
181 * Default empty (no limit).
182 * @type int $paged When used with `$number`, defines the page of results to return.
183 * When used with `$offset`, `$offset` takes precedence. Default 1.
184 * @type int $offset Number of comments to offset the query. Used to build
185 * LIMIT clause. Default 0.
186 * @type bool $no_found_rows Whether to disable the `SQL_CALC_FOUND_ROWS` query.
187 * Default: true.
188 * @type string|array $orderby Comment status or array of statuses. To use 'meta_value'
189 * or 'meta_value_num', `$meta_key` must also be defined.
190 * To sort by a specific `$meta_query` clause, use that
191 * clause's array key. Accepts:
192 * - 'comment_agent'
193 * - 'comment_approved'
194 * - 'comment_author'
195 * - 'comment_author_email'
196 * - 'comment_author_IP'
197 * - 'comment_author_url'
198 * - 'comment_content'
199 * - 'comment_date'
200 * - 'comment_date_gmt'
201 * - 'comment_ID'
202 * - 'comment_karma'
203 * - 'comment_parent'
204 * - 'comment_post_ID'
205 * - 'comment_type'
206 * - 'user_id'
207 * - 'comment__in'
208 * - 'meta_value'
209 * - 'meta_value_num'
210 * - The value of `$meta_key`
211 * - The array keys of `$meta_query`
212 * - false, an empty array, or 'none' to disable `ORDER BY` clause.
213 * Default: 'comment_date_gmt'.
214 * @type string $order How to order retrieved comments. Accepts 'ASC', 'DESC'.
215 * Default: 'DESC'.
216 * @type int $parent Parent ID of comment to retrieve children of.
217 * Default empty.
218 * @type int[] $parent__in Array of parent IDs of comments to retrieve children for.
219 * Default empty.
220 * @type int[] $parent__not_in Array of parent IDs of comments *not* to retrieve
221 * children for. Default empty.
222 * @type int[] $post_author__in Array of author IDs to retrieve comments for.
223 * Default empty.
224 * @type int[] $post_author__not_in Array of author IDs *not* to retrieve comments for.
225 * Default empty.
226 * @type int $post_id Limit results to those affiliated with a given post ID.
227 * Default 0.
228 * @type int[] $post__in Array of post IDs to include affiliated comments for.
229 * Default empty.
230 * @type int[] $post__not_in Array of post IDs to exclude affiliated comments for.
231 * Default empty.
232 * @type int $post_author Post author ID to limit results by. Default empty.
233 * @type string|string[] $post_status Post status or array of post statuses to retrieve
234 * affiliated comments for. Pass 'any' to match any value.
235 * Default empty.
236 * @type string|string[] $post_type Post type or array of post types to retrieve affiliated
237 * comments for. Pass 'any' to match any value. Default empty.
238 * @type string $post_name Post name to retrieve affiliated comments for.
239 * Default empty.
240 * @type int $post_parent Post parent ID to retrieve affiliated comments for.
241 * Default empty.
242 * @type string $search Search term(s) to retrieve matching comments for.
243 * Default empty.
244 * @type string|array $status Comment statuses to limit results by. Accepts an array
245 * or space/comma-separated list of 'hold' (`comment_status=0`),
246 * 'approve' (`comment_status=1`), 'all', or a custom
247 * comment status. Default 'all'.
248 * @type string|string[] $type Include comments of a given type, or array of types.
249 * Accepts 'comment', 'pings' (includes 'pingback' and
250 * 'trackback'), or any custom type string. Default empty.
251 * @type string[] $type__in Include comments from a given array of comment types.
252 * Default empty.
253 * @type string[] $type__not_in Exclude comments from a given array of comment types.
254 * Default empty.
255 * @type int $user_id Include comments for a specific user ID. Default empty.
256 * @type bool|string $hierarchical Whether to include comment descendants in the results.
257 * - 'threaded' returns a tree, with each comment's children
258 * stored in a `children` property on the `WP_Comment` object.
259 * - 'flat' returns a flat array of found comments plus
260 * their children.
261 * - Boolean `false` leaves out descendants.
262 * The parameter is ignored (forced to `false`) when
263 * `$fields` is 'ids' or 'counts'. Accepts 'threaded',
264 * 'flat', or false. Default: false.
265 * @type string $cache_domain Unique cache key to be produced when this query is stored in
266 * an object cache. Default is 'core'.
267 * @type bool $update_comment_meta_cache Whether to prime the metadata cache for found comments.
268 * Default true.
269 * @type bool $update_comment_post_cache Whether to prime the cache for comment posts.
270 * Default false.
271 * }
272 */
273 public function __construct( $query = '' ) {
274 $this->query_var_defaults = array(
275 'author_email' => '',
276 'author_url' => '',
277 'author__in' => '',
278 'author__not_in' => '',
279 'include_unapproved' => '',
280 'fields' => '',
281 'ID' => '',
282 'comment__in' => '',
283 'comment__not_in' => '',
284 'karma' => '',
285 'number' => '',
286 'offset' => '',
287 'no_found_rows' => true,
288 'orderby' => '',
289 'order' => 'DESC',
290 'paged' => 1,
291 'parent' => '',
292 'parent__in' => '',
293 'parent__not_in' => '',
294 'post_author__in' => '',
295 'post_author__not_in' => '',
296 'post_ID' => '',
297 'post_id' => 0,
298 'post__in' => '',
299 'post__not_in' => '',
300 'post_author' => '',
301 'post_name' => '',
302 'post_parent' => '',
303 'post_status' => '',
304 'post_type' => '',
305 'status' => 'all',
306 'type' => '',
307 'type__in' => '',
308 'type__not_in' => '',
309 'user_id' => '',
310 'search' => '',
311 'count' => false,
312 'meta_key' => '',
313 'meta_value' => '',
314 'meta_query' => '',
315 'date_query' => null, // See WP_Date_Query.
316 'hierarchical' => false,
317 'cache_domain' => 'core',
318 'update_comment_meta_cache' => true,
319 'update_comment_post_cache' => false,
320 );
321
322 if ( ! empty( $query ) ) {
323 $this->query( $query );
324 }
325 }
326
327 /**
328 * Parse arguments passed to the comment query with default query parameters.
329 *
330 * @since 4.2.0 Extracted from WP_Comment_Query::query().
331 *
332 * @param string|array $query WP_Comment_Query arguments. See WP_Comment_Query::__construct() for accepted arguments.
333 */
334 public function parse_query( $query = '' ) {
335 if ( empty( $query ) ) {
336 $query = $this->query_vars;
337 }
338
339 $this->query_vars = wp_parse_args( $query, $this->query_var_defaults );
340
341 /**
342 * Fires after the comment query vars have been parsed.
343 *
344 * @since 4.2.0
345 *
346 * @param WP_Comment_Query $query The WP_Comment_Query instance (passed by reference).
347 */
348 do_action_ref_array( 'parse_comment_query', array( &$this ) );
349 }
350
351 /**
352 * Sets up the WordPress query for retrieving comments.
353 *
354 * @since 3.1.0
355 * @since 4.1.0 Introduced 'comment__in', 'comment__not_in', 'post_author__in',
356 * 'post_author__not_in', 'author__in', 'author__not_in', 'post__in',
357 * 'post__not_in', 'include_unapproved', 'type__in', and 'type__not_in'
358 * arguments to $query_vars.
359 * @since 4.2.0 Moved parsing to WP_Comment_Query::parse_query().
360 *
361 * @param string|array $query Array or URL query string of parameters.
362 * @return array|int List of comments, or number of comments when 'count' is passed as a query var.
363 */
364 public function query( $query ) {
365 $this->query_vars = wp_parse_args( $query );
366 return $this->get_comments();
367 }
368
369 /**
370 * Get a list of comments matching the query vars.
371 *
372 * @since 4.2.0
373 *
374 * @global wpdb $wpdb WordPress database abstraction object.
375 *
376 * @return int|int[]|WP_Comment[] List of comments or number of found comments if `$count` argument is true.
377 */
378 public function get_comments() {
379 global $wpdb;
380
381 $this->parse_query();
382
383 // Parse meta query.
384 $this->meta_query = new WP_Meta_Query();
385 $this->meta_query->parse_query_vars( $this->query_vars );
386
387 /**
388 * Fires before comments are retrieved.
389 *
390 * @since 3.1.0
391 *
392 * @param WP_Comment_Query $query Current instance of WP_Comment_Query (passed by reference).
393 */
394 do_action_ref_array( 'pre_get_comments', array( &$this ) );
395
396 // Reparse query vars, in case they were modified in a 'pre_get_comments' callback.
397 $this->meta_query->parse_query_vars( $this->query_vars );
398 if ( ! empty( $this->meta_query->queries ) ) {
399 $this->meta_query_clauses = $this->meta_query->get_sql( 'comment', $wpdb->comments, 'comment_ID', $this );
400 }
401
402 $comment_data = null;
403
404 /**
405 * Filters the comments data before the query takes place.
406 *
407 * Return a non-null value to bypass WordPress' default comment queries.
408 *
409 * The expected return type from this filter depends on the value passed
410 * in the request query vars:
411 * - When `$this->query_vars['count']` is set, the filter should return
412 * the comment count as an integer.
413 * - When `'ids' === $this->query_vars['fields']`, the filter should return
414 * an array of comment IDs.
415 * - Otherwise the filter should return an array of WP_Comment objects.
416 *
417 * Note that if the filter returns an array of comment data, it will be assigned
418 * to the `comments` property of the current WP_Comment_Query instance.
419 *
420 * Filtering functions that require pagination information are encouraged to set
421 * the `found_comments` and `max_num_pages` properties of the WP_Comment_Query object,
422 * passed to the filter by reference. If WP_Comment_Query does not perform a database
423 * query, it will not have enough information to generate these values itself.
424 *
425 * @since 5.3.0
426 * @since 5.6.0 The returned array of comment data is assigned to the `comments` property
427 * of the current WP_Comment_Query instance.
428 *
429 * @param array|int|null $comment_data Return an array of comment data to short-circuit WP's comment query,
430 * the comment count as an integer if `$this->query_vars['count']` is set,
431 * or null to allow WP to run its normal queries.
432 * @param WP_Comment_Query $query The WP_Comment_Query instance, passed by reference.
433 */
434 $comment_data = apply_filters_ref_array( 'comments_pre_query', array( $comment_data, &$this ) );
435
436 if ( null !== $comment_data ) {
437 if ( is_array( $comment_data ) && ! $this->query_vars['count'] ) {
438 $this->comments = $comment_data;
439 }
440
441 return $comment_data;
442 }
443
444 /*
445 * Only use the args defined in the query_var_defaults to compute the key,
446 * but ignore 'fields', 'update_comment_meta_cache', 'update_comment_post_cache' which does not affect query results.
447 */
448 $_args = wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) );
449 unset( $_args['fields'], $_args['update_comment_meta_cache'], $_args['update_comment_post_cache'] );
450
451 $key = md5( serialize( $_args ) );
452 $last_changed = wp_cache_get_last_changed( 'comment' );
453
454 $cache_key = "get_comments:$key";
455 $cache_value = wp_cache_get_salted( $cache_key, 'comment-queries', $last_changed );
456 if ( false === $cache_value ) {
457 $comment_ids = $this->get_comment_ids();
458 if ( $comment_ids ) {
459 $this->set_found_comments();
460 }
461
462 $cache_value = array(
463 'comment_ids' => $comment_ids,
464 'found_comments' => $this->found_comments,
465 );
466 wp_cache_set_salted( $cache_key, $cache_value, 'comment-queries', $last_changed );
467 } else {
468 $comment_ids = $cache_value['comment_ids'];
469 $this->found_comments = $cache_value['found_comments'];
470 }
471
472 if ( $this->found_comments && $this->query_vars['number'] ) {
473 $this->max_num_pages = (int) ceil( $this->found_comments / $this->query_vars['number'] );
474 }
475
476 // If querying for a count only, there's nothing more to do.
477 if ( $this->query_vars['count'] ) {
478 // $comment_ids is actually a count in this case.
479 return (int) $comment_ids;
480 }
481
482 $comment_ids = array_map( 'intval', $comment_ids );
483
484 if ( $this->query_vars['update_comment_meta_cache'] ) {
485 wp_lazyload_comment_meta( $comment_ids );
486 }
487
488 if ( 'ids' === $this->query_vars['fields'] ) {
489 $this->comments = $comment_ids;
490 return $this->comments;
491 }
492
493 _prime_comment_caches( $comment_ids, false );
494
495 // Fetch full comment objects from the primed cache.
496 $_comments = array();
497 foreach ( $comment_ids as $comment_id ) {
498 $_comment = get_comment( $comment_id );
499 if ( $_comment ) {
500 $_comments[] = $_comment;
501 }
502 }
503
504 // Prime comment post caches.
505 if ( $this->query_vars['update_comment_post_cache'] ) {
506 $comment_post_ids = array();
507 foreach ( $_comments as $_comment ) {
508 $comment_post_ids[] = $_comment->comment_post_ID;
509 }
510
511 _prime_post_caches( $comment_post_ids, false, false );
512 }
513
514 /**
515 * Filters the comment query results.
516 *
517 * @since 3.1.0
518 *
519 * @param WP_Comment[] $_comments An array of comments.
520 * @param WP_Comment_Query $query Current instance of WP_Comment_Query (passed by reference).
521 */
522 $_comments = apply_filters_ref_array( 'the_comments', array( $_comments, &$this ) );
523
524 // Convert to WP_Comment instances.
525 $comments = array_map( 'get_comment', $_comments );
526
527 if ( $this->query_vars['hierarchical'] ) {
528 $comments = $this->fill_descendants( $comments );
529 }
530
531 $this->comments = $comments;
532 return $this->comments;
533 }
534
535 /**
536 * Used internally to get a list of comment IDs matching the query vars.
537 *
538 * @since 4.4.0
539 * @since 6.9.0 Excludes the 'note' comment type, unless 'all' or the 'note' types are requested.
540 *
541 * @global wpdb $wpdb WordPress database abstraction object.
542 *
543 * @return int|array A single count of comment IDs if a count query. An array of comment IDs if a full query.
544 */
545 protected function get_comment_ids() {
546 global $wpdb;
547
548 // Assemble clauses related to 'comment_approved'.
549 $approved_clauses = array();
550
551 // 'status' accepts an array or a comma-separated string.
552 $status_clauses = array();
553 $statuses = wp_parse_list( $this->query_vars['status'] );
554
555 // Empty 'status' should be interpreted as 'all'.
556 if ( empty( $statuses ) ) {
557 $statuses = array( 'all' );
558 }
559
560 // 'any' overrides other statuses.
561 if ( ! in_array( 'any', $statuses, true ) ) {
562 foreach ( $statuses as $status ) {
563 switch ( $status ) {
564 case 'hold':
565 $status_clauses[] = "comment_approved = '0'";
566 break;
567
568 case 'approve':
569 $status_clauses[] = "comment_approved = '1'";
570 break;
571
572 case 'all':
573 case '':
574 $status_clauses[] = "( comment_approved = '0' OR comment_approved = '1' )";
575 break;
576
577 default:
578 $status_clauses[] = $wpdb->prepare( 'comment_approved = %s', $status );
579 break;
580 }
581 }
582
583 $approved_clauses[] = '( ' . implode( ' OR ', $status_clauses ) . ' )';
584 }
585
586 // User IDs or emails whose unapproved comments are included, regardless of $status.
587 if ( ! empty( $this->query_vars['include_unapproved'] ) ) {
588 $include_unapproved = wp_parse_list( $this->query_vars['include_unapproved'] );
589
590 foreach ( $include_unapproved as $unapproved_identifier ) {
591 // Numeric values are assumed to be user IDs.
592 if ( is_numeric( $unapproved_identifier ) ) {
593 $approved_clauses[] = $wpdb->prepare( "( user_id = %d AND comment_approved = '0' )", $unapproved_identifier );
594 } else {
595 // Otherwise we match against email addresses.
596 if ( ! empty( $_GET['unapproved'] ) && ! empty( $_GET['moderation-hash'] ) ) {
597 // Only include requested comment.
598 $approved_clauses[] = $wpdb->prepare( "( comment_author_email = %s AND comment_approved = '0' AND {$wpdb->comments}.comment_ID = %d )", $unapproved_identifier, (int) $_GET['unapproved'] );
599 } else {
600 // Include all of the author's unapproved comments.
601 $approved_clauses[] = $wpdb->prepare( "( comment_author_email = %s AND comment_approved = '0' )", $unapproved_identifier );
602 }
603 }
604 }
605 }
606
607 // Collapse comment_approved clauses into a single OR-separated clause.
608 if ( ! empty( $approved_clauses ) ) {
609 if ( 1 === count( $approved_clauses ) ) {
610 $this->sql_clauses['where']['approved'] = $approved_clauses[0];
611 } else {
612 $this->sql_clauses['where']['approved'] = '( ' . implode( ' OR ', $approved_clauses ) . ' )';
613 }
614 }
615
616 $order = ( 'ASC' === strtoupper( $this->query_vars['order'] ) ) ? 'ASC' : 'DESC';
617
618 // Disable ORDER BY with 'none', an empty array, or boolean false.
619 if ( in_array( $this->query_vars['orderby'], array( 'none', array(), false ), true ) ) {
620 $orderby = '';
621 } elseif ( ! empty( $this->query_vars['orderby'] ) ) {
622 $ordersby = is_array( $this->query_vars['orderby'] ) ?
623 $this->query_vars['orderby'] :
624 preg_split( '/[,\s]/', $this->query_vars['orderby'] );
625
626 $orderby_array = array();
627 $found_orderby_comment_id = false;
628 foreach ( $ordersby as $_key => $_value ) {
629 if ( ! $_value ) {
630 continue;
631 }
632
633 if ( is_int( $_key ) ) {
634 $_orderby = $_value;
635 $_order = $order;
636 } else {
637 $_orderby = $_key;
638 $_order = $_value;
639 }
640
641 if ( ! $found_orderby_comment_id && in_array( $_orderby, array( 'comment_ID', 'comment__in' ), true ) ) {
642 $found_orderby_comment_id = true;
643 }
644
645 $parsed = $this->parse_orderby( $_orderby );
646
647 if ( ! $parsed ) {
648 continue;
649 }
650
651 if ( 'comment__in' === $_orderby ) {
652 $orderby_array[] = $parsed;
653 continue;
654 }
655
656 $orderby_array[] = $parsed . ' ' . $this->parse_order( $_order );
657 }
658
659 // If no valid clauses were found, order by comment_date_gmt.
660 if ( empty( $orderby_array ) ) {
661 $orderby_array[] = "$wpdb->comments.comment_date_gmt $order";
662 }
663
664 // To ensure determinate sorting, always include a comment_ID clause.
665 if ( ! $found_orderby_comment_id ) {
666 $comment_id_order = '';
667
668 // Inherit order from comment_date or comment_date_gmt, if available.
669 foreach ( $orderby_array as $orderby_clause ) {
670 if ( preg_match( '/comment_date(?:_gmt)*\ (ASC|DESC)/', $orderby_clause, $match ) ) {
671 $comment_id_order = $match[1];
672 break;
673 }
674 }
675
676 // If no date-related order is available, use the date from the first available clause.
677 if ( ! $comment_id_order ) {
678 foreach ( $orderby_array as $orderby_clause ) {
679 if ( str_contains( 'ASC', $orderby_clause ) ) {
680 $comment_id_order = 'ASC';
681 } else {
682 $comment_id_order = 'DESC';
683 }
684
685 break;
686 }
687 }
688
689 // Default to DESC.
690 if ( ! $comment_id_order ) {
691 $comment_id_order = 'DESC';
692 }
693
694 $orderby_array[] = "$wpdb->comments.comment_ID $comment_id_order";
695 }
696
697 $orderby = implode( ', ', $orderby_array );
698 } else {
699 $orderby = "$wpdb->comments.comment_date_gmt $order";
700 }
701
702 $number = absint( $this->query_vars['number'] );
703 $offset = absint( $this->query_vars['offset'] );
704 $paged = absint( $this->query_vars['paged'] );
705 $limits = '';
706
707 if ( ! empty( $number ) ) {
708 if ( $offset ) {
709 $limits = 'LIMIT ' . $offset . ',' . $number;
710 } else {
711 $limits = 'LIMIT ' . ( $number * ( $paged - 1 ) ) . ',' . $number;
712 }
713 }
714
715 if ( $this->query_vars['count'] ) {
716 $fields = 'COUNT(*)';
717 } else {
718 $fields = "$wpdb->comments.comment_ID";
719 }
720
721 $post_id = absint( $this->query_vars['post_id'] );
722 if ( ! empty( $post_id ) ) {
723 $this->sql_clauses['where']['post_id'] = $wpdb->prepare( 'comment_post_ID = %d', $post_id );
724 }
725
726 // Parse comment IDs for an IN clause.
727 if ( ! empty( $this->query_vars['comment__in'] ) ) {
728 $this->sql_clauses['where']['comment__in'] = "$wpdb->comments.comment_ID IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['comment__in'] ) ) . ' )';
729 }
730
731 // Parse comment IDs for a NOT IN clause.
732 if ( ! empty( $this->query_vars['comment__not_in'] ) ) {
733 $this->sql_clauses['where']['comment__not_in'] = "$wpdb->comments.comment_ID NOT IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['comment__not_in'] ) ) . ' )';
734 }
735
736 // Parse comment parent IDs for an IN clause.
737 if ( ! empty( $this->query_vars['parent__in'] ) ) {
738 $this->sql_clauses['where']['parent__in'] = 'comment_parent IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['parent__in'] ) ) . ' )';
739 }
740
741 // Parse comment parent IDs for a NOT IN clause.
742 if ( ! empty( $this->query_vars['parent__not_in'] ) ) {
743 $this->sql_clauses['where']['parent__not_in'] = 'comment_parent NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['parent__not_in'] ) ) . ' )';
744 }
745
746 // Parse comment post IDs for an IN clause.
747 if ( ! empty( $this->query_vars['post__in'] ) ) {
748 $this->sql_clauses['where']['post__in'] = 'comment_post_ID IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__in'] ) ) . ' )';
749 }
750
751 // Parse comment post IDs for a NOT IN clause.
752 if ( ! empty( $this->query_vars['post__not_in'] ) ) {
753 $this->sql_clauses['where']['post__not_in'] = 'comment_post_ID NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__not_in'] ) ) . ' )';
754 }
755
756 if ( '' !== $this->query_vars['author_email'] ) {
757 $this->sql_clauses['where']['author_email'] = $wpdb->prepare( 'comment_author_email = %s', $this->query_vars['author_email'] );
758 }
759
760 if ( '' !== $this->query_vars['author_url'] ) {
761 $this->sql_clauses['where']['author_url'] = $wpdb->prepare( 'comment_author_url = %s', $this->query_vars['author_url'] );
762 }
763
764 if ( '' !== $this->query_vars['karma'] ) {
765 $this->sql_clauses['where']['karma'] = $wpdb->prepare( 'comment_karma = %d', $this->query_vars['karma'] );
766 }
767
768 // Filtering by comment_type: 'type', 'type__in', 'type__not_in'.
769 $raw_types = array(
770 'IN' => array_merge( (array) $this->query_vars['type'], (array) $this->query_vars['type__in'] ),
771 'NOT IN' => (array) $this->query_vars['type__not_in'],
772 );
773
774 // Exclude the 'note' comment type, unless 'all' types or the 'note' type explicitly are requested.
775 if (
776 ! in_array( 'all', $raw_types['IN'], true ) &&
777 ! in_array( 'note', $raw_types['IN'], true ) &&
778 ! in_array( 'note', $raw_types['NOT IN'], true )
779 ) {
780 $raw_types['NOT IN'][] = 'note';
781 }
782
783 $comment_types = array();
784 foreach ( $raw_types as $operator => $_raw_types ) {
785 $_raw_types = array_unique( $_raw_types );
786
787 foreach ( $_raw_types as $type ) {
788 switch ( $type ) {
789 // An empty translates to 'all', for backward compatibility.
790 case '':
791 case 'all':
792 break;
793
794 case 'comment':
795 case 'comments':
796 $comment_types[ $operator ][] = "''";
797 $comment_types[ $operator ][] = "'comment'";
798 break;
799
800 case 'pings':
801 $comment_types[ $operator ][] = "'pingback'";
802 $comment_types[ $operator ][] = "'trackback'";
803 break;
804
805 default:
806 $comment_types[ $operator ][] = $wpdb->prepare( '%s', $type );
807 break;
808 }
809 }
810
811 if ( ! empty( $comment_types[ $operator ] ) ) {
812 $types_sql = implode( ', ', $comment_types[ $operator ] );
813 $this->sql_clauses['where'][ 'comment_type__' . strtolower( str_replace( ' ', '_', $operator ) ) ] = "comment_type $operator ($types_sql)";
814 }
815 }
816
817 $parent = $this->query_vars['parent'];
818 if ( $this->query_vars['hierarchical'] && ! $parent ) {
819 $parent = 0;
820 }
821
822 if ( '' !== $parent ) {
823 $this->sql_clauses['where']['parent'] = $wpdb->prepare( 'comment_parent = %d', $parent );
824 }
825
826 if ( is_array( $this->query_vars['user_id'] ) ) {
827 $this->sql_clauses['where']['user_id'] = 'user_id IN (' . implode( ',', array_map( 'absint', $this->query_vars['user_id'] ) ) . ')';
828 } elseif ( '' !== $this->query_vars['user_id'] ) {
829 $this->sql_clauses['where']['user_id'] = $wpdb->prepare( 'user_id = %d', $this->query_vars['user_id'] );
830 }
831
832 // Falsey search strings are ignored.
833 if ( isset( $this->query_vars['search'] ) && strlen( $this->query_vars['search'] ) ) {
834 $search_sql = $this->get_search_sql(
835 $this->query_vars['search'],
836 array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_author_IP', 'comment_content' )
837 );
838
839 // Strip leading 'AND'.
840 $this->sql_clauses['where']['search'] = preg_replace( '/^\s*AND\s*/', '', $search_sql );
841 }
842
843 // If any post-related query vars are passed, join the posts table.
844 $join_posts_table = false;
845 $plucked = wp_array_slice_assoc( $this->query_vars, array( 'post_author', 'post_name', 'post_parent' ) );
846 $post_fields = array_filter( $plucked );
847
848 if ( ! empty( $post_fields ) ) {
849 $join_posts_table = true;
850 foreach ( $post_fields as $field_name => $field_value ) {
851 // $field_value may be an array.
852 $esses = array_fill( 0, count( (array) $field_value ), '%s' );
853
854 // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
855 $this->sql_clauses['where'][ $field_name ] = $wpdb->prepare( " {$wpdb->posts}.{$field_name} IN (" . implode( ',', $esses ) . ')', $field_value );
856 }
857 }
858
859 // 'post_status' and 'post_type' are handled separately, due to the specialized behavior of 'any'.
860 foreach ( array( 'post_status', 'post_type' ) as $field_name ) {
861 $q_values = array();
862 if ( ! empty( $this->query_vars[ $field_name ] ) ) {
863 $q_values = $this->query_vars[ $field_name ];
864 if ( ! is_array( $q_values ) ) {
865 $q_values = explode( ',', $q_values );
866 }
867
868 // 'any' will cause the query var to be ignored.
869 if ( in_array( 'any', $q_values, true ) || empty( $q_values ) ) {
870 continue;
871 }
872
873 $join_posts_table = true;
874
875 $esses = array_fill( 0, count( $q_values ), '%s' );
876
877 // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
878 $this->sql_clauses['where'][ $field_name ] = $wpdb->prepare( " {$wpdb->posts}.{$field_name} IN (" . implode( ',', $esses ) . ')', $q_values );
879 }
880 }
881
882 // Comment author IDs for an IN clause.
883 if ( ! empty( $this->query_vars['author__in'] ) ) {
884 $this->sql_clauses['where']['author__in'] = 'user_id IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__in'] ) ) . ' )';
885 }
886
887 // Comment author IDs for a NOT IN clause.
888 if ( ! empty( $this->query_vars['author__not_in'] ) ) {
889 $this->sql_clauses['where']['author__not_in'] = 'user_id NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__not_in'] ) ) . ' )';
890 }
891
892 // Post author IDs for an IN clause.
893 if ( ! empty( $this->query_vars['post_author__in'] ) ) {
894 $join_posts_table = true;
895 $this->sql_clauses['where']['post_author__in'] = 'post_author IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__in'] ) ) . ' )';
896 }
897
898 // Post author IDs for a NOT IN clause.
899 if ( ! empty( $this->query_vars['post_author__not_in'] ) ) {
900 $join_posts_table = true;
901 $this->sql_clauses['where']['post_author__not_in'] = 'post_author NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__not_in'] ) ) . ' )';
902 }
903
904 $join = '';
905 $groupby = '';
906
907 if ( $join_posts_table ) {
908 $join .= "JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->comments.comment_post_ID";
909 }
910
911 if ( ! empty( $this->meta_query_clauses ) ) {
912 $join .= $this->meta_query_clauses['join'];
913
914 // Strip leading 'AND'.
915 $this->sql_clauses['where']['meta_query'] = preg_replace( '/^\s*AND\s*/', '', $this->meta_query_clauses['where'] );
916
917 if ( ! $this->query_vars['count'] ) {
918 $groupby = "{$wpdb->comments}.comment_ID";
919 }
920 }
921
922 if ( ! empty( $this->query_vars['date_query'] ) && is_array( $this->query_vars['date_query'] ) ) {
923 $this->date_query = new WP_Date_Query( $this->query_vars['date_query'], 'comment_date' );
924
925 // Strip leading 'AND'.
926 $this->sql_clauses['where']['date_query'] = preg_replace( '/^\s*AND\s*/', '', $this->date_query->get_sql() );
927 }
928
929 $where = implode( ' AND ', $this->sql_clauses['where'] );
930
931 $pieces = array( 'fields', 'join', 'where', 'orderby', 'limits', 'groupby' );
932
933 /**
934 * Filters the comment query clauses.
935 *
936 * @since 3.1.0
937 *
938 * @param string[] $clauses {
939 * Associative array of the clauses for the query.
940 *
941 * @type string $fields The SELECT clause of the query.
942 * @type string $join The JOIN clause of the query.
943 * @type string $where The WHERE clause of the query.
944 * @type string $orderby The ORDER BY clause of the query.
945 * @type string $limits The LIMIT clause of the query.
946 * @type string $groupby The GROUP BY clause of the query.
947 * }
948 * @param WP_Comment_Query $query Current instance of WP_Comment_Query (passed by reference).
949 */
950 $clauses = apply_filters_ref_array( 'comments_clauses', array( compact( $pieces ), &$this ) );
951
952 $fields = isset( $clauses['fields'] ) ? $clauses['fields'] : '';
953 $join = isset( $clauses['join'] ) ? $clauses['join'] : '';
954 $where = isset( $clauses['where'] ) ? $clauses['where'] : '';
955 $orderby = isset( $clauses['orderby'] ) ? $clauses['orderby'] : '';
956 $limits = isset( $clauses['limits'] ) ? $clauses['limits'] : '';
957 $groupby = isset( $clauses['groupby'] ) ? $clauses['groupby'] : '';
958
959 $this->filtered_where_clause = $where;
960
961 if ( $where ) {
962 $where = 'WHERE ' . $where;
963 }
964
965 if ( $groupby ) {
966 $groupby = 'GROUP BY ' . $groupby;
967 }
968
969 if ( $orderby ) {
970 $orderby = "ORDER BY $orderby";
971 }
972
973 $found_rows = '';
974 if ( ! $this->query_vars['no_found_rows'] ) {
975 $found_rows = 'SQL_CALC_FOUND_ROWS';
976 }
977
978 $this->sql_clauses['select'] = "SELECT $found_rows $fields";
979 $this->sql_clauses['from'] = "FROM $wpdb->comments $join";
980 $this->sql_clauses['groupby'] = $groupby;
981 $this->sql_clauses['orderby'] = $orderby;
982 $this->sql_clauses['limits'] = $limits;
983
984 // Beginning of the string is on a new line to prevent leading whitespace. See https://core.trac.wordpress.org/ticket/56841.
985 $this->request =
986 "{$this->sql_clauses['select']}
987 {$this->sql_clauses['from']}
988 {$where}
989 {$this->sql_clauses['groupby']}
990 {$this->sql_clauses['orderby']}
991 {$this->sql_clauses['limits']}";
992
993 if ( $this->query_vars['count'] ) {
994 return (int) $wpdb->get_var( $this->request );
995 } else {
996 $comment_ids = $wpdb->get_col( $this->request );
997 return array_map( 'intval', $comment_ids );
998 }
999 }
1000
1001 /**
1002 * Populates found_comments and max_num_pages properties for the current
1003 * query if the limit clause was used.
1004 *
1005 * @since 4.6.0
1006 *
1007 * @global wpdb $wpdb WordPress database abstraction object.
1008 */
1009 private function set_found_comments() {
1010 global $wpdb;
1011
1012 if ( $this->query_vars['number'] && ! $this->query_vars['no_found_rows'] ) {
1013 /**
1014 * Filters the query used to retrieve found comment count.
1015 *
1016 * @since 4.4.0
1017 *
1018 * @param string $found_comments_query SQL query. Default 'SELECT FOUND_ROWS()'.
1019 * @param WP_Comment_Query $comment_query The `WP_Comment_Query` instance.
1020 */
1021 $found_comments_query = apply_filters( 'found_comments_query', 'SELECT FOUND_ROWS()', $this );
1022
1023 $this->found_comments = (int) $wpdb->get_var( $found_comments_query );
1024 }
1025 }
1026
1027 /**
1028 * Fetch descendants for located comments.
1029 *
1030 * Instead of calling `get_children()` separately on each child comment, we do a single set of queries to fetch
1031 * the descendant trees for all matched top-level comments.
1032 *
1033 * @since 4.4.0
1034 *
1035 * @param WP_Comment[] $comments Array of top-level comments whose descendants should be filled in.
1036 * @return array
1037 */
1038 protected function fill_descendants( $comments ) {
1039 $levels = array(
1040 0 => wp_list_pluck( $comments, 'comment_ID' ),
1041 );
1042
1043 $key = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ) ) );
1044 $last_changed = wp_cache_get_last_changed( 'comment' );
1045
1046 // Fetch an entire level of the descendant tree at a time.
1047 $level = 0;
1048 $exclude_keys = array( 'parent', 'parent__in', 'parent__not_in' );
1049 do {
1050 // Parent-child relationships may be cached. Only query for those that are not.
1051 $child_ids = array();
1052 $uncached_parent_ids = array();
1053 $_parent_ids = $levels[ $level ];
1054 if ( $_parent_ids ) {
1055 $cache_keys = array();
1056 foreach ( $_parent_ids as $parent_id ) {
1057 $cache_keys[ $parent_id ] = "get_comment_child_ids:$parent_id:$key";
1058 }
1059 $cache_data = wp_cache_get_multiple_salted( array_values( $cache_keys ), 'comment-queries', $last_changed );
1060 foreach ( $_parent_ids as $parent_id ) {
1061 $parent_child_ids = $cache_data[ $cache_keys[ $parent_id ] ];
1062 if ( false !== $parent_child_ids ) {
1063 $child_ids = array_merge( $child_ids, $parent_child_ids );
1064 } else {
1065 $uncached_parent_ids[] = $parent_id;
1066 }
1067 }
1068 }
1069
1070 if ( $uncached_parent_ids ) {
1071 // Fetch this level of comments.
1072 $parent_query_args = $this->query_vars;
1073 foreach ( $exclude_keys as $exclude_key ) {
1074 $parent_query_args[ $exclude_key ] = '';
1075 }
1076 $parent_query_args['parent__in'] = $uncached_parent_ids;
1077 $parent_query_args['no_found_rows'] = true;
1078 $parent_query_args['hierarchical'] = false;
1079 $parent_query_args['offset'] = 0;
1080 $parent_query_args['number'] = 0;
1081
1082 $level_comments = get_comments( $parent_query_args );
1083
1084 // Cache parent-child relationships.
1085 $parent_map = array_fill_keys( $uncached_parent_ids, array() );
1086 foreach ( $level_comments as $level_comment ) {
1087 $parent_map[ $level_comment->comment_parent ][] = $level_comment->comment_ID;
1088 $child_ids[] = $level_comment->comment_ID;
1089 }
1090
1091 $data = array();
1092 foreach ( $parent_map as $parent_id => $children ) {
1093 $cache_key = "get_comment_child_ids:$parent_id:$key";
1094 $data[ $cache_key ] = $children;
1095 }
1096 wp_cache_set_multiple_salted( $data, 'comment-queries', $last_changed );
1097 }
1098
1099 ++$level;
1100 $levels[ $level ] = $child_ids;
1101 } while ( $child_ids );
1102
1103 // Prime comment caches for non-top-level comments.
1104 $descendant_ids = array();
1105 for ( $i = 1, $c = count( $levels ); $i < $c; $i++ ) {
1106 $descendant_ids = array_merge( $descendant_ids, $levels[ $i ] );
1107 }
1108
1109 _prime_comment_caches( $descendant_ids, $this->query_vars['update_comment_meta_cache'] );
1110
1111 // Assemble a flat array of all comments + descendants.
1112 $all_comments = $comments;
1113 foreach ( $descendant_ids as $descendant_id ) {
1114 $all_comments[] = get_comment( $descendant_id );
1115 }
1116
1117 // If a threaded representation was requested, build the tree.
1118 if ( 'threaded' === $this->query_vars['hierarchical'] ) {
1119 $threaded_comments = array();
1120 $ref = array();
1121 foreach ( $all_comments as $k => $c ) {
1122 $_c = get_comment( $c->comment_ID );
1123
1124 // If the comment isn't in the reference array, it goes in the top level of the thread.
1125 if ( ! isset( $ref[ $c->comment_parent ] ) ) {
1126 $threaded_comments[ $_c->comment_ID ] = $_c;
1127 $ref[ $_c->comment_ID ] = $threaded_comments[ $_c->comment_ID ];
1128
1129 // Otherwise, set it as a child of its parent.
1130 } else {
1131
1132 $ref[ $_c->comment_parent ]->add_child( $_c );
1133 $ref[ $_c->comment_ID ] = $ref[ $_c->comment_parent ]->get_child( $_c->comment_ID );
1134 }
1135 }
1136
1137 // Set the 'populated_children' flag, to ensure additional database queries aren't run.
1138 foreach ( $ref as $_ref ) {
1139 $_ref->populated_children( true );
1140 }
1141
1142 $comments = $threaded_comments;
1143 } else {
1144 $comments = $all_comments;
1145 }
1146
1147 return $comments;
1148 }
1149
1150 /**
1151 * Used internally to generate an SQL string for searching across multiple columns.
1152 *
1153 * @since 3.1.0
1154 *
1155 * @global wpdb $wpdb WordPress database abstraction object.
1156 *
1157 * @param string $search Search string.
1158 * @param string[] $columns Array of columns to search.
1159 * @return string Search SQL.
1160 */
1161 protected function get_search_sql( $search, $columns ) {
1162 global $wpdb;
1163
1164 $like = '%' . $wpdb->esc_like( $search ) . '%';
1165
1166 $searches = array();
1167 foreach ( $columns as $column ) {
1168 $searches[] = $wpdb->prepare( "$column LIKE %s", $like );
1169 }
1170
1171 return ' AND (' . implode( ' OR ', $searches ) . ')';
1172 }
1173
1174 /**
1175 * Parse and sanitize 'orderby' keys passed to the comment query.
1176 *
1177 * @since 4.2.0
1178 *
1179 * @global wpdb $wpdb WordPress database abstraction object.
1180 *
1181 * @param string $orderby Alias for the field to order by.
1182 * @return string|false Value to used in the ORDER clause. False otherwise.
1183 */
1184 protected function parse_orderby( $orderby ) {
1185 global $wpdb;
1186
1187 $allowed_keys = array(
1188 'comment_agent',
1189 'comment_approved',
1190 'comment_author',
1191 'comment_author_email',
1192 'comment_author_IP',
1193 'comment_author_url',
1194 'comment_content',
1195 'comment_date',
1196 'comment_date_gmt',
1197 'comment_ID',
1198 'comment_karma',
1199 'comment_parent',
1200 'comment_post_ID',
1201 'comment_type',
1202 'user_id',
1203 );
1204
1205 if ( ! empty( $this->query_vars['meta_key'] ) ) {
1206 $allowed_keys[] = $this->query_vars['meta_key'];
1207 $allowed_keys[] = 'meta_value';
1208 $allowed_keys[] = 'meta_value_num';
1209 }
1210
1211 $meta_query_clauses = $this->meta_query->get_clauses();
1212 if ( $meta_query_clauses ) {
1213 $allowed_keys = array_merge( $allowed_keys, array_keys( $meta_query_clauses ) );
1214 }
1215
1216 $parsed = false;
1217 if ( $this->query_vars['meta_key'] === $orderby || 'meta_value' === $orderby ) {
1218 $parsed = "$wpdb->commentmeta.meta_value";
1219 } elseif ( 'meta_value_num' === $orderby ) {
1220 $parsed = "$wpdb->commentmeta.meta_value+0";
1221 } elseif ( 'comment__in' === $orderby ) {
1222 $comment__in = implode( ',', array_map( 'absint', $this->query_vars['comment__in'] ) );
1223 $parsed = "FIELD( {$wpdb->comments}.comment_ID, $comment__in )";
1224 } elseif ( in_array( $orderby, $allowed_keys, true ) ) {
1225
1226 if ( isset( $meta_query_clauses[ $orderby ] ) ) {
1227 $meta_clause = $meta_query_clauses[ $orderby ];
1228 $parsed = sprintf( 'CAST(%s.meta_value AS %s)', esc_sql( $meta_clause['alias'] ), esc_sql( $meta_clause['cast'] ) );
1229 } else {
1230 $parsed = "$wpdb->comments.$orderby";
1231 }
1232 }
1233
1234 return $parsed;
1235 }
1236
1237 /**
1238 * Parse an 'order' query variable and cast it to ASC or DESC as necessary.
1239 *
1240 * @since 4.2.0
1241 *
1242 * @param string $order The 'order' query variable.
1243 * @return string The sanitized 'order' query variable.
1244 */
1245 protected function parse_order( $order ) {
1246 if ( ! is_string( $order ) || empty( $order ) ) {
1247 return 'DESC';
1248 }
1249
1250 if ( 'ASC' === strtoupper( $order ) ) {
1251 return 'ASC';
1252 } else {
1253 return 'DESC';
1254 }
1255 }
1256}
1257
Ui Ux Design – Teachers Night Out https://cardgames4educators.com Wed, 16 Oct 2024 22:24:18 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://cardgames4educators.com/wp-content/uploads/2024/06/cropped-Card-4-Educators-logo-32x32.png Ui Ux Design – Teachers Night Out https://cardgames4educators.com 32 32 Masters In English How English Speaker https://cardgames4educators.com/masters-in-english-how-english-speaker/ https://cardgames4educators.com/masters-in-english-how-english-speaker/#comments Mon, 27 May 2024 08:54:45 +0000 https://themexriver.com/wp/kadu/?p=1

Erat himenaeos neque id sagittis massa. Hac suscipit pulvinar dignissim platea magnis eu. Don tellus a pharetra inceptos efficitur dui pulvinar. Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent pulvinar odio volutpat parturient. Quisque risus finibus suspendisse mus purus magnis facilisi condimentum consectetur dui. Curae elit suspendisse cursus vehicula.

Turpis taciti class non vel pretium quis pulvinar tempor lobortis nunc. Libero phasellus parturient sapien volutpat malesuada ornare. Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae. Porta est tempor ex eget feugiat vulputate ipsum. Justo nec iaculis habitant diam arcu fermentum.

We offer comprehen sive emplo ment services such as assistance wit employer compliance.Our company is your strategic HR partner as instead of HR. john smithson

Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae.

Exploring Learning Landscapes in Academic

Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent.

]]>
https://cardgames4educators.com/masters-in-english-how-english-speaker/feed/ 1