Make WordPress Core

Changeset 35339


Ignore:
Timestamp:
10/21/2015 06:34:06 PM (11 years ago)
Author:
DrewAPicture
Message:

Comments: Introduce two new filters, notify_moderator and notify_post_author, both of which make it possible to selectively override site notification email settings for new comments.

The notify_moderator filter makes it possible to override the value for the moderation_notify option, which controls whether to send new comment emails to "site moderators", that is to say, the owner of the admin email for the site and the post author if they have the ability to modify the comment.

The notify_post_author filter likewise makes it possible to override the value for the comments_notify option, which controls whether to send new comment emails to the post author. If the post author is the comment author, default behavior is not to send the notification. Note: enabling or disabling notifications via this hook could also affect other recipients added via the 'comment_notification_recipients' filter in wp_notify_postauthor(), if hooked.

Passing a falsey value to either of the new filters will prevent notifications from being sent, regardless of their corresponding option values.

Adds tests.

Props coffee2code, adamsilverstein, DrewAPicture.
Fixes #761.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/comment-functions.php

    r35331 r35339  
    17591759
    17601760        // Only send notifications for pending comments.
    1761         if ( '0' != $comment->comment_approved ) {
     1761        $maybe_notify = ( '0' == $comment->comment_approved );
     1762
     1763        /** This filter is documented in wp-includes/comment-functions.php */
     1764        $maybe_notify = apply_filters( 'notify_moderator', $maybe_notify, $comment_ID );
     1765
     1766        if ( ! $maybe_notify ) {
    17621767                return false;
    17631768        }
    … …  
    17711776 * @since 4.4.0
    17721777 *
    1773  * @param int $comment_ID ID of the comment.
     1778 * Uses the {@see 'notify_post_author'} filter to determine whether the post author
     1779 * should be notified when a new comment is added, overriding site setting.
     1780 *
     1781 * @param int $comment_ID Comment ID.
    17741782 * @return bool True on success, false on failure.
    17751783 */
    … …  
    17771785        $comment = get_comment( $comment_ID );
    17781786
     1787        $maybe_notify = get_option( 'comments_notify' );
     1788
     1789        /**
     1790         * Filter whether to send the post author new comment notification emails,
     1791         * overriding the site setting.
     1792         *
     1793         * @since 4.4.0
     1794         *
     1795         * @param bool $maybe_notify Whether to notify the post author about the new comment.
     1796         * @param int  $comment_ID   The ID of the comment for the notification.
     1797         */
     1798        $maybe_notify = apply_filters( 'notify_post_author', $maybe_notify, $comment_ID );
     1799
    17791800        /*
    1780          * `wp_notify_postauthor()` checks if notifying the author of their own comment.
     1801         * wp_notify_postauthor() checks if notifying the author of their own comment.
    17811802         * By default, it won't, but filters can override this.
    17821803         */
    1783         if ( ! get_option( 'comments_notify' ) ) {
     1804        if ( ! $maybe_notify ) {
    17841805                return false;
    17851806        }
    … …  
    18011822 * @since 1.0.0
    18021823 *
    1803  * global wpdb $wpdb
     1824 * @global wpdb $wpdb WordPress database abstraction object.
    18041825 *
    18051826 * @param int|WP_Comment $comment_id     Comment ID or WP_Comment object.
  • trunk/src/wp-includes/pluggable.php

    r35170 r35339  
    15621562if ( !function_exists('wp_notify_moderator') ) :
    15631563/**
    1564  * Notifies the moderator of the blog about a new comment that is awaiting approval.
     1564 * Notifies the moderator of the site about a new comment that is awaiting approval.
    15651565 *
    15661566 * @since 1.0.0
    … …  
    15681568 * @global wpdb $wpdb WordPress database abstraction object.
    15691569 *
    1570  * @param int $comment_id Comment ID
    1571  * @return true Always returns true
     1570 * Uses the {@see 'notify_moderator'} filter to determine whether the site moderator
     1571 * should be notified, overriding the site setting.
     1572 *
     1573 * @param int $comment_id Comment ID.
     1574 * @return true Always returns true.
    15721575 */
    15731576function wp_notify_moderator($comment_id) {
    15741577        global $wpdb;
    15751578
    1576         if ( 0 == get_option( 'moderation_notify' ) )
     1579        $maybe_notify = get_option( 'moderation_notify' );
     1580
     1581        /**
     1582         * Filter whether to send the site moderator email notifications, overriding the site setting.
     1583         *
     1584         * @since 4.4.0
     1585         *
     1586         * @param bool $maybe_notify Whether to notify blog moderator.
     1587         * @param int  $comment_ID   The id of the comment for the notification.
     1588         */
     1589        $maybe_notify = apply_filters( 'notify_moderator', $maybe_notify, $comment_id );
     1590
     1591        if ( ! $maybe_notify ) {
    15771592                return true;
     1593        }
    15781594
    15791595        $comment = get_comment($comment_id);
    … …  
    21732189                                $use_random_int_functionality = false;
    21742190                        }
    2175                 } catch ( Throwable $t ) { 
     2191                } catch ( Throwable $t ) {
    21762192                        $use_random_int_functionality = false;
    21772193                } catch ( Exception $e ) {
  • trunk/tests/phpunit/tests/comment.php

    r35244 r35339  
    88        protected static $post_id;
    99
     10        public function setUp() {
     11                parent::setUp();
     12                unset( $GLOBALS['phpmailer']->mock_sent );
     13        }
     14
    1015        public static function wpSetUpBeforeClass( $factory ) {
    11                 self::$user_id = $factory->user->create();
     16                self::$user_id = $factory->user->create( array(
     17                        'role'       => 'author',
     18                        'user_login' => 'test_wp_user_get',
     19                        'user_pass'  => 'password',
     20                        'user_email' => 'test@test.com',
     21                ) );
     22
    1223                self::$post_id = $factory->post->create( array(
    1324                        'post_author' => self::$user_id
    … …  
    360371                }
    361372        }
     373
     374
     375        /**
     376         * Helper function to set up comment for 761 tests.
     377         *
     378         * @since 4.4.0
     379         * @access public
     380         */
     381        public function setup_notify_comment(){
     382                /**
     383                 * Mock some server variables.
     384                 */
     385                $_SERVER['SERVER_NAME'] = 'phpunit.wordpress.dev';
     386                $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
     387
     388                /**
     389                 * Prevent flood alert from firing.
     390                 */
     391                add_filter( 'comment_flood_filter', '__return_false' );
     392
     393                /**
     394                 * Set up a comment for testing.
     395                 */
     396                $post = $this->factory->post->create( array(
     397                        'post_author' => self::$user_id,
     398                ) );
     399
     400                $comment = $this->factory->comment->create( array(
     401                        'comment_post_ID' => $post,
     402                ) );
     403
     404                return array(
     405                        'post'    => $post,
     406                        'comment' => $comment,
     407                );
     408        }
     409
     410        /**
     411         * @ticket 761
     412         */
     413        public function test_wp_notify_moderator_filter_moderation_notify_option_true_filter_false() {
     414                $comment_data = $this->setup_notify_comment();
     415
     416                /**
     417                 * Test with moderator notification setting on, filter set to off.
     418                 * Should not send a notification.
     419                 */
     420                update_option( 'moderation_notify', 1 );
     421                add_filter( 'notify_moderator', '__return_false' );
     422
     423                $notification_sent = $this->try_sending_moderator_notification( $comment_data['comment'], $comment_data['post'] );
     424
     425                $this->assertFalse( $notification_sent, 'Moderator notification setting on, filter set to off' );
     426
     427                remove_filter( 'notify_moderator', '__return_false' );
     428
     429        }
     430
     431        /**
     432         * @ticket 761
     433         */
     434        public function test_wp_notify_moderator_filter_moderation_notify_option_false_filter_true() {
     435                $comment_data = $this->setup_notify_comment();
     436
     437                /**
     438                 * Test with moderator notification setting off, filter set to on.
     439                 * Should send a notification.
     440                 */
     441                update_option( 'moderation_notify', 0 );
     442                add_filter( 'notify_moderator', '__return_true' );
     443
     444                $notification_sent = $this->try_sending_moderator_notification( $comment_data['comment'], $comment_data['post'] );
     445
     446                $this->assertTrue( $notification_sent, 'Moderator notification setting off, filter set to on' );
     447
     448                remove_filter( 'notify_moderator', '__return_true' );
     449        }
     450
     451        /**
     452         * @ticket 761
     453         */
     454        public function test_wp_notify_post_author_filter_comments_notify_option_true_filter_false() {
     455
     456                $comment_data = $this->setup_notify_comment();
     457
     458                /**
     459                 * Test with author notification setting on, filter set to off.
     460                 * Should not send a notification.
     461                 */
     462                update_option( 'comments_notify', 1 );
     463                add_filter( 'notify_post_author', '__return_false' );
     464
     465                $notification_sent = $this->try_sending_author_notification( $comment_data['comment'], $comment_data['post'] );
     466
     467                $this->assertFalse( $notification_sent, 'Test with author notification setting on, filter set to off' );
     468
     469                remove_filter( 'notify_post_author', '__return_false' );
     470        }
     471
     472        /**
     473         * @ticket 761
     474         */
     475        public function test_wp_notify_post_author_filter_comments_notify_option_false_filter_true() {
     476                $comment_data = $this->setup_notify_comment();
     477
     478                /**
     479                 * Test with author notification setting off, filter set to on.
     480                 * Should send a notification.
     481                 */
     482                update_option( 'comments_notify', 0 );
     483                add_filter( 'notify_post_author', '__return_true' );
     484
     485                $notification_sent = $this->try_sending_author_notification( $comment_data['comment'], $comment_data['post'] );
     486
     487                $this->assertTrue( $notification_sent, 'Test with author notification setting off, filter set to on' );
     488
     489                remove_filter( 'notify_post_author', '__return_true' );
     490        }
     491
     492        /**
     493         * Helper function to test moderator notifications.
     494         *
     495         * @since 4.4.0
     496         * @access public
     497         */
     498        public function try_sending_moderator_notification( $comment, $post ) {
     499
     500                // Don't approve comments, triggering notifications.
     501                add_filter( 'pre_comment_approved', '__return_false' );
     502
     503                // Moderators are notified when a new comment is added.
     504                $data = array(
     505                        'comment_post_ID'      => $post,
     506                        'comment_author'       => rand_str(),
     507                        'comment_author_url'   => '',
     508                        'comment_author_email' => '',
     509                        'comment_type'         => '',
     510                        'comment_content'      => rand_str(),
     511                );
     512                wp_new_comment( $data );
     513
     514                // Check to see if a notification email was sent to the moderator `admin@example.org`.
     515                if ( isset( $GLOBALS['phpmailer']->mock_sent )
     516                        && ! empty( $GLOBALS['phpmailer']->mock_sent )
     517                        && 'admin@example.org' == $GLOBALS['phpmailer']->mock_sent[0]['to'][0][0]
     518                ) {
     519                        $email_sent_when_comment_added = true;
     520                        unset( $GLOBALS['phpmailer']->mock_sent );
     521                } else {
     522                        $email_sent_when_comment_added = false;
     523                }
     524
     525                return $email_sent_when_comment_added;
     526        }
     527
     528        /**
     529         * Helper function to test sending author notifications.
     530         *
     531         * @since 4.4.0
     532         * @access public
     533         */
     534        public function try_sending_author_notification( $comment, $post ) {
     535
     536                // Approve comments, triggering notifications.
     537                add_filter( 'pre_comment_approved', '__return_true' );
     538
     539                // Post authors possibly notified when a comment is approved on their post.
     540                wp_set_comment_status( $comment, 'approve' );
     541
     542                // Check to see if a notification email was sent to the post author `test@test.com`.
     543                if ( isset( $GLOBALS['phpmailer']->mock_sent )
     544                        && ! empty( $GLOBALS['phpmailer']->mock_sent )
     545                        && 'test@test.com' == $GLOBALS['phpmailer']->mock_sent[0]['to'][0][0]
     546                ) {
     547                        $email_sent_when_comment_approved = true;
     548                } else {
     549                        $email_sent_when_comment_approved = false;
     550                }
     551                unset( $GLOBALS['phpmailer']->mock_sent );
     552
     553                // Post authors are notified when a new comment is added to their post.
     554                $data = array(
     555                        'comment_post_ID'      => $post,
     556                        'comment_author'       => rand_str(),
     557                        'comment_author_url'   => '',
     558                        'comment_author_email' => '',
     559                        'comment_type'         => '',
     560                        'comment_content'      => rand_str(),
     561                );
     562                wp_new_comment( $data );
     563
     564                // Check to see if a notification email was sent to the post author `test@test.com`.
     565                if ( isset( $GLOBALS['phpmailer']->mock_sent ) &&
     566                     ! empty( $GLOBALS['phpmailer']->mock_sent ) &&
     567                     'test@test.com' == $GLOBALS['phpmailer']->mock_sent[0]['to'][0][0] ) {
     568                        $email_sent_when_comment_added = true;
     569                        unset( $GLOBALS['phpmailer']->mock_sent );
     570                } else {
     571                        $email_sent_when_comment_added = false;
     572                }
     573
     574                return $email_sent_when_comment_approved || $email_sent_when_comment_added;
     575        }
    362576}
Note: See TracChangeset for help on using the changeset viewer.