changeset 7 | cf61fcea0001 |
parent 5 | 5e2f62d02dcd |
child 9 | 177826044cd9 |
6:490d5cc509ed | 7:cf61fcea0001 |
---|---|
1 <?php |
1 <?php |
2 /** |
2 /** |
3 * Manages WordPress comments |
3 * Core Comment API |
4 * |
4 * |
5 * @package WordPress |
5 * @package WordPress |
6 * @subpackage Comment |
6 * @subpackage Comment |
7 */ |
7 */ |
8 |
8 |
42 // If manual moderation is enabled, skip all checks and return false. |
42 // If manual moderation is enabled, skip all checks and return false. |
43 if ( 1 == get_option('comment_moderation') ) |
43 if ( 1 == get_option('comment_moderation') ) |
44 return false; |
44 return false; |
45 |
45 |
46 /** This filter is documented in wp-includes/comment-template.php */ |
46 /** This filter is documented in wp-includes/comment-template.php */ |
47 $comment = apply_filters( 'comment_text', $comment ); |
47 $comment = apply_filters( 'comment_text', $comment, null, array() ); |
48 |
48 |
49 // Check for the number of external links if a max allowed number is set. |
49 // Check for the number of external links if a max allowed number is set. |
50 if ( $max_links = get_option( 'comment_max_links' ) ) { |
50 if ( $max_links = get_option( 'comment_max_links' ) ) { |
51 $num_links = preg_match_all( '/<a [^>]*href/i', $comment, $out ); |
51 $num_links = preg_match_all( '/<a [^>]*href/i', $comment, $out ); |
52 |
52 |
53 /** |
53 /** |
54 * Filter the maximum number of links allowed in a comment. |
54 * Filters the number of links found in a comment. |
55 * |
55 * |
56 * @since 3.0.0 |
56 * @since 3.0.0 |
57 * |
57 * @since 4.7.0 Added the `$comment` parameter. |
58 * @param int $num_links The number of links allowed. |
58 * |
59 * @param int $num_links The number of links found. |
|
59 * @param string $url Comment author's URL. Included in allowed links total. |
60 * @param string $url Comment author's URL. Included in allowed links total. |
61 * @param string $comment Content of the comment. |
|
60 */ |
62 */ |
61 $num_links = apply_filters( 'comment_max_links_url', $num_links, $url ); |
63 $num_links = apply_filters( 'comment_max_links_url', $num_links, $url, $comment ); |
62 |
64 |
63 /* |
65 /* |
64 * If the number of links in the comment exceeds the allowed amount, |
66 * If the number of links in the comment exceeds the allowed amount, |
65 * fail the check by returning false. |
67 * fail the check by returning false. |
66 */ |
68 */ |
108 * as well as whether there are any moderation keywords (if set) present in the author |
110 * as well as whether there are any moderation keywords (if set) present in the author |
109 * email address. If both checks pass, return true. Otherwise, return false. |
111 * email address. If both checks pass, return true. Otherwise, return false. |
110 */ |
112 */ |
111 if ( 1 == get_option('comment_whitelist')) { |
113 if ( 1 == get_option('comment_whitelist')) { |
112 if ( 'trackback' != $comment_type && 'pingback' != $comment_type && $author != '' && $email != '' ) { |
114 if ( 'trackback' != $comment_type && 'pingback' != $comment_type && $author != '' && $email != '' ) { |
113 // expected_slashed ($author, $email) |
115 $comment_user = get_user_by( 'email', wp_unslash( $email ) ); |
114 $ok_to_comment = $wpdb->get_var("SELECT comment_approved FROM $wpdb->comments WHERE comment_author = '$author' AND comment_author_email = '$email' and comment_approved = '1' LIMIT 1"); |
116 if ( ! empty( $comment_user->ID ) ) { |
117 $ok_to_comment = $wpdb->get_var( $wpdb->prepare( "SELECT comment_approved FROM $wpdb->comments WHERE user_id = %d AND comment_approved = '1' LIMIT 1", $comment_user->ID ) ); |
|
118 } else { |
|
119 // expected_slashed ($author, $email) |
|
120 $ok_to_comment = $wpdb->get_var( $wpdb->prepare( "SELECT comment_approved FROM $wpdb->comments WHERE comment_author = %s AND comment_author_email = %s and comment_approved = '1' LIMIT 1", $author, $email ) ); |
|
121 } |
|
115 if ( ( 1 == $ok_to_comment ) && |
122 if ( ( 1 == $ok_to_comment ) && |
116 ( empty($mod_keys) || false === strpos( $email, $mod_keys) ) ) |
123 ( empty($mod_keys) || false === strpos( $email, $mod_keys) ) ) |
117 return true; |
124 return true; |
118 else |
125 else |
119 return false; |
126 return false; |
126 |
133 |
127 /** |
134 /** |
128 * Retrieve the approved comments for post $post_id. |
135 * Retrieve the approved comments for post $post_id. |
129 * |
136 * |
130 * @since 2.0.0 |
137 * @since 2.0.0 |
131 * @since 4.1.0 Refactored to leverage {@see WP_Comment_Query} over a direct query. |
138 * @since 4.1.0 Refactored to leverage WP_Comment_Query over a direct query. |
132 * |
139 * |
133 * @param int $post_id The ID of the post. |
140 * @param int $post_id The ID of the post. |
134 * @param array $args Optional. See {@see WP_Comment_Query::query()} for information |
141 * @param array $args Optional. See WP_Comment_Query::__construct() for information on accepted arguments. |
135 * on accepted arguments. |
|
136 * @return int|array $comments The approved comments, or number of comments if `$count` |
142 * @return int|array $comments The approved comments, or number of comments if `$count` |
137 * argument is true. |
143 * argument is true. |
138 */ |
144 */ |
139 function get_approved_comments( $post_id, $args = array() ) { |
145 function get_approved_comments( $post_id, $args = array() ) { |
140 if ( ! $post_id ) { |
146 if ( ! $post_id ) { |
159 * after being passed through a filter. If the comment is empty, then the global |
165 * after being passed through a filter. If the comment is empty, then the global |
160 * comment variable will be used, if it is set. |
166 * comment variable will be used, if it is set. |
161 * |
167 * |
162 * @since 2.0.0 |
168 * @since 2.0.0 |
163 * |
169 * |
164 * @global wpdb $wpdb WordPress database abstraction object. |
170 * @global WP_Comment $comment |
165 * |
171 * |
166 * @param object|string|int $comment Comment to retrieve. |
172 * @param WP_Comment|string|int $comment Comment to retrieve. |
167 * @param string $output Optional. OBJECT or ARRAY_A or ARRAY_N constants. |
173 * @param string $output Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to |
168 * @return object|array|null Depends on $output value. |
174 * a WP_Comment object, an associative array, or a numeric array, respectively. Default OBJECT. |
169 */ |
175 * @return WP_Comment|array|null Depends on $output value. |
170 function get_comment(&$comment, $output = OBJECT) { |
176 */ |
171 global $wpdb; |
177 function get_comment( &$comment = null, $output = OBJECT ) { |
172 |
178 if ( empty( $comment ) && isset( $GLOBALS['comment'] ) ) { |
173 if ( empty($comment) ) { |
179 $comment = $GLOBALS['comment']; |
174 if ( isset($GLOBALS['comment']) ) |
180 } |
175 $_comment = & $GLOBALS['comment']; |
181 |
176 else |
182 if ( $comment instanceof WP_Comment ) { |
177 $_comment = null; |
|
178 } elseif ( is_object($comment) ) { |
|
179 wp_cache_add($comment->comment_ID, $comment, 'comment'); |
|
180 $_comment = $comment; |
183 $_comment = $comment; |
184 } elseif ( is_object( $comment ) ) { |
|
185 $_comment = new WP_Comment( $comment ); |
|
181 } else { |
186 } else { |
182 if ( isset($GLOBALS['comment']) && ($GLOBALS['comment']->comment_ID == $comment) ) { |
187 $_comment = WP_Comment::get_instance( $comment ); |
183 $_comment = & $GLOBALS['comment']; |
188 } |
184 } elseif ( ! $_comment = wp_cache_get($comment, 'comment') ) { |
189 |
185 $_comment = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->comments WHERE comment_ID = %d LIMIT 1", $comment)); |
190 if ( ! $_comment ) { |
186 if ( ! $_comment ) |
191 return null; |
187 return null; |
|
188 wp_cache_add($_comment->comment_ID, $_comment, 'comment'); |
|
189 } |
|
190 } |
192 } |
191 |
193 |
192 /** |
194 /** |
193 * Fires after a comment is retrieved. |
195 * Fires after a comment is retrieved. |
194 * |
196 * |
199 $_comment = apply_filters( 'get_comment', $_comment ); |
201 $_comment = apply_filters( 'get_comment', $_comment ); |
200 |
202 |
201 if ( $output == OBJECT ) { |
203 if ( $output == OBJECT ) { |
202 return $_comment; |
204 return $_comment; |
203 } elseif ( $output == ARRAY_A ) { |
205 } elseif ( $output == ARRAY_A ) { |
204 $__comment = get_object_vars($_comment); |
206 return $_comment->to_array(); |
205 return $__comment; |
|
206 } elseif ( $output == ARRAY_N ) { |
207 } elseif ( $output == ARRAY_N ) { |
207 $__comment = array_values(get_object_vars($_comment)); |
208 return array_values( $_comment->to_array() ); |
208 return $__comment; |
209 } |
209 } else { |
210 return $_comment; |
210 return $_comment; |
|
211 } |
|
212 } |
211 } |
213 |
212 |
214 /** |
213 /** |
215 * Retrieve a list of comments. |
214 * Retrieve a list of comments. |
216 * |
215 * |
217 * The comment list can be for the blog as a whole or for an individual post. |
216 * The comment list can be for the blog as a whole or for an individual post. |
218 * |
217 * |
219 * @since 2.7.0 |
218 * @since 2.7.0 |
220 * |
219 * |
221 * @param string|array $args Optional. Array or string of arguments. See {@see WP_Comment_Query::parse_query()} |
220 * @param string|array $args Optional. Array or string of arguments. See WP_Comment_Query::__construct() |
222 * for information on accepted arguments. Default empty. |
221 * for information on accepted arguments. Default empty. |
223 * @return int|array List of comments or number of found comments if `$count` argument is true. |
222 * @return int|array List of comments or number of found comments if `$count` argument is true. |
224 */ |
223 */ |
225 function get_comments( $args = '' ) { |
224 function get_comments( $args = '' ) { |
226 $query = new WP_Comment_Query; |
225 $query = new WP_Comment_Query; |
227 return $query->query( $args ); |
226 return $query->query( $args ); |
228 } |
227 } |
229 |
228 |
230 /** |
229 /** |
231 * WordPress Comment Query class. |
|
232 * |
|
233 * See WP_Comment_Query::__construct() for accepted arguments. |
|
234 * |
|
235 * @since 3.1.0 |
|
236 */ |
|
237 class WP_Comment_Query { |
|
238 /** |
|
239 * SQL for database query. |
|
240 * |
|
241 * @since 4.0.1 |
|
242 * @access public |
|
243 * @var string |
|
244 */ |
|
245 public $request; |
|
246 |
|
247 /** |
|
248 * Metadata query container |
|
249 * |
|
250 * @since 3.5.0 |
|
251 * @access public |
|
252 * @var object WP_Meta_Query |
|
253 */ |
|
254 public $meta_query = false; |
|
255 |
|
256 /** |
|
257 * Date query container |
|
258 * |
|
259 * @since 3.7.0 |
|
260 * @access public |
|
261 * @var object WP_Date_Query |
|
262 */ |
|
263 public $date_query = false; |
|
264 |
|
265 /** |
|
266 * Query vars set by the user. |
|
267 * |
|
268 * @since 3.1.0 |
|
269 * @access public |
|
270 * @var array |
|
271 */ |
|
272 public $query_vars; |
|
273 |
|
274 /** |
|
275 * Default values for query vars. |
|
276 * |
|
277 * @since 4.2.0 |
|
278 * @access public |
|
279 * @var array |
|
280 */ |
|
281 public $query_var_defaults; |
|
282 |
|
283 /** |
|
284 * List of comments located by the query. |
|
285 * |
|
286 * @since 4.0.0 |
|
287 * @access public |
|
288 * @var array |
|
289 */ |
|
290 public $comments; |
|
291 |
|
292 /** |
|
293 * Make private/protected methods readable for backwards compatibility. |
|
294 * |
|
295 * @since 4.0.0 |
|
296 * @access public |
|
297 * |
|
298 * @param callable $name Method to call. |
|
299 * @param array $arguments Arguments to pass when calling. |
|
300 * @return mixed|bool Return value of the callback, false otherwise. |
|
301 */ |
|
302 public function __call( $name, $arguments ) { |
|
303 if ( 'get_search_sql' === $name ) { |
|
304 return call_user_func_array( array( $this, $name ), $arguments ); |
|
305 } |
|
306 return false; |
|
307 } |
|
308 |
|
309 /** |
|
310 * Constructor. |
|
311 * |
|
312 * Sets up the comment query, based on the query vars passed. |
|
313 * |
|
314 * @since 4.2.0 |
|
315 * @access public |
|
316 * |
|
317 * @param string|array $query { |
|
318 * Optional. Array or query string of comment query parameters. Default empty. |
|
319 * |
|
320 * @type string $author_email Comment author email address. Default empty. |
|
321 * @type array $author__in Array of author IDs to include comments for. Default empty. |
|
322 * @type array $author__not_in Array of author IDs to exclude comments for. Default empty. |
|
323 * @type array $comment__in Array of comment IDs to include. Default empty. |
|
324 * @type array $comment__not_in Array of comment IDs to exclude. Default empty. |
|
325 * @type bool $count Whether to return a comment count (true) or array of comment |
|
326 * objects (false). Default false. |
|
327 * @type array $date_query Date query clauses to limit comments by. See WP_Date_Query. |
|
328 * Default null. |
|
329 * @type string $fields Comment fields to return. Accepts 'ids' for comment IDs only or |
|
330 * empty for all fields. Default empty. |
|
331 * @type int $ID Currently unused. |
|
332 * @type array $include_unapproved Array of IDs or email addresses of users whose unapproved comments |
|
333 * will be returned by the query regardless of `$status`. Default empty. |
|
334 * @type int $karma Karma score to retrieve matching comments for. Default empty. |
|
335 * @type string $meta_key Include comments with a matching comment meta key. Default empty. |
|
336 * @type string $meta_value Include comments with a matching comment meta value. Requires |
|
337 * `$meta_key` to be set. Default empty. |
|
338 * @type array $meta_query Meta query clauses to limit retrieved comments by. |
|
339 * See WP_Meta_Query. Default empty. |
|
340 * @type int $number Maximum number of comments to retrieve. Default null (no limit). |
|
341 * @type int $offset Number of comments to offset the query. Used to build LIMIT clause. |
|
342 * Default 0. |
|
343 * @type string|array $orderby Comment status or array of statuses. To use 'meta_value' or |
|
344 * 'meta_value_num', `$meta_key` must also be defined. To sort by |
|
345 * a specific `$meta_query` clause, use that clause's array key. |
|
346 * Accepts 'comment_agent', 'comment_approved', 'comment_author', |
|
347 * 'comment_author_email', 'comment_author_IP', |
|
348 * 'comment_author_url', 'comment_content', 'comment_date', |
|
349 * 'comment_date_gmt', 'comment_ID', 'comment_karma', |
|
350 * 'comment_parent', 'comment_post_ID', 'comment_type', 'user_id', |
|
351 * 'meta_value', 'meta_value_num', the value of $meta_key, and the |
|
352 * array keys of `$meta_query`. Also accepts false, an empty array, |
|
353 * or 'none' to disable `ORDER BY` clause. |
|
354 * Default: 'comment_date_gmt'. |
|
355 * @type string $order How to order retrieved comments. Accepts 'ASC', 'DESC'. |
|
356 * Default: 'DESC'. |
|
357 * @type int $parent Parent ID of comment to retrieve children of. Default empty. |
|
358 * @type array $post_author__in Array of author IDs to retrieve comments for. Default empty. |
|
359 * @type array $post_author__not_in Array of author IDs *not* to retrieve comments for. Default empty. |
|
360 * @type int $post_ID Currently unused. |
|
361 * @type int $post_id Limit results to those affiliated with a given post ID. Default 0. |
|
362 * @type array $post__in Array of post IDs to include affiliated comments for. Default empty. |
|
363 * @type array $post__not_in Array of post IDs to exclude affiliated comments for. Default empty. |
|
364 * @type int $post_author Comment author ID to limit results by. Default empty. |
|
365 * @type string $post_status Post status to retrieve affiliated comments for. Default empty. |
|
366 * @type string $post_type Post type to retrieve affiliated comments for. Default empty. |
|
367 * @type string $post_name Post name to retrieve affiliated comments for. Default empty. |
|
368 * @type int $post_parent Post parent ID to retrieve affiliated comments for. Default empty. |
|
369 * @type string $search Search term(s) to retrieve matching comments for. Default empty. |
|
370 * @type string $status Comment status to limit results by. Accepts 'hold' |
|
371 * (`comment_status=0`), 'approve' (`comment_status=1`), 'all', or a |
|
372 * custom comment status. Default 'all'. |
|
373 * @type string|array $type Include comments of a given type, or array of types. Accepts |
|
374 * 'comment', 'pings' (includes 'pingback' and 'trackback'), or any |
|
375 * custom type string. Default empty. |
|
376 * @type array $type__in Include comments from a given array of comment types. Default empty. |
|
377 * @type array $type__not_in Exclude comments from a given array of comment types. Default empty. |
|
378 * @type int $user_id Include comments for a specific user ID. Default empty. |
|
379 * } |
|
380 * @return WP_Comment_Query WP_Comment_Query instance. |
|
381 */ |
|
382 public function __construct( $query = '' ) { |
|
383 $this->query_var_defaults = array( |
|
384 'author_email' => '', |
|
385 'author__in' => '', |
|
386 'author__not_in' => '', |
|
387 'include_unapproved' => '', |
|
388 'fields' => '', |
|
389 'ID' => '', |
|
390 'comment__in' => '', |
|
391 'comment__not_in' => '', |
|
392 'karma' => '', |
|
393 'number' => '', |
|
394 'offset' => '', |
|
395 'orderby' => '', |
|
396 'order' => 'DESC', |
|
397 'parent' => '', |
|
398 'post_author__in' => '', |
|
399 'post_author__not_in' => '', |
|
400 'post_ID' => '', |
|
401 'post_id' => 0, |
|
402 'post__in' => '', |
|
403 'post__not_in' => '', |
|
404 'post_author' => '', |
|
405 'post_name' => '', |
|
406 'post_parent' => '', |
|
407 'post_status' => '', |
|
408 'post_type' => '', |
|
409 'status' => 'all', |
|
410 'type' => '', |
|
411 'type__in' => '', |
|
412 'type__not_in' => '', |
|
413 'user_id' => '', |
|
414 'search' => '', |
|
415 'count' => false, |
|
416 'meta_key' => '', |
|
417 'meta_value' => '', |
|
418 'meta_query' => '', |
|
419 'date_query' => null, // See WP_Date_Query |
|
420 ); |
|
421 |
|
422 if ( ! empty( $query ) ) { |
|
423 $this->query( $query ); |
|
424 } |
|
425 } |
|
426 |
|
427 /** |
|
428 * Parse arguments passed to the comment query with default query parameters. |
|
429 * |
|
430 * @since 4.2.0 Extracted from WP_Comment_Query::query(). |
|
431 * |
|
432 * @access public |
|
433 * |
|
434 * @param string|array $query WP_Comment_Query arguments. See WP_Comment_Query::__construct() |
|
435 */ |
|
436 public function parse_query( $query = '' ) { |
|
437 if ( empty( $query ) ) { |
|
438 $query = $this->query_vars; |
|
439 } |
|
440 |
|
441 $this->query_vars = wp_parse_args( $query, $this->query_var_defaults ); |
|
442 do_action_ref_array( 'parse_comment_query', array( &$this ) ); |
|
443 } |
|
444 |
|
445 /** |
|
446 * Sets up the WordPress query for retrieving comments. |
|
447 * |
|
448 * @since 3.1.0 |
|
449 * @since 4.1.0 Introduced 'comment__in', 'comment__not_in', 'post_author__in', |
|
450 * 'post_author__not_in', 'author__in', 'author__not_in', 'post__in', |
|
451 * 'post__not_in', 'include_unapproved', 'type__in', and 'type__not_in' |
|
452 * arguments to $query_vars. |
|
453 * @since 4.2.0 Moved parsing to WP_Comment_Query::parse_query(). |
|
454 * @access public |
|
455 * |
|
456 * @param string|array $query Array or URL query string of parameters. |
|
457 * @return array List of comments. |
|
458 */ |
|
459 public function query( $query ) { |
|
460 $this->query_vars = wp_parse_args( $query ); |
|
461 return $this->get_comments(); |
|
462 } |
|
463 |
|
464 /** |
|
465 * Get a list of comments matching the query vars. |
|
466 * |
|
467 * @since 4.2.0 |
|
468 * @access public |
|
469 * |
|
470 * @global wpdb $wpdb WordPress database abstraction object. |
|
471 * |
|
472 * @return array The list of comments. |
|
473 */ |
|
474 public function get_comments() { |
|
475 global $wpdb; |
|
476 |
|
477 $groupby = ''; |
|
478 |
|
479 $this->parse_query(); |
|
480 |
|
481 // Parse meta query |
|
482 $this->meta_query = new WP_Meta_Query(); |
|
483 $this->meta_query->parse_query_vars( $this->query_vars ); |
|
484 |
|
485 if ( ! empty( $this->meta_query->queries ) ) { |
|
486 $meta_query_clauses = $this->meta_query->get_sql( 'comment', $wpdb->comments, 'comment_ID', $this ); |
|
487 } |
|
488 |
|
489 /** |
|
490 * Fires before comments are retrieved. |
|
491 * |
|
492 * @since 3.1.0 |
|
493 * |
|
494 * @param WP_Comment_Query &$this Current instance of WP_Comment_Query, passed by reference. |
|
495 */ |
|
496 do_action_ref_array( 'pre_get_comments', array( &$this ) ); |
|
497 |
|
498 // $args can include anything. Only use the args defined in the query_var_defaults to compute the key. |
|
499 $key = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ) ) ); |
|
500 $last_changed = wp_cache_get( 'last_changed', 'comment' ); |
|
501 if ( ! $last_changed ) { |
|
502 $last_changed = microtime(); |
|
503 wp_cache_set( 'last_changed', $last_changed, 'comment' ); |
|
504 } |
|
505 $cache_key = "get_comments:$key:$last_changed"; |
|
506 |
|
507 if ( $cache = wp_cache_get( $cache_key, 'comment' ) ) { |
|
508 $this->comments = $cache; |
|
509 return $this->comments; |
|
510 } |
|
511 |
|
512 $where = array(); |
|
513 |
|
514 // Assemble clauses related to 'comment_approved'. |
|
515 $approved_clauses = array(); |
|
516 |
|
517 // 'status' accepts an array or a comma-separated string. |
|
518 $status_clauses = array(); |
|
519 $statuses = $this->query_vars['status']; |
|
520 if ( ! is_array( $statuses ) ) { |
|
521 $statuses = preg_split( '/[\s,]+/', $statuses ); |
|
522 } |
|
523 |
|
524 // 'any' overrides other statuses. |
|
525 if ( ! in_array( 'any', $statuses ) ) { |
|
526 foreach ( $statuses as $status ) { |
|
527 switch ( $status ) { |
|
528 case 'hold' : |
|
529 $status_clauses[] = "comment_approved = '0'"; |
|
530 break; |
|
531 |
|
532 case 'approve' : |
|
533 $status_clauses[] = "comment_approved = '1'"; |
|
534 break; |
|
535 |
|
536 case 'all' : |
|
537 case '' : |
|
538 $status_clauses[] = "( comment_approved = '0' OR comment_approved = '1' )"; |
|
539 break; |
|
540 |
|
541 default : |
|
542 $status_clauses[] = $wpdb->prepare( "comment_approved = %s", $status ); |
|
543 break; |
|
544 } |
|
545 } |
|
546 |
|
547 if ( ! empty( $status_clauses ) ) { |
|
548 $approved_clauses[] = '( ' . implode( ' OR ', $status_clauses ) . ' )'; |
|
549 } |
|
550 } |
|
551 |
|
552 // User IDs or emails whose unapproved comments are included, regardless of $status. |
|
553 if ( ! empty( $this->query_vars['include_unapproved'] ) ) { |
|
554 $include_unapproved = $this->query_vars['include_unapproved']; |
|
555 |
|
556 // Accepts arrays or comma-separated strings. |
|
557 if ( ! is_array( $include_unapproved ) ) { |
|
558 $include_unapproved = preg_split( '/[\s,]+/', $include_unapproved ); |
|
559 } |
|
560 |
|
561 $unapproved_ids = $unapproved_emails = array(); |
|
562 foreach ( $include_unapproved as $unapproved_identifier ) { |
|
563 // Numeric values are assumed to be user ids. |
|
564 if ( is_numeric( $unapproved_identifier ) ) { |
|
565 $approved_clauses[] = $wpdb->prepare( "( user_id = %d AND comment_approved = '0' )", $unapproved_identifier ); |
|
566 |
|
567 // Otherwise we match against email addresses. |
|
568 } else { |
|
569 $approved_clauses[] = $wpdb->prepare( "( comment_author_email = %s AND comment_approved = '0' )", $unapproved_identifier ); |
|
570 } |
|
571 } |
|
572 } |
|
573 |
|
574 // Collapse comment_approved clauses into a single OR-separated clause. |
|
575 if ( ! empty( $approved_clauses ) ) { |
|
576 if ( 1 === count( $approved_clauses ) ) { |
|
577 $where[] = $approved_clauses[0]; |
|
578 } else { |
|
579 $where[] = '( ' . implode( ' OR ', $approved_clauses ) . ' )'; |
|
580 } |
|
581 } |
|
582 |
|
583 $order = ( 'ASC' == strtoupper( $this->query_vars['order'] ) ) ? 'ASC' : 'DESC'; |
|
584 |
|
585 // Disable ORDER BY with 'none', an empty array, or boolean false. |
|
586 if ( in_array( $this->query_vars['orderby'], array( 'none', array(), false ), true ) ) { |
|
587 $orderby = ''; |
|
588 } elseif ( ! empty( $this->query_vars['orderby'] ) ) { |
|
589 $ordersby = is_array( $this->query_vars['orderby'] ) ? |
|
590 $this->query_vars['orderby'] : |
|
591 preg_split( '/[,\s]/', $this->query_vars['orderby'] ); |
|
592 |
|
593 $orderby_array = array(); |
|
594 $found_orderby_comment_ID = false; |
|
595 foreach ( $ordersby as $_key => $_value ) { |
|
596 if ( ! $_value ) { |
|
597 continue; |
|
598 } |
|
599 |
|
600 if ( is_int( $_key ) ) { |
|
601 $_orderby = $_value; |
|
602 $_order = $order; |
|
603 } else { |
|
604 $_orderby = $_key; |
|
605 $_order = $_value; |
|
606 } |
|
607 |
|
608 if ( ! $found_orderby_comment_ID && 'comment_ID' === $_orderby ) { |
|
609 $found_orderby_comment_ID = true; |
|
610 } |
|
611 |
|
612 $parsed = $this->parse_orderby( $_orderby ); |
|
613 |
|
614 if ( ! $parsed ) { |
|
615 continue; |
|
616 } |
|
617 |
|
618 $orderby_array[] = $parsed . ' ' . $this->parse_order( $_order ); |
|
619 } |
|
620 |
|
621 // If no valid clauses were found, order by comment_date_gmt. |
|
622 if ( empty( $orderby_array ) ) { |
|
623 $orderby_array[] = "$wpdb->comments.comment_date_gmt $order"; |
|
624 } |
|
625 |
|
626 // To ensure determinate sorting, always include a comment_ID clause. |
|
627 if ( ! $found_orderby_comment_ID ) { |
|
628 $comment_ID_order = ''; |
|
629 |
|
630 // Inherit order from comment_date or comment_date_gmt, if available. |
|
631 foreach ( $orderby_array as $orderby_clause ) { |
|
632 if ( preg_match( '/comment_date(?:_gmt)*\ (ASC|DESC)/', $orderby_clause, $match ) ) { |
|
633 $comment_ID_order = $match[1]; |
|
634 break; |
|
635 } |
|
636 } |
|
637 |
|
638 // If no date-related order is available, use the date from the first available clause. |
|
639 if ( ! $comment_ID_order ) { |
|
640 foreach ( $orderby_array as $orderby_clause ) { |
|
641 if ( false !== strpos( 'ASC', $orderby_clause ) ) { |
|
642 $comment_ID_order = 'ASC'; |
|
643 } else { |
|
644 $comment_ID_order = 'DESC'; |
|
645 } |
|
646 |
|
647 break; |
|
648 } |
|
649 } |
|
650 |
|
651 // Default to DESC. |
|
652 if ( ! $comment_ID_order ) { |
|
653 $comment_ID_order = 'DESC'; |
|
654 } |
|
655 |
|
656 $orderby_array[] = "$wpdb->comments.comment_ID $comment_ID_order"; |
|
657 } |
|
658 |
|
659 $orderby = implode( ', ', $orderby_array ); |
|
660 } else { |
|
661 $orderby = "$wpdb->comments.comment_date_gmt $order"; |
|
662 } |
|
663 |
|
664 $number = absint( $this->query_vars['number'] ); |
|
665 $offset = absint( $this->query_vars['offset'] ); |
|
666 |
|
667 if ( ! empty( $number ) ) { |
|
668 if ( $offset ) { |
|
669 $limits = 'LIMIT ' . $offset . ',' . $number; |
|
670 } else { |
|
671 $limits = 'LIMIT ' . $number; |
|
672 } |
|
673 } else { |
|
674 $limits = ''; |
|
675 } |
|
676 |
|
677 if ( $this->query_vars['count'] ) { |
|
678 $fields = 'COUNT(*)'; |
|
679 } else { |
|
680 switch ( strtolower( $this->query_vars['fields'] ) ) { |
|
681 case 'ids': |
|
682 $fields = "$wpdb->comments.comment_ID"; |
|
683 break; |
|
684 default: |
|
685 $fields = "*"; |
|
686 break; |
|
687 } |
|
688 } |
|
689 |
|
690 $join = ''; |
|
691 |
|
692 $post_id = absint( $this->query_vars['post_id'] ); |
|
693 if ( ! empty( $post_id ) ) { |
|
694 $where[] = $wpdb->prepare( 'comment_post_ID = %d', $post_id ); |
|
695 } |
|
696 |
|
697 // Parse comment IDs for an IN clause. |
|
698 if ( ! empty( $this->query_vars['comment__in'] ) ) { |
|
699 $where[] = 'comment_ID IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['comment__in'] ) ) . ' )'; |
|
700 } |
|
701 |
|
702 // Parse comment IDs for a NOT IN clause. |
|
703 if ( ! empty( $this->query_vars['comment__not_in'] ) ) { |
|
704 $where[] = 'comment_ID NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['comment__not_in'] ) ) . ' )'; |
|
705 } |
|
706 |
|
707 // Parse comment post IDs for an IN clause. |
|
708 if ( ! empty( $this->query_vars['post__in'] ) ) { |
|
709 $where[] = 'comment_post_ID IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__in'] ) ) . ' )'; |
|
710 } |
|
711 |
|
712 // Parse comment post IDs for a NOT IN clause. |
|
713 if ( ! empty( $this->query_vars['post__not_in'] ) ) { |
|
714 $where[] = 'comment_post_ID NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__not_in'] ) ) . ' )'; |
|
715 } |
|
716 |
|
717 if ( '' !== $this->query_vars['author_email'] ) { |
|
718 $where[] = $wpdb->prepare( 'comment_author_email = %s', $this->query_vars['author_email'] ); |
|
719 } |
|
720 |
|
721 if ( '' !== $this->query_vars['karma'] ) { |
|
722 $where[] = $wpdb->prepare( 'comment_karma = %d', $this->query_vars['karma'] ); |
|
723 } |
|
724 |
|
725 // Filtering by comment_type: 'type', 'type__in', 'type__not_in'. |
|
726 $raw_types = array( |
|
727 'IN' => array_merge( (array) $this->query_vars['type'], (array) $this->query_vars['type__in'] ), |
|
728 'NOT IN' => (array) $this->query_vars['type__not_in'], |
|
729 ); |
|
730 |
|
731 $comment_types = array(); |
|
732 foreach ( $raw_types as $operator => $_raw_types ) { |
|
733 $_raw_types = array_unique( $_raw_types ); |
|
734 |
|
735 foreach ( $_raw_types as $type ) { |
|
736 switch ( $type ) { |
|
737 // An empty translates to 'all', for backward compatibility |
|
738 case '': |
|
739 case 'all' : |
|
740 break; |
|
741 |
|
742 case 'comment': |
|
743 case 'comments': |
|
744 $comment_types[ $operator ][] = "''"; |
|
745 break; |
|
746 |
|
747 case 'pings': |
|
748 $comment_types[ $operator ][] = "'pingback'"; |
|
749 $comment_types[ $operator ][] = "'trackback'"; |
|
750 break; |
|
751 |
|
752 default: |
|
753 $comment_types[ $operator ][] = $wpdb->prepare( '%s', $type ); |
|
754 break; |
|
755 } |
|
756 } |
|
757 |
|
758 if ( ! empty( $comment_types[ $operator ] ) ) { |
|
759 $types_sql = implode( ', ', $comment_types[ $operator ] ); |
|
760 $where[] = "comment_type $operator ($types_sql)"; |
|
761 } |
|
762 } |
|
763 |
|
764 if ( '' !== $this->query_vars['parent'] ) { |
|
765 $where[] = $wpdb->prepare( 'comment_parent = %d', $this->query_vars['parent'] ); |
|
766 } |
|
767 |
|
768 if ( is_array( $this->query_vars['user_id'] ) ) { |
|
769 $where[] = 'user_id IN (' . implode( ',', array_map( 'absint', $this->query_vars['user_id'] ) ) . ')'; |
|
770 } elseif ( '' !== $this->query_vars['user_id'] ) { |
|
771 $where[] = $wpdb->prepare( 'user_id = %d', $this->query_vars['user_id'] ); |
|
772 } |
|
773 |
|
774 if ( '' !== $this->query_vars['search'] ) { |
|
775 $search_sql = $this->get_search_sql( |
|
776 $this->query_vars['search'], |
|
777 array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_author_IP', 'comment_content' ) |
|
778 ); |
|
779 |
|
780 // Strip leading 'AND'. |
|
781 $where[] = preg_replace( '/^\s*AND\s*/', '', $search_sql ); |
|
782 } |
|
783 |
|
784 // If any post-related query vars are passed, join the posts table. |
|
785 $join_posts_table = false; |
|
786 $plucked = wp_array_slice_assoc( $this->query_vars, array( 'post_author', 'post_name', 'post_parent', 'post_status', 'post_type' ) ); |
|
787 $post_fields = array_filter( $plucked ); |
|
788 |
|
789 if ( ! empty( $post_fields ) ) { |
|
790 $join_posts_table = true; |
|
791 foreach ( $post_fields as $field_name => $field_value ) { |
|
792 // $field_value may be an array. |
|
793 $esses = array_fill( 0, count( (array) $field_value ), '%s' ); |
|
794 $where[] = $wpdb->prepare( " {$wpdb->posts}.{$field_name} IN (" . implode( ',', $esses ) . ')', $field_value ); |
|
795 } |
|
796 } |
|
797 |
|
798 // Comment author IDs for an IN clause. |
|
799 if ( ! empty( $this->query_vars['author__in'] ) ) { |
|
800 $where[] = 'user_id IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__in'] ) ) . ' )'; |
|
801 } |
|
802 |
|
803 // Comment author IDs for a NOT IN clause. |
|
804 if ( ! empty( $this->query_vars['author__not_in'] ) ) { |
|
805 $where[] = 'user_id NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['author__not_in'] ) ) . ' )'; |
|
806 } |
|
807 |
|
808 // Post author IDs for an IN clause. |
|
809 if ( ! empty( $this->query_vars['post_author__in'] ) ) { |
|
810 $join_posts_table = true; |
|
811 $where[] = 'post_author IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__in'] ) ) . ' )'; |
|
812 } |
|
813 |
|
814 // Post author IDs for a NOT IN clause. |
|
815 if ( ! empty( $this->query_vars['post_author__not_in'] ) ) { |
|
816 $join_posts_table = true; |
|
817 $where[] = 'post_author NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post_author__not_in'] ) ) . ' )'; |
|
818 } |
|
819 |
|
820 if ( $join_posts_table ) { |
|
821 $join = "JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->comments.comment_post_ID"; |
|
822 } |
|
823 |
|
824 if ( ! empty( $meta_query_clauses ) ) { |
|
825 $join .= $meta_query_clauses['join']; |
|
826 |
|
827 // Strip leading 'AND'. |
|
828 $where[] = preg_replace( '/^\s*AND\s*/', '', $meta_query_clauses['where'] ); |
|
829 |
|
830 if ( ! $this->query_vars['count'] ) { |
|
831 $groupby = "{$wpdb->comments}.comment_ID"; |
|
832 } |
|
833 } |
|
834 |
|
835 $date_query = $this->query_vars['date_query']; |
|
836 if ( ! empty( $date_query ) && is_array( $date_query ) ) { |
|
837 $date_query_object = new WP_Date_Query( $date_query, 'comment_date' ); |
|
838 $where[] = preg_replace( '/^\s*AND\s*/', '', $date_query_object->get_sql() ); |
|
839 } |
|
840 |
|
841 $where = implode( ' AND ', $where ); |
|
842 |
|
843 $pieces = array( 'fields', 'join', 'where', 'orderby', 'limits', 'groupby' ); |
|
844 /** |
|
845 * Filter the comment query clauses. |
|
846 * |
|
847 * @since 3.1.0 |
|
848 * |
|
849 * @param array $pieces A compacted array of comment query clauses. |
|
850 * @param WP_Comment_Query &$this Current instance of WP_Comment_Query, passed by reference. |
|
851 */ |
|
852 $clauses = apply_filters_ref_array( 'comments_clauses', array( compact( $pieces ), &$this ) ); |
|
853 |
|
854 $fields = isset( $clauses[ 'fields' ] ) ? $clauses[ 'fields' ] : ''; |
|
855 $join = isset( $clauses[ 'join' ] ) ? $clauses[ 'join' ] : ''; |
|
856 $where = isset( $clauses[ 'where' ] ) ? $clauses[ 'where' ] : ''; |
|
857 $orderby = isset( $clauses[ 'orderby' ] ) ? $clauses[ 'orderby' ] : ''; |
|
858 $limits = isset( $clauses[ 'limits' ] ) ? $clauses[ 'limits' ] : ''; |
|
859 $groupby = isset( $clauses[ 'groupby' ] ) ? $clauses[ 'groupby' ] : ''; |
|
860 |
|
861 if ( $where ) { |
|
862 $where = 'WHERE ' . $where; |
|
863 } |
|
864 |
|
865 if ( $groupby ) { |
|
866 $groupby = 'GROUP BY ' . $groupby; |
|
867 } |
|
868 |
|
869 if ( $orderby ) { |
|
870 $orderby = "ORDER BY $orderby"; |
|
871 } |
|
872 |
|
873 $this->request = "SELECT $fields FROM $wpdb->comments $join $where $groupby $orderby $limits"; |
|
874 |
|
875 if ( $this->query_vars['count'] ) { |
|
876 return $wpdb->get_var( $this->request ); |
|
877 } |
|
878 |
|
879 if ( 'ids' == $this->query_vars['fields'] ) { |
|
880 $this->comments = $wpdb->get_col( $this->request ); |
|
881 return array_map( 'intval', $this->comments ); |
|
882 } |
|
883 |
|
884 $results = $wpdb->get_results( $this->request ); |
|
885 /** |
|
886 * Filter the comment query results. |
|
887 * |
|
888 * @since 3.1.0 |
|
889 * |
|
890 * @param array $results An array of comments. |
|
891 * @param WP_Comment_Query &$this Current instance of WP_Comment_Query, passed by reference. |
|
892 */ |
|
893 $comments = apply_filters_ref_array( 'the_comments', array( $results, &$this ) ); |
|
894 |
|
895 wp_cache_add( $cache_key, $comments, 'comment' ); |
|
896 |
|
897 $this->comments = $comments; |
|
898 return $this->comments; |
|
899 } |
|
900 |
|
901 /** |
|
902 * Used internally to generate an SQL string for searching across multiple columns |
|
903 * |
|
904 * @access protected |
|
905 * @since 3.1.0 |
|
906 * |
|
907 * @param string $string |
|
908 * @param array $cols |
|
909 * @return string |
|
910 */ |
|
911 protected function get_search_sql( $string, $cols ) { |
|
912 global $wpdb; |
|
913 |
|
914 $like = '%' . $wpdb->esc_like( $string ) . '%'; |
|
915 |
|
916 $searches = array(); |
|
917 foreach ( $cols as $col ) { |
|
918 $searches[] = $wpdb->prepare( "$col LIKE %s", $like ); |
|
919 } |
|
920 |
|
921 return ' AND (' . implode(' OR ', $searches) . ')'; |
|
922 } |
|
923 |
|
924 /** |
|
925 * Parse and sanitize 'orderby' keys passed to the comment query. |
|
926 * |
|
927 * @since 4.2.0 |
|
928 * @access protected |
|
929 * |
|
930 * @global wpdb $wpdb WordPress database abstraction object. |
|
931 * |
|
932 * @param string $orderby Alias for the field to order by. |
|
933 * @return string|bool Value to used in the ORDER clause. False otherwise. |
|
934 */ |
|
935 protected function parse_orderby( $orderby ) { |
|
936 global $wpdb; |
|
937 |
|
938 $allowed_keys = array( |
|
939 'comment_agent', |
|
940 'comment_approved', |
|
941 'comment_author', |
|
942 'comment_author_email', |
|
943 'comment_author_IP', |
|
944 'comment_author_url', |
|
945 'comment_content', |
|
946 'comment_date', |
|
947 'comment_date_gmt', |
|
948 'comment_ID', |
|
949 'comment_karma', |
|
950 'comment_parent', |
|
951 'comment_post_ID', |
|
952 'comment_type', |
|
953 'user_id', |
|
954 ); |
|
955 |
|
956 if ( ! empty( $this->query_vars['meta_key'] ) ) { |
|
957 $allowed_keys[] = $this->query_vars['meta_key']; |
|
958 $allowed_keys[] = 'meta_value'; |
|
959 $allowed_keys[] = 'meta_value_num'; |
|
960 } |
|
961 |
|
962 $meta_query_clauses = $this->meta_query->get_clauses(); |
|
963 if ( $meta_query_clauses ) { |
|
964 $allowed_keys = array_merge( $allowed_keys, array_keys( $meta_query_clauses ) ); |
|
965 } |
|
966 |
|
967 $parsed = false; |
|
968 if ( $orderby == $this->query_vars['meta_key'] || $orderby == 'meta_value' ) { |
|
969 $parsed = "$wpdb->commentmeta.meta_value"; |
|
970 } else if ( $orderby == 'meta_value_num' ) { |
|
971 $parsed = "$wpdb->commentmeta.meta_value+0"; |
|
972 } else if ( in_array( $orderby, $allowed_keys ) ) { |
|
973 |
|
974 if ( isset( $meta_query_clauses[ $orderby ] ) ) { |
|
975 $meta_clause = $meta_query_clauses[ $orderby ]; |
|
976 $parsed = sprintf( "CAST(%s.meta_value AS %s)", esc_sql( $meta_clause['alias'] ), esc_sql( $meta_clause['cast'] ) ); |
|
977 } else { |
|
978 $parsed = "$wpdb->comments.$orderby"; |
|
979 } |
|
980 } |
|
981 |
|
982 return $parsed; |
|
983 } |
|
984 |
|
985 /** |
|
986 * Parse an 'order' query variable and cast it to ASC or DESC as necessary. |
|
987 * |
|
988 * @since 4.2.0 |
|
989 * @access protected |
|
990 * |
|
991 * @param string $order The 'order' query variable. |
|
992 * @return string The sanitized 'order' query variable. |
|
993 */ |
|
994 protected function parse_order( $order ) { |
|
995 if ( ! is_string( $order ) || empty( $order ) ) { |
|
996 return 'DESC'; |
|
997 } |
|
998 |
|
999 if ( 'ASC' === strtoupper( $order ) ) { |
|
1000 return 'ASC'; |
|
1001 } else { |
|
1002 return 'DESC'; |
|
1003 } |
|
1004 } |
|
1005 } |
|
1006 |
|
1007 /** |
|
1008 * Retrieve all of the WordPress supported comment statuses. |
230 * Retrieve all of the WordPress supported comment statuses. |
1009 * |
231 * |
1010 * Comments have a limited set of valid status values, this provides the comment |
232 * Comments have a limited set of valid status values, this provides the comment |
1011 * status values and descriptions. |
233 * status values and descriptions. |
1012 * |
234 * |
1014 * |
236 * |
1015 * @return array List of comment statuses. |
237 * @return array List of comment statuses. |
1016 */ |
238 */ |
1017 function get_comment_statuses() { |
239 function get_comment_statuses() { |
1018 $status = array( |
240 $status = array( |
1019 'hold' => __('Unapproved'), |
241 'hold' => __( 'Unapproved' ), |
1020 /* translators: comment status */ |
242 'approve' => _x( 'Approved', 'comment status' ), |
1021 'approve' => _x('Approved', 'adjective'), |
243 'spam' => _x( 'Spam', 'comment status' ), |
1022 /* translators: comment status */ |
244 'trash' => _x( 'Trash', 'comment status' ), |
1023 'spam' => _x('Spam', 'adjective'), |
|
1024 ); |
245 ); |
1025 |
246 |
1026 return $status; |
247 return $status; |
1027 } |
248 } |
1028 |
249 |
1029 /** |
250 /** |
251 * Gets the default comment status for a post type. |
|
252 * |
|
253 * @since 4.3.0 |
|
254 * |
|
255 * @param string $post_type Optional. Post type. Default 'post'. |
|
256 * @param string $comment_type Optional. Comment type. Default 'comment'. |
|
257 * @return string Expected return value is 'open' or 'closed'. |
|
258 */ |
|
259 function get_default_comment_status( $post_type = 'post', $comment_type = 'comment' ) { |
|
260 switch ( $comment_type ) { |
|
261 case 'pingback' : |
|
262 case 'trackback' : |
|
263 $supports = 'trackbacks'; |
|
264 $option = 'ping'; |
|
265 break; |
|
266 default : |
|
267 $supports = 'comments'; |
|
268 $option = 'comment'; |
|
269 } |
|
270 |
|
271 // Set the status. |
|
272 if ( 'page' === $post_type ) { |
|
273 $status = 'closed'; |
|
274 } elseif ( post_type_supports( $post_type, $supports ) ) { |
|
275 $status = get_option( "default_{$option}_status" ); |
|
276 } else { |
|
277 $status = 'closed'; |
|
278 } |
|
279 |
|
280 /** |
|
281 * Filters the default comment status for the given post type. |
|
282 * |
|
283 * @since 4.3.0 |
|
284 * |
|
285 * @param string $status Default status for the given post type, |
|
286 * either 'open' or 'closed'. |
|
287 * @param string $post_type Post type. Default is `post`. |
|
288 * @param string $comment_type Type of comment. Default is `comment`. |
|
289 */ |
|
290 return apply_filters( 'get_default_comment_status' , $status, $post_type, $comment_type ); |
|
291 } |
|
292 |
|
293 /** |
|
1030 * The date the last comment was modified. |
294 * The date the last comment was modified. |
1031 * |
295 * |
1032 * @since 1.5.0 |
296 * @since 1.5.0 |
297 * @since 4.7.0 Replaced caching the modified date in a local static variable |
|
298 * with the Object Cache API. |
|
1033 * |
299 * |
1034 * @global wpdb $wpdb WordPress database abstraction object. |
300 * @global wpdb $wpdb WordPress database abstraction object. |
1035 * |
301 * |
1036 * @param string $timezone Which timezone to use in reference to 'gmt', 'blog', |
302 * @param string $timezone Which timezone to use in reference to 'gmt', 'blog', or 'server' locations. |
1037 * or 'server' locations. |
303 * @return string|false Last comment modified date on success, false on failure. |
1038 * @return string Last comment modified date. |
304 */ |
1039 */ |
305 function get_lastcommentmodified( $timezone = 'server' ) { |
1040 function get_lastcommentmodified($timezone = 'server') { |
|
1041 global $wpdb; |
306 global $wpdb; |
1042 static $cache_lastcommentmodified = array(); |
307 |
1043 |
308 $timezone = strtolower( $timezone ); |
1044 if ( isset($cache_lastcommentmodified[$timezone]) ) |
309 $key = "lastcommentmodified:$timezone"; |
1045 return $cache_lastcommentmodified[$timezone]; |
310 |
1046 |
311 $comment_modified_date = wp_cache_get( $key, 'timeinfo' ); |
1047 $add_seconds_server = date('Z'); |
312 if ( false !== $comment_modified_date ) { |
1048 |
313 return $comment_modified_date; |
1049 switch ( strtolower($timezone)) { |
314 } |
315 |
|
316 switch ( $timezone ) { |
|
1050 case 'gmt': |
317 case 'gmt': |
1051 $lastcommentmodified = $wpdb->get_var("SELECT comment_date_gmt FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1"); |
318 $comment_modified_date = $wpdb->get_var( "SELECT comment_date_gmt FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1" ); |
1052 break; |
319 break; |
1053 case 'blog': |
320 case 'blog': |
1054 $lastcommentmodified = $wpdb->get_var("SELECT comment_date FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1"); |
321 $comment_modified_date = $wpdb->get_var( "SELECT comment_date FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1" ); |
1055 break; |
322 break; |
1056 case 'server': |
323 case 'server': |
1057 $lastcommentmodified = $wpdb->get_var($wpdb->prepare("SELECT DATE_ADD(comment_date_gmt, INTERVAL %s SECOND) FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1", $add_seconds_server)); |
324 $add_seconds_server = date( 'Z' ); |
325 |
|
326 $comment_modified_date = $wpdb->get_var( $wpdb->prepare( "SELECT DATE_ADD(comment_date_gmt, INTERVAL %s SECOND) FROM $wpdb->comments WHERE comment_approved = '1' ORDER BY comment_date_gmt DESC LIMIT 1", $add_seconds_server ) ); |
|
1058 break; |
327 break; |
1059 } |
328 } |
1060 |
329 |
1061 $cache_lastcommentmodified[$timezone] = $lastcommentmodified; |
330 if ( $comment_modified_date ) { |
1062 |
331 wp_cache_set( $key, $comment_modified_date, 'timeinfo' ); |
1063 return $lastcommentmodified; |
332 |
333 return $comment_modified_date; |
|
334 } |
|
335 |
|
336 return false; |
|
1064 } |
337 } |
1065 |
338 |
1066 /** |
339 /** |
1067 * The amount of comments in a post or total comments. |
340 * The amount of comments in a post or total comments. |
1068 * |
341 * |
1069 * A lot like {@link wp_count_comments()}, in that they both return comment |
342 * A lot like wp_count_comments(), in that they both return comment stats (albeit with different types). |
1070 * stats (albeit with different types). The {@link wp_count_comments()} actual |
343 * The wp_count_comments() actually caches, but this function does not. |
1071 * caches, but this function does not. |
|
1072 * |
344 * |
1073 * @since 2.0.0 |
345 * @since 2.0.0 |
1074 * |
346 * |
1075 * @global wpdb $wpdb WordPress database abstraction object. |
347 * @global wpdb $wpdb WordPress database abstraction object. |
1076 * |
348 * |
1093 {$where} |
365 {$where} |
1094 GROUP BY comment_approved |
366 GROUP BY comment_approved |
1095 ", ARRAY_A); |
367 ", ARRAY_A); |
1096 |
368 |
1097 $comment_count = array( |
369 $comment_count = array( |
1098 "approved" => 0, |
370 'approved' => 0, |
1099 "awaiting_moderation" => 0, |
371 'awaiting_moderation' => 0, |
1100 "spam" => 0, |
372 'spam' => 0, |
1101 "total_comments" => 0 |
373 'trash' => 0, |
374 'post-trashed' => 0, |
|
375 'total_comments' => 0, |
|
376 'all' => 0, |
|
1102 ); |
377 ); |
1103 |
378 |
1104 foreach ( $totals as $row ) { |
379 foreach ( $totals as $row ) { |
1105 switch ( $row['comment_approved'] ) { |
380 switch ( $row['comment_approved'] ) { |
381 case 'trash': |
|
382 $comment_count['trash'] = $row['total']; |
|
383 break; |
|
384 case 'post-trashed': |
|
385 $comment_count['post-trashed'] = $row['total']; |
|
386 break; |
|
1106 case 'spam': |
387 case 'spam': |
1107 $comment_count['spam'] = $row['total']; |
388 $comment_count['spam'] = $row['total']; |
1108 $comment_count["total_comments"] += $row['total']; |
389 $comment_count['total_comments'] += $row['total']; |
1109 break; |
390 break; |
1110 case 1: |
391 case '1': |
1111 $comment_count['approved'] = $row['total']; |
392 $comment_count['approved'] = $row['total']; |
1112 $comment_count['total_comments'] += $row['total']; |
393 $comment_count['total_comments'] += $row['total']; |
394 $comment_count['all'] += $row['total']; |
|
1113 break; |
395 break; |
1114 case 0: |
396 case '0': |
1115 $comment_count['awaiting_moderation'] = $row['total']; |
397 $comment_count['awaiting_moderation'] = $row['total']; |
1116 $comment_count['total_comments'] += $row['total']; |
398 $comment_count['total_comments'] += $row['total']; |
399 $comment_count['all'] += $row['total']; |
|
1117 break; |
400 break; |
1118 default: |
401 default: |
1119 break; |
402 break; |
1120 } |
403 } |
1121 } |
404 } |
1138 * @param mixed $meta_value Metadata value. |
421 * @param mixed $meta_value Metadata value. |
1139 * @param bool $unique Optional, default is false. Whether the same key should not be added. |
422 * @param bool $unique Optional, default is false. Whether the same key should not be added. |
1140 * @return int|bool Meta ID on success, false on failure. |
423 * @return int|bool Meta ID on success, false on failure. |
1141 */ |
424 */ |
1142 function add_comment_meta($comment_id, $meta_key, $meta_value, $unique = false) { |
425 function add_comment_meta($comment_id, $meta_key, $meta_value, $unique = false) { |
1143 return add_metadata('comment', $comment_id, $meta_key, $meta_value, $unique); |
426 $added = add_metadata( 'comment', $comment_id, $meta_key, $meta_value, $unique ); |
427 if ( $added ) { |
|
428 wp_cache_set( 'last_changed', microtime(), 'comment' ); |
|
429 } |
|
430 return $added; |
|
1144 } |
431 } |
1145 |
432 |
1146 /** |
433 /** |
1147 * Remove metadata matching criteria from a comment. |
434 * Remove metadata matching criteria from a comment. |
1148 * |
435 * |
1157 * @param string $meta_key Metadata name. |
444 * @param string $meta_key Metadata name. |
1158 * @param mixed $meta_value Optional. Metadata value. |
445 * @param mixed $meta_value Optional. Metadata value. |
1159 * @return bool True on success, false on failure. |
446 * @return bool True on success, false on failure. |
1160 */ |
447 */ |
1161 function delete_comment_meta($comment_id, $meta_key, $meta_value = '') { |
448 function delete_comment_meta($comment_id, $meta_key, $meta_value = '') { |
1162 return delete_metadata('comment', $comment_id, $meta_key, $meta_value); |
449 $deleted = delete_metadata( 'comment', $comment_id, $meta_key, $meta_value ); |
450 if ( $deleted ) { |
|
451 wp_cache_set( 'last_changed', microtime(), 'comment' ); |
|
452 } |
|
453 return $deleted; |
|
1163 } |
454 } |
1164 |
455 |
1165 /** |
456 /** |
1166 * Retrieve comment meta field for a comment. |
457 * Retrieve comment meta field for a comment. |
1167 * |
458 * |
1194 * @param mixed $meta_value Metadata value. |
485 * @param mixed $meta_value Metadata value. |
1195 * @param mixed $prev_value Optional. Previous value to check before removing. |
486 * @param mixed $prev_value Optional. Previous value to check before removing. |
1196 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure. |
487 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure. |
1197 */ |
488 */ |
1198 function update_comment_meta($comment_id, $meta_key, $meta_value, $prev_value = '') { |
489 function update_comment_meta($comment_id, $meta_key, $meta_value, $prev_value = '') { |
1199 return update_metadata('comment', $comment_id, $meta_key, $meta_value, $prev_value); |
490 $updated = update_metadata( 'comment', $comment_id, $meta_key, $meta_value, $prev_value ); |
491 if ( $updated ) { |
|
492 wp_cache_set( 'last_changed', microtime(), 'comment' ); |
|
493 } |
|
494 return $updated; |
|
495 } |
|
496 |
|
497 /** |
|
498 * Queues comments for metadata lazy-loading. |
|
499 * |
|
500 * @since 4.5.0 |
|
501 * |
|
502 * @param array $comments Array of comment objects. |
|
503 */ |
|
504 function wp_queue_comments_for_comment_meta_lazyload( $comments ) { |
|
505 // Don't use `wp_list_pluck()` to avoid by-reference manipulation. |
|
506 $comment_ids = array(); |
|
507 if ( is_array( $comments ) ) { |
|
508 foreach ( $comments as $comment ) { |
|
509 if ( $comment instanceof WP_Comment ) { |
|
510 $comment_ids[] = $comment->comment_ID; |
|
511 } |
|
512 } |
|
513 } |
|
514 |
|
515 if ( $comment_ids ) { |
|
516 $lazyloader = wp_metadata_lazyloader(); |
|
517 $lazyloader->queue_objects( 'comment', $comment_ids ); |
|
518 } |
|
1200 } |
519 } |
1201 |
520 |
1202 /** |
521 /** |
1203 * Sets the cookies used to store an unauthenticated commentator's identity. Typically used |
522 * Sets the cookies used to store an unauthenticated commentator's identity. Typically used |
1204 * to recall previous comments by this commentator that are still held in moderation. |
523 * to recall previous comments by this commentator that are still held in moderation. |
1205 * |
524 * |
1206 * @param object $comment Comment object. |
|
1207 * @param object $user Comment author's object. |
|
1208 * |
|
1209 * @since 3.4.0 |
525 * @since 3.4.0 |
1210 */ |
526 * @since 4.9.6 The `$cookies_consent` parameter was added. |
1211 function wp_set_comment_cookies($comment, $user) { |
527 * |
1212 if ( $user->exists() ) |
528 * @param WP_Comment $comment Comment object. |
529 * @param WP_User $user Comment author's user object. The user may not exist. |
|
530 * @param boolean $cookies_consent Optional. Comment author's consent to store cookies. Default true. |
|
531 */ |
|
532 function wp_set_comment_cookies( $comment, $user, $cookies_consent = true ) { |
|
533 // If the user already exists, or the user opted out of cookies, don't set cookies. |
|
534 if ( $user->exists() ) { |
|
1213 return; |
535 return; |
536 } |
|
537 |
|
538 if ( false === $cookies_consent ) { |
|
539 // Remove any existing cookies. |
|
540 $past = time() - YEAR_IN_SECONDS; |
|
541 setcookie( 'comment_author_' . COOKIEHASH, ' ', $past, COOKIEPATH, COOKIE_DOMAIN ); |
|
542 setcookie( 'comment_author_email_' . COOKIEHASH, ' ', $past, COOKIEPATH, COOKIE_DOMAIN ); |
|
543 setcookie( 'comment_author_url_' . COOKIEHASH, ' ', $past, COOKIEPATH, COOKIE_DOMAIN ); |
|
544 |
|
545 return; |
|
546 } |
|
1214 |
547 |
1215 /** |
548 /** |
1216 * Filter the lifetime of the comment cookie in seconds. |
549 * Filters the lifetime of the comment cookie in seconds. |
1217 * |
550 * |
1218 * @since 2.8.0 |
551 * @since 2.8.0 |
1219 * |
552 * |
1220 * @param int $seconds Comment cookie lifetime. Default 30000000. |
553 * @param int $seconds Comment cookie lifetime. Default 30000000. |
1221 */ |
554 */ |
1222 $comment_cookie_lifetime = apply_filters( 'comment_cookie_lifetime', 30000000 ); |
555 $comment_cookie_lifetime = time() + apply_filters( 'comment_cookie_lifetime', 30000000 ); |
1223 $secure = ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) ); |
556 $secure = ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) ); |
1224 setcookie( 'comment_author_' . COOKIEHASH, $comment->comment_author, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); |
557 setcookie( 'comment_author_' . COOKIEHASH, $comment->comment_author, $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); |
1225 setcookie( 'comment_author_email_' . COOKIEHASH, $comment->comment_author_email, time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); |
558 setcookie( 'comment_author_email_' . COOKIEHASH, $comment->comment_author_email, $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); |
1226 setcookie( 'comment_author_url_' . COOKIEHASH, esc_url($comment->comment_author_url), time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); |
559 setcookie( 'comment_author_url_' . COOKIEHASH, esc_url( $comment->comment_author_url ), $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); |
1227 } |
560 } |
1228 |
561 |
1229 /** |
562 /** |
1230 * Sanitizes the cookies sent to the user already. |
563 * Sanitizes the cookies sent to the user already. |
1231 * |
564 * |
1235 * @since 2.0.4 |
568 * @since 2.0.4 |
1236 */ |
569 */ |
1237 function sanitize_comment_cookies() { |
570 function sanitize_comment_cookies() { |
1238 if ( isset( $_COOKIE['comment_author_' . COOKIEHASH] ) ) { |
571 if ( isset( $_COOKIE['comment_author_' . COOKIEHASH] ) ) { |
1239 /** |
572 /** |
1240 * Filter the comment author's name cookie before it is set. |
573 * Filters the comment author's name cookie before it is set. |
1241 * |
574 * |
1242 * When this filter hook is evaluated in wp_filter_comment(), |
575 * When this filter hook is evaluated in wp_filter_comment(), |
1243 * the comment author's name string is passed. |
576 * the comment author's name string is passed. |
1244 * |
577 * |
1245 * @since 1.5.0 |
578 * @since 1.5.0 |
1252 $_COOKIE['comment_author_' . COOKIEHASH] = $comment_author; |
585 $_COOKIE['comment_author_' . COOKIEHASH] = $comment_author; |
1253 } |
586 } |
1254 |
587 |
1255 if ( isset( $_COOKIE['comment_author_email_' . COOKIEHASH] ) ) { |
588 if ( isset( $_COOKIE['comment_author_email_' . COOKIEHASH] ) ) { |
1256 /** |
589 /** |
1257 * Filter the comment author's email cookie before it is set. |
590 * Filters the comment author's email cookie before it is set. |
1258 * |
591 * |
1259 * When this filter hook is evaluated in wp_filter_comment(), |
592 * When this filter hook is evaluated in wp_filter_comment(), |
1260 * the comment author's email string is passed. |
593 * the comment author's email string is passed. |
1261 * |
594 * |
1262 * @since 1.5.0 |
595 * @since 1.5.0 |
1269 $_COOKIE['comment_author_email_'.COOKIEHASH] = $comment_author_email; |
602 $_COOKIE['comment_author_email_'.COOKIEHASH] = $comment_author_email; |
1270 } |
603 } |
1271 |
604 |
1272 if ( isset( $_COOKIE['comment_author_url_' . COOKIEHASH] ) ) { |
605 if ( isset( $_COOKIE['comment_author_url_' . COOKIEHASH] ) ) { |
1273 /** |
606 /** |
1274 * Filter the comment author's URL cookie before it is set. |
607 * Filters the comment author's URL cookie before it is set. |
1275 * |
608 * |
1276 * When this filter hook is evaluated in wp_filter_comment(), |
609 * When this filter hook is evaluated in wp_filter_comment(), |
1277 * the comment author's URL string is passed. |
610 * the comment author's URL string is passed. |
1278 * |
611 * |
1279 * @since 1.5.0 |
612 * @since 1.5.0 |
1288 |
621 |
1289 /** |
622 /** |
1290 * Validates whether this comment is allowed to be made. |
623 * Validates whether this comment is allowed to be made. |
1291 * |
624 * |
1292 * @since 2.0.0 |
625 * @since 2.0.0 |
626 * @since 4.7.0 The `$avoid_die` parameter was added, allowing the function to |
|
627 * return a WP_Error object instead of dying. |
|
1293 * |
628 * |
1294 * @global wpdb $wpdb WordPress database abstraction object. |
629 * @global wpdb $wpdb WordPress database abstraction object. |
1295 * |
630 * |
1296 * @param array $commentdata Contains information on the comment |
631 * @param array $commentdata Contains information on the comment. |
1297 * @return mixed Signifies the approval status (0|1|'spam') |
632 * @param bool $avoid_die When true, a disallowed comment will result in the function |
1298 */ |
633 * returning a WP_Error object, rather than executing wp_die(). |
1299 function wp_allow_comment( $commentdata ) { |
634 * Default false. |
635 * @return int|string|WP_Error Allowed comments return the approval status (0|1|'spam'). |
|
636 * If `$avoid_die` is true, disallowed comments return a WP_Error. |
|
637 */ |
|
638 function wp_allow_comment( $commentdata, $avoid_die = false ) { |
|
1300 global $wpdb; |
639 global $wpdb; |
1301 |
640 |
1302 // Simple duplicate check |
641 // Simple duplicate check |
1303 // expected_slashed ($comment_post_ID, $comment_author, $comment_author_email, $comment_content) |
642 // expected_slashed ($comment_post_ID, $comment_author, $comment_author_email, $comment_content) |
1304 $dupe = $wpdb->prepare( |
643 $dupe = $wpdb->prepare( |
1307 wp_unslash( $commentdata['comment_parent'] ), |
646 wp_unslash( $commentdata['comment_parent'] ), |
1308 wp_unslash( $commentdata['comment_author'] ) |
647 wp_unslash( $commentdata['comment_author'] ) |
1309 ); |
648 ); |
1310 if ( $commentdata['comment_author_email'] ) { |
649 if ( $commentdata['comment_author_email'] ) { |
1311 $dupe .= $wpdb->prepare( |
650 $dupe .= $wpdb->prepare( |
1312 "OR comment_author_email = %s ", |
651 "AND comment_author_email = %s ", |
1313 wp_unslash( $commentdata['comment_author_email'] ) |
652 wp_unslash( $commentdata['comment_author_email'] ) |
1314 ); |
653 ); |
1315 } |
654 } |
1316 $dupe .= $wpdb->prepare( |
655 $dupe .= $wpdb->prepare( |
1317 ") AND comment_content = %s LIMIT 1", |
656 ") AND comment_content = %s LIMIT 1", |
1318 wp_unslash( $commentdata['comment_content'] ) |
657 wp_unslash( $commentdata['comment_content'] ) |
1319 ); |
658 ); |
1320 if ( $wpdb->get_var( $dupe ) ) { |
659 |
660 $dupe_id = $wpdb->get_var( $dupe ); |
|
661 |
|
662 /** |
|
663 * Filters the ID, if any, of the duplicate comment found when creating a new comment. |
|
664 * |
|
665 * Return an empty value from this filter to allow what WP considers a duplicate comment. |
|
666 * |
|
667 * @since 4.4.0 |
|
668 * |
|
669 * @param int $dupe_id ID of the comment identified as a duplicate. |
|
670 * @param array $commentdata Data for the comment being created. |
|
671 */ |
|
672 $dupe_id = apply_filters( 'duplicate_comment_id', $dupe_id, $commentdata ); |
|
673 |
|
674 if ( $dupe_id ) { |
|
1321 /** |
675 /** |
1322 * Fires immediately after a duplicate comment is detected. |
676 * Fires immediately after a duplicate comment is detected. |
1323 * |
677 * |
1324 * @since 3.0.0 |
678 * @since 3.0.0 |
1325 * |
679 * |
1326 * @param array $commentdata Comment data. |
680 * @param array $commentdata Comment data. |
1327 */ |
681 */ |
1328 do_action( 'comment_duplicate_trigger', $commentdata ); |
682 do_action( 'comment_duplicate_trigger', $commentdata ); |
1329 if ( defined( 'DOING_AJAX' ) ) { |
683 if ( true === $avoid_die ) { |
1330 die( __('Duplicate comment detected; it looks as though you’ve already said that!') ); |
684 return new WP_Error( 'comment_duplicate', __( 'Duplicate comment detected; it looks as though you’ve already said that!' ), 409 ); |
685 } else { |
|
686 if ( wp_doing_ajax() ) { |
|
687 die( __('Duplicate comment detected; it looks as though you’ve already said that!') ); |
|
688 } |
|
689 |
|
690 wp_die( __( 'Duplicate comment detected; it looks as though you’ve already said that!' ), 409 ); |
|
1331 } |
691 } |
1332 wp_die( __( 'Duplicate comment detected; it looks as though you’ve already said that!' ), 409 ); |
|
1333 } |
692 } |
1334 |
693 |
1335 /** |
694 /** |
1336 * Fires immediately before a comment is marked approved. |
695 * Fires immediately before a comment is marked approved. |
1337 * |
696 * |
1338 * Allows checking for comment flooding. |
697 * Allows checking for comment flooding. |
1339 * |
698 * |
1340 * @since 2.3.0 |
699 * @since 2.3.0 |
700 * @since 4.7.0 The `$avoid_die` parameter was added. |
|
1341 * |
701 * |
1342 * @param string $comment_author_IP Comment author's IP address. |
702 * @param string $comment_author_IP Comment author's IP address. |
1343 * @param string $comment_author_email Comment author's email. |
703 * @param string $comment_author_email Comment author's email. |
1344 * @param string $comment_date_gmt GMT date the comment was posted. |
704 * @param string $comment_date_gmt GMT date the comment was posted. |
705 * @param bool $avoid_die Whether to prevent executing wp_die() |
|
706 * or die() if a comment flood is occurring. |
|
1345 */ |
707 */ |
1346 do_action( |
708 do_action( |
1347 'check_comment_flood', |
709 'check_comment_flood', |
1348 $commentdata['comment_author_IP'], |
710 $commentdata['comment_author_IP'], |
1349 $commentdata['comment_author_email'], |
711 $commentdata['comment_author_email'], |
1350 $commentdata['comment_date_gmt'] |
712 $commentdata['comment_date_gmt'], |
713 $avoid_die |
|
1351 ); |
714 ); |
715 |
|
716 /** |
|
717 * Filters whether a comment is part of a comment flood. |
|
718 * |
|
719 * The default check is wp_check_comment_flood(). See check_comment_flood_db(). |
|
720 * |
|
721 * @since 4.7.0 |
|
722 * |
|
723 * @param bool $is_flood Is a comment flooding occurring? Default false. |
|
724 * @param string $comment_author_IP Comment author's IP address. |
|
725 * @param string $comment_author_email Comment author's email. |
|
726 * @param string $comment_date_gmt GMT date the comment was posted. |
|
727 * @param bool $avoid_die Whether to prevent executing wp_die() |
|
728 * or die() if a comment flood is occurring. |
|
729 */ |
|
730 $is_flood = apply_filters( |
|
731 'wp_is_comment_flood', |
|
732 false, |
|
733 $commentdata['comment_author_IP'], |
|
734 $commentdata['comment_author_email'], |
|
735 $commentdata['comment_date_gmt'], |
|
736 $avoid_die |
|
737 ); |
|
738 |
|
739 if ( $is_flood ) { |
|
740 return new WP_Error( 'comment_flood', __( 'You are posting comments too quickly. Slow down.' ), 429 ); |
|
741 } |
|
1352 |
742 |
1353 if ( ! empty( $commentdata['user_id'] ) ) { |
743 if ( ! empty( $commentdata['user_id'] ) ) { |
1354 $user = get_userdata( $commentdata['user_id'] ); |
744 $user = get_userdata( $commentdata['user_id'] ); |
1355 $post_author = $wpdb->get_var( $wpdb->prepare( |
745 $post_author = $wpdb->get_var( $wpdb->prepare( |
1356 "SELECT post_author FROM $wpdb->posts WHERE ID = %d LIMIT 1", |
746 "SELECT post_author FROM $wpdb->posts WHERE ID = %d LIMIT 1", |
1383 $commentdata['comment_author_url'], |
773 $commentdata['comment_author_url'], |
1384 $commentdata['comment_content'], |
774 $commentdata['comment_content'], |
1385 $commentdata['comment_author_IP'], |
775 $commentdata['comment_author_IP'], |
1386 $commentdata['comment_agent'] |
776 $commentdata['comment_agent'] |
1387 ) ) { |
777 ) ) { |
1388 $approved = 'spam'; |
778 $approved = EMPTY_TRASH_DAYS ? 'trash' : 'spam'; |
1389 } |
779 } |
1390 } |
780 } |
1391 |
781 |
1392 /** |
782 /** |
1393 * Filter a comment's approval status before it is set. |
783 * Filters a comment's approval status before it is set. |
1394 * |
784 * |
1395 * @since 2.1.0 |
785 * @since 2.1.0 |
1396 * |
786 * @since 4.9.0 Returning a WP_Error value from the filter will shortcircuit comment insertion and |
1397 * @param bool|string $approved The approval status. Accepts 1, 0, or 'spam'. |
787 * allow skipping further processing. |
1398 * @param array $commentdata Comment data. |
788 * |
789 * @param bool|string|WP_Error $approved The approval status. Accepts 1, 0, 'spam' or WP_Error. |
|
790 * @param array $commentdata Comment data. |
|
1399 */ |
791 */ |
1400 $approved = apply_filters( 'pre_comment_approved', $approved, $commentdata ); |
792 $approved = apply_filters( 'pre_comment_approved', $approved, $commentdata ); |
1401 return $approved; |
793 return $approved; |
1402 } |
794 } |
1403 |
795 |
1404 /** |
796 /** |
1405 * Check whether comment flooding is occurring. |
797 * Hooks WP's native database-based comment-flood check. |
798 * |
|
799 * This wrapper maintains backward compatibility with plugins that expect to |
|
800 * be able to unhook the legacy check_comment_flood_db() function from |
|
801 * 'check_comment_flood' using remove_action(). |
|
802 * |
|
803 * @since 2.3.0 |
|
804 * @since 4.7.0 Converted to be an add_filter() wrapper. |
|
805 */ |
|
806 function check_comment_flood_db() { |
|
807 add_filter( 'wp_is_comment_flood', 'wp_check_comment_flood', 10, 5 ); |
|
808 } |
|
809 |
|
810 /** |
|
811 * Checks whether comment flooding is occurring. |
|
1406 * |
812 * |
1407 * Won't run, if current user can manage options, so to not block |
813 * Won't run, if current user can manage options, so to not block |
1408 * administrators. |
814 * administrators. |
1409 * |
815 * |
1410 * @since 2.3.0 |
816 * @since 4.7.0 |
1411 * |
817 * |
1412 * @global wpdb $wpdb WordPress database abstraction object. |
818 * @global wpdb $wpdb WordPress database abstraction object. |
1413 * |
819 * |
1414 * @param string $ip Comment IP. |
820 * @param bool $is_flood Is a comment flooding occurring? |
1415 * @param string $email Comment author email address. |
821 * @param string $ip Comment author's IP address. |
1416 * @param string $date MySQL time string. |
822 * @param string $email Comment author's email address. |
1417 */ |
823 * @param string $date MySQL time string. |
1418 function check_comment_flood_db( $ip, $email, $date ) { |
824 * @param bool $avoid_die When true, a disallowed comment will result in the function |
825 * returning a WP_Error object, rather than executing wp_die(). |
|
826 * Default false. |
|
827 * @return bool Whether comment flooding is occurring. |
|
828 */ |
|
829 function wp_check_comment_flood( $is_flood, $ip, $email, $date, $avoid_die = false ) { |
|
830 |
|
1419 global $wpdb; |
831 global $wpdb; |
1420 if ( current_user_can( 'manage_options' ) ) |
832 |
1421 return; // don't throttle admins |
833 // Another callback has declared a flood. Trust it. |
834 if ( true === $is_flood ) { |
|
835 return $is_flood; |
|
836 } |
|
837 |
|
838 // don't throttle admins or moderators |
|
839 if ( current_user_can( 'manage_options' ) || current_user_can( 'moderate_comments' ) ) { |
|
840 return false; |
|
841 } |
|
1422 $hour_ago = gmdate( 'Y-m-d H:i:s', time() - HOUR_IN_SECONDS ); |
842 $hour_ago = gmdate( 'Y-m-d H:i:s', time() - HOUR_IN_SECONDS ); |
1423 if ( $lasttime = $wpdb->get_var( $wpdb->prepare( "SELECT `comment_date_gmt` FROM `$wpdb->comments` WHERE `comment_date_gmt` >= %s AND ( `comment_author_IP` = %s OR `comment_author_email` = %s ) ORDER BY `comment_date_gmt` DESC LIMIT 1", $hour_ago, $ip, $email ) ) ) { |
843 |
844 if ( is_user_logged_in() ) { |
|
845 $user = get_current_user_id(); |
|
846 $check_column = '`user_id`'; |
|
847 } else { |
|
848 $user = $ip; |
|
849 $check_column = '`comment_author_IP`'; |
|
850 } |
|
851 |
|
852 $sql = $wpdb->prepare( |
|
853 "SELECT `comment_date_gmt` FROM `$wpdb->comments` WHERE `comment_date_gmt` >= %s AND ( $check_column = %s OR `comment_author_email` = %s ) ORDER BY `comment_date_gmt` DESC LIMIT 1", |
|
854 $hour_ago, |
|
855 $user, |
|
856 $email |
|
857 ); |
|
858 $lasttime = $wpdb->get_var( $sql ); |
|
859 if ( $lasttime ) { |
|
1424 $time_lastcomment = mysql2date('U', $lasttime, false); |
860 $time_lastcomment = mysql2date('U', $lasttime, false); |
1425 $time_newcomment = mysql2date('U', $date, false); |
861 $time_newcomment = mysql2date('U', $date, false); |
1426 /** |
862 /** |
1427 * Filter the comment flood status. |
863 * Filters the comment flood status. |
1428 * |
864 * |
1429 * @since 2.1.0 |
865 * @since 2.1.0 |
1430 * |
866 * |
1431 * @param bool $bool Whether a comment flood is occurring. Default false. |
867 * @param bool $bool Whether a comment flood is occurring. Default false. |
1432 * @param int $time_lastcomment Timestamp of when the last comment was posted. |
868 * @param int $time_lastcomment Timestamp of when the last comment was posted. |
1441 * |
877 * |
1442 * @param int $time_lastcomment Timestamp of when the last comment was posted. |
878 * @param int $time_lastcomment Timestamp of when the last comment was posted. |
1443 * @param int $time_newcomment Timestamp of when the new comment was posted. |
879 * @param int $time_newcomment Timestamp of when the new comment was posted. |
1444 */ |
880 */ |
1445 do_action( 'comment_flood_trigger', $time_lastcomment, $time_newcomment ); |
881 do_action( 'comment_flood_trigger', $time_lastcomment, $time_newcomment ); |
1446 |
882 if ( true === $avoid_die ) { |
1447 if ( defined('DOING_AJAX') ) |
883 return true; |
1448 die( __('You are posting comments too quickly. Slow down.') ); |
884 } else { |
1449 |
885 if ( wp_doing_ajax() ) { |
1450 wp_die( __( 'You are posting comments too quickly. Slow down.' ), 429 ); |
886 die( __('You are posting comments too quickly. Slow down.') ); |
887 } |
|
888 |
|
889 wp_die( __( 'You are posting comments too quickly. Slow down.' ), 429 ); |
|
890 } |
|
1451 } |
891 } |
1452 } |
892 } |
893 |
|
894 return false; |
|
1453 } |
895 } |
1454 |
896 |
1455 /** |
897 /** |
1456 * Separates an array of comments into an array keyed by comment_type. |
898 * Separates an array of comments into an array keyed by comment_type. |
1457 * |
899 * |
1480 * |
922 * |
1481 * @since 2.7.0 |
923 * @since 2.7.0 |
1482 * |
924 * |
1483 * @uses Walker_Comment |
925 * @uses Walker_Comment |
1484 * |
926 * |
1485 * @param array $comments Optional array of comment objects. Defaults to $wp_query->comments |
927 * @global WP_Query $wp_query |
1486 * @param int $per_page Optional comments per page. |
928 * |
1487 * @param boolean $threaded Optional control over flat or threaded comments. |
929 * @param array $comments Optional array of WP_Comment objects. Defaults to $wp_query->comments |
930 * @param int $per_page Optional comments per page. |
|
931 * @param bool $threaded Optional control over flat or threaded comments. |
|
1488 * @return int Number of comment pages. |
932 * @return int Number of comment pages. |
1489 */ |
933 */ |
1490 function get_comment_pages_count( $comments = null, $per_page = null, $threaded = null ) { |
934 function get_comment_pages_count( $comments = null, $per_page = null, $threaded = null ) { |
1491 global $wp_query; |
935 global $wp_query; |
1492 |
936 |
1497 $comments = $wp_query->comments; |
941 $comments = $wp_query->comments; |
1498 |
942 |
1499 if ( empty($comments) ) |
943 if ( empty($comments) ) |
1500 return 0; |
944 return 0; |
1501 |
945 |
1502 if ( ! get_option( 'page_comments' ) ) |
946 if ( ! get_option( 'page_comments' ) ) { |
1503 return 1; |
947 return 1; |
948 } |
|
1504 |
949 |
1505 if ( !isset($per_page) ) |
950 if ( !isset($per_page) ) |
1506 $per_page = (int) get_query_var('comments_per_page'); |
951 $per_page = (int) get_query_var('comments_per_page'); |
1507 if ( 0 === $per_page ) |
952 if ( 0 === $per_page ) |
1508 $per_page = (int) get_option('comments_per_page'); |
953 $per_page = (int) get_option('comments_per_page'); |
1525 /** |
970 /** |
1526 * Calculate what page number a comment will appear on for comment paging. |
971 * Calculate what page number a comment will appear on for comment paging. |
1527 * |
972 * |
1528 * @since 2.7.0 |
973 * @since 2.7.0 |
1529 * |
974 * |
1530 * @param int $comment_ID Comment ID. |
975 * @global wpdb $wpdb WordPress database abstraction object. |
1531 * @param array $args Optional args. |
976 * |
977 * @param int $comment_ID Comment ID. |
|
978 * @param array $args { |
|
979 * Array of optional arguments. |
|
980 * @type string $type Limit paginated comments to those matching a given type. Accepts 'comment', |
|
981 * 'trackback', 'pingback', 'pings' (trackbacks and pingbacks), or 'all'. |
|
982 * Default is 'all'. |
|
983 * @type int $per_page Per-page count to use when calculating pagination. Defaults to the value of the |
|
984 * 'comments_per_page' option. |
|
985 * @type int|string $max_depth If greater than 1, comment page will be determined for the top-level parent of |
|
986 * `$comment_ID`. Defaults to the value of the 'thread_comments_depth' option. |
|
987 * } * |
|
1532 * @return int|null Comment page number or null on error. |
988 * @return int|null Comment page number or null on error. |
1533 */ |
989 */ |
1534 function get_page_of_comment( $comment_ID, $args = array() ) { |
990 function get_page_of_comment( $comment_ID, $args = array() ) { |
1535 global $wpdb; |
991 global $wpdb; |
1536 |
992 |
993 $page = null; |
|
994 |
|
1537 if ( !$comment = get_comment( $comment_ID ) ) |
995 if ( !$comment = get_comment( $comment_ID ) ) |
1538 return; |
996 return; |
1539 |
997 |
1540 $defaults = array( 'type' => 'all', 'page' => '', 'per_page' => '', 'max_depth' => '' ); |
998 $defaults = array( 'type' => 'all', 'page' => '', 'per_page' => '', 'max_depth' => '' ); |
1541 $args = wp_parse_args( $args, $defaults ); |
999 $args = wp_parse_args( $args, $defaults ); |
1542 |
1000 $original_args = $args; |
1543 if ( '' === $args['per_page'] && get_option('page_comments') ) |
1001 |
1544 $args['per_page'] = get_query_var('comments_per_page'); |
1002 // Order of precedence: 1. `$args['per_page']`, 2. 'comments_per_page' query_var, 3. 'comments_per_page' option. |
1003 if ( get_option( 'page_comments' ) ) { |
|
1004 if ( '' === $args['per_page'] ) { |
|
1005 $args['per_page'] = get_query_var( 'comments_per_page' ); |
|
1006 } |
|
1007 |
|
1008 if ( '' === $args['per_page'] ) { |
|
1009 $args['per_page'] = get_option( 'comments_per_page' ); |
|
1010 } |
|
1011 } |
|
1012 |
|
1545 if ( empty($args['per_page']) ) { |
1013 if ( empty($args['per_page']) ) { |
1546 $args['per_page'] = 0; |
1014 $args['per_page'] = 0; |
1547 $args['page'] = 0; |
1015 $args['page'] = 0; |
1548 } |
1016 } |
1549 if ( $args['per_page'] < 1 ) |
1017 |
1550 return 1; |
1018 if ( $args['per_page'] < 1 ) { |
1551 |
1019 $page = 1; |
1552 if ( '' === $args['max_depth'] ) { |
1020 } |
1553 if ( get_option('thread_comments') ) |
1021 |
1554 $args['max_depth'] = get_option('thread_comments_depth'); |
1022 if ( null === $page ) { |
1555 else |
1023 if ( '' === $args['max_depth'] ) { |
1556 $args['max_depth'] = -1; |
1024 if ( get_option('thread_comments') ) |
1557 } |
1025 $args['max_depth'] = get_option('thread_comments_depth'); |
1558 |
1026 else |
1559 // Find this comment's top level parent if threading is enabled |
1027 $args['max_depth'] = -1; |
1560 if ( $args['max_depth'] > 1 && 0 != $comment->comment_parent ) |
1028 } |
1561 return get_page_of_comment( $comment->comment_parent, $args ); |
1029 |
1562 |
1030 // Find this comment's top level parent if threading is enabled |
1563 $allowedtypes = array( |
1031 if ( $args['max_depth'] > 1 && 0 != $comment->comment_parent ) |
1564 'comment' => '', |
1032 return get_page_of_comment( $comment->comment_parent, $args ); |
1565 'pingback' => 'pingback', |
1033 |
1566 'trackback' => 'trackback', |
1034 $comment_args = array( |
1035 'type' => $args['type'], |
|
1036 'post_id' => $comment->comment_post_ID, |
|
1037 'fields' => 'ids', |
|
1038 'count' => true, |
|
1039 'status' => 'approve', |
|
1040 'parent' => 0, |
|
1041 'date_query' => array( |
|
1042 array( |
|
1043 'column' => "$wpdb->comments.comment_date_gmt", |
|
1044 'before' => $comment->comment_date_gmt, |
|
1045 ) |
|
1046 ), |
|
1047 ); |
|
1048 |
|
1049 $comment_query = new WP_Comment_Query(); |
|
1050 $older_comment_count = $comment_query->query( $comment_args ); |
|
1051 |
|
1052 // No older comments? Then it's page #1. |
|
1053 if ( 0 == $older_comment_count ) { |
|
1054 $page = 1; |
|
1055 |
|
1056 // Divide comments older than this one by comments per page to get this comment's page number |
|
1057 } else { |
|
1058 $page = ceil( ( $older_comment_count + 1 ) / $args['per_page'] ); |
|
1059 } |
|
1060 } |
|
1061 |
|
1062 /** |
|
1063 * Filters the calculated page on which a comment appears. |
|
1064 * |
|
1065 * @since 4.4.0 |
|
1066 * @since 4.7.0 Introduced the `$comment_ID` parameter. |
|
1067 * |
|
1068 * @param int $page Comment page. |
|
1069 * @param array $args { |
|
1070 * Arguments used to calculate pagination. These include arguments auto-detected by the function, |
|
1071 * based on query vars, system settings, etc. For pristine arguments passed to the function, |
|
1072 * see `$original_args`. |
|
1073 * |
|
1074 * @type string $type Type of comments to count. |
|
1075 * @type int $page Calculated current page. |
|
1076 * @type int $per_page Calculated number of comments per page. |
|
1077 * @type int $max_depth Maximum comment threading depth allowed. |
|
1078 * } |
|
1079 * @param array $original_args { |
|
1080 * Array of arguments passed to the function. Some or all of these may not be set. |
|
1081 * |
|
1082 * @type string $type Type of comments to count. |
|
1083 * @type int $page Current comment page. |
|
1084 * @type int $per_page Number of comments per page. |
|
1085 * @type int $max_depth Maximum comment threading depth allowed. |
|
1086 * } |
|
1087 * @param int $comment_ID ID of the comment. |
|
1088 */ |
|
1089 return apply_filters( 'get_page_of_comment', (int) $page, $args, $original_args, $comment_ID ); |
|
1090 } |
|
1091 |
|
1092 /** |
|
1093 * Retrieves the maximum character lengths for the comment form fields. |
|
1094 * |
|
1095 * @since 4.5.0 |
|
1096 * |
|
1097 * @global wpdb $wpdb WordPress database abstraction object. |
|
1098 * |
|
1099 * @return array Maximum character length for the comment form fields. |
|
1100 */ |
|
1101 function wp_get_comment_fields_max_lengths() { |
|
1102 global $wpdb; |
|
1103 |
|
1104 $lengths = array( |
|
1105 'comment_author' => 245, |
|
1106 'comment_author_email' => 100, |
|
1107 'comment_author_url' => 200, |
|
1108 'comment_content' => 65525, |
|
1567 ); |
1109 ); |
1568 |
1110 |
1569 $comtypewhere = ( 'all' != $args['type'] && isset($allowedtypes[$args['type']]) ) ? " AND comment_type = '" . $allowedtypes[$args['type']] . "'" : ''; |
1111 if ( $wpdb->is_mysql ) { |
1570 |
1112 foreach ( $lengths as $column => $length ) { |
1571 // Count comments older than this one |
1113 $col_length = $wpdb->get_col_length( $wpdb->comments, $column ); |
1572 $oldercoms = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_parent = 0 AND comment_approved = '1' AND comment_date_gmt < '%s'" . $comtypewhere, $comment->comment_post_ID, $comment->comment_date_gmt ) ); |
1114 $max_length = 0; |
1573 |
1115 |
1574 // No older comments? Then it's page #1. |
1116 // No point if we can't get the DB column lengths |
1575 if ( 0 == $oldercoms ) |
1117 if ( is_wp_error( $col_length ) ) { |
1576 return 1; |
1118 break; |
1577 |
1119 } |
1578 // Divide comments older than this one by comments per page to get this comment's page number |
1120 |
1579 return ceil( ( $oldercoms + 1 ) / $args['per_page'] ); |
1121 if ( ! is_array( $col_length ) && (int) $col_length > 0 ) { |
1122 $max_length = (int) $col_length; |
|
1123 } elseif ( is_array( $col_length ) && isset( $col_length['length'] ) && intval( $col_length['length'] ) > 0 ) { |
|
1124 $max_length = (int) $col_length['length']; |
|
1125 |
|
1126 if ( ! empty( $col_length['type'] ) && 'byte' === $col_length['type'] ) { |
|
1127 $max_length = $max_length - 10; |
|
1128 } |
|
1129 } |
|
1130 |
|
1131 if ( $max_length > 0 ) { |
|
1132 $lengths[ $column ] = $max_length; |
|
1133 } |
|
1134 } |
|
1135 } |
|
1136 |
|
1137 /** |
|
1138 * Filters the lengths for the comment form fields. |
|
1139 * |
|
1140 * @since 4.5.0 |
|
1141 * |
|
1142 * @param array $lengths Associative array `'field_name' => 'maximum length'`. |
|
1143 */ |
|
1144 return apply_filters( 'wp_get_comment_fields_max_lengths', $lengths ); |
|
1145 } |
|
1146 |
|
1147 /** |
|
1148 * Compares the lengths of comment data against the maximum character limits. |
|
1149 * |
|
1150 * @since 4.7.0 |
|
1151 * |
|
1152 * @param array $comment_data Array of arguments for inserting a comment. |
|
1153 * @return WP_Error|true WP_Error when a comment field exceeds the limit, |
|
1154 * otherwise true. |
|
1155 */ |
|
1156 function wp_check_comment_data_max_lengths( $comment_data ) { |
|
1157 $max_lengths = wp_get_comment_fields_max_lengths(); |
|
1158 |
|
1159 if ( isset( $comment_data['comment_author'] ) && mb_strlen( $comment_data['comment_author'], '8bit' ) > $max_lengths['comment_author'] ) { |
|
1160 return new WP_Error( 'comment_author_column_length', __( '<strong>ERROR</strong>: your name is too long.' ), 200 ); |
|
1161 } |
|
1162 |
|
1163 if ( isset( $comment_data['comment_author_email'] ) && strlen( $comment_data['comment_author_email'] ) > $max_lengths['comment_author_email'] ) { |
|
1164 return new WP_Error( 'comment_author_email_column_length', __( '<strong>ERROR</strong>: your email address is too long.' ), 200 ); |
|
1165 } |
|
1166 |
|
1167 if ( isset( $comment_data['comment_author_url'] ) && strlen( $comment_data['comment_author_url'] ) > $max_lengths['comment_author_url'] ) { |
|
1168 return new WP_Error( 'comment_author_url_column_length', __( '<strong>ERROR</strong>: your url is too long.' ), 200 ); |
|
1169 } |
|
1170 |
|
1171 if ( isset( $comment_data['comment_content'] ) && mb_strlen( $comment_data['comment_content'], '8bit' ) > $max_lengths['comment_content'] ) { |
|
1172 return new WP_Error( 'comment_content_column_length', __( '<strong>ERROR</strong>: your comment is too long.' ), 200 ); |
|
1173 } |
|
1174 |
|
1175 return true; |
|
1580 } |
1176 } |
1581 |
1177 |
1582 /** |
1178 /** |
1583 * Does comment contain blacklisted characters or words. |
1179 * Does comment contain blacklisted characters or words. |
1584 * |
1180 * |
1586 * |
1182 * |
1587 * @param string $author The author of the comment |
1183 * @param string $author The author of the comment |
1588 * @param string $email The email of the comment |
1184 * @param string $email The email of the comment |
1589 * @param string $url The url used in the comment |
1185 * @param string $url The url used in the comment |
1590 * @param string $comment The comment content |
1186 * @param string $comment The comment content |
1591 * @param string $user_ip The comment author IP address |
1187 * @param string $user_ip The comment author's IP address |
1592 * @param string $user_agent The author's browser user agent |
1188 * @param string $user_agent The author's browser user agent |
1593 * @return bool True if comment contains blacklisted content, false if comment does not |
1189 * @return bool True if comment contains blacklisted content, false if comment does not |
1594 */ |
1190 */ |
1595 function wp_blacklist_check($author, $email, $url, $comment, $user_ip, $user_agent) { |
1191 function wp_blacklist_check($author, $email, $url, $comment, $user_ip, $user_agent) { |
1596 /** |
1192 /** |
1608 do_action( 'wp_blacklist_check', $author, $email, $url, $comment, $user_ip, $user_agent ); |
1204 do_action( 'wp_blacklist_check', $author, $email, $url, $comment, $user_ip, $user_agent ); |
1609 |
1205 |
1610 $mod_keys = trim( get_option('blacklist_keys') ); |
1206 $mod_keys = trim( get_option('blacklist_keys') ); |
1611 if ( '' == $mod_keys ) |
1207 if ( '' == $mod_keys ) |
1612 return false; // If moderation keys are empty |
1208 return false; // If moderation keys are empty |
1209 |
|
1210 // Ensure HTML tags are not being used to bypass the blacklist. |
|
1211 $comment_without_html = wp_strip_all_tags( $comment ); |
|
1212 |
|
1613 $words = explode("\n", $mod_keys ); |
1213 $words = explode("\n", $mod_keys ); |
1614 |
1214 |
1615 foreach ( (array) $words as $word ) { |
1215 foreach ( (array) $words as $word ) { |
1616 $word = trim($word); |
1216 $word = trim($word); |
1617 |
1217 |
1626 if ( |
1226 if ( |
1627 preg_match($pattern, $author) |
1227 preg_match($pattern, $author) |
1628 || preg_match($pattern, $email) |
1228 || preg_match($pattern, $email) |
1629 || preg_match($pattern, $url) |
1229 || preg_match($pattern, $url) |
1630 || preg_match($pattern, $comment) |
1230 || preg_match($pattern, $comment) |
1231 || preg_match($pattern, $comment_without_html) |
|
1631 || preg_match($pattern, $user_ip) |
1232 || preg_match($pattern, $user_ip) |
1632 || preg_match($pattern, $user_agent) |
1233 || preg_match($pattern, $user_agent) |
1633 ) |
1234 ) |
1634 return true; |
1235 return true; |
1635 } |
1236 } |
1648 * cache. |
1249 * cache. |
1649 * |
1250 * |
1650 * @since 2.5.0 |
1251 * @since 2.5.0 |
1651 * |
1252 * |
1652 * @param int $post_id Optional. Post ID. |
1253 * @param int $post_id Optional. Post ID. |
1653 * @return object Comment stats. |
1254 * @return object|array Comment stats. |
1654 */ |
1255 */ |
1655 function wp_count_comments( $post_id = 0 ) { |
1256 function wp_count_comments( $post_id = 0 ) { |
1656 global $wpdb; |
|
1657 |
|
1658 $post_id = (int) $post_id; |
1257 $post_id = (int) $post_id; |
1659 |
1258 |
1660 /** |
1259 /** |
1661 * Filter the comments count for a given post. |
1260 * Filters the comments count for a given post. |
1662 * |
1261 * |
1663 * @since 2.7.0 |
1262 * @since 2.7.0 |
1664 * |
1263 * |
1665 * @param array $count An empty array. |
1264 * @param array $count An empty array. |
1666 * @param int $post_id The post ID. |
1265 * @param int $post_id The post ID. |
1667 */ |
1266 */ |
1668 $stats = apply_filters( 'wp_count_comments', array(), $post_id ); |
1267 $filtered = apply_filters( 'wp_count_comments', array(), $post_id ); |
1669 if ( !empty($stats) ) |
1268 if ( ! empty( $filtered ) ) { |
1670 return $stats; |
1269 return $filtered; |
1671 |
1270 } |
1672 $count = wp_cache_get("comments-{$post_id}", 'counts'); |
1271 |
1673 |
1272 $count = wp_cache_get( "comments-{$post_id}", 'counts' ); |
1674 if ( false !== $count ) |
1273 if ( false !== $count ) { |
1675 return $count; |
1274 return $count; |
1676 |
1275 } |
1677 $where = ''; |
1276 |
1678 if ( $post_id > 0 ) |
1277 $stats = get_comment_count( $post_id ); |
1679 $where = $wpdb->prepare( "WHERE comment_post_ID = %d", $post_id ); |
1278 $stats['moderated'] = $stats['awaiting_moderation']; |
1680 |
1279 unset( $stats['awaiting_moderation'] ); |
1681 $count = $wpdb->get_results( "SELECT comment_approved, COUNT( * ) AS num_comments FROM {$wpdb->comments} {$where} GROUP BY comment_approved", ARRAY_A ); |
1280 |
1682 |
1281 $stats_object = (object) $stats; |
1683 $total = 0; |
1282 wp_cache_set( "comments-{$post_id}", $stats_object, 'counts' ); |
1684 $approved = array('0' => 'moderated', '1' => 'approved', 'spam' => 'spam', 'trash' => 'trash', 'post-trashed' => 'post-trashed'); |
1283 |
1685 foreach ( (array) $count as $row ) { |
1284 return $stats_object; |
1686 // Don't count post-trashed toward totals |
|
1687 if ( 'post-trashed' != $row['comment_approved'] && 'trash' != $row['comment_approved'] ) |
|
1688 $total += $row['num_comments']; |
|
1689 if ( isset( $approved[$row['comment_approved']] ) ) |
|
1690 $stats[$approved[$row['comment_approved']]] = $row['num_comments']; |
|
1691 } |
|
1692 |
|
1693 $stats['total_comments'] = $total; |
|
1694 foreach ( $approved as $key ) { |
|
1695 if ( empty($stats[$key]) ) |
|
1696 $stats[$key] = 0; |
|
1697 } |
|
1698 |
|
1699 $stats = (object) $stats; |
|
1700 wp_cache_set("comments-{$post_id}", $stats, 'counts'); |
|
1701 |
|
1702 return $stats; |
|
1703 } |
1285 } |
1704 |
1286 |
1705 /** |
1287 /** |
1706 * Trashes or deletes a comment. |
1288 * Trashes or deletes a comment. |
1707 * |
1289 * |
1713 * |
1295 * |
1714 * @since 2.0.0 |
1296 * @since 2.0.0 |
1715 * |
1297 * |
1716 * @global wpdb $wpdb WordPress database abstraction object. |
1298 * @global wpdb $wpdb WordPress database abstraction object. |
1717 * |
1299 * |
1718 * @param int $comment_id Comment ID |
1300 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object. |
1719 * @param bool $force_delete Whether to bypass trash and force deletion. Default is false. |
1301 * @param bool $force_delete Whether to bypass trash and force deletion. Default is false. |
1720 * @return bool True on success, false on failure. |
1302 * @return bool True on success, false on failure. |
1721 */ |
1303 */ |
1722 function wp_delete_comment($comment_id, $force_delete = false) { |
1304 function wp_delete_comment($comment_id, $force_delete = false) { |
1723 global $wpdb; |
1305 global $wpdb; |
1724 if (!$comment = get_comment($comment_id)) |
1306 if (!$comment = get_comment($comment_id)) |
1725 return false; |
1307 return false; |
1726 |
1308 |
1727 if ( !$force_delete && EMPTY_TRASH_DAYS && !in_array( wp_get_comment_status($comment_id), array( 'trash', 'spam' ) ) ) |
1309 if ( !$force_delete && EMPTY_TRASH_DAYS && !in_array( wp_get_comment_status( $comment ), array( 'trash', 'spam' ) ) ) |
1728 return wp_trash_comment($comment_id); |
1310 return wp_trash_comment($comment_id); |
1729 |
1311 |
1730 /** |
1312 /** |
1731 * Fires immediately before a comment is deleted from the database. |
1313 * Fires immediately before a comment is deleted from the database. |
1732 * |
1314 * |
1733 * @since 1.2.0 |
1315 * @since 1.2.0 |
1734 * |
1316 * @since 4.9.0 Added the `$comment` parameter. |
1735 * @param int $comment_id The comment ID. |
1317 * |
1736 */ |
1318 * @param int $comment_id The comment ID. |
1737 do_action( 'delete_comment', $comment_id ); |
1319 * @param WP_Comment $comment The comment to be deleted. |
1320 */ |
|
1321 do_action( 'delete_comment', $comment->comment_ID, $comment ); |
|
1738 |
1322 |
1739 // Move children up a level. |
1323 // Move children up a level. |
1740 $children = $wpdb->get_col( $wpdb->prepare("SELECT comment_ID FROM $wpdb->comments WHERE comment_parent = %d", $comment_id) ); |
1324 $children = $wpdb->get_col( $wpdb->prepare("SELECT comment_ID FROM $wpdb->comments WHERE comment_parent = %d", $comment->comment_ID) ); |
1741 if ( !empty($children) ) { |
1325 if ( !empty($children) ) { |
1742 $wpdb->update($wpdb->comments, array('comment_parent' => $comment->comment_parent), array('comment_parent' => $comment_id)); |
1326 $wpdb->update($wpdb->comments, array('comment_parent' => $comment->comment_parent), array('comment_parent' => $comment->comment_ID)); |
1743 clean_comment_cache($children); |
1327 clean_comment_cache($children); |
1744 } |
1328 } |
1745 |
1329 |
1746 // Delete metadata |
1330 // Delete metadata |
1747 $meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->commentmeta WHERE comment_id = %d", $comment_id ) ); |
1331 $meta_ids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->commentmeta WHERE comment_id = %d", $comment->comment_ID ) ); |
1748 foreach ( $meta_ids as $mid ) |
1332 foreach ( $meta_ids as $mid ) |
1749 delete_metadata_by_mid( 'comment', $mid ); |
1333 delete_metadata_by_mid( 'comment', $mid ); |
1750 |
1334 |
1751 if ( ! $wpdb->delete( $wpdb->comments, array( 'comment_ID' => $comment_id ) ) ) |
1335 if ( ! $wpdb->delete( $wpdb->comments, array( 'comment_ID' => $comment->comment_ID ) ) ) |
1752 return false; |
1336 return false; |
1753 |
1337 |
1754 /** |
1338 /** |
1755 * Fires immediately after a comment is deleted from the database. |
1339 * Fires immediately after a comment is deleted from the database. |
1756 * |
1340 * |
1757 * @since 2.9.0 |
1341 * @since 2.9.0 |
1758 * |
1342 * @since 4.9.0 Added the `$comment` parameter. |
1759 * @param int $comment_id The comment ID. |
1343 * |
1760 */ |
1344 * @param int $comment_id The comment ID. |
1761 do_action( 'deleted_comment', $comment_id ); |
1345 * @param WP_Comment $comment The deleted comment. |
1346 */ |
|
1347 do_action( 'deleted_comment', $comment->comment_ID, $comment ); |
|
1762 |
1348 |
1763 $post_id = $comment->comment_post_ID; |
1349 $post_id = $comment->comment_post_ID; |
1764 if ( $post_id && $comment->comment_approved == 1 ) |
1350 if ( $post_id && $comment->comment_approved == 1 ) |
1765 wp_update_comment_count($post_id); |
1351 wp_update_comment_count($post_id); |
1766 |
1352 |
1767 clean_comment_cache($comment_id); |
1353 clean_comment_cache( $comment->comment_ID ); |
1768 |
1354 |
1769 /** This action is documented in wp-includes/comment.php */ |
1355 /** This action is documented in wp-includes/comment.php */ |
1770 do_action( 'wp_set_comment_status', $comment_id, 'delete' ); |
1356 do_action( 'wp_set_comment_status', $comment->comment_ID, 'delete' ); |
1771 |
1357 |
1772 wp_transition_comment_status('delete', $comment->comment_approved, $comment); |
1358 wp_transition_comment_status('delete', $comment->comment_approved, $comment); |
1773 return true; |
1359 return true; |
1774 } |
1360 } |
1775 |
1361 |
1778 * |
1364 * |
1779 * If trash is disabled, comment is permanently deleted. |
1365 * If trash is disabled, comment is permanently deleted. |
1780 * |
1366 * |
1781 * @since 2.9.0 |
1367 * @since 2.9.0 |
1782 * |
1368 * |
1783 * @param int $comment_id Comment ID. |
1369 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object. |
1784 * @return bool True on success, false on failure. |
1370 * @return bool True on success, false on failure. |
1785 */ |
1371 */ |
1786 function wp_trash_comment($comment_id) { |
1372 function wp_trash_comment($comment_id) { |
1787 if ( !EMPTY_TRASH_DAYS ) |
1373 if ( !EMPTY_TRASH_DAYS ) |
1788 return wp_delete_comment($comment_id, true); |
1374 return wp_delete_comment($comment_id, true); |
1792 |
1378 |
1793 /** |
1379 /** |
1794 * Fires immediately before a comment is sent to the Trash. |
1380 * Fires immediately before a comment is sent to the Trash. |
1795 * |
1381 * |
1796 * @since 2.9.0 |
1382 * @since 2.9.0 |
1797 * |
1383 * @since 4.9.0 Added the `$comment` parameter. |
1798 * @param int $comment_id The comment ID. |
1384 * |
1799 */ |
1385 * @param int $comment_id The comment ID. |
1800 do_action( 'trash_comment', $comment_id ); |
1386 * @param WP_Comment $comment The comment to be trashed. |
1801 |
1387 */ |
1802 if ( wp_set_comment_status($comment_id, 'trash') ) { |
1388 do_action( 'trash_comment', $comment->comment_ID, $comment ); |
1803 add_comment_meta($comment_id, '_wp_trash_meta_status', $comment->comment_approved); |
1389 |
1804 add_comment_meta($comment_id, '_wp_trash_meta_time', time() ); |
1390 if ( wp_set_comment_status( $comment, 'trash' ) ) { |
1391 delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_status' ); |
|
1392 delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_time' ); |
|
1393 add_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', $comment->comment_approved ); |
|
1394 add_comment_meta( $comment->comment_ID, '_wp_trash_meta_time', time() ); |
|
1805 |
1395 |
1806 /** |
1396 /** |
1807 * Fires immediately after a comment is sent to Trash. |
1397 * Fires immediately after a comment is sent to Trash. |
1808 * |
1398 * |
1809 * @since 2.9.0 |
1399 * @since 2.9.0 |
1810 * |
1400 * @since 4.9.0 Added the `$comment` parameter. |
1811 * @param int $comment_id The comment ID. |
1401 * |
1402 * @param int $comment_id The comment ID. |
|
1403 * @param WP_Comment $comment The trashed comment. |
|
1812 */ |
1404 */ |
1813 do_action( 'trashed_comment', $comment_id ); |
1405 do_action( 'trashed_comment', $comment->comment_ID, $comment ); |
1814 return true; |
1406 return true; |
1815 } |
1407 } |
1816 |
1408 |
1817 return false; |
1409 return false; |
1818 } |
1410 } |
1820 /** |
1412 /** |
1821 * Removes a comment from the Trash |
1413 * Removes a comment from the Trash |
1822 * |
1414 * |
1823 * @since 2.9.0 |
1415 * @since 2.9.0 |
1824 * |
1416 * |
1825 * @param int $comment_id Comment ID. |
1417 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object. |
1826 * @return bool True on success, false on failure. |
1418 * @return bool True on success, false on failure. |
1827 */ |
1419 */ |
1828 function wp_untrash_comment($comment_id) { |
1420 function wp_untrash_comment($comment_id) { |
1829 if ( ! (int)$comment_id ) |
1421 $comment = get_comment( $comment_id ); |
1422 if ( ! $comment ) { |
|
1830 return false; |
1423 return false; |
1424 } |
|
1831 |
1425 |
1832 /** |
1426 /** |
1833 * Fires immediately before a comment is restored from the Trash. |
1427 * Fires immediately before a comment is restored from the Trash. |
1834 * |
1428 * |
1835 * @since 2.9.0 |
1429 * @since 2.9.0 |
1836 * |
1430 * @since 4.9.0 Added the `$comment` parameter. |
1837 * @param int $comment_id The comment ID. |
1431 * |
1838 */ |
1432 * @param int $comment_id The comment ID. |
1839 do_action( 'untrash_comment', $comment_id ); |
1433 * @param WP_Comment $comment The comment to be untrashed. |
1840 |
1434 */ |
1841 $status = (string) get_comment_meta($comment_id, '_wp_trash_meta_status', true); |
1435 do_action( 'untrash_comment', $comment->comment_ID, $comment ); |
1436 |
|
1437 $status = (string) get_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', true ); |
|
1842 if ( empty($status) ) |
1438 if ( empty($status) ) |
1843 $status = '0'; |
1439 $status = '0'; |
1844 |
1440 |
1845 if ( wp_set_comment_status($comment_id, $status) ) { |
1441 if ( wp_set_comment_status( $comment, $status ) ) { |
1846 delete_comment_meta($comment_id, '_wp_trash_meta_time'); |
1442 delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_time' ); |
1847 delete_comment_meta($comment_id, '_wp_trash_meta_status'); |
1443 delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_status' ); |
1848 /** |
1444 /** |
1849 * Fires immediately after a comment is restored from the Trash. |
1445 * Fires immediately after a comment is restored from the Trash. |
1850 * |
1446 * |
1851 * @since 2.9.0 |
1447 * @since 2.9.0 |
1852 * |
1448 * @since 4.9.0 Added the `$comment` parameter. |
1853 * @param int $comment_id The comment ID. |
1449 * |
1450 * @param int $comment_id The comment ID. |
|
1451 * @param WP_Comment $comment The untrashed comment. |
|
1854 */ |
1452 */ |
1855 do_action( 'untrashed_comment', $comment_id ); |
1453 do_action( 'untrashed_comment', $comment->comment_ID, $comment ); |
1856 return true; |
1454 return true; |
1857 } |
1455 } |
1858 |
1456 |
1859 return false; |
1457 return false; |
1860 } |
1458 } |
1862 /** |
1460 /** |
1863 * Marks a comment as Spam |
1461 * Marks a comment as Spam |
1864 * |
1462 * |
1865 * @since 2.9.0 |
1463 * @since 2.9.0 |
1866 * |
1464 * |
1867 * @param int $comment_id Comment ID. |
1465 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object. |
1868 * @return bool True on success, false on failure. |
1466 * @return bool True on success, false on failure. |
1869 */ |
1467 */ |
1870 function wp_spam_comment($comment_id) { |
1468 function wp_spam_comment( $comment_id ) { |
1871 if ( !$comment = get_comment($comment_id) ) |
1469 $comment = get_comment( $comment_id ); |
1470 if ( ! $comment ) { |
|
1872 return false; |
1471 return false; |
1472 } |
|
1873 |
1473 |
1874 /** |
1474 /** |
1875 * Fires immediately before a comment is marked as Spam. |
1475 * Fires immediately before a comment is marked as Spam. |
1876 * |
1476 * |
1877 * @since 2.9.0 |
1477 * @since 2.9.0 |
1878 * |
1478 * @since 4.9.0 Added the `$comment` parameter. |
1879 * @param int $comment_id The comment ID. |
1479 * |
1880 */ |
1480 * @param int $comment_id The comment ID. |
1881 do_action( 'spam_comment', $comment_id ); |
1481 * @param WP_Comment $comment The comment to be marked as spam. |
1882 |
1482 */ |
1883 if ( wp_set_comment_status($comment_id, 'spam') ) { |
1483 do_action( 'spam_comment', $comment->comment_ID, $comment ); |
1884 add_comment_meta($comment_id, '_wp_trash_meta_status', $comment->comment_approved); |
1484 |
1485 if ( wp_set_comment_status( $comment, 'spam' ) ) { |
|
1486 delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_status' ); |
|
1487 delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_time' ); |
|
1488 add_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', $comment->comment_approved ); |
|
1489 add_comment_meta( $comment->comment_ID, '_wp_trash_meta_time', time() ); |
|
1885 /** |
1490 /** |
1886 * Fires immediately after a comment is marked as Spam. |
1491 * Fires immediately after a comment is marked as Spam. |
1887 * |
1492 * |
1888 * @since 2.9.0 |
1493 * @since 2.9.0 |
1889 * |
1494 * @since 4.9.0 Added the `$comment` parameter. |
1890 * @param int $comment_id The comment ID. |
1495 * |
1496 * @param int $comment_id The comment ID. |
|
1497 * @param WP_Comment $comment The comment marked as spam. |
|
1891 */ |
1498 */ |
1892 do_action( 'spammed_comment', $comment_id ); |
1499 do_action( 'spammed_comment', $comment->comment_ID, $comment ); |
1893 return true; |
1500 return true; |
1894 } |
1501 } |
1895 |
1502 |
1896 return false; |
1503 return false; |
1897 } |
1504 } |
1899 /** |
1506 /** |
1900 * Removes a comment from the Spam |
1507 * Removes a comment from the Spam |
1901 * |
1508 * |
1902 * @since 2.9.0 |
1509 * @since 2.9.0 |
1903 * |
1510 * |
1904 * @param int $comment_id Comment ID. |
1511 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object. |
1905 * @return bool True on success, false on failure. |
1512 * @return bool True on success, false on failure. |
1906 */ |
1513 */ |
1907 function wp_unspam_comment($comment_id) { |
1514 function wp_unspam_comment( $comment_id ) { |
1908 if ( ! (int)$comment_id ) |
1515 $comment = get_comment( $comment_id ); |
1516 if ( ! $comment ) { |
|
1909 return false; |
1517 return false; |
1518 } |
|
1910 |
1519 |
1911 /** |
1520 /** |
1912 * Fires immediately before a comment is unmarked as Spam. |
1521 * Fires immediately before a comment is unmarked as Spam. |
1913 * |
1522 * |
1914 * @since 2.9.0 |
1523 * @since 2.9.0 |
1915 * |
1524 * @since 4.9.0 Added the `$comment` parameter. |
1916 * @param int $comment_id The comment ID. |
1525 * |
1917 */ |
1526 * @param int $comment_id The comment ID. |
1918 do_action( 'unspam_comment', $comment_id ); |
1527 * @param WP_Comment $comment The comment to be unmarked as spam. |
1919 |
1528 */ |
1920 $status = (string) get_comment_meta($comment_id, '_wp_trash_meta_status', true); |
1529 do_action( 'unspam_comment', $comment->comment_ID, $comment ); |
1530 |
|
1531 $status = (string) get_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', true ); |
|
1921 if ( empty($status) ) |
1532 if ( empty($status) ) |
1922 $status = '0'; |
1533 $status = '0'; |
1923 |
1534 |
1924 if ( wp_set_comment_status($comment_id, $status) ) { |
1535 if ( wp_set_comment_status( $comment, $status ) ) { |
1925 delete_comment_meta($comment_id, '_wp_trash_meta_status'); |
1536 delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_status' ); |
1537 delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_time' ); |
|
1926 /** |
1538 /** |
1927 * Fires immediately after a comment is unmarked as Spam. |
1539 * Fires immediately after a comment is unmarked as Spam. |
1928 * |
1540 * |
1929 * @since 2.9.0 |
1541 * @since 2.9.0 |
1930 * |
1542 * @since 4.9.0 Added the `$comment` parameter. |
1931 * @param int $comment_id The comment ID. |
1543 * |
1544 * @param int $comment_id The comment ID. |
|
1545 * @param WP_Comment $comment The comment unmarked as spam. |
|
1932 */ |
1546 */ |
1933 do_action( 'unspammed_comment', $comment_id ); |
1547 do_action( 'unspammed_comment', $comment->comment_ID, $comment ); |
1934 return true; |
1548 return true; |
1935 } |
1549 } |
1936 |
1550 |
1937 return false; |
1551 return false; |
1938 } |
1552 } |
1940 /** |
1554 /** |
1941 * The status of a comment by ID. |
1555 * The status of a comment by ID. |
1942 * |
1556 * |
1943 * @since 1.0.0 |
1557 * @since 1.0.0 |
1944 * |
1558 * |
1945 * @param int $comment_id Comment ID |
1559 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object |
1946 * @return false|string Status might be 'trash', 'approved', 'unapproved', 'spam'. False on failure. |
1560 * @return false|string Status might be 'trash', 'approved', 'unapproved', 'spam'. False on failure. |
1947 */ |
1561 */ |
1948 function wp_get_comment_status($comment_id) { |
1562 function wp_get_comment_status($comment_id) { |
1949 $comment = get_comment($comment_id); |
1563 $comment = get_comment($comment_id); |
1950 if ( !$comment ) |
1564 if ( !$comment ) |
1969 /** |
1583 /** |
1970 * Call hooks for when a comment status transition occurs. |
1584 * Call hooks for when a comment status transition occurs. |
1971 * |
1585 * |
1972 * Calls hooks for comment status transitions. If the new comment status is not the same |
1586 * Calls hooks for comment status transitions. If the new comment status is not the same |
1973 * as the previous comment status, then two hooks will be ran, the first is |
1587 * as the previous comment status, then two hooks will be ran, the first is |
1974 * 'transition_comment_status' with new status, old status, and comment data. The |
1588 * {@see 'transition_comment_status'} with new status, old status, and comment data. The |
1975 * next action called is 'comment_OLDSTATUS_to_NEWSTATUS' the NEWSTATUS is the |
1589 * next action called is {@see comment_$old_status_to_$new_status'}. It has the |
1976 * $new_status parameter and the OLDSTATUS is $old_status parameter; it has the |
|
1977 * comment data. |
1590 * comment data. |
1978 * |
1591 * |
1979 * The final action will run whether or not the comment statuses are the same. The |
1592 * The final action will run whether or not the comment statuses are the same. The |
1980 * action is named 'comment_NEWSTATUS_COMMENTTYPE', NEWSTATUS is from the $new_status |
1593 * action is named {@see 'comment_$new_status_$comment->comment_type'}. |
1981 * parameter and COMMENTTYPE is comment_type comment data. |
|
1982 * |
1594 * |
1983 * @since 2.7.0 |
1595 * @since 2.7.0 |
1984 * |
1596 * |
1985 * @param string $new_status New comment status. |
1597 * @param string $new_status New comment status. |
1986 * @param string $old_status Previous comment status. |
1598 * @param string $old_status Previous comment status. |
2019 * The dynamic portions of the hook name, `$old_status`, and `$new_status`, |
1631 * The dynamic portions of the hook name, `$old_status`, and `$new_status`, |
2020 * refer to the old and new comment statuses, respectively. |
1632 * refer to the old and new comment statuses, respectively. |
2021 * |
1633 * |
2022 * @since 2.7.0 |
1634 * @since 2.7.0 |
2023 * |
1635 * |
2024 * @param object $comment Comment object. |
1636 * @param WP_Comment $comment Comment object. |
2025 */ |
1637 */ |
2026 do_action( "comment_{$old_status}_to_{$new_status}", $comment ); |
1638 do_action( "comment_{$old_status}_to_{$new_status}", $comment ); |
2027 } |
1639 } |
2028 /** |
1640 /** |
2029 * Fires when the status of a specific comment type is in transition. |
1641 * Fires when the status of a specific comment type is in transition. |
2034 * Typical comment types include an empty string (standard comment), 'pingback', |
1646 * Typical comment types include an empty string (standard comment), 'pingback', |
2035 * or 'trackback'. |
1647 * or 'trackback'. |
2036 * |
1648 * |
2037 * @since 2.7.0 |
1649 * @since 2.7.0 |
2038 * |
1650 * |
2039 * @param int $comment_ID The comment ID. |
1651 * @param int $comment_ID The comment ID. |
2040 * @param obj $comment Comment object. |
1652 * @param WP_Comment $comment Comment object. |
2041 */ |
1653 */ |
2042 do_action( "comment_{$new_status}_{$comment->comment_type}", $comment->comment_ID, $comment ); |
1654 do_action( "comment_{$new_status}_{$comment->comment_type}", $comment->comment_ID, $comment ); |
1655 } |
|
1656 |
|
1657 /** |
|
1658 * Clear the lastcommentmodified cached value when a comment status is changed. |
|
1659 * |
|
1660 * Deletes the lastcommentmodified cache key when a comment enters or leaves |
|
1661 * 'approved' status. |
|
1662 * |
|
1663 * @since 4.7.0 |
|
1664 * @access private |
|
1665 * |
|
1666 * @param string $new_status The new comment status. |
|
1667 * @param string $old_status The old comment status. |
|
1668 */ |
|
1669 function _clear_modified_cache_on_transition_comment_status( $new_status, $old_status ) { |
|
1670 if ( 'approved' === $new_status || 'approved' === $old_status ) { |
|
1671 foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) { |
|
1672 wp_cache_delete( "lastcommentmodified:$timezone", 'timeinfo' ); |
|
1673 } |
|
1674 } |
|
2043 } |
1675 } |
2044 |
1676 |
2045 /** |
1677 /** |
2046 * Get current commenter's name, email, and URL. |
1678 * Get current commenter's name, email, and URL. |
2047 * |
1679 * |
2068 $comment_author_url = ''; |
1700 $comment_author_url = ''; |
2069 if ( isset($_COOKIE['comment_author_url_'.COOKIEHASH]) ) |
1701 if ( isset($_COOKIE['comment_author_url_'.COOKIEHASH]) ) |
2070 $comment_author_url = $_COOKIE['comment_author_url_'.COOKIEHASH]; |
1702 $comment_author_url = $_COOKIE['comment_author_url_'.COOKIEHASH]; |
2071 |
1703 |
2072 /** |
1704 /** |
2073 * Filter the current commenter's name, email, and URL. |
1705 * Filters the current commenter's name, email, and URL. |
2074 * |
1706 * |
2075 * @since 3.1.0 |
1707 * @since 3.1.0 |
2076 * |
1708 * |
2077 * @param string $comment_author Comment author's name. |
1709 * @param array $comment_author_data { |
2078 * @param string $comment_author_email Comment author's email. |
1710 * An array of current commenter variables. |
2079 * @param string $comment_author_url Comment author's URL. |
1711 * |
1712 * @type string $comment_author The name of the author of the comment. Default empty. |
|
1713 * @type string $comment_author_email The email address of the `$comment_author`. Default empty. |
|
1714 * @type string $comment_author_url The URL address of the `$comment_author`. Default empty. |
|
1715 * } |
|
2080 */ |
1716 */ |
2081 return apply_filters( 'wp_get_current_commenter', compact('comment_author', 'comment_author_email', 'comment_author_url') ); |
1717 return apply_filters( 'wp_get_current_commenter', compact('comment_author', 'comment_author_email', 'comment_author_url') ); |
2082 } |
1718 } |
2083 |
1719 |
2084 /** |
1720 /** |
2085 * Inserts a comment to the database. |
1721 * Inserts a comment into the database. |
2086 * |
|
2087 * The available comment data key names are 'comment_author_IP', 'comment_date', |
|
2088 * 'comment_date_gmt', 'comment_parent', 'comment_approved', and 'user_id'. |
|
2089 * |
1722 * |
2090 * @since 2.0.0 |
1723 * @since 2.0.0 |
1724 * @since 4.4.0 Introduced `$comment_meta` argument. |
|
2091 * |
1725 * |
2092 * @global wpdb $wpdb WordPress database abstraction object. |
1726 * @global wpdb $wpdb WordPress database abstraction object. |
2093 * |
1727 * |
2094 * @param array $commentdata Contains information on the comment. |
1728 * @param array $commentdata { |
2095 * @return int|bool The new comment's ID on success, false on failure. |
1729 * Array of arguments for inserting a new comment. |
1730 * |
|
1731 * @type string $comment_agent The HTTP user agent of the `$comment_author` when |
|
1732 * the comment was submitted. Default empty. |
|
1733 * @type int|string $comment_approved Whether the comment has been approved. Default 1. |
|
1734 * @type string $comment_author The name of the author of the comment. Default empty. |
|
1735 * @type string $comment_author_email The email address of the `$comment_author`. Default empty. |
|
1736 * @type string $comment_author_IP The IP address of the `$comment_author`. Default empty. |
|
1737 * @type string $comment_author_url The URL address of the `$comment_author`. Default empty. |
|
1738 * @type string $comment_content The content of the comment. Default empty. |
|
1739 * @type string $comment_date The date the comment was submitted. To set the date |
|
1740 * manually, `$comment_date_gmt` must also be specified. |
|
1741 * Default is the current time. |
|
1742 * @type string $comment_date_gmt The date the comment was submitted in the GMT timezone. |
|
1743 * Default is `$comment_date` in the site's GMT timezone. |
|
1744 * @type int $comment_karma The karma of the comment. Default 0. |
|
1745 * @type int $comment_parent ID of this comment's parent, if any. Default 0. |
|
1746 * @type int $comment_post_ID ID of the post that relates to the comment, if any. |
|
1747 * Default 0. |
|
1748 * @type string $comment_type Comment type. Default empty. |
|
1749 * @type array $comment_meta Optional. Array of key/value pairs to be stored in commentmeta for the |
|
1750 * new comment. |
|
1751 * @type int $user_id ID of the user who submitted the comment. Default 0. |
|
1752 * } |
|
1753 * @return int|false The new comment's ID on success, false on failure. |
|
2096 */ |
1754 */ |
2097 function wp_insert_comment( $commentdata ) { |
1755 function wp_insert_comment( $commentdata ) { |
2098 global $wpdb; |
1756 global $wpdb; |
2099 $data = wp_unslash( $commentdata ); |
1757 $data = wp_unslash( $commentdata ); |
2100 |
1758 |
2104 $comment_author_IP = ! isset( $data['comment_author_IP'] ) ? '' : $data['comment_author_IP']; |
1762 $comment_author_IP = ! isset( $data['comment_author_IP'] ) ? '' : $data['comment_author_IP']; |
2105 |
1763 |
2106 $comment_date = ! isset( $data['comment_date'] ) ? current_time( 'mysql' ) : $data['comment_date']; |
1764 $comment_date = ! isset( $data['comment_date'] ) ? current_time( 'mysql' ) : $data['comment_date']; |
2107 $comment_date_gmt = ! isset( $data['comment_date_gmt'] ) ? get_gmt_from_date( $comment_date ) : $data['comment_date_gmt']; |
1765 $comment_date_gmt = ! isset( $data['comment_date_gmt'] ) ? get_gmt_from_date( $comment_date ) : $data['comment_date_gmt']; |
2108 |
1766 |
2109 $comment_post_ID = ! isset( $data['comment_post_ID'] ) ? '' : $data['comment_post_ID']; |
1767 $comment_post_ID = ! isset( $data['comment_post_ID'] ) ? 0 : $data['comment_post_ID']; |
2110 $comment_content = ! isset( $data['comment_content'] ) ? '' : $data['comment_content']; |
1768 $comment_content = ! isset( $data['comment_content'] ) ? '' : $data['comment_content']; |
2111 $comment_karma = ! isset( $data['comment_karma'] ) ? 0 : $data['comment_karma']; |
1769 $comment_karma = ! isset( $data['comment_karma'] ) ? 0 : $data['comment_karma']; |
2112 $comment_approved = ! isset( $data['comment_approved'] ) ? 1 : $data['comment_approved']; |
1770 $comment_approved = ! isset( $data['comment_approved'] ) ? 1 : $data['comment_approved']; |
2113 $comment_agent = ! isset( $data['comment_agent'] ) ? '' : $data['comment_agent']; |
1771 $comment_agent = ! isset( $data['comment_agent'] ) ? '' : $data['comment_agent']; |
2114 $comment_type = ! isset( $data['comment_type'] ) ? '' : $data['comment_type']; |
1772 $comment_type = ! isset( $data['comment_type'] ) ? '' : $data['comment_type']; |
2123 |
1781 |
2124 $id = (int) $wpdb->insert_id; |
1782 $id = (int) $wpdb->insert_id; |
2125 |
1783 |
2126 if ( $comment_approved == 1 ) { |
1784 if ( $comment_approved == 1 ) { |
2127 wp_update_comment_count( $comment_post_ID ); |
1785 wp_update_comment_count( $comment_post_ID ); |
2128 } |
1786 |
1787 foreach ( array( 'server', 'gmt', 'blog' ) as $timezone ) { |
|
1788 wp_cache_delete( "lastcommentmodified:$timezone", 'timeinfo' ); |
|
1789 } |
|
1790 } |
|
1791 |
|
1792 clean_comment_cache( $id ); |
|
1793 |
|
2129 $comment = get_comment( $id ); |
1794 $comment = get_comment( $id ); |
1795 |
|
1796 // If metadata is provided, store it. |
|
1797 if ( isset( $commentdata['comment_meta'] ) && is_array( $commentdata['comment_meta'] ) ) { |
|
1798 foreach ( $commentdata['comment_meta'] as $meta_key => $meta_value ) { |
|
1799 add_comment_meta( $comment->comment_ID, $meta_key, $meta_value, true ); |
|
1800 } |
|
1801 } |
|
2130 |
1802 |
2131 /** |
1803 /** |
2132 * Fires immediately after a comment is inserted into the database. |
1804 * Fires immediately after a comment is inserted into the database. |
2133 * |
1805 * |
2134 * @since 2.8.0 |
1806 * @since 2.8.0 |
2135 * |
1807 * |
2136 * @param int $id The comment ID. |
1808 * @param int $id The comment ID. |
2137 * @param obj $comment Comment object. |
1809 * @param WP_Comment $comment Comment object. |
2138 */ |
1810 */ |
2139 do_action( 'wp_insert_comment', $id, $comment ); |
1811 do_action( 'wp_insert_comment', $id, $comment ); |
2140 |
|
2141 wp_cache_set( 'last_changed', microtime(), 'comment' ); |
|
2142 |
1812 |
2143 return $id; |
1813 return $id; |
2144 } |
1814 } |
2145 |
1815 |
2146 /** |
1816 /** |
2156 * @return array Parsed comment information. |
1826 * @return array Parsed comment information. |
2157 */ |
1827 */ |
2158 function wp_filter_comment($commentdata) { |
1828 function wp_filter_comment($commentdata) { |
2159 if ( isset( $commentdata['user_ID'] ) ) { |
1829 if ( isset( $commentdata['user_ID'] ) ) { |
2160 /** |
1830 /** |
2161 * Filter the comment author's user id before it is set. |
1831 * Filters the comment author's user id before it is set. |
2162 * |
1832 * |
2163 * The first time this filter is evaluated, 'user_ID' is checked |
1833 * The first time this filter is evaluated, 'user_ID' is checked |
2164 * (for back-compat), followed by the standard 'user_id' value. |
1834 * (for back-compat), followed by the standard 'user_id' value. |
2165 * |
1835 * |
2166 * @since 1.5.0 |
1836 * @since 1.5.0 |
2172 /** This filter is documented in wp-includes/comment.php */ |
1842 /** This filter is documented in wp-includes/comment.php */ |
2173 $commentdata['user_id'] = apply_filters( 'pre_user_id', $commentdata['user_id'] ); |
1843 $commentdata['user_id'] = apply_filters( 'pre_user_id', $commentdata['user_id'] ); |
2174 } |
1844 } |
2175 |
1845 |
2176 /** |
1846 /** |
2177 * Filter the comment author's browser user agent before it is set. |
1847 * Filters the comment author's browser user agent before it is set. |
2178 * |
1848 * |
2179 * @since 1.5.0 |
1849 * @since 1.5.0 |
2180 * |
1850 * |
2181 * @param int $comment_agent The comment author's browser user agent. |
1851 * @param string $comment_agent The comment author's browser user agent. |
2182 */ |
1852 */ |
2183 $commentdata['comment_agent'] = apply_filters( 'pre_comment_user_agent', ( isset( $commentdata['comment_agent'] ) ? $commentdata['comment_agent'] : '' ) ); |
1853 $commentdata['comment_agent'] = apply_filters( 'pre_comment_user_agent', ( isset( $commentdata['comment_agent'] ) ? $commentdata['comment_agent'] : '' ) ); |
2184 /** This filter is documented in wp-includes/comment.php */ |
1854 /** This filter is documented in wp-includes/comment.php */ |
2185 $commentdata['comment_author'] = apply_filters( 'pre_comment_author_name', $commentdata['comment_author'] ); |
1855 $commentdata['comment_author'] = apply_filters( 'pre_comment_author_name', $commentdata['comment_author'] ); |
2186 /** |
1856 /** |
2187 * Filter the comment content before it is set. |
1857 * Filters the comment content before it is set. |
2188 * |
1858 * |
2189 * @since 1.5.0 |
1859 * @since 1.5.0 |
2190 * |
1860 * |
2191 * @param int $comment_content The comment content. |
1861 * @param string $comment_content The comment content. |
2192 */ |
1862 */ |
2193 $commentdata['comment_content'] = apply_filters( 'pre_comment_content', $commentdata['comment_content'] ); |
1863 $commentdata['comment_content'] = apply_filters( 'pre_comment_content', $commentdata['comment_content'] ); |
2194 /** |
1864 /** |
2195 * Filter the comment author's IP before it is set. |
1865 * Filters the comment author's IP address before it is set. |
2196 * |
1866 * |
2197 * @since 1.5.0 |
1867 * @since 1.5.0 |
2198 * |
1868 * |
2199 * @param int $comment_author_ip The comment author's IP. |
1869 * @param string $comment_author_ip The comment author's IP address. |
2200 */ |
1870 */ |
2201 $commentdata['comment_author_IP'] = apply_filters( 'pre_comment_user_ip', $commentdata['comment_author_IP'] ); |
1871 $commentdata['comment_author_IP'] = apply_filters( 'pre_comment_user_ip', $commentdata['comment_author_IP'] ); |
2202 /** This filter is documented in wp-includes/comment.php */ |
1872 /** This filter is documented in wp-includes/comment.php */ |
2203 $commentdata['comment_author_url'] = apply_filters( 'pre_comment_author_url', $commentdata['comment_author_url'] ); |
1873 $commentdata['comment_author_url'] = apply_filters( 'pre_comment_author_url', $commentdata['comment_author_url'] ); |
2204 /** This filter is documented in wp-includes/comment.php */ |
1874 /** This filter is documented in wp-includes/comment.php */ |
2227 |
1897 |
2228 /** |
1898 /** |
2229 * Adds a new comment to the database. |
1899 * Adds a new comment to the database. |
2230 * |
1900 * |
2231 * Filters new comment to ensure that the fields are sanitized and valid before |
1901 * Filters new comment to ensure that the fields are sanitized and valid before |
2232 * inserting comment into database. Calls 'comment_post' action with comment ID |
1902 * inserting comment into database. Calls {@see 'comment_post'} action with comment ID |
2233 * and whether comment is approved by WordPress. Also has 'preprocess_comment' |
1903 * and whether comment is approved by WordPress. Also has {@see 'preprocess_comment'} |
2234 * filter for processing the comment data before the function handles it. |
1904 * filter for processing the comment data before the function handles it. |
2235 * |
1905 * |
2236 * We use REMOTE_ADDR here directly. If you are behind a proxy, you should ensure |
1906 * We use `REMOTE_ADDR` here directly. If you are behind a proxy, you should ensure |
2237 * that it is properly set, such as in wp-config.php, for your environment. |
1907 * that it is properly set, such as in wp-config.php, for your environment. |
1908 * |
|
2238 * See {@link https://core.trac.wordpress.org/ticket/9235} |
1909 * See {@link https://core.trac.wordpress.org/ticket/9235} |
2239 * |
1910 * |
2240 * @since 1.5.0 |
1911 * @since 1.5.0 |
2241 * @param array $commentdata Contains information on the comment. |
1912 * @since 4.3.0 'comment_agent' and 'comment_author_IP' can be set via `$commentdata`. |
2242 * @return int|bool The ID of the comment on success, false on failure. |
1913 * @since 4.7.0 The `$avoid_die` parameter was added, allowing the function to |
2243 */ |
1914 * return a WP_Error object instead of dying. |
2244 function wp_new_comment( $commentdata ) { |
1915 * |
1916 * @see wp_insert_comment() |
|
1917 * @global wpdb $wpdb WordPress database abstraction object. |
|
1918 * |
|
1919 * @param array $commentdata { |
|
1920 * Comment data. |
|
1921 * |
|
1922 * @type string $comment_author The name of the comment author. |
|
1923 * @type string $comment_author_email The comment author email address. |
|
1924 * @type string $comment_author_url The comment author URL. |
|
1925 * @type string $comment_content The content of the comment. |
|
1926 * @type string $comment_date The date the comment was submitted. Default is the current time. |
|
1927 * @type string $comment_date_gmt The date the comment was submitted in the GMT timezone. |
|
1928 * Default is `$comment_date` in the GMT timezone. |
|
1929 * @type int $comment_parent The ID of this comment's parent, if any. Default 0. |
|
1930 * @type int $comment_post_ID The ID of the post that relates to the comment. |
|
1931 * @type int $user_id The ID of the user who submitted the comment. Default 0. |
|
1932 * @type int $user_ID Kept for backward-compatibility. Use `$user_id` instead. |
|
1933 * @type string $comment_agent Comment author user agent. Default is the value of 'HTTP_USER_AGENT' |
|
1934 * in the `$_SERVER` superglobal sent in the original request. |
|
1935 * @type string $comment_author_IP Comment author IP address in IPv4 format. Default is the value of |
|
1936 * 'REMOTE_ADDR' in the `$_SERVER` superglobal sent in the original request. |
|
1937 * } |
|
1938 * @param bool $avoid_die Should errors be returned as WP_Error objects instead of |
|
1939 * executing wp_die()? Default false. |
|
1940 * @return int|false|WP_Error The ID of the comment on success, false or WP_Error on failure. |
|
1941 */ |
|
1942 function wp_new_comment( $commentdata, $avoid_die = false ) { |
|
2245 global $wpdb; |
1943 global $wpdb; |
2246 |
1944 |
2247 if ( isset( $commentdata['user_ID'] ) ) { |
1945 if ( isset( $commentdata['user_ID'] ) ) { |
2248 $commentdata['user_id'] = $commentdata['user_ID'] = (int) $commentdata['user_ID']; |
1946 $commentdata['user_id'] = $commentdata['user_ID'] = (int) $commentdata['user_ID']; |
2249 } |
1947 } |
2250 |
1948 |
2251 $prefiltered_user_id = ( isset( $commentdata['user_id'] ) ) ? (int) $commentdata['user_id'] : 0; |
1949 $prefiltered_user_id = ( isset( $commentdata['user_id'] ) ) ? (int) $commentdata['user_id'] : 0; |
2252 |
1950 |
2253 /** |
1951 /** |
2254 * Filter a comment's data before it is sanitized and inserted into the database. |
1952 * Filters a comment's data before it is sanitized and inserted into the database. |
2255 * |
1953 * |
2256 * @since 1.5.0 |
1954 * @since 1.5.0 |
2257 * |
1955 * |
2258 * @param array $commentdata Comment data. |
1956 * @param array $commentdata Comment data. |
2259 */ |
1957 */ |
2268 |
1966 |
2269 $commentdata['comment_parent'] = isset($commentdata['comment_parent']) ? absint($commentdata['comment_parent']) : 0; |
1967 $commentdata['comment_parent'] = isset($commentdata['comment_parent']) ? absint($commentdata['comment_parent']) : 0; |
2270 $parent_status = ( 0 < $commentdata['comment_parent'] ) ? wp_get_comment_status($commentdata['comment_parent']) : ''; |
1968 $parent_status = ( 0 < $commentdata['comment_parent'] ) ? wp_get_comment_status($commentdata['comment_parent']) : ''; |
2271 $commentdata['comment_parent'] = ( 'approved' == $parent_status || 'unapproved' == $parent_status ) ? $commentdata['comment_parent'] : 0; |
1969 $commentdata['comment_parent'] = ( 'approved' == $parent_status || 'unapproved' == $parent_status ) ? $commentdata['comment_parent'] : 0; |
2272 |
1970 |
2273 $commentdata['comment_author_IP'] = preg_replace( '/[^0-9a-fA-F:., ]/', '',$_SERVER['REMOTE_ADDR'] ); |
1971 if ( ! isset( $commentdata['comment_author_IP'] ) ) { |
2274 $commentdata['comment_agent'] = isset( $_SERVER['HTTP_USER_AGENT'] ) ? substr( $_SERVER['HTTP_USER_AGENT'], 0, 254 ) : ''; |
1972 $commentdata['comment_author_IP'] = $_SERVER['REMOTE_ADDR']; |
1973 } |
|
1974 $commentdata['comment_author_IP'] = preg_replace( '/[^0-9a-fA-F:., ]/', '', $commentdata['comment_author_IP'] ); |
|
1975 |
|
1976 if ( ! isset( $commentdata['comment_agent'] ) ) { |
|
1977 $commentdata['comment_agent'] = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT']: ''; |
|
1978 } |
|
1979 $commentdata['comment_agent'] = substr( $commentdata['comment_agent'], 0, 254 ); |
|
2275 |
1980 |
2276 if ( empty( $commentdata['comment_date'] ) ) { |
1981 if ( empty( $commentdata['comment_date'] ) ) { |
2277 $commentdata['comment_date'] = current_time('mysql'); |
1982 $commentdata['comment_date'] = current_time('mysql'); |
2278 } |
1983 } |
2279 |
1984 |
2281 $commentdata['comment_date_gmt'] = current_time( 'mysql', 1 ); |
1986 $commentdata['comment_date_gmt'] = current_time( 'mysql', 1 ); |
2282 } |
1987 } |
2283 |
1988 |
2284 $commentdata = wp_filter_comment($commentdata); |
1989 $commentdata = wp_filter_comment($commentdata); |
2285 |
1990 |
2286 $commentdata['comment_approved'] = wp_allow_comment($commentdata); |
1991 $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $avoid_die ); |
1992 if ( is_wp_error( $commentdata['comment_approved'] ) ) { |
|
1993 return $commentdata['comment_approved']; |
|
1994 } |
|
2287 |
1995 |
2288 $comment_ID = wp_insert_comment($commentdata); |
1996 $comment_ID = wp_insert_comment($commentdata); |
2289 if ( ! $comment_ID ) { |
1997 if ( ! $comment_ID ) { |
2290 $fields = array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content' ); |
1998 $fields = array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content' ); |
2291 |
1999 |
2292 foreach( $fields as $field ) { |
2000 foreach ( $fields as $field ) { |
2293 if ( isset( $commentdata[ $field ] ) ) { |
2001 if ( isset( $commentdata[ $field ] ) ) { |
2294 $commentdata[ $field ] = $wpdb->strip_invalid_text_for_column( $wpdb->comments, $field, $commentdata[ $field ] ); |
2002 $commentdata[ $field ] = $wpdb->strip_invalid_text_for_column( $wpdb->comments, $field, $commentdata[ $field ] ); |
2295 } |
2003 } |
2296 } |
2004 } |
2297 |
2005 |
2298 $commentdata = wp_filter_comment( $commentdata ); |
2006 $commentdata = wp_filter_comment( $commentdata ); |
2299 |
2007 |
2300 $commentdata['comment_approved'] = wp_allow_comment( $commentdata ); |
2008 $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $avoid_die ); |
2009 if ( is_wp_error( $commentdata['comment_approved'] ) ) { |
|
2010 return $commentdata['comment_approved']; |
|
2011 } |
|
2301 |
2012 |
2302 $comment_ID = wp_insert_comment( $commentdata ); |
2013 $comment_ID = wp_insert_comment( $commentdata ); |
2303 if ( ! $comment_ID ) { |
2014 if ( ! $comment_ID ) { |
2304 return false; |
2015 return false; |
2305 } |
2016 } |
2307 |
2018 |
2308 /** |
2019 /** |
2309 * Fires immediately after a comment is inserted into the database. |
2020 * Fires immediately after a comment is inserted into the database. |
2310 * |
2021 * |
2311 * @since 1.2.0 |
2022 * @since 1.2.0 |
2312 * |
2023 * @since 4.5.0 The `$commentdata` parameter was added. |
2313 * @param int $comment_ID The comment ID. |
2024 * |
2314 * @param int $comment_approved 1 (true) if the comment is approved, 0 (false) if not. |
2025 * @param int $comment_ID The comment ID. |
2315 */ |
2026 * @param int|string $comment_approved 1 if the comment is approved, 0 if not, 'spam' if spam. |
2316 do_action( 'comment_post', $comment_ID, $commentdata['comment_approved'] ); |
2027 * @param array $commentdata Comment data. |
2317 |
2028 */ |
2318 if ( 'spam' !== $commentdata['comment_approved'] ) { // If it's spam save it silently for later crunching |
2029 do_action( 'comment_post', $comment_ID, $commentdata['comment_approved'], $commentdata ); |
2319 if ( '0' == $commentdata['comment_approved'] ) { |
|
2320 wp_notify_moderator( $comment_ID ); |
|
2321 } |
|
2322 |
|
2323 // wp_notify_postauthor() checks if notifying the author of their own comment. |
|
2324 // By default, it won't, but filters can override this. |
|
2325 if ( get_option( 'comments_notify' ) && $commentdata['comment_approved'] ) { |
|
2326 wp_notify_postauthor( $comment_ID ); |
|
2327 } |
|
2328 } |
|
2329 |
2030 |
2330 return $comment_ID; |
2031 return $comment_ID; |
2331 } |
2032 } |
2332 |
2033 |
2333 /** |
2034 /** |
2035 * Send a comment moderation notification to the comment moderator. |
|
2036 * |
|
2037 * @since 4.4.0 |
|
2038 * |
|
2039 * @param int $comment_ID ID of the comment. |
|
2040 * @return bool True on success, false on failure. |
|
2041 */ |
|
2042 function wp_new_comment_notify_moderator( $comment_ID ) { |
|
2043 $comment = get_comment( $comment_ID ); |
|
2044 |
|
2045 // Only send notifications for pending comments. |
|
2046 $maybe_notify = ( '0' == $comment->comment_approved ); |
|
2047 |
|
2048 /** This filter is documented in wp-includes/comment.php */ |
|
2049 $maybe_notify = apply_filters( 'notify_moderator', $maybe_notify, $comment_ID ); |
|
2050 |
|
2051 if ( ! $maybe_notify ) { |
|
2052 return false; |
|
2053 } |
|
2054 |
|
2055 return wp_notify_moderator( $comment_ID ); |
|
2056 } |
|
2057 |
|
2058 /** |
|
2059 * Send a notification of a new comment to the post author. |
|
2060 * |
|
2061 * @since 4.4.0 |
|
2062 * |
|
2063 * Uses the {@see 'notify_post_author'} filter to determine whether the post author |
|
2064 * should be notified when a new comment is added, overriding site setting. |
|
2065 * |
|
2066 * @param int $comment_ID Comment ID. |
|
2067 * @return bool True on success, false on failure. |
|
2068 */ |
|
2069 function wp_new_comment_notify_postauthor( $comment_ID ) { |
|
2070 $comment = get_comment( $comment_ID ); |
|
2071 |
|
2072 $maybe_notify = get_option( 'comments_notify' ); |
|
2073 |
|
2074 /** |
|
2075 * Filters whether to send the post author new comment notification emails, |
|
2076 * overriding the site setting. |
|
2077 * |
|
2078 * @since 4.4.0 |
|
2079 * |
|
2080 * @param bool $maybe_notify Whether to notify the post author about the new comment. |
|
2081 * @param int $comment_ID The ID of the comment for the notification. |
|
2082 */ |
|
2083 $maybe_notify = apply_filters( 'notify_post_author', $maybe_notify, $comment_ID ); |
|
2084 |
|
2085 /* |
|
2086 * wp_notify_postauthor() checks if notifying the author of their own comment. |
|
2087 * By default, it won't, but filters can override this. |
|
2088 */ |
|
2089 if ( ! $maybe_notify ) { |
|
2090 return false; |
|
2091 } |
|
2092 |
|
2093 // Only send notifications for approved comments. |
|
2094 if ( ! isset( $comment->comment_approved ) || '1' != $comment->comment_approved ) { |
|
2095 return false; |
|
2096 } |
|
2097 |
|
2098 return wp_notify_postauthor( $comment_ID ); |
|
2099 } |
|
2100 |
|
2101 /** |
|
2334 * Sets the status of a comment. |
2102 * Sets the status of a comment. |
2335 * |
2103 * |
2336 * The 'wp_set_comment_status' action is called after the comment is handled. |
2104 * The {@see 'wp_set_comment_status'} action is called after the comment is handled. |
2337 * If the comment status is not in the list, then false is returned. |
2105 * If the comment status is not in the list, then false is returned. |
2338 * |
2106 * |
2339 * @since 1.0.0 |
2107 * @since 1.0.0 |
2340 * |
2108 * |
2341 * @param int $comment_id Comment ID. |
2109 * @global wpdb $wpdb WordPress database abstraction object. |
2342 * @param string $comment_status New comment status, either 'hold', 'approve', 'spam', or 'trash'. |
2110 * |
2343 * @param bool $wp_error Whether to return a WP_Error object if there is a failure. Default is false. |
2111 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object. |
2112 * @param string $comment_status New comment status, either 'hold', 'approve', 'spam', or 'trash'. |
|
2113 * @param bool $wp_error Whether to return a WP_Error object if there is a failure. Default is false. |
|
2344 * @return bool|WP_Error True on success, false or WP_Error on failure. |
2114 * @return bool|WP_Error True on success, false or WP_Error on failure. |
2345 */ |
2115 */ |
2346 function wp_set_comment_status($comment_id, $comment_status, $wp_error = false) { |
2116 function wp_set_comment_status($comment_id, $comment_status, $wp_error = false) { |
2347 global $wpdb; |
2117 global $wpdb; |
2348 |
2118 |
2352 $status = '0'; |
2122 $status = '0'; |
2353 break; |
2123 break; |
2354 case 'approve': |
2124 case 'approve': |
2355 case '1': |
2125 case '1': |
2356 $status = '1'; |
2126 $status = '1'; |
2357 if ( get_option('comments_notify') ) { |
2127 add_action( 'wp_set_comment_status', 'wp_new_comment_notify_postauthor' ); |
2358 wp_notify_postauthor( $comment_id ); |
|
2359 } |
|
2360 break; |
2128 break; |
2361 case 'spam': |
2129 case 'spam': |
2362 $status = 'spam'; |
2130 $status = 'spam'; |
2363 break; |
2131 break; |
2364 case 'trash': |
2132 case 'trash': |
2368 return false; |
2136 return false; |
2369 } |
2137 } |
2370 |
2138 |
2371 $comment_old = clone get_comment($comment_id); |
2139 $comment_old = clone get_comment($comment_id); |
2372 |
2140 |
2373 if ( !$wpdb->update( $wpdb->comments, array('comment_approved' => $status), array('comment_ID' => $comment_id) ) ) { |
2141 if ( !$wpdb->update( $wpdb->comments, array('comment_approved' => $status), array( 'comment_ID' => $comment_old->comment_ID ) ) ) { |
2374 if ( $wp_error ) |
2142 if ( $wp_error ) |
2375 return new WP_Error('db_update_error', __('Could not update comment status'), $wpdb->last_error); |
2143 return new WP_Error('db_update_error', __('Could not update comment status'), $wpdb->last_error); |
2376 else |
2144 else |
2377 return false; |
2145 return false; |
2378 } |
2146 } |
2379 |
2147 |
2380 clean_comment_cache($comment_id); |
2148 clean_comment_cache( $comment_old->comment_ID ); |
2381 |
2149 |
2382 $comment = get_comment($comment_id); |
2150 $comment = get_comment( $comment_old->comment_ID ); |
2383 |
2151 |
2384 /** |
2152 /** |
2385 * Fires immediately before transitioning a comment's status from one to another |
2153 * Fires immediately before transitioning a comment's status from one to another |
2386 * in the database. |
2154 * in the database. |
2387 * |
2155 * |
2389 * |
2157 * |
2390 * @param int $comment_id Comment ID. |
2158 * @param int $comment_id Comment ID. |
2391 * @param string|bool $comment_status Current comment status. Possible values include |
2159 * @param string|bool $comment_status Current comment status. Possible values include |
2392 * 'hold', 'approve', 'spam', 'trash', or false. |
2160 * 'hold', 'approve', 'spam', 'trash', or false. |
2393 */ |
2161 */ |
2394 do_action( 'wp_set_comment_status', $comment_id, $comment_status ); |
2162 do_action( 'wp_set_comment_status', $comment->comment_ID, $comment_status ); |
2395 |
2163 |
2396 wp_transition_comment_status($comment_status, $comment_old->comment_approved, $comment); |
2164 wp_transition_comment_status($comment_status, $comment_old->comment_approved, $comment); |
2397 |
2165 |
2398 wp_update_comment_count($comment->comment_post_ID); |
2166 wp_update_comment_count($comment->comment_post_ID); |
2399 |
2167 |
2404 * Updates an existing comment in the database. |
2172 * Updates an existing comment in the database. |
2405 * |
2173 * |
2406 * Filters the comment and makes sure certain fields are valid before updating. |
2174 * Filters the comment and makes sure certain fields are valid before updating. |
2407 * |
2175 * |
2408 * @since 2.0.0 |
2176 * @since 2.0.0 |
2177 * @since 4.9.0 Add updating comment meta during comment update. |
|
2409 * |
2178 * |
2410 * @global wpdb $wpdb WordPress database abstraction object. |
2179 * @global wpdb $wpdb WordPress database abstraction object. |
2411 * |
2180 * |
2412 * @param array $commentarr Contains information on the comment. |
2181 * @param array $commentarr Contains information on the comment. |
2413 * @return int Comment was updated if value is 1, or was not updated if value is 0. |
2182 * @return int Comment was updated if value is 1, or was not updated if value is 0. |
2420 if ( empty( $comment ) ) { |
2189 if ( empty( $comment ) ) { |
2421 return 0; |
2190 return 0; |
2422 } |
2191 } |
2423 |
2192 |
2424 // Make sure that the comment post ID is valid (if specified). |
2193 // Make sure that the comment post ID is valid (if specified). |
2425 if ( isset( $commentarr['comment_post_ID'] ) && ! get_post( $commentarr['comment_post_ID'] ) ) { |
2194 if ( ! empty( $commentarr['comment_post_ID'] ) && ! get_post( $commentarr['comment_post_ID'] ) ) { |
2426 return 0; |
2195 return 0; |
2427 } |
2196 } |
2428 |
2197 |
2429 // Escape data pulled from DB. |
2198 // Escape data pulled from DB. |
2430 $comment = wp_slash($comment); |
2199 $comment = wp_slash($comment); |
2438 |
2207 |
2439 // Now extract the merged array. |
2208 // Now extract the merged array. |
2440 $data = wp_unslash( $commentarr ); |
2209 $data = wp_unslash( $commentarr ); |
2441 |
2210 |
2442 /** |
2211 /** |
2443 * Filter the comment content before it is updated in the database. |
2212 * Filters the comment content before it is updated in the database. |
2444 * |
2213 * |
2445 * @since 1.5.0 |
2214 * @since 1.5.0 |
2446 * |
2215 * |
2447 * @param string $comment_content The comment data. |
2216 * @param string $comment_content The comment data. |
2448 */ |
2217 */ |
2458 $data['comment_approved'] = 1; |
2227 $data['comment_approved'] = 1; |
2459 } |
2228 } |
2460 |
2229 |
2461 $comment_ID = $data['comment_ID']; |
2230 $comment_ID = $data['comment_ID']; |
2462 $comment_post_ID = $data['comment_post_ID']; |
2231 $comment_post_ID = $data['comment_post_ID']; |
2463 $keys = array( 'comment_post_ID', 'comment_content', 'comment_author', 'comment_author_email', 'comment_approved', 'comment_karma', 'comment_author_url', 'comment_date', 'comment_date_gmt', 'comment_type', 'comment_parent', 'user_id' ); |
2232 |
2233 /** |
|
2234 * Filters the comment data immediately before it is updated in the database. |
|
2235 * |
|
2236 * Note: data being passed to the filter is already unslashed. |
|
2237 * |
|
2238 * @since 4.7.0 |
|
2239 * |
|
2240 * @param array $data The new, processed comment data. |
|
2241 * @param array $comment The old, unslashed comment data. |
|
2242 * @param array $commentarr The new, raw comment data. |
|
2243 */ |
|
2244 $data = apply_filters( 'wp_update_comment_data', $data, $comment, $commentarr ); |
|
2245 |
|
2246 $keys = array( 'comment_post_ID', 'comment_content', 'comment_author', 'comment_author_email', 'comment_approved', 'comment_karma', 'comment_author_url', 'comment_date', 'comment_date_gmt', 'comment_type', 'comment_parent', 'user_id', 'comment_agent', 'comment_author_IP' ); |
|
2464 $data = wp_array_slice_assoc( $data, $keys ); |
2247 $data = wp_array_slice_assoc( $data, $keys ); |
2248 |
|
2465 $rval = $wpdb->update( $wpdb->comments, $data, compact( 'comment_ID' ) ); |
2249 $rval = $wpdb->update( $wpdb->comments, $data, compact( 'comment_ID' ) ); |
2250 |
|
2251 // If metadata is provided, store it. |
|
2252 if ( isset( $commentarr['comment_meta'] ) && is_array( $commentarr['comment_meta'] ) ) { |
|
2253 foreach ( $commentarr['comment_meta'] as $meta_key => $meta_value ) { |
|
2254 update_comment_meta( $comment_ID, $meta_key, $meta_value ); |
|
2255 } |
|
2256 } |
|
2466 |
2257 |
2467 clean_comment_cache( $comment_ID ); |
2258 clean_comment_cache( $comment_ID ); |
2468 wp_update_comment_count( $comment_post_ID ); |
2259 wp_update_comment_count( $comment_post_ID ); |
2469 /** |
2260 /** |
2470 * Fires immediately after a comment is updated in the database. |
2261 * Fires immediately after a comment is updated in the database. |
2471 * |
2262 * |
2472 * The hook also fires immediately before comment status transition hooks are fired. |
2263 * The hook also fires immediately before comment status transition hooks are fired. |
2473 * |
2264 * |
2474 * @since 1.2.0 |
2265 * @since 1.2.0 |
2475 * |
2266 * @since 4.6.0 Added the `$data` parameter. |
2476 * @param int $comment_ID The comment ID. |
2267 * |
2477 */ |
2268 * @param int $comment_ID The comment ID. |
2478 do_action( 'edit_comment', $comment_ID ); |
2269 * @param array $data Comment data. |
2270 */ |
|
2271 do_action( 'edit_comment', $comment_ID, $data ); |
|
2479 $comment = get_comment($comment_ID); |
2272 $comment = get_comment($comment_ID); |
2480 wp_transition_comment_status($comment->comment_approved, $old_status, $comment); |
2273 wp_transition_comment_status($comment->comment_approved, $old_status, $comment); |
2481 return $rval; |
2274 return $rval; |
2482 } |
2275 } |
2483 |
2276 |
2520 * IDs will be updated along with the current $post_id. |
2313 * IDs will be updated along with the current $post_id. |
2521 * |
2314 * |
2522 * @since 2.1.0 |
2315 * @since 2.1.0 |
2523 * @see wp_update_comment_count_now() For what could cause a false return value |
2316 * @see wp_update_comment_count_now() For what could cause a false return value |
2524 * |
2317 * |
2525 * @param int $post_id Post ID |
2318 * @staticvar array $_deferred |
2526 * @param bool $do_deferred Whether to process previously deferred post comment counts |
2319 * |
2527 * @return bool|null True on success, false on failure |
2320 * @param int|null $post_id Post ID. |
2321 * @param bool $do_deferred Optional. Whether to process previously deferred |
|
2322 * post comment counts. Default false. |
|
2323 * @return bool|void True on success, false on failure or if post with ID does |
|
2324 * not exist. |
|
2528 */ |
2325 */ |
2529 function wp_update_comment_count($post_id, $do_deferred=false) { |
2326 function wp_update_comment_count($post_id, $do_deferred=false) { |
2530 static $_deferred = array(); |
2327 static $_deferred = array(); |
2328 |
|
2329 if ( empty( $post_id ) && ! $do_deferred ) { |
|
2330 return false; |
|
2331 } |
|
2531 |
2332 |
2532 if ( $do_deferred ) { |
2333 if ( $do_deferred ) { |
2533 $_deferred = array_unique($_deferred); |
2334 $_deferred = array_unique($_deferred); |
2534 foreach ( $_deferred as $i => $_post_id ) { |
2335 foreach ( $_deferred as $i => $_post_id ) { |
2535 wp_update_comment_count_now($_post_id); |
2336 wp_update_comment_count_now($_post_id); |
2560 function wp_update_comment_count_now($post_id) { |
2361 function wp_update_comment_count_now($post_id) { |
2561 global $wpdb; |
2362 global $wpdb; |
2562 $post_id = (int) $post_id; |
2363 $post_id = (int) $post_id; |
2563 if ( !$post_id ) |
2364 if ( !$post_id ) |
2564 return false; |
2365 return false; |
2366 |
|
2367 wp_cache_delete( 'comments-0', 'counts' ); |
|
2368 wp_cache_delete( "comments-{$post_id}", 'counts' ); |
|
2369 |
|
2565 if ( !$post = get_post($post_id) ) |
2370 if ( !$post = get_post($post_id) ) |
2566 return false; |
2371 return false; |
2567 |
2372 |
2568 $old = (int) $post->comment_count; |
2373 $old = (int) $post->comment_count; |
2569 $new = (int) $wpdb->get_var( $wpdb->prepare("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved = '1'", $post_id) ); |
2374 |
2375 /** |
|
2376 * Filters a post's comment count before it is updated in the database. |
|
2377 * |
|
2378 * @since 4.5.0 |
|
2379 * |
|
2380 * @param int $new The new comment count. Default null. |
|
2381 * @param int $old The old comment count. |
|
2382 * @param int $post_id Post ID. |
|
2383 */ |
|
2384 $new = apply_filters( 'pre_wp_update_comment_count_now', null, $old, $post_id ); |
|
2385 |
|
2386 if ( is_null( $new ) ) { |
|
2387 $new = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved = '1'", $post_id ) ); |
|
2388 } else { |
|
2389 $new = (int) $new; |
|
2390 } |
|
2391 |
|
2570 $wpdb->update( $wpdb->posts, array('comment_count' => $new), array('ID' => $post_id) ); |
2392 $wpdb->update( $wpdb->posts, array('comment_count' => $new), array('ID' => $post_id) ); |
2571 |
2393 |
2572 clean_post_cache( $post ); |
2394 clean_post_cache( $post ); |
2573 |
2395 |
2574 /** |
2396 /** |
2604 * @param int $deprecated Not Used. |
2426 * @param int $deprecated Not Used. |
2605 * @return false|string False on failure, string containing URI on success. |
2427 * @return false|string False on failure, string containing URI on success. |
2606 */ |
2428 */ |
2607 function discover_pingback_server_uri( $url, $deprecated = '' ) { |
2429 function discover_pingback_server_uri( $url, $deprecated = '' ) { |
2608 if ( !empty( $deprecated ) ) |
2430 if ( !empty( $deprecated ) ) |
2609 _deprecated_argument( __FUNCTION__, '2.7' ); |
2431 _deprecated_argument( __FUNCTION__, '2.7.0' ); |
2610 |
2432 |
2611 $pingback_str_dquote = 'rel="pingback"'; |
2433 $pingback_str_dquote = 'rel="pingback"'; |
2612 $pingback_str_squote = 'rel=\'pingback\''; |
2434 $pingback_str_squote = 'rel=\'pingback\''; |
2613 |
2435 |
2614 /** @todo Should use Filter Extension or custom preg_match instead. */ |
2436 /** @todo Should use Filter Extension or custom preg_match instead. */ |
2615 $parsed_url = parse_url($url); |
2437 $parsed_url = parse_url($url); |
2616 |
2438 |
2617 if ( ! isset( $parsed_url['host'] ) ) // Not an URL. This should never happen. |
2439 if ( ! isset( $parsed_url['host'] ) ) // Not a URL. This should never happen. |
2618 return false; |
2440 return false; |
2619 |
2441 |
2620 //Do not search for a pingback server on our own uploads |
2442 //Do not search for a pingback server on our own uploads |
2621 $uploads_dir = wp_upload_dir(); |
2443 $uploads_dir = wp_get_upload_dir(); |
2622 if ( 0 === strpos($url, $uploads_dir['baseurl']) ) |
2444 if ( 0 === strpos($url, $uploads_dir['baseurl']) ) |
2623 return false; |
2445 return false; |
2624 |
2446 |
2625 $response = wp_safe_remote_head( $url, array( 'timeout' => 2, 'httpversion' => '1.0' ) ); |
2447 $response = wp_safe_remote_head( $url, array( 'timeout' => 2, 'httpversion' => '1.0' ) ); |
2626 |
2448 |
2696 |
2518 |
2697 /** |
2519 /** |
2698 * Perform trackbacks. |
2520 * Perform trackbacks. |
2699 * |
2521 * |
2700 * @since 1.5.0 |
2522 * @since 1.5.0 |
2523 * @since 4.7.0 $post_id can be a WP_Post object. |
|
2701 * |
2524 * |
2702 * @global wpdb $wpdb WordPress database abstraction object. |
2525 * @global wpdb $wpdb WordPress database abstraction object. |
2703 * |
2526 * |
2704 * @param int $post_id Post ID to do trackbacks on. |
2527 * @param int|WP_Post $post_id Post object or ID to do trackbacks on. |
2705 */ |
2528 */ |
2706 function do_trackbacks($post_id) { |
2529 function do_trackbacks( $post_id ) { |
2707 global $wpdb; |
2530 global $wpdb; |
2708 |
|
2709 $post = get_post( $post_id ); |
2531 $post = get_post( $post_id ); |
2710 $to_ping = get_to_ping($post_id); |
2532 if ( ! $post ) { |
2711 $pinged = get_pung($post_id); |
2533 return false; |
2712 if ( empty($to_ping) ) { |
2534 } |
2713 $wpdb->update($wpdb->posts, array('to_ping' => ''), array('ID' => $post_id) ); |
2535 |
2536 $to_ping = get_to_ping( $post ); |
|
2537 $pinged = get_pung( $post ); |
|
2538 if ( empty( $to_ping ) ) { |
|
2539 $wpdb->update($wpdb->posts, array( 'to_ping' => '' ), array( 'ID' => $post->ID ) ); |
|
2714 return; |
2540 return; |
2715 } |
2541 } |
2716 |
2542 |
2717 if ( empty($post->post_excerpt) ) { |
2543 if ( empty($post->post_excerpt) ) { |
2718 /** This filter is documented in wp-includes/post-template.php */ |
2544 /** This filter is documented in wp-includes/post-template.php */ |
2731 |
2557 |
2732 if ( $to_ping ) { |
2558 if ( $to_ping ) { |
2733 foreach ( (array) $to_ping as $tb_ping ) { |
2559 foreach ( (array) $to_ping as $tb_ping ) { |
2734 $tb_ping = trim($tb_ping); |
2560 $tb_ping = trim($tb_ping); |
2735 if ( !in_array($tb_ping, $pinged) ) { |
2561 if ( !in_array($tb_ping, $pinged) ) { |
2736 trackback($tb_ping, $post_title, $excerpt, $post_id); |
2562 trackback( $tb_ping, $post_title, $excerpt, $post->ID ); |
2737 $pinged[] = $tb_ping; |
2563 $pinged[] = $tb_ping; |
2738 } else { |
2564 } else { |
2739 $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET to_ping = TRIM(REPLACE(to_ping, %s, '')) WHERE ID = %d", $tb_ping, $post_id) ); |
2565 $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET to_ping = TRIM(REPLACE(to_ping, %s, |
2566 '')) WHERE ID = %d", $tb_ping, $post->ID ) ); |
|
2740 } |
2567 } |
2741 } |
2568 } |
2742 } |
2569 } |
2743 } |
2570 } |
2744 |
2571 |
2765 |
2592 |
2766 /** |
2593 /** |
2767 * Pings back the links found in a post. |
2594 * Pings back the links found in a post. |
2768 * |
2595 * |
2769 * @since 0.71 |
2596 * @since 0.71 |
2770 * @uses $wp_version |
2597 * @since 4.7.0 $post_id can be a WP_Post object. |
2771 * |
2598 * |
2772 * @param string $content Post content to check for links. |
2599 * @param string $content Post content to check for links. If empty will retrieve from post. |
2773 * @param int $post_ID Post ID. |
2600 * @param int|WP_Post $post_id Post Object or ID. |
2774 */ |
2601 */ |
2775 function pingback($content, $post_ID) { |
2602 function pingback( $content, $post_id ) { |
2776 global $wp_version; |
2603 include_once( ABSPATH . WPINC . '/class-IXR.php' ); |
2777 include_once(ABSPATH . WPINC . '/class-IXR.php'); |
2604 include_once( ABSPATH . WPINC . '/class-wp-http-ixr-client.php' ); |
2778 include_once(ABSPATH . WPINC . '/class-wp-http-ixr-client.php'); |
|
2779 |
2605 |
2780 // original code by Mort (http://mort.mine.nu:8080) |
2606 // original code by Mort (http://mort.mine.nu:8080) |
2781 $post_links = array(); |
2607 $post_links = array(); |
2782 |
2608 |
2783 $pung = get_pung($post_ID); |
2609 $post = get_post( $post_id ); |
2610 if ( ! $post ) { |
|
2611 return; |
|
2612 } |
|
2613 |
|
2614 $pung = get_pung( $post ); |
|
2615 |
|
2616 if ( empty( $content ) ) { |
|
2617 $content = $post->post_content; |
|
2618 } |
|
2784 |
2619 |
2785 // Step 1 |
2620 // Step 1 |
2786 // Parsing the post, external links (if any) are stored in the $post_links array |
2621 // Parsing the post, external links (if any) are stored in the $post_links array |
2787 $post_links_temp = wp_extract_urls( $content ); |
2622 $post_links_temp = wp_extract_urls( $content ); |
2788 |
2623 |
2794 // http://dummy-weblog.org/ |
2629 // http://dummy-weblog.org/ |
2795 // http://dummy-weblog.org/post.php |
2630 // http://dummy-weblog.org/post.php |
2796 // We don't wanna ping first and second types, even if they have a valid <link/> |
2631 // We don't wanna ping first and second types, even if they have a valid <link/> |
2797 |
2632 |
2798 foreach ( (array) $post_links_temp as $link_test ) : |
2633 foreach ( (array) $post_links_temp as $link_test ) : |
2799 if ( !in_array($link_test, $pung) && (url_to_postid($link_test) != $post_ID) // If we haven't pung it already and it isn't a link to itself |
2634 if ( ! in_array( $link_test, $pung ) && ( url_to_postid( $link_test ) != $post->ID ) // If we haven't pung it already and it isn't a link to itself |
2800 && !is_local_attachment($link_test) ) : // Also, let's never ping local attachments. |
2635 && !is_local_attachment($link_test) ) : // Also, let's never ping local attachments. |
2801 if ( $test = @parse_url($link_test) ) { |
2636 if ( $test = @parse_url($link_test) ) { |
2802 if ( isset($test['query']) ) |
2637 if ( isset($test['query']) ) |
2803 $post_links[] = $link_test; |
2638 $post_links[] = $link_test; |
2804 elseif ( isset( $test['path'] ) && ( $test['path'] != '/' ) && ( $test['path'] != '' ) ) |
2639 elseif ( isset( $test['path'] ) && ( $test['path'] != '/' ) && ( $test['path'] != '' ) ) |
2811 /** |
2646 /** |
2812 * Fires just before pinging back links found in a post. |
2647 * Fires just before pinging back links found in a post. |
2813 * |
2648 * |
2814 * @since 2.0.0 |
2649 * @since 2.0.0 |
2815 * |
2650 * |
2816 * @param array &$post_links An array of post links to be checked, passed by reference. |
2651 * @param array $post_links An array of post links to be checked (passed by reference). |
2817 * @param array &$pung Whether a link has already been pinged, passed by reference. |
2652 * @param array $pung Whether a link has already been pinged (passed by reference). |
2818 * @param int $post_ID The post ID. |
2653 * @param int $post_ID The post ID. |
2819 */ |
2654 */ |
2820 do_action_ref_array( 'pre_ping', array( &$post_links, &$pung, $post_ID ) ); |
2655 do_action_ref_array( 'pre_ping', array( &$post_links, &$pung, $post->ID ) ); |
2821 |
2656 |
2822 foreach ( (array) $post_links as $pagelinkedto ) { |
2657 foreach ( (array) $post_links as $pagelinkedto ) { |
2823 $pingback_server_url = discover_pingback_server_uri( $pagelinkedto ); |
2658 $pingback_server_url = discover_pingback_server_uri( $pagelinkedto ); |
2824 |
2659 |
2825 if ( $pingback_server_url ) { |
2660 if ( $pingback_server_url ) { |
2826 @ set_time_limit( 60 ); |
2661 @ set_time_limit( 60 ); |
2827 // Now, the RPC call |
2662 // Now, the RPC call |
2828 $pagelinkedfrom = get_permalink($post_ID); |
2663 $pagelinkedfrom = get_permalink( $post ); |
2829 |
2664 |
2830 // using a timeout of 3 seconds should be enough to cover slow servers |
2665 // using a timeout of 3 seconds should be enough to cover slow servers |
2831 $client = new WP_HTTP_IXR_Client($pingback_server_url); |
2666 $client = new WP_HTTP_IXR_Client($pingback_server_url); |
2832 $client->timeout = 3; |
2667 $client->timeout = 3; |
2833 /** |
2668 /** |
2834 * Filter the user agent sent when pinging-back a URL. |
2669 * Filters the user agent sent when pinging-back a URL. |
2835 * |
2670 * |
2836 * @since 2.9.0 |
2671 * @since 2.9.0 |
2837 * |
2672 * |
2838 * @param string $concat_useragent The user agent concatenated with ' -- WordPress/' |
2673 * @param string $concat_useragent The user agent concatenated with ' -- WordPress/' |
2839 * and the WordPress version. |
2674 * and the WordPress version. |
2840 * @param string $useragent The useragent. |
2675 * @param string $useragent The useragent. |
2841 * @param string $pingback_server_url The server URL being linked to. |
2676 * @param string $pingback_server_url The server URL being linked to. |
2842 * @param string $pagelinkedto URL of page linked to. |
2677 * @param string $pagelinkedto URL of page linked to. |
2843 * @param string $pagelinkedfrom URL of page linked from. |
2678 * @param string $pagelinkedfrom URL of page linked from. |
2844 */ |
2679 */ |
2845 $client->useragent = apply_filters( 'pingback_useragent', $client->useragent . ' -- WordPress/' . $wp_version, $client->useragent, $pingback_server_url, $pagelinkedto, $pagelinkedfrom ); |
2680 $client->useragent = apply_filters( 'pingback_useragent', $client->useragent . ' -- WordPress/' . get_bloginfo( 'version' ), $client->useragent, $pingback_server_url, $pagelinkedto, $pagelinkedfrom ); |
2846 // when set to true, this outputs debug messages by itself |
2681 // when set to true, this outputs debug messages by itself |
2847 $client->debug = false; |
2682 $client->debug = false; |
2848 |
2683 |
2849 if ( $client->query('pingback.ping', $pagelinkedfrom, $pagelinkedto) || ( isset($client->error->code) && 48 == $client->error->code ) ) // Already registered |
2684 if ( $client->query('pingback.ping', $pagelinkedfrom, $pagelinkedto) || ( isset($client->error->code) && 48 == $client->error->code ) ) // Already registered |
2850 add_ping( $post_ID, $pagelinkedto ); |
2685 add_ping( $post, $pagelinkedto ); |
2851 } |
2686 } |
2852 } |
2687 } |
2853 } |
2688 } |
2854 |
2689 |
2855 /** |
2690 /** |
2878 * |
2713 * |
2879 * @param string $trackback_url URL to send trackbacks. |
2714 * @param string $trackback_url URL to send trackbacks. |
2880 * @param string $title Title of post. |
2715 * @param string $title Title of post. |
2881 * @param string $excerpt Excerpt of post. |
2716 * @param string $excerpt Excerpt of post. |
2882 * @param int $ID Post ID. |
2717 * @param int $ID Post ID. |
2883 * @return mixed Database query from update. |
2718 * @return int|false|void Database query from update. |
2884 */ |
2719 */ |
2885 function trackback($trackback_url, $title, $excerpt, $ID) { |
2720 function trackback($trackback_url, $title, $excerpt, $ID) { |
2886 global $wpdb; |
2721 global $wpdb; |
2887 |
2722 |
2888 if ( empty($trackback_url) ) |
2723 if ( empty($trackback_url) ) |
2889 return; |
2724 return; |
2890 |
2725 |
2891 $options = array(); |
2726 $options = array(); |
2892 $options['timeout'] = 4; |
2727 $options['timeout'] = 10; |
2893 $options['body'] = array( |
2728 $options['body'] = array( |
2894 'title' => $title, |
2729 'title' => $title, |
2895 'url' => get_permalink($ID), |
2730 'url' => get_permalink($ID), |
2896 'blog_name' => get_option('blogname'), |
2731 'blog_name' => get_option('blogname'), |
2897 'excerpt' => $excerpt |
2732 'excerpt' => $excerpt |
2908 |
2743 |
2909 /** |
2744 /** |
2910 * Send a pingback. |
2745 * Send a pingback. |
2911 * |
2746 * |
2912 * @since 1.2.0 |
2747 * @since 1.2.0 |
2913 * @uses $wp_version |
|
2914 * |
2748 * |
2915 * @param string $server Host of blog to connect to. |
2749 * @param string $server Host of blog to connect to. |
2916 * @param string $path Path to send the ping. |
2750 * @param string $path Path to send the ping. |
2917 */ |
2751 */ |
2918 function weblog_ping($server = '', $path = '') { |
2752 function weblog_ping($server = '', $path = '') { |
2919 global $wp_version; |
2753 include_once( ABSPATH . WPINC . '/class-IXR.php' ); |
2920 include_once(ABSPATH . WPINC . '/class-IXR.php'); |
2754 include_once( ABSPATH . WPINC . '/class-wp-http-ixr-client.php' ); |
2921 include_once(ABSPATH . WPINC . '/class-wp-http-ixr-client.php'); |
|
2922 |
2755 |
2923 // using a timeout of 3 seconds should be enough to cover slow servers |
2756 // using a timeout of 3 seconds should be enough to cover slow servers |
2924 $client = new WP_HTTP_IXR_Client($server, ((!strlen(trim($path)) || ('/' == $path)) ? false : $path)); |
2757 $client = new WP_HTTP_IXR_Client($server, ((!strlen(trim($path)) || ('/' == $path)) ? false : $path)); |
2925 $client->timeout = 3; |
2758 $client->timeout = 3; |
2926 $client->useragent .= ' -- WordPress/'.$wp_version; |
2759 $client->useragent .= ' -- WordPress/' . get_bloginfo( 'version' ); |
2927 |
2760 |
2928 // when set to true, this outputs debug messages by itself |
2761 // when set to true, this outputs debug messages by itself |
2929 $client->debug = false; |
2762 $client->debug = false; |
2930 $home = trailingslashit( home_url() ); |
2763 $home = trailingslashit( home_url() ); |
2931 if ( !$client->query('weblogUpdates.extendedPing', get_option('blogname'), $home, get_bloginfo('rss2_url') ) ) // then try a normal ping |
2764 if ( !$client->query('weblogUpdates.extendedPing', get_option('blogname'), $home, get_bloginfo('rss2_url') ) ) // then try a normal ping |
2950 * |
2783 * |
2951 * Returns a generic pingback error code unless the error code is 48, |
2784 * Returns a generic pingback error code unless the error code is 48, |
2952 * which reports that the pingback is already registered. |
2785 * which reports that the pingback is already registered. |
2953 * |
2786 * |
2954 * @since 3.5.1 |
2787 * @since 3.5.1 |
2955 * @link http://www.hixie.ch/specs/pingback/pingback#TOC3 |
2788 * @link https://www.hixie.ch/specs/pingback/pingback#TOC3 |
2956 * |
2789 * |
2957 * @param IXR_Error $ixr_error |
2790 * @param IXR_Error $ixr_error |
2958 * @return IXR_Error |
2791 * @return IXR_Error |
2959 */ |
2792 */ |
2960 function xmlrpc_pingback_error( $ixr_error ) { |
2793 function xmlrpc_pingback_error( $ixr_error ) { |
2966 // |
2799 // |
2967 // Cache |
2800 // Cache |
2968 // |
2801 // |
2969 |
2802 |
2970 /** |
2803 /** |
2971 * Removes comment ID from the comment cache. |
2804 * Removes a comment from the object cache. |
2972 * |
2805 * |
2973 * @since 2.3.0 |
2806 * @since 2.3.0 |
2974 * |
2807 * |
2975 * @param int|array $ids Comment ID or array of comment IDs to remove from cache |
2808 * @param int|array $ids Comment ID or an array of comment IDs to remove from cache. |
2976 */ |
2809 */ |
2977 function clean_comment_cache($ids) { |
2810 function clean_comment_cache($ids) { |
2978 foreach ( (array) $ids as $id ) |
2811 foreach ( (array) $ids as $id ) { |
2979 wp_cache_delete($id, 'comment'); |
2812 wp_cache_delete( $id, 'comment' ); |
2813 |
|
2814 /** |
|
2815 * Fires immediately after a comment has been removed from the object cache. |
|
2816 * |
|
2817 * @since 4.5.0 |
|
2818 * |
|
2819 * @param int $id Comment ID. |
|
2820 */ |
|
2821 do_action( 'clean_comment_cache', $id ); |
|
2822 } |
|
2980 |
2823 |
2981 wp_cache_set( 'last_changed', microtime(), 'comment' ); |
2824 wp_cache_set( 'last_changed', microtime(), 'comment' ); |
2982 } |
2825 } |
2983 |
2826 |
2984 /** |
2827 /** |
2987 * Will add the comments in $comments to the cache. If comment ID already exists |
2830 * Will add the comments in $comments to the cache. If comment ID already exists |
2988 * in the comment cache then it will not be updated. The comment is added to the |
2831 * in the comment cache then it will not be updated. The comment is added to the |
2989 * cache using the comment group with the key using the ID of the comments. |
2832 * cache using the comment group with the key using the ID of the comments. |
2990 * |
2833 * |
2991 * @since 2.3.0 |
2834 * @since 2.3.0 |
2992 * |
2835 * @since 4.4.0 Introduced the `$update_meta_cache` parameter. |
2993 * @param array $comments Array of comment row objects |
2836 * |
2994 */ |
2837 * @param array $comments Array of comment row objects |
2995 function update_comment_cache($comments) { |
2838 * @param bool $update_meta_cache Whether to update commentmeta cache. Default true. |
2839 */ |
|
2840 function update_comment_cache( $comments, $update_meta_cache = true ) { |
|
2996 foreach ( (array) $comments as $comment ) |
2841 foreach ( (array) $comments as $comment ) |
2997 wp_cache_add($comment->comment_ID, $comment, 'comment'); |
2842 wp_cache_add($comment->comment_ID, $comment, 'comment'); |
2843 |
|
2844 if ( $update_meta_cache ) { |
|
2845 // Avoid `wp_list_pluck()` in case `$comments` is passed by reference. |
|
2846 $comment_ids = array(); |
|
2847 foreach ( $comments as $comment ) { |
|
2848 $comment_ids[] = $comment->comment_ID; |
|
2849 } |
|
2850 update_meta_cache( 'comment', $comment_ids ); |
|
2851 } |
|
2852 } |
|
2853 |
|
2854 /** |
|
2855 * Adds any comments from the given IDs to the cache that do not already exist in cache. |
|
2856 * |
|
2857 * @since 4.4.0 |
|
2858 * @access private |
|
2859 * |
|
2860 * @see update_comment_cache() |
|
2861 * @global wpdb $wpdb WordPress database abstraction object. |
|
2862 * |
|
2863 * @param array $comment_ids Array of comment IDs. |
|
2864 * @param bool $update_meta_cache Optional. Whether to update the meta cache. Default true. |
|
2865 */ |
|
2866 function _prime_comment_caches( $comment_ids, $update_meta_cache = true ) { |
|
2867 global $wpdb; |
|
2868 |
|
2869 $non_cached_ids = _get_non_cached_ids( $comment_ids, 'comment' ); |
|
2870 if ( !empty( $non_cached_ids ) ) { |
|
2871 $fresh_comments = $wpdb->get_results( sprintf( "SELECT $wpdb->comments.* FROM $wpdb->comments WHERE comment_ID IN (%s)", join( ",", array_map( 'intval', $non_cached_ids ) ) ) ); |
|
2872 |
|
2873 update_comment_cache( $fresh_comments, $update_meta_cache ); |
|
2874 } |
|
2998 } |
2875 } |
2999 |
2876 |
3000 // |
2877 // |
3001 // Internal |
2878 // Internal |
3002 // |
2879 // |
3005 * Close comments on old posts on the fly, without any extra DB queries. Hooked to the_posts. |
2882 * Close comments on old posts on the fly, without any extra DB queries. Hooked to the_posts. |
3006 * |
2883 * |
3007 * @access private |
2884 * @access private |
3008 * @since 2.7.0 |
2885 * @since 2.7.0 |
3009 * |
2886 * |
3010 * @param object $posts Post data object. |
2887 * @param WP_Post $posts Post data object. |
3011 * @param object $query Query object. |
2888 * @param WP_Query $query Query object. |
3012 * @return object |
2889 * @return array |
3013 */ |
2890 */ |
3014 function _close_comments_for_old_posts( $posts, $query ) { |
2891 function _close_comments_for_old_posts( $posts, $query ) { |
3015 if ( empty( $posts ) || ! $query->is_singular() || ! get_option( 'close_comments_for_old_posts' ) ) |
2892 if ( empty( $posts ) || ! $query->is_singular() || ! get_option( 'close_comments_for_old_posts' ) ) |
3016 return $posts; |
2893 return $posts; |
3017 |
2894 |
3018 /** |
2895 /** |
3019 * Filter the list of post types to automatically close comments for. |
2896 * Filters the list of post types to automatically close comments for. |
3020 * |
2897 * |
3021 * @since 3.2.0 |
2898 * @since 3.2.0 |
3022 * |
2899 * |
3023 * @param array $post_types An array of registered post types. Default array with 'post'. |
2900 * @param array $post_types An array of registered post types. Default array with 'post'. |
3024 */ |
2901 */ |
3064 /** This filter is documented in wp-includes/comment.php */ |
2941 /** This filter is documented in wp-includes/comment.php */ |
3065 $post_types = apply_filters( 'close_comments_for_post_types', array( 'post' ) ); |
2942 $post_types = apply_filters( 'close_comments_for_post_types', array( 'post' ) ); |
3066 if ( ! in_array( $post->post_type, $post_types ) ) |
2943 if ( ! in_array( $post->post_type, $post_types ) ) |
3067 return $open; |
2944 return $open; |
3068 |
2945 |
2946 // Undated drafts should not show up as comments closed. |
|
2947 if ( '0000-00-00 00:00:00' === $post->post_date_gmt ) { |
|
2948 return $open; |
|
2949 } |
|
2950 |
|
3069 if ( time() - strtotime( $post->post_date_gmt ) > ( $days_old * DAY_IN_SECONDS ) ) |
2951 if ( time() - strtotime( $post->post_date_gmt ) > ( $days_old * DAY_IN_SECONDS ) ) |
3070 return false; |
2952 return false; |
3071 |
2953 |
3072 return $open; |
2954 return $open; |
3073 } |
2955 } |
2956 |
|
2957 /** |
|
2958 * Handles the submission of a comment, usually posted to wp-comments-post.php via a comment form. |
|
2959 * |
|
2960 * This function expects unslashed data, as opposed to functions such as `wp_new_comment()` which |
|
2961 * expect slashed data. |
|
2962 * |
|
2963 * @since 4.4.0 |
|
2964 * |
|
2965 * @param array $comment_data { |
|
2966 * Comment data. |
|
2967 * |
|
2968 * @type string|int $comment_post_ID The ID of the post that relates to the comment. |
|
2969 * @type string $author The name of the comment author. |
|
2970 * @type string $email The comment author email address. |
|
2971 * @type string $url The comment author URL. |
|
2972 * @type string $comment The content of the comment. |
|
2973 * @type string|int $comment_parent The ID of this comment's parent, if any. Default 0. |
|
2974 * @type string $_wp_unfiltered_html_comment The nonce value for allowing unfiltered HTML. |
|
2975 * } |
|
2976 * @return WP_Comment|WP_Error A WP_Comment object on success, a WP_Error object on failure. |
|
2977 */ |
|
2978 function wp_handle_comment_submission( $comment_data ) { |
|
2979 |
|
2980 $comment_post_ID = $comment_parent = 0; |
|
2981 $comment_author = $comment_author_email = $comment_author_url = $comment_content = null; |
|
2982 |
|
2983 if ( isset( $comment_data['comment_post_ID'] ) ) { |
|
2984 $comment_post_ID = (int) $comment_data['comment_post_ID']; |
|
2985 } |
|
2986 if ( isset( $comment_data['author'] ) && is_string( $comment_data['author'] ) ) { |
|
2987 $comment_author = trim( strip_tags( $comment_data['author'] ) ); |
|
2988 } |
|
2989 if ( isset( $comment_data['email'] ) && is_string( $comment_data['email'] ) ) { |
|
2990 $comment_author_email = trim( $comment_data['email'] ); |
|
2991 } |
|
2992 if ( isset( $comment_data['url'] ) && is_string( $comment_data['url'] ) ) { |
|
2993 $comment_author_url = trim( $comment_data['url'] ); |
|
2994 } |
|
2995 if ( isset( $comment_data['comment'] ) && is_string( $comment_data['comment'] ) ) { |
|
2996 $comment_content = trim( $comment_data['comment'] ); |
|
2997 } |
|
2998 if ( isset( $comment_data['comment_parent'] ) ) { |
|
2999 $comment_parent = absint( $comment_data['comment_parent'] ); |
|
3000 } |
|
3001 |
|
3002 $post = get_post( $comment_post_ID ); |
|
3003 |
|
3004 if ( empty( $post->comment_status ) ) { |
|
3005 |
|
3006 /** |
|
3007 * Fires when a comment is attempted on a post that does not exist. |
|
3008 * |
|
3009 * @since 1.5.0 |
|
3010 * |
|
3011 * @param int $comment_post_ID Post ID. |
|
3012 */ |
|
3013 do_action( 'comment_id_not_found', $comment_post_ID ); |
|
3014 |
|
3015 return new WP_Error( 'comment_id_not_found' ); |
|
3016 |
|
3017 } |
|
3018 |
|
3019 // get_post_status() will get the parent status for attachments. |
|
3020 $status = get_post_status( $post ); |
|
3021 |
|
3022 if ( ( 'private' == $status ) && ! current_user_can( 'read_post', $comment_post_ID ) ) { |
|
3023 return new WP_Error( 'comment_id_not_found' ); |
|
3024 } |
|
3025 |
|
3026 $status_obj = get_post_status_object( $status ); |
|
3027 |
|
3028 if ( ! comments_open( $comment_post_ID ) ) { |
|
3029 |
|
3030 /** |
|
3031 * Fires when a comment is attempted on a post that has comments closed. |
|
3032 * |
|
3033 * @since 1.5.0 |
|
3034 * |
|
3035 * @param int $comment_post_ID Post ID. |
|
3036 */ |
|
3037 do_action( 'comment_closed', $comment_post_ID ); |
|
3038 |
|
3039 return new WP_Error( 'comment_closed', __( 'Sorry, comments are closed for this item.' ), 403 ); |
|
3040 |
|
3041 } elseif ( 'trash' == $status ) { |
|
3042 |
|
3043 /** |
|
3044 * Fires when a comment is attempted on a trashed post. |
|
3045 * |
|
3046 * @since 2.9.0 |
|
3047 * |
|
3048 * @param int $comment_post_ID Post ID. |
|
3049 */ |
|
3050 do_action( 'comment_on_trash', $comment_post_ID ); |
|
3051 |
|
3052 return new WP_Error( 'comment_on_trash' ); |
|
3053 |
|
3054 } elseif ( ! $status_obj->public && ! $status_obj->private ) { |
|
3055 |
|
3056 /** |
|
3057 * Fires when a comment is attempted on a post in draft mode. |
|
3058 * |
|
3059 * @since 1.5.1 |
|
3060 * |
|
3061 * @param int $comment_post_ID Post ID. |
|
3062 */ |
|
3063 do_action( 'comment_on_draft', $comment_post_ID ); |
|
3064 |
|
3065 if ( current_user_can( 'read_post', $comment_post_ID ) ) { |
|
3066 return new WP_Error( 'comment_on_draft', __( 'Sorry, comments are not allowed for this item.' ), 403 ); |
|
3067 } else { |
|
3068 return new WP_Error( 'comment_on_draft' ); |
|
3069 } |
|
3070 |
|
3071 } elseif ( post_password_required( $comment_post_ID ) ) { |
|
3072 |
|
3073 /** |
|
3074 * Fires when a comment is attempted on a password-protected post. |
|
3075 * |
|
3076 * @since 2.9.0 |
|
3077 * |
|
3078 * @param int $comment_post_ID Post ID. |
|
3079 */ |
|
3080 do_action( 'comment_on_password_protected', $comment_post_ID ); |
|
3081 |
|
3082 return new WP_Error( 'comment_on_password_protected' ); |
|
3083 |
|
3084 } else { |
|
3085 |
|
3086 /** |
|
3087 * Fires before a comment is posted. |
|
3088 * |
|
3089 * @since 2.8.0 |
|
3090 * |
|
3091 * @param int $comment_post_ID Post ID. |
|
3092 */ |
|
3093 do_action( 'pre_comment_on_post', $comment_post_ID ); |
|
3094 |
|
3095 } |
|
3096 |
|
3097 // If the user is logged in |
|
3098 $user = wp_get_current_user(); |
|
3099 if ( $user->exists() ) { |
|
3100 if ( empty( $user->display_name ) ) { |
|
3101 $user->display_name=$user->user_login; |
|
3102 } |
|
3103 $comment_author = $user->display_name; |
|
3104 $comment_author_email = $user->user_email; |
|
3105 $comment_author_url = $user->user_url; |
|
3106 $user_ID = $user->ID; |
|
3107 if ( current_user_can( 'unfiltered_html' ) ) { |
|
3108 if ( ! isset( $comment_data['_wp_unfiltered_html_comment'] ) |
|
3109 || ! wp_verify_nonce( $comment_data['_wp_unfiltered_html_comment'], 'unfiltered-html-comment_' . $comment_post_ID ) |
|
3110 ) { |
|
3111 kses_remove_filters(); // start with a clean slate |
|
3112 kses_init_filters(); // set up the filters |
|
3113 } |
|
3114 } |
|
3115 } else { |
|
3116 if ( get_option( 'comment_registration' ) ) { |
|
3117 return new WP_Error( 'not_logged_in', __( 'Sorry, you must be logged in to comment.' ), 403 ); |
|
3118 } |
|
3119 } |
|
3120 |
|
3121 $comment_type = ''; |
|
3122 |
|
3123 if ( get_option( 'require_name_email' ) && ! $user->exists() ) { |
|
3124 if ( '' == $comment_author_email || '' == $comment_author ) { |
|
3125 return new WP_Error( 'require_name_email', __( '<strong>ERROR</strong>: please fill the required fields (name, email).' ), 200 ); |
|
3126 } elseif ( ! is_email( $comment_author_email ) ) { |
|
3127 return new WP_Error( 'require_valid_email', __( '<strong>ERROR</strong>: please enter a valid email address.' ), 200 ); |
|
3128 } |
|
3129 } |
|
3130 |
|
3131 if ( '' == $comment_content ) { |
|
3132 return new WP_Error( 'require_valid_comment', __( '<strong>ERROR</strong>: please type a comment.' ), 200 ); |
|
3133 } |
|
3134 |
|
3135 $commentdata = compact( |
|
3136 'comment_post_ID', |
|
3137 'comment_author', |
|
3138 'comment_author_email', |
|
3139 'comment_author_url', |
|
3140 'comment_content', |
|
3141 'comment_type', |
|
3142 'comment_parent', |
|
3143 'user_ID' |
|
3144 ); |
|
3145 |
|
3146 $check_max_lengths = wp_check_comment_data_max_lengths( $commentdata ); |
|
3147 if ( is_wp_error( $check_max_lengths ) ) { |
|
3148 return $check_max_lengths; |
|
3149 } |
|
3150 |
|
3151 $comment_id = wp_new_comment( wp_slash( $commentdata ), true ); |
|
3152 if ( is_wp_error( $comment_id ) ) { |
|
3153 return $comment_id; |
|
3154 } |
|
3155 |
|
3156 if ( ! $comment_id ) { |
|
3157 return new WP_Error( 'comment_save_error', __( '<strong>ERROR</strong>: The comment could not be saved. Please try again later.' ), 500 ); |
|
3158 } |
|
3159 |
|
3160 return get_comment( $comment_id ); |
|
3161 } |
|
3162 |
|
3163 /** |
|
3164 * Registers the personal data exporter for comments. |
|
3165 * |
|
3166 * @since 4.9.6 |
|
3167 * |
|
3168 * @param array $exporters An array of personal data exporters. |
|
3169 * @return array $exporters An array of personal data exporters. |
|
3170 */ |
|
3171 function wp_register_comment_personal_data_exporter( $exporters ) { |
|
3172 $exporters['wordpress-comments'] = array( |
|
3173 'exporter_friendly_name' => __( 'WordPress Comments' ), |
|
3174 'callback' => 'wp_comments_personal_data_exporter', |
|
3175 ); |
|
3176 |
|
3177 return $exporters; |
|
3178 } |
|
3179 |
|
3180 /** |
|
3181 * Finds and exports personal data associated with an email address from the comments table. |
|
3182 * |
|
3183 * @since 4.9.6 |
|
3184 * |
|
3185 * @param string $email_address The comment author email address. |
|
3186 * @param int $page Comment page. |
|
3187 * @return array $return An array of personal data. |
|
3188 */ |
|
3189 function wp_comments_personal_data_exporter( $email_address, $page = 1 ) { |
|
3190 // Limit us to 500 comments at a time to avoid timing out. |
|
3191 $number = 500; |
|
3192 $page = (int) $page; |
|
3193 |
|
3194 $data_to_export = array(); |
|
3195 |
|
3196 $comments = get_comments( |
|
3197 array( |
|
3198 'author_email' => $email_address, |
|
3199 'number' => $number, |
|
3200 'paged' => $page, |
|
3201 'order_by' => 'comment_ID', |
|
3202 'order' => 'ASC', |
|
3203 'update_comment_meta_cache' => false, |
|
3204 ) |
|
3205 ); |
|
3206 |
|
3207 $comment_prop_to_export = array( |
|
3208 'comment_author' => __( 'Comment Author' ), |
|
3209 'comment_author_email' => __( 'Comment Author Email' ), |
|
3210 'comment_author_url' => __( 'Comment Author URL' ), |
|
3211 'comment_author_IP' => __( 'Comment Author IP' ), |
|
3212 'comment_agent' => __( 'Comment Author User Agent' ), |
|
3213 'comment_date' => __( 'Comment Date' ), |
|
3214 'comment_content' => __( 'Comment Content' ), |
|
3215 'comment_link' => __( 'Comment URL' ), |
|
3216 ); |
|
3217 |
|
3218 foreach ( (array) $comments as $comment ) { |
|
3219 $comment_data_to_export = array(); |
|
3220 |
|
3221 foreach ( $comment_prop_to_export as $key => $name ) { |
|
3222 $value = ''; |
|
3223 |
|
3224 switch ( $key ) { |
|
3225 case 'comment_author': |
|
3226 case 'comment_author_email': |
|
3227 case 'comment_author_url': |
|
3228 case 'comment_author_IP': |
|
3229 case 'comment_agent': |
|
3230 case 'comment_date': |
|
3231 $value = $comment->{$key}; |
|
3232 break; |
|
3233 |
|
3234 case 'comment_content': |
|
3235 $value = get_comment_text( $comment->comment_ID ); |
|
3236 break; |
|
3237 |
|
3238 case 'comment_link': |
|
3239 $value = get_comment_link( $comment->comment_ID ); |
|
3240 $value = sprintf( |
|
3241 '<a href="%s" target="_blank" rel="noreferrer noopener">%s</a>', |
|
3242 esc_url( $value ), |
|
3243 esc_html( $value ) |
|
3244 ); |
|
3245 break; |
|
3246 } |
|
3247 |
|
3248 if ( ! empty( $value ) ) { |
|
3249 $comment_data_to_export[] = array( |
|
3250 'name' => $name, |
|
3251 'value' => $value, |
|
3252 ); |
|
3253 } |
|
3254 } |
|
3255 |
|
3256 $data_to_export[] = array( |
|
3257 'group_id' => 'comments', |
|
3258 'group_label' => __( 'Comments' ), |
|
3259 'item_id' => "comment-{$comment->comment_ID}", |
|
3260 'data' => $comment_data_to_export, |
|
3261 ); |
|
3262 } |
|
3263 |
|
3264 $done = count( $comments ) < $number; |
|
3265 |
|
3266 return array( |
|
3267 'data' => $data_to_export, |
|
3268 'done' => $done, |
|
3269 ); |
|
3270 } |
|
3271 |
|
3272 /** |
|
3273 * Registers the personal data eraser for comments. |
|
3274 * |
|
3275 * @since 4.9.6 |
|
3276 * |
|
3277 * @param array $erasers An array of personal data erasers. |
|
3278 * @return array $erasers An array of personal data erasers. |
|
3279 */ |
|
3280 function wp_register_comment_personal_data_eraser( $erasers ) { |
|
3281 $erasers['wordpress-comments'] = array( |
|
3282 'eraser_friendly_name' => __( 'WordPress Comments' ), |
|
3283 'callback' => 'wp_comments_personal_data_eraser', |
|
3284 ); |
|
3285 |
|
3286 return $erasers; |
|
3287 } |
|
3288 |
|
3289 /** |
|
3290 * Erases personal data associated with an email address from the comments table. |
|
3291 * |
|
3292 * @since 4.9.6 |
|
3293 * |
|
3294 * @param string $email_address The comment author email address. |
|
3295 * @param int $page Comment page. |
|
3296 * @return array |
|
3297 */ |
|
3298 function wp_comments_personal_data_eraser( $email_address, $page = 1 ) { |
|
3299 global $wpdb; |
|
3300 |
|
3301 if ( empty( $email_address ) ) { |
|
3302 return array( |
|
3303 'items_removed' => false, |
|
3304 'items_retained' => false, |
|
3305 'messages' => array(), |
|
3306 'done' => true, |
|
3307 ); |
|
3308 } |
|
3309 |
|
3310 // Limit us to 500 comments at a time to avoid timing out. |
|
3311 $number = 500; |
|
3312 $page = (int) $page; |
|
3313 $items_removed = false; |
|
3314 $items_retained = false; |
|
3315 |
|
3316 $comments = get_comments( |
|
3317 array( |
|
3318 'author_email' => $email_address, |
|
3319 'number' => $number, |
|
3320 'paged' => $page, |
|
3321 'order_by' => 'comment_ID', |
|
3322 'order' => 'ASC', |
|
3323 'include_unapproved' => true, |
|
3324 ) |
|
3325 ); |
|
3326 |
|
3327 /* translators: Name of a comment's author after being anonymized. */ |
|
3328 $anon_author = __( 'Anonymous' ); |
|
3329 $messages = array(); |
|
3330 |
|
3331 foreach ( (array) $comments as $comment ) { |
|
3332 $anonymized_comment = array(); |
|
3333 $anonymized_comment['comment_agent'] = ''; |
|
3334 $anonymized_comment['comment_author'] = $anon_author; |
|
3335 $anonymized_comment['comment_author_email'] = ''; |
|
3336 $anonymized_comment['comment_author_IP'] = wp_privacy_anonymize_data( 'ip', $comment->comment_author_IP ); |
|
3337 $anonymized_comment['comment_author_url'] = ''; |
|
3338 $anonymized_comment['user_id'] = 0; |
|
3339 |
|
3340 $comment_id = (int) $comment->comment_ID; |
|
3341 |
|
3342 /** |
|
3343 * Filters whether to anonymize the comment. |
|
3344 * |
|
3345 * @since 4.9.6 |
|
3346 * |
|
3347 * @param bool|string Whether to apply the comment anonymization (bool). |
|
3348 * Custom prevention message (string). Default true. |
|
3349 * @param WP_Comment $comment WP_Comment object. |
|
3350 * @param array $anonymized_comment Anonymized comment data. |
|
3351 */ |
|
3352 $anon_message = apply_filters( 'wp_anonymize_comment', true, $comment, $anonymized_comment ); |
|
3353 |
|
3354 if ( true !== $anon_message ) { |
|
3355 if ( $anon_message && is_string( $anon_message ) ) { |
|
3356 $messages[] = esc_html( $anon_message ); |
|
3357 } else { |
|
3358 /* translators: %d: Comment ID */ |
|
3359 $messages[] = sprintf( __( 'Comment %d contains personal data but could not be anonymized.' ), $comment_id ); |
|
3360 } |
|
3361 |
|
3362 $items_retained = true; |
|
3363 |
|
3364 continue; |
|
3365 } |
|
3366 |
|
3367 $args = array( |
|
3368 'comment_ID' => $comment_id, |
|
3369 ); |
|
3370 |
|
3371 $updated = $wpdb->update( $wpdb->comments, $anonymized_comment, $args ); |
|
3372 |
|
3373 if ( $updated ) { |
|
3374 $items_removed = true; |
|
3375 clean_comment_cache( $comment_id ); |
|
3376 } else { |
|
3377 $items_retained = true; |
|
3378 } |
|
3379 } |
|
3380 |
|
3381 $done = count( $comments ) < $number; |
|
3382 |
|
3383 return array( |
|
3384 'items_removed' => $items_removed, |
|
3385 'items_retained' => $items_retained, |
|
3386 'messages' => $messages, |
|
3387 'done' => $done, |
|
3388 ); |
|
3389 } |