diff --git a/wp-comments-post.php b/wp-comments-post.php index 06cbd460f4..19cf0a34df 100644 --- a/wp-comments-post.php +++ b/wp-comments-post.php @@ -22,38 +22,55 @@ require __DIR__ . '/wp-load.php'; nocache_headers(); -$comment = wp_handle_comment_submission( wp_unslash( $_POST ) ); -if ( is_wp_error( $comment ) ) { - $data = (int) $comment->get_error_data(); - if ( ! empty( $data ) ) { +if ( isset( $_POST['wp-comment-approved-notification-optin'], $_POST['comment_ID'], $_POST['moderation-hash'] ) ) { + $comment = get_comment( $_POST['comment_ID'] ); + + if ( $comment && hash_equals( $_POST['moderation-hash'], wp_hash( $comment->comment_date_gmt ) ) ) { + update_comment_meta( $comment->comment_ID, '_wp_comment_author_notification_optin', true ); + } else { wp_die( - '
' . $comment->get_error_message() . '
', - __( 'Comment Submission Failure' ), + '' . __( 'Invalid comment ID.' ) . '
', + __( 'Comment Notification Opt-in Failure' ), array( - 'response' => $data, + 'response' => 404, 'back_link' => true, ) ); - } else { - exit; } +} else { + $comment = wp_handle_comment_submission( wp_unslash( $_POST ) ); + if ( is_wp_error( $comment ) ) { + $data = (int) $comment->get_error_data(); + if ( ! empty( $data ) ) { + wp_die( + '' . $comment->get_error_message() . '
', + __( 'Comment Submission Failure' ), + array( + 'response' => $data, + 'back_link' => true, + ) + ); + } else { + exit; + } + } + + $user = wp_get_current_user(); + $cookies_consent = ( isset( $_POST['wp-comment-cookies-consent'] ) ); + + /** + * Perform other actions when comment cookies are set. + * + * @since 3.4.0 + * @since 4.9.6 The `$cookies_consent` parameter was added. + * + * @param WP_Comment $comment Comment object. + * @param WP_User $user Comment author's user object. The user may not exist. + * @param bool $cookies_consent Comment author's consent to store cookies. + */ + do_action( 'set_comment_cookies', $comment, $user, $cookies_consent ); } -$user = wp_get_current_user(); -$cookies_consent = ( isset( $_POST['wp-comment-cookies-consent'] ) ); - -/** - * Perform other actions when comment cookies are set. - * - * @since 3.4.0 - * @since 4.9.6 The `$cookies_consent` parameter was added. - * - * @param WP_Comment $comment Comment object. - * @param WP_User $user Comment author's user object. The user may not exist. - * @param bool $cookies_consent Comment author's consent to store cookies. - */ -do_action( 'set_comment_cookies', $comment, $user, $cookies_consent ); - $location = empty( $_POST['redirect_to'] ) ? get_comment_link( $comment ) : $_POST['redirect_to'] . '#comment-' . $comment->comment_ID; // If user didn't consent to cookies, add specific query arguments to display the awaiting moderation message. diff --git a/wp-includes/class-walker-comment.php b/wp-includes/class-walker-comment.php index 9df2d20b3b..a1bf5d48fe 100644 --- a/wp-includes/class-walker-comment.php +++ b/wp-includes/class-walker-comment.php @@ -40,6 +40,16 @@ class Walker_Comment extends Walker { 'id' => 'comment_ID', ); + /** + * Whether the comment approval notification opt-in form or message needs to be + * output automatically. + * + * @since 5.7.0 + * + * @var bool + */ + protected $needs_comment_approval_notification_output = true; + /** * Starts the list before the elements are added. * @@ -255,10 +265,13 @@ class Walker_Comment extends Walker { /** * Filters the comment text. * - * Removes links from the pending comment's text if the commenter did not consent - * to the comment cookies. + * - Removes links from the pending comment's text if the commenter did not consent + * to the comment cookies + * - Prepends the approval notification opt-in form or message to pending comments * * @since 5.4.2 + * @since 5.7.0 Comment approval notification opt-in form is now automatically + * appended if necessary. * * @param string $comment_text Text of the current comment. * @param WP_Comment|null $comment The comment object. Null if not found. @@ -272,9 +285,90 @@ class Walker_Comment extends Walker { $comment_text = wp_kses( $comment_text, array() ); } + /* + * Checks if we need to output the comment approval notification opt-in form. + */ + if ( $this->needs_comment_approval_notification_output ) { + $comment_text = $this->comment_approval_notification_form( $comment ) . "\n" . $comment_text; + } + + $this->needs_comment_approval_notification_output = true; + return $comment_text; } + /** + * Outputs the awaiting moderation text. + * + * @since 5.7.0 + * + * @param WP_Comment $comment Comment to display. + */ + protected function awaiting_moderation_text( $comment ) { + if ( '0' !== $comment->comment_approved ) { + return; + } + + $commenter = wp_get_current_commenter(); + + if ( $commenter['comment_author_email'] ) { + $moderation_note = __( 'Your comment is awaiting moderation.' ); + } else { + $moderation_note = __( 'Your comment is awaiting moderation. This is a preview, your comment will be visible after it has been approved.' ); + } + + printf( + '%s', + esc_html( $moderation_note ) + ); + } + + /** + * Gets the comment approval notification opt-in form or message for a pending comment. + * + * @since 5.7.0 + * + * @param WP_Comment $comment Comment to display. + * @return string HTML output. + */ + protected function comment_approval_notification_form( $comment ) { + $comment_approval_output = ''; + + if ( '0' === $comment->comment_approved && has_action( 'comment_unapproved_to_approved', 'wp_new_comment_notify_comment_author' ) ) { + if ( get_comment_meta( $comment->comment_ID, '_wp_comment_author_notification_optin', true ) ) { + $comment_approval_output = sprintf( + '%s
', + esc_html__( 'You will receive an email when your comment is approved.' ) + ); + } else { + $comment_approval_output = sprintf( + '', + esc_url( site_url( '/wp-comments-post.php' ) ), + esc_html__( 'I want to be notified by email when my comment is approved.' ), + absint( $comment->comment_ID ), + wp_hash( $comment->comment_date_gmt ), + esc_html_x( 'Save', 'comment approval notification form' ) + ); + } + } + + // Disable the backcompat output. + $this->needs_comment_approval_notification_output = false; + + // Return the approval notification opt-in form. + return $comment_approval_output; + } + /** * Outputs a single comment. * @@ -297,12 +391,6 @@ class Walker_Comment extends Walker { $commenter = wp_get_current_commenter(); $show_pending_links = isset( $commenter['comment_author'] ) && $commenter['comment_author']; - - if ( $commenter['comment_author_email'] ) { - $moderation_note = __( 'Your comment is awaiting moderation.' ); - } else { - $moderation_note = __( 'Your comment is awaiting moderation. This is a preview; your comment will be visible after it has been approved.' ); - } ?> < has_children ? 'parent' : '', $comment ); ?> id="comment-"> @@ -328,10 +416,14 @@ class Walker_Comment extends Walker { ); ?> - comment_approved ) : ?> - -