Ticket #33717: 337171.14.patch
| File 337171.14.patch, 16.0 KB (added by , 6 years ago) |
|---|
-
src/wp-admin/css/dashboard.css
diff --git src/wp-admin/css/dashboard.css src/wp-admin/css/dashboard.css index 2411c79900..e76acdeaa5 100644
body #dashboard-widgets .postbox form .submit { 821 821 position: relative; 822 822 } 823 823 824 #activity-widget #the-comment-list .comment-item .attention { 825 display: none; 826 color: #d54e21; 827 font-size: 90%; 828 } 829 824 830 #activity-widget #the-comment-list .avatar { 825 831 position: absolute; 826 832 top: 12px; … … body #dashboard-widgets .postbox form .submit { 857 863 width: 4px; 858 864 } 859 865 866 #activity-widget #the-comment-list .unapproved .attention { 867 display: block; 868 } 869 860 870 #activity-widget #the-comment-list .spam-undo-inside .avatar, 861 871 #activity-widget #the-comment-list .trash-undo-inside .avatar { 862 872 position: relative; -
src/wp-admin/css/list-tables.css
diff --git src/wp-admin/css/list-tables.css src/wp-admin/css/list-tables.css index 1febe4e837..56334925a7 100644
217 217 background-color: #f5f5f5; 218 218 } 219 219 220 #the-comment-list .comment .attention { 221 display: none; 222 color: #d54e21; 223 font-size: 90%; 224 } 225 220 226 #the-comment-list .unapproved th, 221 227 #the-comment-list .unapproved td { 222 228 background-color: #fef7f1; … … 230 236 margin-left: 4px; 231 237 } 232 238 239 #the-comment-list .comment.unapproved .attention { 240 display: block; 241 } 242 233 243 #the-comment-list .approve a { 234 244 color: #006505; 235 245 } -
src/wp-admin/includes/class-wp-comments-list-table.php
diff --git src/wp-admin/includes/class-wp-comments-list-table.php src/wp-admin/includes/class-wp-comments-list-table.php index 563187ffe4..daf837aaa6 100644
class WP_Comments_List_Table extends WP_List_Table { 882 882 } 883 883 } 884 884 885 if ( 0 === (int) $comment->comment_approved && true === (bool) get_comment_meta( $comment->comment_ID, '_wp_comment_author_notification_optin', true ) ) { 886 /* translators: %s is the comment author name. */ 887 echo '<p class="attention"><span class="dashicons dashicons-info"></span> ' . sprintf( esc_html__( '%s has opted in to receive a notification on comment’s approval.' ), get_comment_author( $comment ) ) . '</p>'; 888 } 889 885 890 comment_text( $comment ); 886 891 887 892 if ( $this->user_can ) { -
src/wp-admin/includes/dashboard.php
diff --git src/wp-admin/includes/dashboard.php src/wp-admin/includes/dashboard.php index 6855aa6c96..7042972aad 100644
function _wp_dashboard_recent_comments_row( &$comment, $show_date = true ) { 827 827 } 828 828 ?> 829 829 </p> 830 831 830 <?php 831 if ( 0 === (int) $comment->comment_approved && true === (bool) get_comment_meta( $comment->comment_ID, '_wp_comment_author_notification_optin', true ) ) : 832 ?> 833 <p class="attention"> 834 <span class="dashicons dashicons-info"></span> 835 <?php 836 /* translators: %s is the comment author name. */ 837 printf( esc_html__( '%s has opted in to receive a notification on comment’s approval.' ), get_comment_author( $comment ) ); 838 ?> 839 </p> 840 <?php 841 endif; 842 832 843 else : 833 844 switch ( $comment->comment_type ) { 834 845 case 'pingback': -
src/wp-comments-post.php
diff --git src/wp-comments-post.php src/wp-comments-post.php index 06cbd460f4..3b1a8b44ca 100644
require __DIR__ . '/wp-load.php'; 22 22 23 23 nocache_headers(); 24 24 25 $comment = wp_handle_comment_submission( wp_unslash( $_POST ) ); 26 if ( is_wp_error( $comment ) ) { 27 $data = (int) $comment->get_error_data(); 28 if ( ! empty( $data ) ) { 25 if ( isset( $_POST['wp-comment-approved-notification-optin'], $_POST['comment_ID'], $_POST['moderation-hash'] ) ) { 26 $comment = get_comment( $_POST['comment_ID'] ); 27 28 if ( ! is_null( $comment->comment_ID ) && hash_equals( $_POST['moderation-hash'], wp_hash( $comment->comment_date_gmt ) ) ) { 29 update_comment_meta( $comment->comment_ID, '_wp_comment_author_notification_optin', true ); 30 } else { 29 31 wp_die( 30 '<p>' . $comment->get_error_message() . '</p>',31 __( 'Comment Submission Failure' ),32 '<p>' . __( 'Sorry we haven’t found your comment.' ) . '</p>', 33 __( 'Comment Notification opt-in failure' ), 32 34 array( 33 'response' => $data,34 35 'back_link' => true, 35 36 ) 36 37 ); 37 } else {38 exit;39 38 } 40 } 39 } else { 40 $comment = wp_handle_comment_submission( wp_unslash( $_POST ) ); 41 if ( is_wp_error( $comment ) ) { 42 $data = (int) $comment->get_error_data(); 43 if ( ! empty( $data ) ) { 44 wp_die( 45 '<p>' . $comment->get_error_message() . '</p>', 46 __( 'Comment Submission Failure' ), 47 array( 48 'response' => $data, 49 'back_link' => true, 50 ) 51 ); 52 } else { 53 exit; 54 } 55 } 41 56 42 $user = wp_get_current_user();43 $cookies_consent = ( isset( $_POST['wp-comment-cookies-consent'] ) );57 $user = wp_get_current_user(); 58 $cookies_consent = ( isset( $_POST['wp-comment-cookies-consent'] ) ); 44 59 45 /** 46 * Perform other actions when comment cookies are set. 47 * 48 * @since 3.4.0 49 * @since 4.9.6 The `$cookies_consent` parameter was added. 50 * 51 * @param WP_Comment $comment Comment object. 52 * @param WP_User $user Comment author's user object. The user may not exist. 53 * @param bool $cookies_consent Comment author's consent to store cookies. 54 */ 55 do_action( 'set_comment_cookies', $comment, $user, $cookies_consent ); 60 /** 61 * Perform other actions when comment cookies are set. 62 * 63 * @since 3.4.0 64 * @since 4.9.6 The `$cookies_consent` parameter was added. 65 * 66 * @param WP_Comment $comment Comment object. 67 * @param WP_User $user Comment author's user object. The user may not exist. 68 * @param bool $cookies_consent Comment author's consent to store cookies. 69 */ 70 do_action( 'set_comment_cookies', $comment, $user, $cookies_consent ); 71 } 56 72 57 73 $location = empty( $_POST['redirect_to'] ) ? get_comment_link( $comment ) : $_POST['redirect_to'] . '#comment-' . $comment->comment_ID; 58 74 -
src/wp-includes/class-walker-comment.php
diff --git src/wp-includes/class-walker-comment.php src/wp-includes/class-walker-comment.php index 9df2d20b3b..72f536118e 100644
class Walker_Comment extends Walker { 275 275 return $comment_text; 276 276 } 277 277 278 /** 279 * Outputs the awaiting moderation text. 280 * 281 * @since 5.7.0 282 * 283 * @param WP_Comment $comment Comment to display. 284 */ 285 protected function awaiting_moderation_text( $comment ) { 286 if ( 0 !== (int) $comment->comment_approved ) { 287 return; 288 } 289 290 $commenter = wp_get_current_commenter(); 291 if ( $commenter['comment_author_email'] ) { 292 $moderation_note = __( 'Your comment is awaiting moderation.' ); 293 } else { 294 $moderation_note = __( 'Your comment is awaiting moderation. This is a preview, your comment will be visible after it has been approved.' ); 295 } 296 297 printf( '<em class="comment-awaiting-moderation">%s</em>', esc_html( $moderation_note ) ); 298 } 299 300 /** 301 * Outputs the comment's approval notification form. 302 * 303 * @since 5.7.0 304 * 305 * @param WP_Comment $comment Comment to display. 306 */ 307 protected function comment_approval_notification_form( $comment ) { 308 if ( 0 !== (int) $comment->comment_approved || ! has_action( 'comment_unapproved_to_approved', 'wp_new_comment_notify_comment_author' ) ) { 309 return; 310 } 311 312 if ( true === (bool) get_comment_meta( $comment->comment_ID, '_wp_comment_author_notification_optin', true ) ) : 313 ?> 314 <p class="wp-comment-approved-notification-optedin"><?php esc_html_e( 'You will receive an email when your comment has been approved.' ); ?></p> 315 <?php else : ?> 316 <form action="<?php echo esc_url( site_url( '/wp-comments-post.php' ) ); ?>" method="post"> 317 <p> 318 <label for="wp-comment-approved-notification-optin"> 319 <input type="checkbox" id="wp-comment-approved-notification-optin" name="wp-comment-approved-notification-optin"> 320 <?php esc_html_e( 'I want to be notified by email when my comment is approved.' ); ?> 321 </label> 322 </p> 323 <input type="hidden" name="comment_ID" value="<?php echo absint( $comment->comment_ID ); ?>"> 324 <input type="hidden" name="moderation-hash" value="<?php echo wp_hash( $comment->comment_date_gmt ); ?>"> 325 <input type="submit" class="button" value="<?php echo esc_html_x( 'Save', 'comment approved notification form' ); ?>"> 326 </form> 327 <?php 328 endif; 329 } 330 278 331 /** 279 332 * Outputs a single comment. 280 333 * … … class Walker_Comment extends Walker { 297 350 298 351 $commenter = wp_get_current_commenter(); 299 352 $show_pending_links = isset( $commenter['comment_author'] ) && $commenter['comment_author']; 300 301 if ( $commenter['comment_author_email'] ) {302 $moderation_note = __( 'Your comment is awaiting moderation.' );303 } else {304 $moderation_note = __( 'Your comment is awaiting moderation. This is a preview; your comment will be visible after it has been approved.' );305 }306 353 ?> 307 354 <<?php echo $tag; ?> <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?> id="comment-<?php comment_ID(); ?>"> 308 355 <?php if ( 'div' !== $args['style'] ) : ?> … … class Walker_Comment extends Walker { 328 375 ); 329 376 ?> 330 377 </div> 331 <?php if ( '0' == $comment->comment_approved ) : ?> 332 <em class="comment-awaiting-moderation"><?php echo $moderation_note; ?></em> 378 <?php $this->awaiting_moderation_text( $comment ); ?> 333 379 <br /> 334 <?php endif; ?>335 380 336 381 <div class="comment-meta commentmetadata"> 337 382 <?php … … class Walker_Comment extends Walker { 362 407 ) 363 408 ) 364 409 ); 410 411 // Output the comment approval notification form if needed. 412 $this->comment_approval_notification_form( $comment ); 365 413 ?> 366 414 367 415 <?php … … class Walker_Comment extends Walker { 401 449 402 450 $commenter = wp_get_current_commenter(); 403 451 $show_pending_links = ! empty( $commenter['comment_author'] ); 404 405 if ( $commenter['comment_author_email'] ) {406 $moderation_note = __( 'Your comment is awaiting moderation.' );407 } else {408 $moderation_note = __( 'Your comment is awaiting moderation. This is a preview; your comment will be visible after it has been approved.' );409 }410 452 ?> 411 453 <<?php echo $tag; ?> id="comment-<?php comment_ID(); ?>" <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?>> 412 454 <article id="div-comment-<?php comment_ID(); ?>" class="comment-body"> … … class Walker_Comment extends Walker { 450 492 ?> 451 493 </div><!-- .comment-metadata --> 452 494 453 <?php if ( '0' == $comment->comment_approved ) : ?> 454 <em class="comment-awaiting-moderation"><?php echo $moderation_note; ?></em> 455 <?php endif; ?> 495 <?php $this->awaiting_moderation_text( $comment ); ?> 456 496 </footer><!-- .comment-meta --> 457 497 458 498 <div class="comment-content"> 459 <?php comment_text(); ?> 499 <?php 500 comment_text(); 501 502 // Output the comment approval notification form if needed. 503 $this->comment_approval_notification_form( $comment ); 504 ?> 460 505 </div><!-- .comment-content --> 461 506 462 507 <?php -
src/wp-includes/comment.php
diff --git src/wp-includes/comment.php src/wp-includes/comment.php index ac37540be0..a01e553b4a 100644
function wp_new_comment_notify_postauthor( $comment_ID ) { 2348 2348 return wp_notify_postauthor( $comment_ID ); 2349 2349 } 2350 2350 2351 /** 2352 * Notify a comment author when their comment gets approved. 2353 * 2354 * This notification is only sent once when the comment status 2355 * changes from unapproved to approved. 2356 * 2357 * @since 5.7.0 2358 * 2359 * @param int|WP_Comment $comment_id Comment ID or WP_Comment object. 2360 * @return bool Whether the email was sent successfully. 2361 */ 2362 function wp_new_comment_notify_comment_author( $comment_id ) { 2363 $comment = get_comment( $comment_id ); 2364 2365 if ( ! $comment ) { 2366 return false; 2367 } 2368 2369 $post = get_post( $comment->comment_post_ID ); 2370 $comment_author = get_user_by( 'email', $comment->comment_author_email ); 2371 2372 if ( ! $post ) { 2373 return false; 2374 } 2375 2376 // The comment was left by the post author. 2377 if ( $comment->user_id === $post->post_author || get_userdata( $post->post_author ) === $comment_author ) { 2378 return false; 2379 } 2380 2381 // Make sure the comment author can notified by email. 2382 if ( empty( $comment->comment_author_email ) ) { 2383 return false; 2384 } 2385 2386 if ( true !== (bool) get_comment_meta( $comment->comment_ID, '_wp_comment_author_notification_optin', true ) ) { 2387 return false; 2388 } 2389 2390 /** 2391 * The blogname option is escaped with esc_html when 2392 * saved into the database, we need to reverse this for 2393 * the plain text area of the email. 2394 */ 2395 $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); 2396 2397 /* translators: 1: blog name, 2: post title */ 2398 $subject = sprintf( __( '[%1$s] Your comment on "%2$s" has been approved' ), $blogname, $post->post_title ); 2399 2400 if ( ! empty( $comment->comment_author ) ) { 2401 /* translators: 1: comment author's name */ 2402 $notify_message = sprintf( __( 'Howdy %s,' ), $comment->comment_author ) . "\r\n\r\n"; 2403 } else { 2404 $notify_message = __( 'Howdy,' ) . "\r\n\r\n"; 2405 } 2406 2407 /* translators: 1: post title */ 2408 $notify_message .= sprintf( __( 'Your comment on the post "%s" has been approved.' ), $post->post_title ) . "\r\n\r\n"; 2409 /* translators: 1: comment permalink */ 2410 $notify_message .= sprintf( __( 'View comment: %s' ), get_comment_link( $comment ) ) . "\r\n"; 2411 2412 /** 2413 * Filter the comment approval notification email text. 2414 * 2415 * @since 5.7.0 2416 * 2417 * @param string $notify_message The comment notification email text. 2418 * @param WP_Comment $comment Comment object. 2419 */ 2420 $notify_message = apply_filters( 'comment_approval_notification_text', $notify_message, $comment ); 2421 2422 /** 2423 * Filter the comment approval notification email subject. 2424 * 2425 * @since 5.7.0 2426 * 2427 * @param string $subject The comment notification email subject. 2428 * @param WP_Comment $comment Comment object. 2429 */ 2430 $subject = apply_filters( 'comment_approval_notification_subject', $subject, $comment ); 2431 2432 $sent = wp_mail( $comment->comment_author_email, wp_specialchars_decode( $subject ), $notify_message ); 2433 2434 // Delete the opt-in now the notification has been sent. 2435 delete_comment_meta( $comment->comment_ID, '_wp_comment_author_notification_optin' ); 2436 2437 return $sent; 2438 } 2439 2351 2440 /** 2352 2441 * Sets the status of a comment. 2353 2442 * -
src/wp-includes/default-filters.php
diff --git src/wp-includes/default-filters.php src/wp-includes/default-filters.php index 96ef7d82eb..fd1d02a0f3 100644
add_action( 'comment_post', 'wp_new_comment_notify_postauthor' ); 458 458 add_action( 'after_password_reset', 'wp_password_change_notification' ); 459 459 add_action( 'register_new_user', 'wp_send_new_user_notifications' ); 460 460 add_action( 'edit_user_created_user', 'wp_send_new_user_notifications', 10, 2 ); 461 add_action( 'comment_unapproved_to_approved', 'wp_new_comment_notify_comment_author' ); 461 462 462 463 // REST API actions. 463 464 add_action( 'init', 'rest_api_init' ); -
tests/phpunit/tests/comment.php
diff --git tests/phpunit/tests/comment.php tests/phpunit/tests/comment.php index c3013ad2c6..2bd1fd690e 100644
class Tests_Comment extends WP_UnitTestCase { 554 554 return $notify_message; 555 555 } 556 556 557 /** 558 * @ticket 33717 559 */ 560 public function test_wp_new_comment_notify_comment_author_once_only() { 561 $c = self::factory()->comment->create( 562 array( 563 'comment_post_ID' => self::$post_id, 564 'comment_approved' => '0', 565 'comment_author_email' => 'foo@bar.mail', 566 ) 567 ); 568 569 // The user subscribed to receive an email once comment is approved. 570 update_comment_meta( $c, '_wp_comment_author_notification_optin', true ); 571 572 // For the purpose of the test we are removing this hook to directly use the function to notify the comment author. 573 remove_action( 'comment_unapproved_to_approved', 'wp_new_comment_notify_comment_author' ); 574 575 // Approve the comment. 576 wp_set_comment_status( $c, 'approve' ); 577 578 $sent = wp_new_comment_notify_comment_author( $c ); 579 $this->assertTrue( $sent ); 580 581 $resent = wp_new_comment_notify_comment_author( $c ); 582 $this->assertFalse( $resent ); 583 } 584 557 585 /** 558 586 * @ticket 12431 559 587 */
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)