Search code examples
phpwordpresswordpress-gutenberg

Sending Email Notifications To Admin When New Posts/Pages Are Pending


We have a script to notify admins by email when a new page or post is created by a contributor and is therefore 'pending' but the notifications are duplicating. The pages/posts are using gutenberg editor which I think is whats causing this (see here: https://github.com/WordPress/gutenberg/issues/15094) but I dont know what the solution is.

add_action( 'transition_post_status', 'pending_submission_notifications_send_email', 10, 3 );
function pending_submission_notifications_send_email( $new_status, $old_status, $post ) {
    // Notify Admin that Contributor has written a post.
    if ( 'pending' === $new_status && user_can( $post->post_author, 'edit_posts' ) && ! user_can( $post->post_author, 'publish_posts' ) ) {
        $pending_submission_email = 'example@email.com';
        $admins                   = ( empty( $pending_submission_email ) ) ? get_option( 'admin_email' ) : $pending_submission_email;
        $edit_link                = get_edit_post_link( $post->ID, '' );
        $preview_link             = get_permalink( $post->ID ) . '&preview=true';
        $username                 = get_userdata( $post->post_author );
        $username_last_edit       = get_the_modified_author();
        $subject                  = __( 'New post or page pending review', 'pending-submission-notifications' ) . ': "' . $post->post_title . '"';
        $message                  = __( 'A new post or page is pending review.', 'pending-submission-notifications' );
        $message                 .= "\r\n\r\n";
        $message                 .= __( 'Author', 'pending-submission-notifications' ) . ': ' . $username->user_login . "\r\n";
        $message                 .= __( 'Title', 'pending-submission-notifications' ) . ': ' . $post->post_title . "\r\n";
        $message                 .= "\r\n\r\n";
        $message                 .= __( 'Edit the submission', 'pending-submission-notifications' ) . ': ' . $edit_link . "\r\n";
        $message                 .= __( 'Preview the submission', 'pending-submission-notifications' ) . ': ' . $preview_link;
        $result                   = wp_mail( $admins, $subject, $message );
    } // Notify Contributor that Admin has published their post.
    elseif ( 'pending' === $old_status && 'publish' === $new_status && user_can( $post->post_author, 'edit_posts' ) && ! user_can( $post->post_author, 'publish_posts' ) ) {
        $username = get_userdata( $post->post_author );
        $url      = get_permalink( $post->ID );
        $subject  = __( 'Your submission is now live! ', 'pending-submission-notifications' );
        $message  = '"' . $post->post_title . '" ' . __( 'was just published ', 'pending-submission-notifications' ) . "! \r\n\r\n";
        $message .= $url;
        $result   = wp_mail( $username->user_email, $subject, $message );
    }
}

Solution

  • You're correct, it does seem to be directly linked to the Gutenberg issue you linked to. (The reason why was answered in that thread here https://github.com/WordPress/gutenberg/issues/15094#issuecomment-558986406).

    Essentially, if you use a plugin that adds custom meta data to a Gutenberg enabled post, the hook is fired twice for backwards compatibility to ensure that plugins that can't use the Gutenberg REST calls can still save their data.

    To get your case working, you'll have to add a conditional check to your script to make sure you're running it on the correct pass (ie the non Rest call)

    add_action( 'transition_post_status', 'pending_submission_notifications_send_email', 10, 3 );
    function pending_submission_notifications_send_email( $new_status, $old_status, $post ) {
    
        // If this is running in the Gutenberg REST call, ignore it
        if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { return false; }
    
        // Notify Admin that Contributor has written a post.
        if ( 'pending' === $new_status && user_can( $post->post_author, 'edit_posts' ) && ! user_can( $post->post_author, 'publish_posts' ) ) {
            $pending_submission_email = 'example@email.com';
            $admins                   = ( empty( $pending_submission_email ) ) ? get_option( 'admin_email' ) : $pending_submission_email;
            $edit_link                = get_edit_post_link( $post->ID, '' );
            $preview_link             = get_permalink( $post->ID ) . '&preview=true';
            $username                 = get_userdata( $post->post_author );
            $username_last_edit       = get_the_modified_author();
            $subject                  = __( 'New post or page pending review', 'pending-submission-notifications' ) . ': "' . $post->post_title . '"';
            $message                  = __( 'A new post or page is pending review.', 'pending-submission-notifications' );
            $message                 .= "\r\n\r\n";
            $message                 .= __( 'Author', 'pending-submission-notifications' ) . ': ' . $username->user_login . "\r\n";
            $message                 .= __( 'Title', 'pending-submission-notifications' ) . ': ' . $post->post_title . "\r\n";
            $message                 .= "\r\n\r\n";
            $message                 .= __( 'Edit the submission', 'pending-submission-notifications' ) . ': ' . $edit_link . "\r\n";
            $message                 .= __( 'Preview the submission', 'pending-submission-notifications' ) . ': ' . $preview_link;
            $result                   = wp_mail( $admins, $subject, $message );
        } // Notify Contributor that Admin has published their post.
        elseif ( 'pending' === $old_status && 'publish' === $new_status && user_can( $post->post_author, 'edit_posts' ) && ! user_can( $post->post_author, 'publish_posts' ) ) {
            $username = get_userdata( $post->post_author );
            $url      = get_permalink( $post->ID );
            $subject  = __( 'Your submission is now live! ', 'pending-submission-notifications' );
            $message  = '"' . $post->post_title . '" ' . __( 'was just published ', 'pending-submission-notifications' ) . "! \r\n\r\n";
            $message .= $url;
            $result   = wp_mail( $username->user_email, $subject, $message );
        }
    }
    

    Bear in mind this is untested, but according to the issue report linked above, this should ignore the first pass through the Gutenberg editor and only pass in the version with the correct post data.