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.


git-svn-id: https://develop.svn.wordpress.org/trunk@35339 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Drew Jaynes 2015-10-21 18:34:06 +00:00
parent ac3edc61fd
commit 1a7298861b
3 changed files with 262 additions and 11 deletions

View File

@ -1758,7 +1758,12 @@ function wp_new_comment_notify_moderator( $comment_ID ) {
$comment = get_comment( $comment_ID );
// Only send notifications for pending comments.
if ( '0' != $comment->comment_approved ) {
$maybe_notify = ( '0' == $comment->comment_approved );
/** This filter is documented in wp-includes/comment-functions.php */
$maybe_notify = apply_filters( 'notify_moderator', $maybe_notify, $comment_ID );
if ( ! $maybe_notify ) {
return false;
}
@ -1770,17 +1775,33 @@ function wp_new_comment_notify_moderator( $comment_ID ) {
*
* @since 4.4.0
*
* @param int $comment_ID ID of the comment.
* Uses the {@see 'notify_post_author'} filter to determine whether the post author
* should be notified when a new comment is added, overriding site setting.
*
* @param int $comment_ID Comment ID.
* @return bool True on success, false on failure.
*/
function wp_new_comment_notify_postauthor( $comment_ID ) {
$comment = get_comment( $comment_ID );
$maybe_notify = get_option( 'comments_notify' );
/**
* Filter whether to send the post author new comment notification emails,
* overriding the site setting.
*
* @since 4.4.0
*
* @param bool $maybe_notify Whether to notify the post author about the new comment.
* @param int $comment_ID The ID of the comment for the notification.
*/
$maybe_notify = apply_filters( 'notify_post_author', $maybe_notify, $comment_ID );
/*
* `wp_notify_postauthor()` checks if notifying the author of their own comment.
* wp_notify_postauthor() checks if notifying the author of their own comment.
* By default, it won't, but filters can override this.
*/
if ( ! get_option( 'comments_notify' ) ) {
if ( ! $maybe_notify ) {
return false;
}
@ -1800,7 +1821,7 @@ function wp_new_comment_notify_postauthor( $comment_ID ) {
*
* @since 1.0.0
*
* global wpdb $wpdb
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param int|WP_Comment $comment_id Comment ID or WP_Comment object.
* @param string $comment_status New comment status, either 'hold', 'approve', 'spam', or 'trash'.

View File

@ -1561,20 +1561,36 @@ endif;
if ( !function_exists('wp_notify_moderator') ) :
/**
* Notifies the moderator of the blog about a new comment that is awaiting approval.
* Notifies the moderator of the site about a new comment that is awaiting approval.
*
* @since 1.0.0
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param int $comment_id Comment ID
* @return true Always returns true
* Uses the {@see 'notify_moderator'} filter to determine whether the site moderator
* should be notified, overriding the site setting.
*
* @param int $comment_id Comment ID.
* @return true Always returns true.
*/
function wp_notify_moderator($comment_id) {
global $wpdb;
if ( 0 == get_option( 'moderation_notify' ) )
$maybe_notify = get_option( 'moderation_notify' );
/**
* Filter whether to send the site moderator email notifications, overriding the site setting.
*
* @since 4.4.0
*
* @param bool $maybe_notify Whether to notify blog moderator.
* @param int $comment_ID The id of the comment for the notification.
*/
$maybe_notify = apply_filters( 'notify_moderator', $maybe_notify, $comment_id );
if ( ! $maybe_notify ) {
return true;
}
$comment = get_comment($comment_id);
$post = get_post($comment->comment_post_ID);
@ -2172,7 +2188,7 @@ function wp_rand( $min = 0, $max = 0 ) {
} else {
$use_random_int_functionality = false;
}
} catch ( Throwable $t ) {
} catch ( Throwable $t ) {
$use_random_int_functionality = false;
} catch ( Exception $e ) {
$use_random_int_functionality = false;

View File

@ -7,8 +7,19 @@ class Tests_Comment extends WP_UnitTestCase {
protected static $user_id;
protected static $post_id;
public function setUp() {
parent::setUp();
unset( $GLOBALS['phpmailer']->mock_sent );
}
public static function wpSetUpBeforeClass( $factory ) {
self::$user_id = $factory->user->create();
self::$user_id = $factory->user->create( array(
'role' => 'author',
'user_login' => 'test_wp_user_get',
'user_pass' => 'password',
'user_email' => 'test@test.com',
) );
self::$post_id = $factory->post->create( array(
'post_author' => self::$user_id
) );
@ -359,4 +370,207 @@ class Tests_Comment extends WP_UnitTestCase {
$this->assertSame( $post->$pf, $comment->$pf, $pf );
}
}
/**
* Helper function to set up comment for 761 tests.
*
* @since 4.4.0
* @access public
*/
public function setup_notify_comment(){
/**
* Mock some server variables.
*/
$_SERVER['SERVER_NAME'] = 'phpunit.wordpress.dev';
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
/**
* Prevent flood alert from firing.
*/
add_filter( 'comment_flood_filter', '__return_false' );
/**
* Set up a comment for testing.
*/
$post = $this->factory->post->create( array(
'post_author' => self::$user_id,
) );
$comment = $this->factory->comment->create( array(
'comment_post_ID' => $post,
) );
return array(
'post' => $post,
'comment' => $comment,
);
}
/**
* @ticket 761
*/
public function test_wp_notify_moderator_filter_moderation_notify_option_true_filter_false() {
$comment_data = $this->setup_notify_comment();
/**
* Test with moderator notification setting on, filter set to off.
* Should not send a notification.
*/
update_option( 'moderation_notify', 1 );
add_filter( 'notify_moderator', '__return_false' );
$notification_sent = $this->try_sending_moderator_notification( $comment_data['comment'], $comment_data['post'] );
$this->assertFalse( $notification_sent, 'Moderator notification setting on, filter set to off' );
remove_filter( 'notify_moderator', '__return_false' );
}
/**
* @ticket 761
*/
public function test_wp_notify_moderator_filter_moderation_notify_option_false_filter_true() {
$comment_data = $this->setup_notify_comment();
/**
* Test with moderator notification setting off, filter set to on.
* Should send a notification.
*/
update_option( 'moderation_notify', 0 );
add_filter( 'notify_moderator', '__return_true' );
$notification_sent = $this->try_sending_moderator_notification( $comment_data['comment'], $comment_data['post'] );
$this->assertTrue( $notification_sent, 'Moderator notification setting off, filter set to on' );
remove_filter( 'notify_moderator', '__return_true' );
}
/**
* @ticket 761
*/
public function test_wp_notify_post_author_filter_comments_notify_option_true_filter_false() {
$comment_data = $this->setup_notify_comment();
/**
* Test with author notification setting on, filter set to off.
* Should not send a notification.
*/
update_option( 'comments_notify', 1 );
add_filter( 'notify_post_author', '__return_false' );
$notification_sent = $this->try_sending_author_notification( $comment_data['comment'], $comment_data['post'] );
$this->assertFalse( $notification_sent, 'Test with author notification setting on, filter set to off' );
remove_filter( 'notify_post_author', '__return_false' );
}
/**
* @ticket 761
*/
public function test_wp_notify_post_author_filter_comments_notify_option_false_filter_true() {
$comment_data = $this->setup_notify_comment();
/**
* Test with author notification setting off, filter set to on.
* Should send a notification.
*/
update_option( 'comments_notify', 0 );
add_filter( 'notify_post_author', '__return_true' );
$notification_sent = $this->try_sending_author_notification( $comment_data['comment'], $comment_data['post'] );
$this->assertTrue( $notification_sent, 'Test with author notification setting off, filter set to on' );
remove_filter( 'notify_post_author', '__return_true' );
}
/**
* Helper function to test moderator notifications.
*
* @since 4.4.0
* @access public
*/
public function try_sending_moderator_notification( $comment, $post ) {
// Don't approve comments, triggering notifications.
add_filter( 'pre_comment_approved', '__return_false' );
// Moderators are notified when a new comment is added.
$data = array(
'comment_post_ID' => $post,
'comment_author' => rand_str(),
'comment_author_url' => '',
'comment_author_email' => '',
'comment_type' => '',
'comment_content' => rand_str(),
);
wp_new_comment( $data );
// Check to see if a notification email was sent to the moderator `admin@example.org`.
if ( isset( $GLOBALS['phpmailer']->mock_sent )
&& ! empty( $GLOBALS['phpmailer']->mock_sent )
&& 'admin@example.org' == $GLOBALS['phpmailer']->mock_sent[0]['to'][0][0]
) {
$email_sent_when_comment_added = true;
unset( $GLOBALS['phpmailer']->mock_sent );
} else {
$email_sent_when_comment_added = false;
}
return $email_sent_when_comment_added;
}
/**
* Helper function to test sending author notifications.
*
* @since 4.4.0
* @access public
*/
public function try_sending_author_notification( $comment, $post ) {
// Approve comments, triggering notifications.
add_filter( 'pre_comment_approved', '__return_true' );
// Post authors possibly notified when a comment is approved on their post.
wp_set_comment_status( $comment, 'approve' );
// Check to see if a notification email was sent to the post author `test@test.com`.
if ( isset( $GLOBALS['phpmailer']->mock_sent )
&& ! empty( $GLOBALS['phpmailer']->mock_sent )
&& 'test@test.com' == $GLOBALS['phpmailer']->mock_sent[0]['to'][0][0]
) {
$email_sent_when_comment_approved = true;
} else {
$email_sent_when_comment_approved = false;
}
unset( $GLOBALS['phpmailer']->mock_sent );
// Post authors are notified when a new comment is added to their post.
$data = array(
'comment_post_ID' => $post,
'comment_author' => rand_str(),
'comment_author_url' => '',
'comment_author_email' => '',
'comment_type' => '',
'comment_content' => rand_str(),
);
wp_new_comment( $data );
// Check to see if a notification email was sent to the post author `test@test.com`.
if ( isset( $GLOBALS['phpmailer']->mock_sent ) &&
! empty( $GLOBALS['phpmailer']->mock_sent ) &&
'test@test.com' == $GLOBALS['phpmailer']->mock_sent[0]['to'][0][0] ) {
$email_sent_when_comment_added = true;
unset( $GLOBALS['phpmailer']->mock_sent );
} else {
$email_sent_when_comment_added = false;
}
return $email_sent_when_comment_approved || $email_sent_when_comment_added;
}
}