123 * |
124 * |
124 * If it is enabled, check whether the comment author has a previously-approved comment, |
125 * If it is enabled, check whether the comment author has a previously-approved comment, |
125 * as well as whether there are any moderation keywords (if set) present in the author |
126 * as well as whether there are any moderation keywords (if set) present in the author |
126 * email address. If both checks pass, return true. Otherwise, return false. |
127 * email address. If both checks pass, return true. Otherwise, return false. |
127 */ |
128 */ |
128 if ( 1 == get_option( 'comment_whitelist' ) ) { |
129 if ( 1 == get_option( 'comment_previously_approved' ) ) { |
129 if ( 'trackback' != $comment_type && 'pingback' != $comment_type && $author != '' && $email != '' ) { |
130 if ( 'trackback' !== $comment_type && 'pingback' !== $comment_type && '' !== $author && '' !== $email ) { |
130 $comment_user = get_user_by( 'email', wp_unslash( $email ) ); |
131 $comment_user = get_user_by( 'email', wp_unslash( $email ) ); |
131 if ( ! empty( $comment_user->ID ) ) { |
132 if ( ! empty( $comment_user->ID ) ) { |
132 $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 ) ); |
133 $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 ) ); |
133 } else { |
134 } else { |
134 // expected_slashed ($author, $email) |
135 // expected_slashed ($author, $email) |
151 * Retrieve the approved comments for post $post_id. |
152 * Retrieve the approved comments for post $post_id. |
152 * |
153 * |
153 * @since 2.0.0 |
154 * @since 2.0.0 |
154 * @since 4.1.0 Refactored to leverage WP_Comment_Query over a direct query. |
155 * @since 4.1.0 Refactored to leverage WP_Comment_Query over a direct query. |
155 * |
156 * |
156 * @param int $post_id The ID of the post. |
157 * @param int $post_id The ID of the post. |
157 * @param array $args Optional. See WP_Comment_Query::__construct() for information on accepted arguments. |
158 * @param array $args Optional. See WP_Comment_Query::__construct() for information on accepted arguments. |
158 * @return int|array $comments The approved comments, or number of comments if `$count` |
159 * @return int|array The approved comments, or number of comments if `$count` |
159 * argument is true. |
160 * argument is true. |
160 */ |
161 */ |
161 function get_approved_comments( $post_id, $args = array() ) { |
162 function get_approved_comments( $post_id, $args = array() ) { |
162 if ( ! $post_id ) { |
163 if ( ! $post_id ) { |
163 return array(); |
164 return array(); |
164 } |
165 } |
165 |
166 |
166 $defaults = array( |
167 $defaults = array( |
167 'status' => 1, |
168 'status' => 1, |
168 'post_id' => $post_id, |
169 'post_id' => $post_id, |
169 'order' => 'ASC', |
170 'order' => 'ASC', |
170 ); |
171 ); |
171 $r = wp_parse_args( $args, $defaults ); |
172 $parsed_args = wp_parse_args( $args, $defaults ); |
172 |
173 |
173 $query = new WP_Comment_Query; |
174 $query = new WP_Comment_Query; |
174 return $query->query( $r ); |
175 return $query->query( $parsed_args ); |
175 } |
176 } |
176 |
177 |
177 /** |
178 /** |
178 * Retrieves comment data given a comment ID or comment object. |
179 * Retrieves comment data given a comment ID or comment object. |
179 * |
180 * |
181 * after being passed through a filter. If the comment is empty, then the global |
182 * after being passed through a filter. If the comment is empty, then the global |
182 * comment variable will be used, if it is set. |
183 * comment variable will be used, if it is set. |
183 * |
184 * |
184 * @since 2.0.0 |
185 * @since 2.0.0 |
185 * |
186 * |
186 * @global WP_Comment $comment |
187 * @global WP_Comment $comment Global comment object. |
187 * |
188 * |
188 * @param WP_Comment|string|int $comment Comment to retrieve. |
189 * @param WP_Comment|string|int $comment Comment to retrieve. |
189 * @param string $output Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to |
190 * @param string $output Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which |
190 * a WP_Comment object, an associative array, or a numeric array, respectively. Default OBJECT. |
191 * correspond to a WP_Comment object, an associative array, or a numeric array, |
|
192 * respectively. Default OBJECT. |
191 * @return WP_Comment|array|null Depends on $output value. |
193 * @return WP_Comment|array|null Depends on $output value. |
192 */ |
194 */ |
193 function get_comment( &$comment = null, $output = OBJECT ) { |
195 function get_comment( &$comment = null, $output = OBJECT ) { |
194 if ( empty( $comment ) && isset( $GLOBALS['comment'] ) ) { |
196 if ( empty( $comment ) && isset( $GLOBALS['comment'] ) ) { |
195 $comment = $GLOBALS['comment']; |
197 $comment = $GLOBALS['comment']; |
351 |
354 |
352 return false; |
355 return false; |
353 } |
356 } |
354 |
357 |
355 /** |
358 /** |
356 * The amount of comments in a post or total comments. |
359 * Retrieves the total comment counts for the whole site or a single post. |
357 * |
360 * |
358 * A lot like wp_count_comments(), in that they both return comment stats (albeit with different types). |
361 * Unlike wp_count_comments(), this function always returns the live comment counts without caching. |
359 * The wp_count_comments() actually caches, but this function does not. |
|
360 * |
362 * |
361 * @since 2.0.0 |
363 * @since 2.0.0 |
362 * |
364 * |
363 * @global wpdb $wpdb WordPress database abstraction object. |
365 * @global wpdb $wpdb WordPress database abstraction object. |
364 * |
366 * |
365 * @param int $post_id Optional. Comment amount in post if > 0, else total comments blog wide. |
367 * @param int $post_id Optional. Restrict the comment counts to the given post. Default 0, which indicates that |
366 * @return array The amount of spam, approved, awaiting moderation, and total comments. |
368 * comment counts for the whole site will be retrieved. |
|
369 * @return array() { |
|
370 * The number of comments keyed by their status. |
|
371 * |
|
372 * @type int $approved The number of approved comments. |
|
373 * @type int $awaiting_moderation The number of comments awaiting moderation (a.k.a. pending). |
|
374 * @type int $spam The number of spam comments. |
|
375 * @type int $trash The number of trashed comments. |
|
376 * @type int $post-trashed The number of comments for posts that are in the trash. |
|
377 * @type int $total_comments The total number of non-trashed comments, including spam. |
|
378 * @type int $all The total number of pending or approved comments. |
|
379 * } |
367 */ |
380 */ |
368 function get_comment_count( $post_id = 0 ) { |
381 function get_comment_count( $post_id = 0 ) { |
369 global $wpdb; |
382 global $wpdb; |
370 |
383 |
371 $post_id = (int) $post_id; |
384 $post_id = (int) $post_id; |
420 default: |
433 default: |
421 break; |
434 break; |
422 } |
435 } |
423 } |
436 } |
424 |
437 |
425 return $comment_count; |
438 return array_map( 'intval', $comment_count ); |
426 } |
439 } |
427 |
440 |
428 // |
441 // |
429 // Comment meta functions |
442 // Comment meta functions. |
430 // |
443 // |
431 |
444 |
432 /** |
445 /** |
433 * Add meta data field to a comment. |
446 * Add meta data field to a comment. |
434 * |
447 * |
435 * @since 2.9.0 |
448 * @since 2.9.0 |
436 * @link https://codex.wordpress.org/Function_Reference/add_comment_meta |
449 * |
437 * |
450 * @link https://developer.wordpress.org/reference/functions/add_comment_meta/ |
438 * @param int $comment_id Comment ID. |
451 * |
439 * @param string $meta_key Metadata name. |
452 * @param int $comment_id Comment ID. |
440 * @param mixed $meta_value Metadata value. |
453 * @param string $meta_key Metadata name. |
441 * @param bool $unique Optional, default is false. Whether the same key should not be added. |
454 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar. |
|
455 * @param bool $unique Optional. Whether the same key should not be added. |
|
456 * Default false. |
442 * @return int|bool Meta ID on success, false on failure. |
457 * @return int|bool Meta ID on success, false on failure. |
443 */ |
458 */ |
444 function add_comment_meta( $comment_id, $meta_key, $meta_value, $unique = false ) { |
459 function add_comment_meta( $comment_id, $meta_key, $meta_value, $unique = false ) { |
445 return add_metadata( 'comment', $comment_id, $meta_key, $meta_value, $unique ); |
460 return add_metadata( 'comment', $comment_id, $meta_key, $meta_value, $unique ); |
446 } |
461 } |
451 * You can match based on the key, or key and value. Removing based on key and |
466 * You can match based on the key, or key and value. Removing based on key and |
452 * value, will keep from removing duplicate metadata with the same key. It also |
467 * value, will keep from removing duplicate metadata with the same key. It also |
453 * allows removing all metadata matching key, if needed. |
468 * allows removing all metadata matching key, if needed. |
454 * |
469 * |
455 * @since 2.9.0 |
470 * @since 2.9.0 |
456 * @link https://codex.wordpress.org/Function_Reference/delete_comment_meta |
471 * |
457 * |
472 * @link https://developer.wordpress.org/reference/functions/delete_comment_meta/ |
458 * @param int $comment_id comment ID |
473 * |
459 * @param string $meta_key Metadata name. |
474 * @param int $comment_id Comment ID. |
460 * @param mixed $meta_value Optional. Metadata value. |
475 * @param string $meta_key Metadata name. |
|
476 * @param mixed $meta_value Optional. Metadata value. If provided, |
|
477 * rows will only be removed that match the value. |
|
478 * Must be serializable if non-scalar. Default empty. |
461 * @return bool True on success, false on failure. |
479 * @return bool True on success, false on failure. |
462 */ |
480 */ |
463 function delete_comment_meta( $comment_id, $meta_key, $meta_value = '' ) { |
481 function delete_comment_meta( $comment_id, $meta_key, $meta_value = '' ) { |
464 return delete_metadata( 'comment', $comment_id, $meta_key, $meta_value ); |
482 return delete_metadata( 'comment', $comment_id, $meta_key, $meta_value ); |
465 } |
483 } |
466 |
484 |
467 /** |
485 /** |
468 * Retrieve comment meta field for a comment. |
486 * Retrieve comment meta field for a comment. |
469 * |
487 * |
470 * @since 2.9.0 |
488 * @since 2.9.0 |
471 * @link https://codex.wordpress.org/Function_Reference/get_comment_meta |
489 * |
472 * |
490 * @link https://developer.wordpress.org/reference/functions/get_comment_meta/ |
473 * @param int $comment_id Comment ID. |
491 * |
474 * @param string $key Optional. The meta key to retrieve. By default, returns data for all keys. |
492 * @param int $comment_id Comment ID. |
475 * @param bool $single Whether to return a single value. |
493 * @param string $key Optional. The meta key to retrieve. By default, |
476 * @return mixed Will be an array if $single is false. Will be value of meta data field if $single |
494 * returns data for all keys. |
477 * is true. |
495 * @param bool $single Optional. Whether to return a single value. |
|
496 * This parameter has no effect if $key is not specified. |
|
497 * Default false. |
|
498 * @return mixed An array if $single is false. The value of meta data field |
|
499 * if $single is true. False for an invalid $comment_id. |
478 */ |
500 */ |
479 function get_comment_meta( $comment_id, $key = '', $single = false ) { |
501 function get_comment_meta( $comment_id, $key = '', $single = false ) { |
480 return get_metadata( 'comment', $comment_id, $key, $single ); |
502 return get_metadata( 'comment', $comment_id, $key, $single ); |
481 } |
503 } |
482 |
504 |
487 * same key and comment ID. |
509 * same key and comment ID. |
488 * |
510 * |
489 * If the meta field for the comment does not exist, it will be added. |
511 * If the meta field for the comment does not exist, it will be added. |
490 * |
512 * |
491 * @since 2.9.0 |
513 * @since 2.9.0 |
492 * @link https://codex.wordpress.org/Function_Reference/update_comment_meta |
514 * |
493 * |
515 * @link https://developer.wordpress.org/reference/functions/update_comment_meta/ |
494 * @param int $comment_id Comment ID. |
516 * |
495 * @param string $meta_key Metadata key. |
517 * @param int $comment_id Comment ID. |
496 * @param mixed $meta_value Metadata value. |
518 * @param string $meta_key Metadata key. |
497 * @param mixed $prev_value Optional. Previous value to check before removing. |
519 * @param mixed $meta_value Metadata value. Must be serializable if non-scalar. |
498 * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure. |
520 * @param mixed $prev_value Optional. Previous value to check before updating. |
|
521 * If specified, only update existing metadata entries with |
|
522 * this value. Otherwise, update all entries. Default empty. |
|
523 * @return int|bool Meta ID if the key didn't exist, true on successful update, |
|
524 * false on failure or if the value passed to the function |
|
525 * is the same as the one that is already in the database. |
499 */ |
526 */ |
500 function update_comment_meta( $comment_id, $meta_key, $meta_value, $prev_value = '' ) { |
527 function update_comment_meta( $comment_id, $meta_key, $meta_value, $prev_value = '' ) { |
501 return update_metadata( 'comment', $comment_id, $meta_key, $meta_value, $prev_value ); |
528 return update_metadata( 'comment', $comment_id, $meta_key, $meta_value, $prev_value ); |
502 } |
529 } |
503 |
530 |
558 * @since 2.8.0 |
585 * @since 2.8.0 |
559 * |
586 * |
560 * @param int $seconds Comment cookie lifetime. Default 30000000. |
587 * @param int $seconds Comment cookie lifetime. Default 30000000. |
561 */ |
588 */ |
562 $comment_cookie_lifetime = time() + apply_filters( 'comment_cookie_lifetime', 30000000 ); |
589 $comment_cookie_lifetime = time() + apply_filters( 'comment_cookie_lifetime', 30000000 ); |
563 $secure = ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) ); |
590 |
|
591 $secure = ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) ); |
|
592 |
564 setcookie( 'comment_author_' . COOKIEHASH, $comment->comment_author, $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); |
593 setcookie( 'comment_author_' . COOKIEHASH, $comment->comment_author, $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); |
565 setcookie( 'comment_author_email_' . COOKIEHASH, $comment->comment_author_email, $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); |
594 setcookie( 'comment_author_email_' . COOKIEHASH, $comment->comment_author_email, $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); |
566 setcookie( 'comment_author_url_' . COOKIEHASH, esc_url( $comment->comment_author_url ), $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); |
595 setcookie( 'comment_author_url_' . COOKIEHASH, esc_url( $comment->comment_author_url ), $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure ); |
567 } |
596 } |
568 |
597 |
628 |
657 |
629 /** |
658 /** |
630 * Validates whether this comment is allowed to be made. |
659 * Validates whether this comment is allowed to be made. |
631 * |
660 * |
632 * @since 2.0.0 |
661 * @since 2.0.0 |
633 * @since 4.7.0 The `$avoid_die` parameter was added, allowing the function to |
662 * @since 4.7.0 The `$avoid_die` parameter was added, allowing the function |
634 * return a WP_Error object instead of dying. |
663 * to return a WP_Error object instead of dying. |
|
664 * @since 5.5.0 The `$avoid_die` parameter was renamed to `$wp_error`. |
635 * |
665 * |
636 * @global wpdb $wpdb WordPress database abstraction object. |
666 * @global wpdb $wpdb WordPress database abstraction object. |
637 * |
667 * |
638 * @param array $commentdata Contains information on the comment. |
668 * @param array $commentdata Contains information on the comment. |
639 * @param bool $avoid_die When true, a disallowed comment will result in the function |
669 * @param bool $wp_error When true, a disallowed comment will result in the function |
640 * returning a WP_Error object, rather than executing wp_die(). |
670 * returning a WP_Error object, rather than executing wp_die(). |
641 * Default false. |
671 * Default false. |
642 * @return int|string|WP_Error Allowed comments return the approval status (0|1|'spam'). |
672 * @return int|string|WP_Error Allowed comments return the approval status (0|1|'spam'|'trash'). |
643 * If `$avoid_die` is true, disallowed comments return a WP_Error. |
673 * If `$wp_error` is true, disallowed comments return a WP_Error. |
644 */ |
674 */ |
645 function wp_allow_comment( $commentdata, $avoid_die = false ) { |
675 function wp_allow_comment( $commentdata, $wp_error = false ) { |
646 global $wpdb; |
676 global $wpdb; |
647 |
677 |
648 // Simple duplicate check |
678 // Simple duplicate check. |
649 // expected_slashed ($comment_post_ID, $comment_author, $comment_author_email, $comment_content) |
679 // expected_slashed ($comment_post_ID, $comment_author, $comment_author_email, $comment_content) |
650 $dupe = $wpdb->prepare( |
680 $dupe = $wpdb->prepare( |
651 "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_parent = %s AND comment_approved != 'trash' AND ( comment_author = %s ", |
681 "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_parent = %s AND comment_approved != 'trash' AND ( comment_author = %s ", |
652 wp_unslash( $commentdata['comment_post_ID'] ), |
682 wp_unslash( $commentdata['comment_post_ID'] ), |
653 wp_unslash( $commentdata['comment_parent'] ), |
683 wp_unslash( $commentdata['comment_parent'] ), |
713 * |
743 * |
714 * Allows checking for comment flooding. |
744 * Allows checking for comment flooding. |
715 * |
745 * |
716 * @since 2.3.0 |
746 * @since 2.3.0 |
717 * @since 4.7.0 The `$avoid_die` parameter was added. |
747 * @since 4.7.0 The `$avoid_die` parameter was added. |
|
748 * @since 5.5.0 The `$avoid_die` parameter was renamed to `$wp_error`. |
718 * |
749 * |
719 * @param string $comment_author_IP Comment author's IP address. |
750 * @param string $comment_author_IP Comment author's IP address. |
720 * @param string $comment_author_email Comment author's email. |
751 * @param string $comment_author_email Comment author's email. |
721 * @param string $comment_date_gmt GMT date the comment was posted. |
752 * @param string $comment_date_gmt GMT date the comment was posted. |
722 * @param bool $avoid_die Whether to prevent executing wp_die() |
753 * @param bool $wp_error Whether to return a WP_Error object instead of executing |
723 * or die() if a comment flood is occurring. |
754 * wp_die() or die() if a comment flood is occurring. |
724 */ |
755 */ |
725 do_action( |
756 do_action( |
726 'check_comment_flood', |
757 'check_comment_flood', |
727 $commentdata['comment_author_IP'], |
758 $commentdata['comment_author_IP'], |
728 $commentdata['comment_author_email'], |
759 $commentdata['comment_author_email'], |
729 $commentdata['comment_date_gmt'], |
760 $commentdata['comment_date_gmt'], |
730 $avoid_die |
761 $wp_error |
731 ); |
762 ); |
732 |
763 |
733 /** |
764 /** |
734 * Filters whether a comment is part of a comment flood. |
765 * Filters whether a comment is part of a comment flood. |
735 * |
766 * |
736 * The default check is wp_check_comment_flood(). See check_comment_flood_db(). |
767 * The default check is wp_check_comment_flood(). See check_comment_flood_db(). |
737 * |
768 * |
738 * @since 4.7.0 |
769 * @since 4.7.0 |
|
770 * @since 5.5.0 The `$avoid_die` parameter was renamed to `$wp_error`. |
739 * |
771 * |
740 * @param bool $is_flood Is a comment flooding occurring? Default false. |
772 * @param bool $is_flood Is a comment flooding occurring? Default false. |
741 * @param string $comment_author_IP Comment author's IP address. |
773 * @param string $comment_author_IP Comment author's IP address. |
742 * @param string $comment_author_email Comment author's email. |
774 * @param string $comment_author_email Comment author's email. |
743 * @param string $comment_date_gmt GMT date the comment was posted. |
775 * @param string $comment_date_gmt GMT date the comment was posted. |
744 * @param bool $avoid_die Whether to prevent executing wp_die() |
776 * @param bool $wp_error Whether to return a WP_Error object instead of executing |
745 * or die() if a comment flood is occurring. |
777 * wp_die() or die() if a comment flood is occurring. |
746 */ |
778 */ |
747 $is_flood = apply_filters( |
779 $is_flood = apply_filters( |
748 'wp_is_comment_flood', |
780 'wp_is_comment_flood', |
749 false, |
781 false, |
750 $commentdata['comment_author_IP'], |
782 $commentdata['comment_author_IP'], |
751 $commentdata['comment_author_email'], |
783 $commentdata['comment_author_email'], |
752 $commentdata['comment_date_gmt'], |
784 $commentdata['comment_date_gmt'], |
753 $avoid_die |
785 $wp_error |
754 ); |
786 ); |
755 |
787 |
756 if ( $is_flood ) { |
788 if ( $is_flood ) { |
757 /** This filter is documented in wp-includes/comment-template.php */ |
789 /** This filter is documented in wp-includes/comment-template.php */ |
758 $comment_flood_message = apply_filters( 'comment_flood_message', __( 'You are posting comments too quickly. Slow down.' ) ); |
790 $comment_flood_message = apply_filters( 'comment_flood_message', __( 'You are posting comments too quickly. Slow down.' ) ); |
855 // Another callback has declared a flood. Trust it. |
886 // Another callback has declared a flood. Trust it. |
856 if ( true === $is_flood ) { |
887 if ( true === $is_flood ) { |
857 return $is_flood; |
888 return $is_flood; |
858 } |
889 } |
859 |
890 |
860 // don't throttle admins or moderators |
891 // Don't throttle admins or moderators. |
861 if ( current_user_can( 'manage_options' ) || current_user_can( 'moderate_comments' ) ) { |
892 if ( current_user_can( 'manage_options' ) || current_user_can( 'moderate_comments' ) ) { |
862 return false; |
893 return false; |
863 } |
894 } |
|
895 |
864 $hour_ago = gmdate( 'Y-m-d H:i:s', time() - HOUR_IN_SECONDS ); |
896 $hour_ago = gmdate( 'Y-m-d H:i:s', time() - HOUR_IN_SECONDS ); |
865 |
897 |
866 if ( is_user_logged_in() ) { |
898 if ( is_user_logged_in() ) { |
867 $user = get_current_user_id(); |
899 $user = get_current_user_id(); |
868 $check_column = '`user_id`'; |
900 $check_column = '`user_id`'; |
869 } else { |
901 } else { |
870 $user = $ip; |
902 $user = $ip; |
871 $check_column = '`comment_author_IP`'; |
903 $check_column = '`comment_author_IP`'; |
872 } |
904 } |
873 |
905 |
874 $sql = $wpdb->prepare( |
906 $sql = $wpdb->prepare( |
875 "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", |
907 "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", |
876 $hour_ago, |
908 $hour_ago, |
877 $user, |
909 $user, |
878 $email |
910 $email |
879 ); |
911 ); |
|
912 |
880 $lasttime = $wpdb->get_var( $sql ); |
913 $lasttime = $wpdb->get_var( $sql ); |
|
914 |
881 if ( $lasttime ) { |
915 if ( $lasttime ) { |
882 $time_lastcomment = mysql2date( 'U', $lasttime, false ); |
916 $time_lastcomment = mysql2date( 'U', $lasttime, false ); |
883 $time_newcomment = mysql2date( 'U', $date, false ); |
917 $time_newcomment = mysql2date( 'U', $date, false ); |
|
918 |
884 /** |
919 /** |
885 * Filters the comment flood status. |
920 * Filters the comment flood status. |
886 * |
921 * |
887 * @since 2.1.0 |
922 * @since 2.1.0 |
888 * |
923 * |
889 * @param bool $bool Whether a comment flood is occurring. Default false. |
924 * @param bool $bool Whether a comment flood is occurring. Default false. |
890 * @param int $time_lastcomment Timestamp of when the last comment was posted. |
925 * @param int $time_lastcomment Timestamp of when the last comment was posted. |
891 * @param int $time_newcomment Timestamp of when the new comment was posted. |
926 * @param int $time_newcomment Timestamp of when the new comment was posted. |
892 */ |
927 */ |
893 $flood_die = apply_filters( 'comment_flood_filter', false, $time_lastcomment, $time_newcomment ); |
928 $flood_die = apply_filters( 'comment_flood_filter', false, $time_lastcomment, $time_newcomment ); |
|
929 |
894 if ( $flood_die ) { |
930 if ( $flood_die ) { |
895 /** |
931 /** |
896 * Fires before the comment flood message is triggered. |
932 * Fires before the comment flood message is triggered. |
897 * |
933 * |
898 * @since 1.5.0 |
934 * @since 1.5.0 |
1020 * |
1061 * |
1021 * @global wpdb $wpdb WordPress database abstraction object. |
1062 * @global wpdb $wpdb WordPress database abstraction object. |
1022 * |
1063 * |
1023 * @param int $comment_ID Comment ID. |
1064 * @param int $comment_ID Comment ID. |
1024 * @param array $args { |
1065 * @param array $args { |
1025 * Array of optional arguments. |
1066 * Array of optional arguments. |
1026 * @type string $type Limit paginated comments to those matching a given type. Accepts 'comment', |
1067 * |
1027 * 'trackback', 'pingback', 'pings' (trackbacks and pingbacks), or 'all'. |
1068 * @type string $type Limit paginated comments to those matching a given type. |
1028 * Default is 'all'. |
1069 * Accepts 'comment', 'trackback', 'pingback', 'pings' |
1029 * @type int $per_page Per-page count to use when calculating pagination. Defaults to the value of the |
1070 * (trackbacks and pingbacks), or 'all'. Default 'all'. |
1030 * 'comments_per_page' option. |
1071 * @type int $per_page Per-page count to use when calculating pagination. |
1031 * @type int|string $max_depth If greater than 1, comment page will be determined for the top-level parent of |
1072 * Defaults to the value of the 'comments_per_page' option. |
1032 * `$comment_ID`. Defaults to the value of the 'thread_comments_depth' option. |
1073 * @type int|string $max_depth If greater than 1, comment page will be determined |
|
1074 * for the top-level parent `$comment_ID`. |
|
1075 * Defaults to the value of the 'thread_comments_depth' option. |
1033 * } * |
1076 * } * |
1034 * @return int|null Comment page number or null on error. |
1077 * @return int|null Comment page number or null on error. |
1035 */ |
1078 */ |
1036 function get_page_of_comment( $comment_ID, $args = array() ) { |
1079 function get_page_of_comment( $comment_ID, $args = array() ) { |
1037 global $wpdb; |
1080 global $wpdb; |
1038 |
1081 |
1039 $page = null; |
1082 $page = null; |
1040 |
1083 |
1041 if ( ! $comment = get_comment( $comment_ID ) ) { |
1084 $comment = get_comment( $comment_ID ); |
|
1085 if ( ! $comment ) { |
1042 return; |
1086 return; |
1043 } |
1087 } |
1044 |
1088 |
1045 $defaults = array( |
1089 $defaults = array( |
1046 'type' => 'all', |
1090 'type' => 'all', |
1098 'before' => $comment->comment_date_gmt, |
1142 'before' => $comment->comment_date_gmt, |
1099 ), |
1143 ), |
1100 ), |
1144 ), |
1101 ); |
1145 ); |
1102 |
1146 |
|
1147 if ( is_user_logged_in() ) { |
|
1148 $comment_args['include_unapproved'] = array( get_current_user_id() ); |
|
1149 } else { |
|
1150 $unapproved_email = wp_get_unapproved_comment_author_email(); |
|
1151 |
|
1152 if ( $unapproved_email ) { |
|
1153 $comment_args['include_unapproved'] = array( $unapproved_email ); |
|
1154 } |
|
1155 } |
|
1156 |
|
1157 /** |
|
1158 * Filters the arguments used to query comments in get_page_of_comment(). |
|
1159 * |
|
1160 * @since 5.5.0 |
|
1161 * |
|
1162 * @see WP_Comment_Query::__construct() |
|
1163 * |
|
1164 * @param array $comment_args { |
|
1165 * Array of WP_Comment_Query arguments. |
|
1166 * |
|
1167 * @type string $type Limit paginated comments to those matching a given type. |
|
1168 * Accepts 'comment', 'trackback', 'pingback', 'pings' |
|
1169 * (trackbacks and pingbacks), or 'all'. Default 'all'. |
|
1170 * @type int $post_id ID of the post. |
|
1171 * @type string $fields Comment fields to return. |
|
1172 * @type bool $count Whether to return a comment count (true) or array |
|
1173 * of comment objects (false). |
|
1174 * @type string $status Comment status. |
|
1175 * @type int $parent Parent ID of comment to retrieve children of. |
|
1176 * @type array $date_query Date query clauses to limit comments by. See WP_Date_Query. |
|
1177 * @type array $include_unapproved Array of IDs or email addresses whose unapproved comments |
|
1178 * will be included in paginated comments. |
|
1179 * } |
|
1180 */ |
|
1181 $comment_args = apply_filters( 'get_page_of_comment_query_args', $comment_args ); |
|
1182 |
1103 $comment_query = new WP_Comment_Query(); |
1183 $comment_query = new WP_Comment_Query(); |
1104 $older_comment_count = $comment_query->query( $comment_args ); |
1184 $older_comment_count = $comment_query->query( $comment_args ); |
1105 |
1185 |
1106 // No older comments? Then it's page #1. |
1186 // No older comments? Then it's page #1. |
1107 if ( 0 == $older_comment_count ) { |
1187 if ( 0 == $older_comment_count ) { |
1108 $page = 1; |
1188 $page = 1; |
1109 |
1189 |
1110 // Divide comments older than this one by comments per page to get this comment's page number |
1190 // Divide comments older than this one by comments per page to get this comment's page number. |
1111 } else { |
1191 } else { |
1112 $page = ceil( ( $older_comment_count + 1 ) / $args['per_page'] ); |
1192 $page = ceil( ( $older_comment_count + 1 ) / $args['per_page'] ); |
1113 } |
1193 } |
1114 } |
1194 } |
1115 |
1195 |
1209 */ |
1289 */ |
1210 function wp_check_comment_data_max_lengths( $comment_data ) { |
1290 function wp_check_comment_data_max_lengths( $comment_data ) { |
1211 $max_lengths = wp_get_comment_fields_max_lengths(); |
1291 $max_lengths = wp_get_comment_fields_max_lengths(); |
1212 |
1292 |
1213 if ( isset( $comment_data['comment_author'] ) && mb_strlen( $comment_data['comment_author'], '8bit' ) > $max_lengths['comment_author'] ) { |
1293 if ( isset( $comment_data['comment_author'] ) && mb_strlen( $comment_data['comment_author'], '8bit' ) > $max_lengths['comment_author'] ) { |
1214 return new WP_Error( 'comment_author_column_length', __( '<strong>ERROR</strong>: your name is too long.' ), 200 ); |
1294 return new WP_Error( 'comment_author_column_length', __( '<strong>Error</strong>: Your name is too long.' ), 200 ); |
1215 } |
1295 } |
1216 |
1296 |
1217 if ( isset( $comment_data['comment_author_email'] ) && strlen( $comment_data['comment_author_email'] ) > $max_lengths['comment_author_email'] ) { |
1297 if ( isset( $comment_data['comment_author_email'] ) && strlen( $comment_data['comment_author_email'] ) > $max_lengths['comment_author_email'] ) { |
1218 return new WP_Error( 'comment_author_email_column_length', __( '<strong>ERROR</strong>: your email address is too long.' ), 200 ); |
1298 return new WP_Error( 'comment_author_email_column_length', __( '<strong>Error</strong>: Your email address is too long.' ), 200 ); |
1219 } |
1299 } |
1220 |
1300 |
1221 if ( isset( $comment_data['comment_author_url'] ) && strlen( $comment_data['comment_author_url'] ) > $max_lengths['comment_author_url'] ) { |
1301 if ( isset( $comment_data['comment_author_url'] ) && strlen( $comment_data['comment_author_url'] ) > $max_lengths['comment_author_url'] ) { |
1222 return new WP_Error( 'comment_author_url_column_length', __( '<strong>ERROR</strong>: your url is too long.' ), 200 ); |
1302 return new WP_Error( 'comment_author_url_column_length', __( '<strong>Error</strong>: Your URL is too long.' ), 200 ); |
1223 } |
1303 } |
1224 |
1304 |
1225 if ( isset( $comment_data['comment_content'] ) && mb_strlen( $comment_data['comment_content'], '8bit' ) > $max_lengths['comment_content'] ) { |
1305 if ( isset( $comment_data['comment_content'] ) && mb_strlen( $comment_data['comment_content'], '8bit' ) > $max_lengths['comment_content'] ) { |
1226 return new WP_Error( 'comment_content_column_length', __( '<strong>ERROR</strong>: your comment is too long.' ), 200 ); |
1306 return new WP_Error( 'comment_content_column_length', __( '<strong>Error</strong>: Your comment is too long.' ), 200 ); |
1227 } |
1307 } |
1228 |
1308 |
1229 return true; |
1309 return true; |
1230 } |
1310 } |
1231 |
1311 |
1232 /** |
1312 /** |
1233 * Does comment contain blacklisted characters or words. |
1313 * Checks if a comment contains disallowed characters or words. |
1234 * |
1314 * |
1235 * @since 1.5.0 |
1315 * @since 5.5.0 |
1236 * |
1316 * |
1237 * @param string $author The author of the comment |
1317 * @param string $author The author of the comment |
1238 * @param string $email The email of the comment |
1318 * @param string $email The email of the comment |
1239 * @param string $url The url used in the comment |
1319 * @param string $url The url used in the comment |
1240 * @param string $comment The comment content |
1320 * @param string $comment The comment content |
1241 * @param string $user_ip The comment author's IP address |
1321 * @param string $user_ip The comment author's IP address |
1242 * @param string $user_agent The author's browser user agent |
1322 * @param string $user_agent The author's browser user agent |
1243 * @return bool True if comment contains blacklisted content, false if comment does not |
1323 * @return bool True if comment contains disallowed content, false if comment does not |
1244 */ |
1324 */ |
1245 function wp_blacklist_check( $author, $email, $url, $comment, $user_ip, $user_agent ) { |
1325 function wp_check_comment_disallowed_list( $author, $email, $url, $comment, $user_ip, $user_agent ) { |
1246 /** |
1326 /** |
1247 * Fires before the comment is tested for blacklisted characters or words. |
1327 * Fires before the comment is tested for disallowed characters or words. |
1248 * |
1328 * |
1249 * @since 1.5.0 |
1329 * @since 1.5.0 |
|
1330 * @deprecated 5.5.0 Use {@see 'wp_check_comment_disallowed_list'} instead. |
1250 * |
1331 * |
1251 * @param string $author Comment author. |
1332 * @param string $author Comment author. |
1252 * @param string $email Comment author's email. |
1333 * @param string $email Comment author's email. |
1253 * @param string $url Comment author's URL. |
1334 * @param string $url Comment author's URL. |
1254 * @param string $comment Comment content. |
1335 * @param string $comment Comment content. |
1255 * @param string $user_ip Comment author's IP address. |
1336 * @param string $user_ip Comment author's IP address. |
1256 * @param string $user_agent Comment author's browser user agent. |
1337 * @param string $user_agent Comment author's browser user agent. |
1257 */ |
1338 */ |
1258 do_action( 'wp_blacklist_check', $author, $email, $url, $comment, $user_ip, $user_agent ); |
1339 do_action_deprecated( |
1259 |
1340 'wp_blacklist_check', |
1260 $mod_keys = trim( get_option( 'blacklist_keys' ) ); |
1341 array( $author, $email, $url, $comment, $user_ip, $user_agent ), |
1261 if ( '' == $mod_keys ) { |
1342 '5.5.0', |
1262 return false; // If moderation keys are empty |
1343 'wp_check_comment_disallowed_list', |
1263 } |
1344 __( 'Please consider writing more inclusive code.' ) |
1264 |
1345 ); |
1265 // Ensure HTML tags are not being used to bypass the blacklist. |
1346 |
|
1347 /** |
|
1348 * Fires before the comment is tested for disallowed characters or words. |
|
1349 * |
|
1350 * @since 5.5.0 |
|
1351 * |
|
1352 * @param string $author Comment author. |
|
1353 * @param string $email Comment author's email. |
|
1354 * @param string $url Comment author's URL. |
|
1355 * @param string $comment Comment content. |
|
1356 * @param string $user_ip Comment author's IP address. |
|
1357 * @param string $user_agent Comment author's browser user agent. |
|
1358 */ |
|
1359 do_action( 'wp_check_comment_disallowed_list', $author, $email, $url, $comment, $user_ip, $user_agent ); |
|
1360 |
|
1361 $mod_keys = trim( get_option( 'disallowed_keys' ) ); |
|
1362 if ( '' === $mod_keys ) { |
|
1363 return false; // If moderation keys are empty. |
|
1364 } |
|
1365 |
|
1366 // Ensure HTML tags are not being used to bypass the list of disallowed characters and words. |
1266 $comment_without_html = wp_strip_all_tags( $comment ); |
1367 $comment_without_html = wp_strip_all_tags( $comment ); |
1267 |
1368 |
1268 $words = explode( "\n", $mod_keys ); |
1369 $words = explode( "\n", $mod_keys ); |
1269 |
1370 |
1270 foreach ( (array) $words as $word ) { |
1371 foreach ( (array) $words as $word ) { |
1271 $word = trim( $word ); |
1372 $word = trim( $word ); |
1272 |
1373 |
1273 // Skip empty lines |
1374 // Skip empty lines. |
1274 if ( empty( $word ) ) { |
1375 if ( empty( $word ) ) { |
1275 continue; } |
1376 continue; } |
1276 |
1377 |
1277 // Do some escaping magic so that '#' chars in the |
1378 // Do some escaping magic so that '#' chars |
1278 // spam words don't break things: |
1379 // in the spam words don't break things: |
1279 $word = preg_quote( $word, '#' ); |
1380 $word = preg_quote( $word, '#' ); |
1280 |
1381 |
1281 $pattern = "#$word#i"; |
1382 $pattern = "#$word#i"; |
1282 if ( preg_match( $pattern, $author ) |
1383 if ( preg_match( $pattern, $author ) |
1283 || preg_match( $pattern, $email ) |
1384 || preg_match( $pattern, $email ) |
1292 } |
1393 } |
1293 return false; |
1394 return false; |
1294 } |
1395 } |
1295 |
1396 |
1296 /** |
1397 /** |
1297 * Retrieve total comments for blog or single post. |
1398 * Retrieves the total comment counts for the whole site or a single post. |
1298 * |
|
1299 * The properties of the returned object contain the 'moderated', 'approved', |
|
1300 * and spam comments for either the entire blog or single post. Those properties |
|
1301 * contain the amount of comments that match the status. The 'total_comments' |
|
1302 * property contains the integer of total comments. |
|
1303 * |
1399 * |
1304 * The comment stats are cached and then retrieved, if they already exist in the |
1400 * The comment stats are cached and then retrieved, if they already exist in the |
1305 * cache. |
1401 * cache. |
1306 * |
1402 * |
|
1403 * @see get_comment_count() Which handles fetching the live comment counts. |
|
1404 * |
1307 * @since 2.5.0 |
1405 * @since 2.5.0 |
1308 * |
1406 * |
1309 * @param int $post_id Optional. Post ID. |
1407 * @param int $post_id Optional. Restrict the comment counts to the given post. Default 0, which indicates that |
1310 * @return object|array Comment stats. |
1408 * comment counts for the whole site will be retrieved. |
|
1409 * @return stdClass { |
|
1410 * The number of comments keyed by their status. |
|
1411 * |
|
1412 * @type int $approved The number of approved comments. |
|
1413 * @type int $moderated The number of comments awaiting moderation (a.k.a. pending). |
|
1414 * @type int $spam The number of spam comments. |
|
1415 * @type int $trash The number of trashed comments. |
|
1416 * @type int $post-trashed The number of comments for posts that are in the trash. |
|
1417 * @type int $total_comments The total number of non-trashed comments, including spam. |
|
1418 * @type int $all The total number of pending or approved comments. |
|
1419 * } |
1311 */ |
1420 */ |
1312 function wp_count_comments( $post_id = 0 ) { |
1421 function wp_count_comments( $post_id = 0 ) { |
1313 $post_id = (int) $post_id; |
1422 $post_id = (int) $post_id; |
1314 |
1423 |
1315 /** |
1424 /** |
1316 * Filters the comments count for a given post. |
1425 * Filters the comments count for a given post or the whole site. |
1317 * |
1426 * |
1318 * @since 2.7.0 |
1427 * @since 2.7.0 |
1319 * |
1428 * |
1320 * @param array $count An empty array. |
1429 * @param array|stdClass $count An empty array or an object containing comment counts. |
1321 * @param int $post_id The post ID. |
1430 * @param int $post_id The post ID. Can be 0 to represent the whole site. |
1322 */ |
1431 */ |
1323 $filtered = apply_filters( 'wp_count_comments', array(), $post_id ); |
1432 $filtered = apply_filters( 'wp_count_comments', array(), $post_id ); |
1324 if ( ! empty( $filtered ) ) { |
1433 if ( ! empty( $filtered ) ) { |
1325 return $filtered; |
1434 return $filtered; |
1326 } |
1435 } |
1341 } |
1450 } |
1342 |
1451 |
1343 /** |
1452 /** |
1344 * Trashes or deletes a comment. |
1453 * Trashes or deletes a comment. |
1345 * |
1454 * |
1346 * The comment is moved to trash instead of permanently deleted unless trash is |
1455 * The comment is moved to Trash instead of permanently deleted unless Trash is |
1347 * disabled, item is already in the trash, or $force_delete is true. |
1456 * disabled, item is already in the Trash, or $force_delete is true. |
1348 * |
1457 * |
1349 * The post comment count will be updated if the comment was approved and has a |
1458 * The post comment count will be updated if the comment was approved and has a |
1350 * post ID available. |
1459 * post ID available. |
1351 * |
1460 * |
1352 * @since 2.0.0 |
1461 * @since 2.0.0 |
1353 * |
1462 * |
1354 * @global wpdb $wpdb WordPress database abstraction object. |
1463 * @global wpdb $wpdb WordPress database abstraction object. |
1355 * |
1464 * |
1356 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object. |
1465 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object. |
1357 * @param bool $force_delete Whether to bypass trash and force deletion. Default is false. |
1466 * @param bool $force_delete Whether to bypass Trash and force deletion. Default false. |
1358 * @return bool True on success, false on failure. |
1467 * @return bool True on success, false on failure. |
1359 */ |
1468 */ |
1360 function wp_delete_comment( $comment_id, $force_delete = false ) { |
1469 function wp_delete_comment( $comment_id, $force_delete = false ) { |
1361 global $wpdb; |
1470 global $wpdb; |
1362 if ( ! $comment = get_comment( $comment_id ) ) { |
1471 $comment = get_comment( $comment_id ); |
|
1472 if ( ! $comment ) { |
1363 return false; |
1473 return false; |
1364 } |
1474 } |
1365 |
1475 |
1366 if ( ! $force_delete && EMPTY_TRASH_DAYS && ! in_array( wp_get_comment_status( $comment ), array( 'trash', 'spam' ) ) ) { |
1476 if ( ! $force_delete && EMPTY_TRASH_DAYS && ! in_array( wp_get_comment_status( $comment ), array( 'trash', 'spam' ), true ) ) { |
1367 return wp_trash_comment( $comment_id ); |
1477 return wp_trash_comment( $comment_id ); |
1368 } |
1478 } |
1369 |
1479 |
1370 /** |
1480 /** |
1371 * Fires immediately before a comment is deleted from the database. |
1481 * Fires immediately before a comment is deleted from the database. |
1405 * @param WP_Comment $comment The deleted comment. |
1515 * @param WP_Comment $comment The deleted comment. |
1406 */ |
1516 */ |
1407 do_action( 'deleted_comment', $comment->comment_ID, $comment ); |
1517 do_action( 'deleted_comment', $comment->comment_ID, $comment ); |
1408 |
1518 |
1409 $post_id = $comment->comment_post_ID; |
1519 $post_id = $comment->comment_post_ID; |
1410 if ( $post_id && $comment->comment_approved == 1 ) { |
1520 if ( $post_id && 1 == $comment->comment_approved ) { |
1411 wp_update_comment_count( $post_id ); |
1521 wp_update_comment_count( $post_id ); |
1412 } |
1522 } |
1413 |
1523 |
1414 clean_comment_cache( $comment->comment_ID ); |
1524 clean_comment_cache( $comment->comment_ID ); |
1415 |
1525 |
1416 /** This action is documented in wp-includes/comment.php */ |
1526 /** This action is documented in wp-includes/comment.php */ |
1417 do_action( 'wp_set_comment_status', $comment->comment_ID, 'delete' ); |
1527 do_action( 'wp_set_comment_status', $comment->comment_ID, 'delete' ); |
1418 |
1528 |
1419 wp_transition_comment_status( 'delete', $comment->comment_approved, $comment ); |
1529 wp_transition_comment_status( 'delete', $comment->comment_approved, $comment ); |
|
1530 |
1420 return true; |
1531 return true; |
1421 } |
1532 } |
1422 |
1533 |
1423 /** |
1534 /** |
1424 * Moves a comment to the Trash |
1535 * Moves a comment to the Trash |
1425 * |
1536 * |
1426 * If trash is disabled, comment is permanently deleted. |
1537 * If Trash is disabled, comment is permanently deleted. |
1427 * |
1538 * |
1428 * @since 2.9.0 |
1539 * @since 2.9.0 |
1429 * |
1540 * |
1430 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object. |
1541 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object. |
1431 * @return bool True on success, false on failure. |
1542 * @return bool True on success, false on failure. |
1549 if ( wp_set_comment_status( $comment, 'spam' ) ) { |
1664 if ( wp_set_comment_status( $comment, 'spam' ) ) { |
1550 delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_status' ); |
1665 delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_status' ); |
1551 delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_time' ); |
1666 delete_comment_meta( $comment->comment_ID, '_wp_trash_meta_time' ); |
1552 add_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', $comment->comment_approved ); |
1667 add_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', $comment->comment_approved ); |
1553 add_comment_meta( $comment->comment_ID, '_wp_trash_meta_time', time() ); |
1668 add_comment_meta( $comment->comment_ID, '_wp_trash_meta_time', time() ); |
|
1669 |
1554 /** |
1670 /** |
1555 * Fires immediately after a comment is marked as Spam. |
1671 * Fires immediately after a comment is marked as Spam. |
1556 * |
1672 * |
1557 * @since 2.9.0 |
1673 * @since 2.9.0 |
1558 * @since 4.9.0 Added the `$comment` parameter. |
1674 * @since 4.9.0 Added the `$comment` parameter. |
1559 * |
1675 * |
1560 * @param int $comment_id The comment ID. |
1676 * @param int $comment_id The comment ID. |
1561 * @param WP_Comment $comment The comment marked as spam. |
1677 * @param WP_Comment $comment The comment marked as spam. |
1562 */ |
1678 */ |
1563 do_action( 'spammed_comment', $comment->comment_ID, $comment ); |
1679 do_action( 'spammed_comment', $comment->comment_ID, $comment ); |
|
1680 |
1564 return true; |
1681 return true; |
1565 } |
1682 } |
1566 |
1683 |
1567 return false; |
1684 return false; |
1568 } |
1685 } |
1650 /** |
1769 /** |
1651 * Call hooks for when a comment status transition occurs. |
1770 * Call hooks for when a comment status transition occurs. |
1652 * |
1771 * |
1653 * Calls hooks for comment status transitions. If the new comment status is not the same |
1772 * Calls hooks for comment status transitions. If the new comment status is not the same |
1654 * as the previous comment status, then two hooks will be ran, the first is |
1773 * as the previous comment status, then two hooks will be ran, the first is |
1655 * {@see 'transition_comment_status'} with new status, old status, and comment data. The |
1774 * {@see 'transition_comment_status'} with new status, old status, and comment data. |
1656 * next action called is {@see comment_$old_status_to_$new_status'}. It has the |
1775 * The next action called is {@see 'comment_$old_status_to_$new_status'}. It has |
1657 * comment data. |
1776 * the comment data. |
1658 * |
1777 * |
1659 * The final action will run whether or not the comment statuses are the same. The |
1778 * The final action will run whether or not the comment statuses are the same. |
1660 * action is named {@see 'comment_$new_status_$comment->comment_type'}. |
1779 * The action is named {@see 'comment_$new_status_$comment->comment_type'}. |
1661 * |
1780 * |
1662 * @since 2.7.0 |
1781 * @since 2.7.0 |
1663 * |
1782 * |
1664 * @param string $new_status New comment status. |
1783 * @param string $new_status New comment status. |
1665 * @param string $old_status Previous comment status. |
1784 * @param string $old_status Previous comment status. |
1666 * @param object $comment Comment data. |
1785 * @param WP_Comment $comment Comment object. |
1667 */ |
1786 */ |
1668 function wp_transition_comment_status( $new_status, $old_status, $comment ) { |
1787 function wp_transition_comment_status( $new_status, $old_status, $comment ) { |
1669 /* |
1788 /* |
1670 * Translate raw statuses to human readable formats for the hooks. |
1789 * Translate raw statuses to human-readable formats for the hooks. |
1671 * This is not a complete list of comment status, it's only the ones |
1790 * This is not a complete list of comment status, it's only the ones |
1672 * that need to be renamed |
1791 * that need to be renamed. |
1673 */ |
1792 */ |
1674 $comment_statuses = array( |
1793 $comment_statuses = array( |
1675 0 => 'unapproved', |
1794 0 => 'unapproved', |
1676 'hold' => 'unapproved', // wp_set_comment_status() uses "hold" |
1795 'hold' => 'unapproved', // wp_set_comment_status() uses "hold". |
1677 1 => 'approved', |
1796 1 => 'approved', |
1678 'approve' => 'approved', // wp_set_comment_status() uses "approve" |
1797 'approve' => 'approved', // wp_set_comment_status() uses "approve". |
1679 ); |
1798 ); |
1680 if ( isset( $comment_statuses[ $new_status ] ) ) { |
1799 if ( isset( $comment_statuses[ $new_status ] ) ) { |
1681 $new_status = $comment_statuses[ $new_status ]; |
1800 $new_status = $comment_statuses[ $new_status ]; |
1682 } |
1801 } |
1683 if ( isset( $comment_statuses[ $old_status ] ) ) { |
1802 if ( isset( $comment_statuses[ $old_status ] ) ) { |
1684 $old_status = $comment_statuses[ $old_status ]; |
1803 $old_status = $comment_statuses[ $old_status ]; |
1685 } |
1804 } |
1686 |
1805 |
1687 // Call the hooks |
1806 // Call the hooks. |
1688 if ( $new_status != $old_status ) { |
1807 if ( $new_status != $old_status ) { |
1689 /** |
1808 /** |
1690 * Fires when the comment status is in transition. |
1809 * Fires when the comment status is in transition. |
1691 * |
1810 * |
1692 * @since 2.7.0 |
1811 * @since 2.7.0 |
1693 * |
1812 * |
1694 * @param int|string $new_status The new comment status. |
1813 * @param int|string $new_status The new comment status. |
1695 * @param int|string $old_status The old comment status. |
1814 * @param int|string $old_status The old comment status. |
1696 * @param object $comment The comment data. |
1815 * @param WP_Comment $comment Comment object. |
1697 */ |
1816 */ |
1698 do_action( 'transition_comment_status', $new_status, $old_status, $comment ); |
1817 do_action( 'transition_comment_status', $new_status, $old_status, $comment ); |
1699 /** |
1818 /** |
1700 * Fires when the comment status is in transition from one specific status to another. |
1819 * Fires when the comment status is in transition from one specific status to another. |
1701 * |
1820 * |
1870 $comment_post_ID = ! isset( $data['comment_post_ID'] ) ? 0 : $data['comment_post_ID']; |
2001 $comment_post_ID = ! isset( $data['comment_post_ID'] ) ? 0 : $data['comment_post_ID']; |
1871 $comment_content = ! isset( $data['comment_content'] ) ? '' : $data['comment_content']; |
2002 $comment_content = ! isset( $data['comment_content'] ) ? '' : $data['comment_content']; |
1872 $comment_karma = ! isset( $data['comment_karma'] ) ? 0 : $data['comment_karma']; |
2003 $comment_karma = ! isset( $data['comment_karma'] ) ? 0 : $data['comment_karma']; |
1873 $comment_approved = ! isset( $data['comment_approved'] ) ? 1 : $data['comment_approved']; |
2004 $comment_approved = ! isset( $data['comment_approved'] ) ? 1 : $data['comment_approved']; |
1874 $comment_agent = ! isset( $data['comment_agent'] ) ? '' : $data['comment_agent']; |
2005 $comment_agent = ! isset( $data['comment_agent'] ) ? '' : $data['comment_agent']; |
1875 $comment_type = ! isset( $data['comment_type'] ) ? '' : $data['comment_type']; |
2006 $comment_type = empty( $data['comment_type'] ) ? 'comment' : $data['comment_type']; |
1876 $comment_parent = ! isset( $data['comment_parent'] ) ? 0 : $data['comment_parent']; |
2007 $comment_parent = ! isset( $data['comment_parent'] ) ? 0 : $data['comment_parent']; |
1877 |
2008 |
1878 $user_id = ! isset( $data['user_id'] ) ? 0 : $data['user_id']; |
2009 $user_id = ! isset( $data['user_id'] ) ? 0 : $data['user_id']; |
1879 |
2010 |
1880 $compacted = compact( 'comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_author_IP', 'comment_date', 'comment_date_gmt', 'comment_content', 'comment_karma', 'comment_approved', 'comment_agent', 'comment_type', 'comment_parent', 'user_id' ); |
2011 $compacted = compact( 'comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_author_IP', 'comment_date', 'comment_date_gmt', 'comment_content', 'comment_karma', 'comment_approved', 'comment_agent', 'comment_type', 'comment_parent', 'user_id' ); |
2029 * @type string $comment_author_url The comment author URL. |
2162 * @type string $comment_author_url The comment author URL. |
2030 * @type string $comment_content The content of the comment. |
2163 * @type string $comment_content The content of the comment. |
2031 * @type string $comment_date The date the comment was submitted. Default is the current time. |
2164 * @type string $comment_date The date the comment was submitted. Default is the current time. |
2032 * @type string $comment_date_gmt The date the comment was submitted in the GMT timezone. |
2165 * @type string $comment_date_gmt The date the comment was submitted in the GMT timezone. |
2033 * Default is `$comment_date` in the GMT timezone. |
2166 * Default is `$comment_date` in the GMT timezone. |
|
2167 * @type string $comment_type Comment type. Default 'comment'. |
2034 * @type int $comment_parent The ID of this comment's parent, if any. Default 0. |
2168 * @type int $comment_parent The ID of this comment's parent, if any. Default 0. |
2035 * @type int $comment_post_ID The ID of the post that relates to the comment. |
2169 * @type int $comment_post_ID The ID of the post that relates to the comment. |
2036 * @type int $user_id The ID of the user who submitted the comment. Default 0. |
2170 * @type int $user_id The ID of the user who submitted the comment. Default 0. |
2037 * @type int $user_ID Kept for backward-compatibility. Use `$user_id` instead. |
2171 * @type int $user_ID Kept for backward-compatibility. Use `$user_id` instead. |
2038 * @type string $comment_agent Comment author user agent. Default is the value of 'HTTP_USER_AGENT' |
2172 * @type string $comment_agent Comment author user agent. Default is the value of 'HTTP_USER_AGENT' |
2039 * in the `$_SERVER` superglobal sent in the original request. |
2173 * in the `$_SERVER` superglobal sent in the original request. |
2040 * @type string $comment_author_IP Comment author IP address in IPv4 format. Default is the value of |
2174 * @type string $comment_author_IP Comment author IP address in IPv4 format. Default is the value of |
2041 * 'REMOTE_ADDR' in the `$_SERVER` superglobal sent in the original request. |
2175 * 'REMOTE_ADDR' in the `$_SERVER` superglobal sent in the original request. |
2042 * } |
2176 * } |
2043 * @param bool $avoid_die Should errors be returned as WP_Error objects instead of |
2177 * @param bool $wp_error Should errors be returned as WP_Error objects instead of |
2044 * executing wp_die()? Default false. |
2178 * executing wp_die()? Default false. |
2045 * @return int|false|WP_Error The ID of the comment on success, false or WP_Error on failure. |
2179 * @return int|false|WP_Error The ID of the comment on success, false or WP_Error on failure. |
2046 */ |
2180 */ |
2047 function wp_new_comment( $commentdata, $avoid_die = false ) { |
2181 function wp_new_comment( $commentdata, $wp_error = false ) { |
2048 global $wpdb; |
2182 global $wpdb; |
2049 |
2183 |
2050 if ( isset( $commentdata['user_ID'] ) ) { |
2184 if ( isset( $commentdata['user_ID'] ) ) { |
2051 $commentdata['user_id'] = $commentdata['user_ID'] = (int) $commentdata['user_ID']; |
2185 $commentdata['user_ID'] = (int) $commentdata['user_ID']; |
|
2186 $commentdata['user_id'] = $commentdata['user_ID']; |
2052 } |
2187 } |
2053 |
2188 |
2054 $prefiltered_user_id = ( isset( $commentdata['user_id'] ) ) ? (int) $commentdata['user_id'] : 0; |
2189 $prefiltered_user_id = ( isset( $commentdata['user_id'] ) ) ? (int) $commentdata['user_id'] : 0; |
2055 |
2190 |
2056 /** |
2191 /** |
2062 */ |
2197 */ |
2063 $commentdata = apply_filters( 'preprocess_comment', $commentdata ); |
2198 $commentdata = apply_filters( 'preprocess_comment', $commentdata ); |
2064 |
2199 |
2065 $commentdata['comment_post_ID'] = (int) $commentdata['comment_post_ID']; |
2200 $commentdata['comment_post_ID'] = (int) $commentdata['comment_post_ID']; |
2066 if ( isset( $commentdata['user_ID'] ) && $prefiltered_user_id !== (int) $commentdata['user_ID'] ) { |
2201 if ( isset( $commentdata['user_ID'] ) && $prefiltered_user_id !== (int) $commentdata['user_ID'] ) { |
2067 $commentdata['user_id'] = $commentdata['user_ID'] = (int) $commentdata['user_ID']; |
2202 $commentdata['user_ID'] = (int) $commentdata['user_ID']; |
|
2203 $commentdata['user_id'] = $commentdata['user_ID']; |
2068 } elseif ( isset( $commentdata['user_id'] ) ) { |
2204 } elseif ( isset( $commentdata['user_id'] ) ) { |
2069 $commentdata['user_id'] = (int) $commentdata['user_id']; |
2205 $commentdata['user_id'] = (int) $commentdata['user_id']; |
2070 } |
2206 } |
2071 |
2207 |
2072 $commentdata['comment_parent'] = isset( $commentdata['comment_parent'] ) ? absint( $commentdata['comment_parent'] ) : 0; |
2208 $commentdata['comment_parent'] = isset( $commentdata['comment_parent'] ) ? absint( $commentdata['comment_parent'] ) : 0; |
2073 $parent_status = ( 0 < $commentdata['comment_parent'] ) ? wp_get_comment_status( $commentdata['comment_parent'] ) : ''; |
2209 |
2074 $commentdata['comment_parent'] = ( 'approved' == $parent_status || 'unapproved' == $parent_status ) ? $commentdata['comment_parent'] : 0; |
2210 $parent_status = ( $commentdata['comment_parent'] > 0 ) ? wp_get_comment_status( $commentdata['comment_parent'] ) : ''; |
|
2211 |
|
2212 $commentdata['comment_parent'] = ( 'approved' === $parent_status || 'unapproved' === $parent_status ) ? $commentdata['comment_parent'] : 0; |
2075 |
2213 |
2076 if ( ! isset( $commentdata['comment_author_IP'] ) ) { |
2214 if ( ! isset( $commentdata['comment_author_IP'] ) ) { |
2077 $commentdata['comment_author_IP'] = $_SERVER['REMOTE_ADDR']; |
2215 $commentdata['comment_author_IP'] = $_SERVER['REMOTE_ADDR']; |
2078 } |
2216 } |
2079 $commentdata['comment_author_IP'] = preg_replace( '/[^0-9a-fA-F:., ]/', '', $commentdata['comment_author_IP'] ); |
2217 $commentdata['comment_author_IP'] = preg_replace( '/[^0-9a-fA-F:., ]/', '', $commentdata['comment_author_IP'] ); |
2279 * |
2421 * |
2280 * Filters the comment and makes sure certain fields are valid before updating. |
2422 * Filters the comment and makes sure certain fields are valid before updating. |
2281 * |
2423 * |
2282 * @since 2.0.0 |
2424 * @since 2.0.0 |
2283 * @since 4.9.0 Add updating comment meta during comment update. |
2425 * @since 4.9.0 Add updating comment meta during comment update. |
|
2426 * @since 5.5.0 The `$wp_error` parameter was added. |
|
2427 * @since 5.5.0 The return values for an invalid comment or post ID |
|
2428 * were changed to false instead of 0. |
2284 * |
2429 * |
2285 * @global wpdb $wpdb WordPress database abstraction object. |
2430 * @global wpdb $wpdb WordPress database abstraction object. |
2286 * |
2431 * |
2287 * @param array $commentarr Contains information on the comment. |
2432 * @param array $commentarr Contains information on the comment. |
2288 * @return int Comment was updated if value is 1, or was not updated if value is 0. |
2433 * @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false. |
2289 */ |
2434 * @return int|false|WP_Error The value 1 if the comment was updated, 0 if not updated. |
2290 function wp_update_comment( $commentarr ) { |
2435 * False or a WP_Error object on failure. |
|
2436 */ |
|
2437 function wp_update_comment( $commentarr, $wp_error = false ) { |
2291 global $wpdb; |
2438 global $wpdb; |
2292 |
2439 |
2293 // First, get all of the original fields |
2440 // First, get all of the original fields. |
2294 $comment = get_comment( $commentarr['comment_ID'], ARRAY_A ); |
2441 $comment = get_comment( $commentarr['comment_ID'], ARRAY_A ); |
2295 if ( empty( $comment ) ) { |
2442 if ( empty( $comment ) ) { |
2296 return 0; |
2443 if ( $wp_error ) { |
|
2444 return new WP_Error( 'invalid_comment_id', __( 'Invalid comment ID.' ) ); |
|
2445 } else { |
|
2446 return false; |
|
2447 } |
2297 } |
2448 } |
2298 |
2449 |
2299 // Make sure that the comment post ID is valid (if specified). |
2450 // Make sure that the comment post ID is valid (if specified). |
2300 if ( ! empty( $commentarr['comment_post_ID'] ) && ! get_post( $commentarr['comment_post_ID'] ) ) { |
2451 if ( ! empty( $commentarr['comment_post_ID'] ) && ! get_post( $commentarr['comment_post_ID'] ) ) { |
2301 return 0; |
2452 if ( $wp_error ) { |
|
2453 return new WP_Error( 'invalid_post_id', __( 'Invalid post ID.' ) ); |
|
2454 } else { |
|
2455 return false; |
|
2456 } |
2302 } |
2457 } |
2303 |
2458 |
2304 // Escape data pulled from DB. |
2459 // Escape data pulled from DB. |
2305 $comment = wp_slash( $comment ); |
2460 $comment = wp_slash( $comment ); |
2306 |
2461 |
2340 * Filters the comment data immediately before it is updated in the database. |
2495 * Filters the comment data immediately before it is updated in the database. |
2341 * |
2496 * |
2342 * Note: data being passed to the filter is already unslashed. |
2497 * Note: data being passed to the filter is already unslashed. |
2343 * |
2498 * |
2344 * @since 4.7.0 |
2499 * @since 4.7.0 |
2345 * |
2500 * @since 5.5.0 Returning a WP_Error value from the filter will short-circuit comment update |
2346 * @param array $data The new, processed comment data. |
2501 * and allow skipping further processing. |
2347 * @param array $comment The old, unslashed comment data. |
2502 * |
2348 * @param array $commentarr The new, raw comment data. |
2503 * @param array|WP_Error $data The new, processed comment data, or WP_Error. |
|
2504 * @param array $comment The old, unslashed comment data. |
|
2505 * @param array $commentarr The new, raw comment data. |
2349 */ |
2506 */ |
2350 $data = apply_filters( 'wp_update_comment_data', $data, $comment, $commentarr ); |
2507 $data = apply_filters( 'wp_update_comment_data', $data, $comment, $commentarr ); |
|
2508 |
|
2509 // Do not carry on on failure. |
|
2510 if ( is_wp_error( $data ) ) { |
|
2511 if ( $wp_error ) { |
|
2512 return $data; |
|
2513 } else { |
|
2514 return false; |
|
2515 } |
|
2516 } |
2351 |
2517 |
2352 $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' ); |
2518 $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' ); |
2353 $data = wp_array_slice_assoc( $data, $keys ); |
2519 $data = wp_array_slice_assoc( $data, $keys ); |
2354 |
2520 |
2355 $rval = $wpdb->update( $wpdb->comments, $data, compact( 'comment_ID' ) ); |
2521 $rval = $wpdb->update( $wpdb->comments, $data, compact( 'comment_ID' ) ); |
|
2522 |
|
2523 if ( false === $rval ) { |
|
2524 if ( $wp_error ) { |
|
2525 return new WP_Error( 'db_update_error', __( 'Could not update comment in the database.' ), $wpdb->last_error ); |
|
2526 } else { |
|
2527 return false; |
|
2528 } |
|
2529 } |
2356 |
2530 |
2357 // If metadata is provided, store it. |
2531 // If metadata is provided, store it. |
2358 if ( isset( $commentarr['comment_meta'] ) && is_array( $commentarr['comment_meta'] ) ) { |
2532 if ( isset( $commentarr['comment_meta'] ) && is_array( $commentarr['comment_meta'] ) ) { |
2359 foreach ( $commentarr['comment_meta'] as $meta_key => $meta_value ) { |
2533 foreach ( $commentarr['comment_meta'] as $meta_key => $meta_value ) { |
2360 update_comment_meta( $comment_ID, $meta_key, $meta_value ); |
2534 update_comment_meta( $comment_ID, $meta_key, $meta_value ); |
2361 } |
2535 } |
2362 } |
2536 } |
2363 |
2537 |
2364 clean_comment_cache( $comment_ID ); |
2538 clean_comment_cache( $comment_ID ); |
2365 wp_update_comment_count( $comment_post_ID ); |
2539 wp_update_comment_count( $comment_post_ID ); |
|
2540 |
2366 /** |
2541 /** |
2367 * Fires immediately after a comment is updated in the database. |
2542 * Fires immediately after a comment is updated in the database. |
2368 * |
2543 * |
2369 * The hook also fires immediately before comment status transition hooks are fired. |
2544 * The hook also fires immediately before comment status transition hooks are fired. |
2370 * |
2545 * |
2473 } |
2649 } |
2474 |
2650 |
2475 wp_cache_delete( 'comments-0', 'counts' ); |
2651 wp_cache_delete( 'comments-0', 'counts' ); |
2476 wp_cache_delete( "comments-{$post_id}", 'counts' ); |
2652 wp_cache_delete( "comments-{$post_id}", 'counts' ); |
2477 |
2653 |
2478 if ( ! $post = get_post( $post_id ) ) { |
2654 $post = get_post( $post_id ); |
|
2655 if ( ! $post ) { |
2479 return false; |
2656 return false; |
2480 } |
2657 } |
2481 |
2658 |
2482 $old = (int) $post->comment_count; |
2659 $old = (int) $post->comment_count; |
2483 |
2660 |
2484 /** |
2661 /** |
2485 * Filters a post's comment count before it is updated in the database. |
2662 * Filters a post's comment count before it is updated in the database. |
2486 * |
2663 * |
2487 * @since 4.5.0 |
2664 * @since 4.5.0 |
2488 * |
2665 * |
2489 * @param int $new The new comment count. Default null. |
2666 * @param int|null $new The new comment count. Default null. |
2490 * @param int $old The old comment count. |
2667 * @param int $old The old comment count. |
2491 * @param int $post_id Post ID. |
2668 * @param int $post_id Post ID. |
2492 */ |
2669 */ |
2493 $new = apply_filters( 'pre_wp_update_comment_count_now', null, $old, $post_id ); |
2670 $new = apply_filters( 'pre_wp_update_comment_count_now', null, $old, $post_id ); |
2494 |
2671 |
2495 if ( is_null( $new ) ) { |
2672 if ( is_null( $new ) ) { |
2496 $new = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved = '1'", $post_id ) ); |
2673 $new = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved = '1'", $post_id ) ); |
2598 |
2775 |
2599 $pingback_link_offset_dquote = strpos( $contents, $pingback_str_dquote ); |
2776 $pingback_link_offset_dquote = strpos( $contents, $pingback_str_dquote ); |
2600 $pingback_link_offset_squote = strpos( $contents, $pingback_str_squote ); |
2777 $pingback_link_offset_squote = strpos( $contents, $pingback_str_squote ); |
2601 if ( $pingback_link_offset_dquote || $pingback_link_offset_squote ) { |
2778 if ( $pingback_link_offset_dquote || $pingback_link_offset_squote ) { |
2602 $quote = ( $pingback_link_offset_dquote ) ? '"' : '\''; |
2779 $quote = ( $pingback_link_offset_dquote ) ? '"' : '\''; |
2603 $pingback_link_offset = ( $quote == '"' ) ? $pingback_link_offset_dquote : $pingback_link_offset_squote; |
2780 $pingback_link_offset = ( '"' === $quote ) ? $pingback_link_offset_dquote : $pingback_link_offset_squote; |
2604 $pingback_href_pos = @strpos( $contents, 'href=', $pingback_link_offset ); |
2781 $pingback_href_pos = strpos( $contents, 'href=', $pingback_link_offset ); |
2605 $pingback_href_start = $pingback_href_pos + 6; |
2782 $pingback_href_start = $pingback_href_pos + 6; |
2606 $pingback_href_end = @strpos( $contents, $quote, $pingback_href_start ); |
2783 $pingback_href_end = strpos( $contents, $quote, $pingback_href_start ); |
2607 $pingback_server_url_len = $pingback_href_end - $pingback_href_start; |
2784 $pingback_server_url_len = $pingback_href_end - $pingback_href_start; |
2608 $pingback_server_url = substr( $contents, $pingback_href_start, $pingback_server_url_len ); |
2785 $pingback_server_url = substr( $contents, $pingback_href_start, $pingback_server_url_len ); |
2609 |
2786 |
2610 // We may find rel="pingback" but an incomplete pingback URL |
2787 // We may find rel="pingback" but an incomplete pingback URL. |
2611 if ( $pingback_server_url_len > 0 ) { // We got it! |
2788 if ( $pingback_server_url_len > 0 ) { // We got it! |
2612 return $pingback_server_url; |
2789 return $pingback_server_url; |
2613 } |
2790 } |
2614 } |
2791 } |
2615 |
2792 |
2624 * @global wpdb $wpdb WordPress database abstraction object. |
2801 * @global wpdb $wpdb WordPress database abstraction object. |
2625 */ |
2802 */ |
2626 function do_all_pings() { |
2803 function do_all_pings() { |
2627 global $wpdb; |
2804 global $wpdb; |
2628 |
2805 |
2629 // Do pingbacks |
2806 // Do pingbacks. |
2630 while ( $ping = $wpdb->get_row( "SELECT ID, post_content, meta_id FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '_pingme' LIMIT 1" ) ) { |
2807 $pings = get_posts( |
2631 delete_metadata_by_mid( 'post', $ping->meta_id ); |
2808 array( |
2632 pingback( $ping->post_content, $ping->ID ); |
2809 'post_type' => get_post_types(), |
2633 } |
2810 'suppress_filters' => false, |
2634 |
2811 'nopaging' => true, |
2635 // Do Enclosures |
2812 'meta_key' => '_pingme', |
2636 while ( $enclosure = $wpdb->get_row( "SELECT ID, post_content, meta_id FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '_encloseme' LIMIT 1" ) ) { |
2813 'fields' => 'ids', |
2637 delete_metadata_by_mid( 'post', $enclosure->meta_id ); |
2814 ) |
2638 do_enclose( $enclosure->post_content, $enclosure->ID ); |
2815 ); |
2639 } |
2816 |
2640 |
2817 foreach ( $pings as $ping ) { |
2641 // Do Trackbacks |
2818 delete_post_meta( $ping, '_pingme' ); |
2642 $trackbacks = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE to_ping <> '' AND post_status = 'publish'" ); |
2819 pingback( null, $ping ); |
2643 if ( is_array( $trackbacks ) ) { |
2820 } |
2644 foreach ( $trackbacks as $trackback ) { |
2821 |
2645 do_trackbacks( $trackback ); |
2822 // Do enclosures. |
2646 } |
2823 $enclosures = get_posts( |
2647 } |
2824 array( |
2648 |
2825 'post_type' => get_post_types(), |
2649 //Do Update Services/Generic Pings |
2826 'suppress_filters' => false, |
|
2827 'nopaging' => true, |
|
2828 'meta_key' => '_encloseme', |
|
2829 'fields' => 'ids', |
|
2830 ) |
|
2831 ); |
|
2832 |
|
2833 foreach ( $enclosures as $enclosure ) { |
|
2834 delete_post_meta( $enclosure, '_encloseme' ); |
|
2835 do_enclose( null, $enclosure ); |
|
2836 } |
|
2837 |
|
2838 // Do trackbacks. |
|
2839 $trackbacks = get_posts( |
|
2840 array( |
|
2841 'post_type' => get_post_types(), |
|
2842 'suppress_filters' => false, |
|
2843 'nopaging' => true, |
|
2844 'meta_key' => '_trackbackme', |
|
2845 'fields' => 'ids', |
|
2846 ) |
|
2847 ); |
|
2848 |
|
2849 foreach ( $trackbacks as $trackback ) { |
|
2850 delete_post_meta( $trackback, '_trackbackme' ); |
|
2851 do_trackbacks( $trackback ); |
|
2852 } |
|
2853 |
|
2854 // Do Update Services/Generic Pings. |
2650 generic_ping(); |
2855 generic_ping(); |
2651 } |
2856 } |
2652 |
2857 |
2653 /** |
2858 /** |
2654 * Perform trackbacks. |
2859 * Perform trackbacks. |
2756 |
2961 |
2757 if ( empty( $content ) ) { |
2962 if ( empty( $content ) ) { |
2758 $content = $post->post_content; |
2963 $content = $post->post_content; |
2759 } |
2964 } |
2760 |
2965 |
2761 // Step 1 |
2966 /* |
2762 // Parsing the post, external links (if any) are stored in the $post_links array |
2967 * Step 1. |
|
2968 * Parsing the post, external links (if any) are stored in the $post_links array. |
|
2969 */ |
2763 $post_links_temp = wp_extract_urls( $content ); |
2970 $post_links_temp = wp_extract_urls( $content ); |
2764 |
2971 |
2765 // Step 2. |
2972 /* |
2766 // Walking thru the links array |
2973 * Step 2. |
2767 // first we get rid of links pointing to sites, not to specific files |
2974 * Walking through the links array. |
2768 // Example: |
2975 * First we get rid of links pointing to sites, not to specific files. |
2769 // http://dummy-weblog.org |
2976 * Example: |
2770 // http://dummy-weblog.org/ |
2977 * http://dummy-weblog.org |
2771 // http://dummy-weblog.org/post.php |
2978 * http://dummy-weblog.org/ |
2772 // We don't wanna ping first and second types, even if they have a valid <link/> |
2979 * http://dummy-weblog.org/post.php |
2773 |
2980 * We don't wanna ping first and second types, even if they have a valid <link/>. |
2774 foreach ( (array) $post_links_temp as $link_test ) : |
2981 */ |
2775 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 |
2982 foreach ( (array) $post_links_temp as $link_test ) { |
2776 && ! is_local_attachment( $link_test ) ) : // Also, let's never ping local attachments. |
2983 // If we haven't pung it already and it isn't a link to itself. |
2777 if ( $test = @parse_url( $link_test ) ) { |
2984 if ( ! in_array( $link_test, $pung, true ) && ( url_to_postid( $link_test ) != $post->ID ) |
|
2985 // Also, let's never ping local attachments. |
|
2986 && ! is_local_attachment( $link_test ) |
|
2987 ) { |
|
2988 $test = parse_url( $link_test ); |
|
2989 if ( $test ) { |
2778 if ( isset( $test['query'] ) ) { |
2990 if ( isset( $test['query'] ) ) { |
2779 $post_links[] = $link_test; |
2991 $post_links[] = $link_test; |
2780 } elseif ( isset( $test['path'] ) && ( $test['path'] != '/' ) && ( $test['path'] != '' ) ) { |
2992 } elseif ( isset( $test['path'] ) && ( '/' !== $test['path'] ) && ( '' !== $test['path'] ) ) { |
2781 $post_links[] = $link_test; |
2993 $post_links[] = $link_test; |
2782 } |
2994 } |
2783 } |
2995 } |
2784 endif; |
2996 } |
2785 endforeach; |
2997 } |
2786 |
2998 |
2787 $post_links = array_unique( $post_links ); |
2999 $post_links = array_unique( $post_links ); |
|
3000 |
2788 /** |
3001 /** |
2789 * Fires just before pinging back links found in a post. |
3002 * Fires just before pinging back links found in a post. |
2790 * |
3003 * |
2791 * @since 2.0.0 |
3004 * @since 2.0.0 |
2792 * |
3005 * |
2818 * @param string $pingback_server_url The server URL being linked to. |
3031 * @param string $pingback_server_url The server URL being linked to. |
2819 * @param string $pagelinkedto URL of page linked to. |
3032 * @param string $pagelinkedto URL of page linked to. |
2820 * @param string $pagelinkedfrom URL of page linked from. |
3033 * @param string $pagelinkedfrom URL of page linked from. |
2821 */ |
3034 */ |
2822 $client->useragent = apply_filters( 'pingback_useragent', $client->useragent . ' -- WordPress/' . get_bloginfo( 'version' ), $client->useragent, $pingback_server_url, $pagelinkedto, $pagelinkedfrom ); |
3035 $client->useragent = apply_filters( 'pingback_useragent', $client->useragent . ' -- WordPress/' . get_bloginfo( 'version' ), $client->useragent, $pingback_server_url, $pagelinkedto, $pagelinkedfrom ); |
2823 // when set to true, this outputs debug messages by itself |
3036 // When set to true, this outputs debug messages by itself. |
2824 $client->debug = false; |
3037 $client->debug = false; |
2825 |
3038 |
2826 if ( $client->query( 'pingback.ping', $pagelinkedfrom, $pagelinkedto ) || ( isset( $client->error->code ) && 48 == $client->error->code ) ) { // Already registered |
3039 if ( $client->query( 'pingback.ping', $pagelinkedfrom, $pagelinkedto ) || ( isset( $client->error->code ) && 48 == $client->error->code ) ) { // Already registered. |
2827 add_ping( $post, $pagelinkedto ); |
3040 add_ping( $post, $pagelinkedto ); |
2828 } |
3041 } |
2829 } |
3042 } |
2830 } |
3043 } |
2831 } |
3044 } |
2894 * |
3107 * |
2895 * @param string $server Host of blog to connect to. |
3108 * @param string $server Host of blog to connect to. |
2896 * @param string $path Path to send the ping. |
3109 * @param string $path Path to send the ping. |
2897 */ |
3110 */ |
2898 function weblog_ping( $server = '', $path = '' ) { |
3111 function weblog_ping( $server = '', $path = '' ) { |
2899 include_once( ABSPATH . WPINC . '/class-IXR.php' ); |
3112 include_once ABSPATH . WPINC . '/class-IXR.php'; |
2900 include_once( ABSPATH . WPINC . '/class-wp-http-ixr-client.php' ); |
3113 include_once ABSPATH . WPINC . '/class-wp-http-ixr-client.php'; |
2901 |
3114 |
2902 // using a timeout of 3 seconds should be enough to cover slow servers |
3115 // Using a timeout of 3 seconds should be enough to cover slow servers. |
2903 $client = new WP_HTTP_IXR_Client( $server, ( ( ! strlen( trim( $path ) ) || ( '/' == $path ) ) ? false : $path ) ); |
3116 $client = new WP_HTTP_IXR_Client( $server, ( ( ! strlen( trim( $path ) ) || ( '/' === $path ) ) ? false : $path ) ); |
2904 $client->timeout = 3; |
3117 $client->timeout = 3; |
2905 $client->useragent .= ' -- WordPress/' . get_bloginfo( 'version' ); |
3118 $client->useragent .= ' -- WordPress/' . get_bloginfo( 'version' ); |
2906 |
3119 |
2907 // when set to true, this outputs debug messages by itself |
3120 // When set to true, this outputs debug messages by itself. |
2908 $client->debug = false; |
3121 $client->debug = false; |
2909 $home = trailingslashit( home_url() ); |
3122 $home = trailingslashit( home_url() ); |
2910 if ( ! $client->query( 'weblogUpdates.extendedPing', get_option( 'blogname' ), $home, get_bloginfo( 'rss2_url' ) ) ) { // then try a normal ping |
3123 if ( ! $client->query( 'weblogUpdates.extendedPing', get_option( 'blogname' ), $home, get_bloginfo( 'rss2_url' ) ) ) { // Then try a normal ping. |
2911 $client->query( 'weblogUpdates.ping', get_option( 'blogname' ), $home ); |
3124 $client->query( 'weblogUpdates.ping', get_option( 'blogname' ), $home ); |
2912 } |
3125 } |
2913 } |
3126 } |
2914 |
3127 |
2915 /** |
3128 /** |
2916 * Default filter attached to pingback_ping_source_uri to validate the pingback's Source URI |
3129 * Default filter attached to pingback_ping_source_uri to validate the pingback's Source URI |
2917 * |
3130 * |
2918 * @since 3.5.1 |
3131 * @since 3.5.1 |
|
3132 * |
2919 * @see wp_http_validate_url() |
3133 * @see wp_http_validate_url() |
2920 * |
3134 * |
2921 * @param string $source_uri |
3135 * @param string $source_uri |
2922 * @return string |
3136 * @return string |
2923 */ |
3137 */ |
3262 $user_ID = $user->ID; |
3482 $user_ID = $user->ID; |
3263 if ( current_user_can( 'unfiltered_html' ) ) { |
3483 if ( current_user_can( 'unfiltered_html' ) ) { |
3264 if ( ! isset( $comment_data['_wp_unfiltered_html_comment'] ) |
3484 if ( ! isset( $comment_data['_wp_unfiltered_html_comment'] ) |
3265 || ! wp_verify_nonce( $comment_data['_wp_unfiltered_html_comment'], 'unfiltered-html-comment_' . $comment_post_ID ) |
3485 || ! wp_verify_nonce( $comment_data['_wp_unfiltered_html_comment'], 'unfiltered-html-comment_' . $comment_post_ID ) |
3266 ) { |
3486 ) { |
3267 kses_remove_filters(); // start with a clean slate |
3487 kses_remove_filters(); // Start with a clean slate. |
3268 kses_init_filters(); // set up the filters |
3488 kses_init_filters(); // Set up the filters. |
3269 remove_filter( 'pre_comment_content', 'wp_filter_post_kses' ); |
3489 remove_filter( 'pre_comment_content', 'wp_filter_post_kses' ); |
3270 add_filter( 'pre_comment_content', 'wp_filter_kses' ); |
3490 add_filter( 'pre_comment_content', 'wp_filter_kses' ); |
3271 } |
3491 } |
3272 } |
3492 } |
3273 } else { |
3493 } else { |
3274 if ( get_option( 'comment_registration' ) ) { |
3494 if ( get_option( 'comment_registration' ) ) { |
3275 return new WP_Error( 'not_logged_in', __( 'Sorry, you must be logged in to comment.' ), 403 ); |
3495 return new WP_Error( 'not_logged_in', __( 'Sorry, you must be logged in to comment.' ), 403 ); |
3276 } |
3496 } |
3277 } |
3497 } |
3278 |
3498 |
3279 $comment_type = ''; |
3499 $comment_type = 'comment'; |
3280 |
3500 |
3281 if ( get_option( 'require_name_email' ) && ! $user->exists() ) { |
3501 if ( get_option( 'require_name_email' ) && ! $user->exists() ) { |
3282 if ( '' == $comment_author_email || '' == $comment_author ) { |
3502 if ( '' == $comment_author_email || '' == $comment_author ) { |
3283 return new WP_Error( 'require_name_email', __( '<strong>ERROR</strong>: please fill the required fields (name, email).' ), 200 ); |
3503 return new WP_Error( 'require_name_email', __( '<strong>Error</strong>: Please fill the required fields (name, email).' ), 200 ); |
3284 } elseif ( ! is_email( $comment_author_email ) ) { |
3504 } elseif ( ! is_email( $comment_author_email ) ) { |
3285 return new WP_Error( 'require_valid_email', __( '<strong>ERROR</strong>: please enter a valid email address.' ), 200 ); |
3505 return new WP_Error( 'require_valid_email', __( '<strong>Error</strong>: Please enter a valid email address.' ), 200 ); |
3286 } |
3506 } |
3287 } |
3507 } |
3288 |
3508 |
3289 $commentdata = compact( |
3509 $commentdata = compact( |
3290 'comment_post_ID', |
3510 'comment_post_ID', |
3509 /** |
3730 /** |
3510 * Filters whether to anonymize the comment. |
3731 * Filters whether to anonymize the comment. |
3511 * |
3732 * |
3512 * @since 4.9.6 |
3733 * @since 4.9.6 |
3513 * |
3734 * |
3514 * @param bool|string Whether to apply the comment anonymization (bool). |
3735 * @param bool|string $anon_message Whether to apply the comment anonymization (bool) or a custom |
3515 * Custom prevention message (string). Default true. |
3736 * message (string). Default true. |
3516 * @param WP_Comment $comment WP_Comment object. |
3737 * @param WP_Comment $comment WP_Comment object. |
3517 * @param array $anonymized_comment Anonymized comment data. |
3738 * @param array $anonymized_comment Anonymized comment data. |
3518 */ |
3739 */ |
3519 $anon_message = apply_filters( 'wp_anonymize_comment', true, $comment, $anonymized_comment ); |
3740 $anon_message = apply_filters( 'wp_anonymize_comment', true, $comment, $anonymized_comment ); |
3520 |
3741 |
3521 if ( true !== $anon_message ) { |
3742 if ( true !== $anon_message ) { |
3522 if ( $anon_message && is_string( $anon_message ) ) { |
3743 if ( $anon_message && is_string( $anon_message ) ) { |
3523 $messages[] = esc_html( $anon_message ); |
3744 $messages[] = esc_html( $anon_message ); |
3524 } else { |
3745 } else { |
3525 /* translators: %d: Comment ID */ |
3746 /* translators: %d: Comment ID. */ |
3526 $messages[] = sprintf( __( 'Comment %d contains personal data but could not be anonymized.' ), $comment_id ); |
3747 $messages[] = sprintf( __( 'Comment %d contains personal data but could not be anonymized.' ), $comment_id ); |
3527 } |
3748 } |
3528 |
3749 |
3529 $items_retained = true; |
3750 $items_retained = true; |
3530 |
3751 |
3561 * @since 5.0.0 |
3782 * @since 5.0.0 |
3562 */ |
3783 */ |
3563 function wp_cache_set_comments_last_changed() { |
3784 function wp_cache_set_comments_last_changed() { |
3564 wp_cache_set( 'last_changed', microtime(), 'comment' ); |
3785 wp_cache_set( 'last_changed', microtime(), 'comment' ); |
3565 } |
3786 } |
|
3787 |
|
3788 /** |
|
3789 * Updates the comment type for a batch of comments. |
|
3790 * |
|
3791 * @since 5.5.0 |
|
3792 * |
|
3793 * @global wpdb $wpdb WordPress database abstraction object. |
|
3794 */ |
|
3795 function _wp_batch_update_comment_type() { |
|
3796 global $wpdb; |
|
3797 |
|
3798 $lock_name = 'update_comment_type.lock'; |
|
3799 |
|
3800 // Try to lock. |
|
3801 $lock_result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO `$wpdb->options` ( `option_name`, `option_value`, `autoload` ) VALUES (%s, %s, 'no') /* LOCK */", $lock_name, time() ) ); |
|
3802 |
|
3803 if ( ! $lock_result ) { |
|
3804 $lock_result = get_option( $lock_name ); |
|
3805 |
|
3806 // Bail if we were unable to create a lock, or if the existing lock is still valid. |
|
3807 if ( ! $lock_result || ( $lock_result > ( time() - HOUR_IN_SECONDS ) ) ) { |
|
3808 wp_schedule_single_event( time() + ( 5 * MINUTE_IN_SECONDS ), 'wp_update_comment_type_batch' ); |
|
3809 return; |
|
3810 } |
|
3811 } |
|
3812 |
|
3813 // Update the lock, as by this point we've definitely got a lock, just need to fire the actions. |
|
3814 update_option( $lock_name, time() ); |
|
3815 |
|
3816 // Check if there's still an empty comment type. |
|
3817 $empty_comment_type = $wpdb->get_var( |
|
3818 "SELECT comment_ID FROM $wpdb->comments |
|
3819 WHERE comment_type = '' |
|
3820 LIMIT 1" |
|
3821 ); |
|
3822 |
|
3823 // No empty comment type, we're done here. |
|
3824 if ( ! $empty_comment_type ) { |
|
3825 update_option( 'finished_updating_comment_type', true ); |
|
3826 delete_option( $lock_name ); |
|
3827 return; |
|
3828 } |
|
3829 |
|
3830 // Empty comment type found? We'll need to run this script again. |
|
3831 wp_schedule_single_event( time() + ( 2 * MINUTE_IN_SECONDS ), 'wp_update_comment_type_batch' ); |
|
3832 |
|
3833 /** |
|
3834 * Filters the comment batch size for updating the comment type. |
|
3835 * |
|
3836 * @since 5.5.0 |
|
3837 * |
|
3838 * @param int $comment_batch_size The comment batch size. Default 100. |
|
3839 */ |
|
3840 $comment_batch_size = (int) apply_filters( 'wp_update_comment_type_batch_size', 100 ); |
|
3841 |
|
3842 // Get the IDs of the comments to update. |
|
3843 $comment_ids = $wpdb->get_col( |
|
3844 $wpdb->prepare( |
|
3845 "SELECT comment_ID |
|
3846 FROM {$wpdb->comments} |
|
3847 WHERE comment_type = '' |
|
3848 ORDER BY comment_ID DESC |
|
3849 LIMIT %d", |
|
3850 $comment_batch_size |
|
3851 ) |
|
3852 ); |
|
3853 |
|
3854 if ( $comment_ids ) { |
|
3855 $comment_id_list = implode( ',', $comment_ids ); |
|
3856 |
|
3857 // Update the `comment_type` field value to be `comment` for the next batch of comments. |
|
3858 $wpdb->query( |
|
3859 "UPDATE {$wpdb->comments} |
|
3860 SET comment_type = 'comment' |
|
3861 WHERE comment_type = '' |
|
3862 AND comment_ID IN ({$comment_id_list})" // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
|
3863 ); |
|
3864 |
|
3865 // Make sure to clean the comment cache. |
|
3866 clean_comment_cache( $comment_ids ); |
|
3867 } |
|
3868 |
|
3869 delete_option( $lock_name ); |
|
3870 } |
|
3871 |
|
3872 /** |
|
3873 * In order to avoid the _wp_batch_update_comment_type() job being accidentally removed, |
|
3874 * check that it's still scheduled while we haven't finished updating comment types. |
|
3875 * |
|
3876 * @ignore |
|
3877 * @since 5.5.0 |
|
3878 */ |
|
3879 function _wp_check_for_scheduled_update_comment_type() { |
|
3880 if ( ! get_option( 'finished_updating_comment_type' ) && ! wp_next_scheduled( 'wp_update_comment_type_batch' ) ) { |
|
3881 wp_schedule_single_event( time() + MINUTE_IN_SECONDS, 'wp_update_comment_type_batch' ); |
|
3882 } |
|
3883 } |