0

I would like to add a button for each user in the user page in wordpress admin area that will send an email to that specific user when clicked.

The code adds the action link "Send Verification Email" to each user in the table. But for some reason, the email is only sent to the user on the first row. It is not sent to the other users when I click the "Send Verification Email" on their row.

The strange thing though is that when I use this code on my development site, the email is sent to every user there. I only have about 6 users registered on the development site while my main site has over 200 users. I am not sure the number of registered users is causing the problem since the email is sent to a specific user when the button is clicked on that user's row.

What am I doing wrong that is causing the issue. Any ideas?

P.S. I am not a coder, I saw this code online and only tried to modify it to my requirements. I will appreciate it if you can provide me with a working solution and not just a comment.

// Adds "Send verification email" action to Users page
function send_verification_email_link($actions, $user_object) {
    if( ($_GET['action'] == 'send_verification_email') && ($_GET['user'] == $user_object->user_email) ) {

    $my_logo = "<img src='https://example.com/' alt='logo' />";
    $sendto = $_GET['user'];
    $subject = 'Your Example Account is not yet verified';
    $headers = array('Content-Type: text/html; charset=UTF-8');

        $message = '<p style="text-align: center;">'.$my_logo.'</p>

        <div style="max-width: 600px; margin: 30px auto; padding: 15px; font-family: Roboto,Open Sans,Helvetica,Arial; border: 1px solid #e8e8e8; line-height: 1.6; text-align: center; background-color: white;">

        <div style="text-align: left;">
        <p>Hi '.$user_object->first_name.',</p>

        <p>Thank you for registering your business on Example.com. Your account is not yet verified because you have not provided the verification information or the information you provided is invalid. Please provide the necessary information below to get verified:</p>

        <p><strong>Private person:</strong></p>
        <ul>
        <li>Upload a profile photo.</li>
        <li>Upload an identification document.</li>
        </ul>

        <p><strong>Company:</strong></p>
        <ul>
        <li>Upload a profile photo.</li>
        <li>Upload an identification document.</li>
        <li>Provide your registered company name.</li>
        <li>Provide your company registration number.</li>
        </ul>

        <a style="text-align: center;" href="https://example.com/login/" rel="noopener noreferrer" target="_blank">Click here to login to your account.</a>

        <p>When you are logged in, click the settings icon on your profile page and click edit profile. Scroll to the verification section to provide the verification information.</p>

        <p>Please let us know if you have any questions.</p>

        <p>Kind regards,<br>Example Team</p>

        </div>        
        </div>

    wp_mail($sendto, $subject, $message, $headers);
    echo '<div class="updated notice"><p>Success! The verification email has been sent to ' . $_GET['user'] . '.</p></div>';
          }

    $actions['send_rejection'] = "<a class='send_verification_email' href='" . admin_url( "users.php?action=send_verification_email&amp;user=" . $user_object->user_email ) . "'>" . __( 'Send Verification Email' ) . "</a>";
    return $actions;
}
add_filter('user_row_actions', 'send_verification_email_link', 10, 2);

1 Answer 1

1

There's a flaw in your approach.

The filter hook you are using - user_row_actions - is for adding a "hover link" to the user row. It is run on each user row in the Users > All Users screen. That part by itself would be OK if what you were doing with the filter was just adding the link; but you're using the filter to also process your action of sending an email.

The filter is run 20 times on a page load of Users > All Users (the default number of users shown in a table view), so when you do it this way, you end up sending 20 emails (or the number of users in the view).

So here's a rule of thumb - filters are for changing the way something displays. Actions are for running some type of process. So use the filter to add the link, and an action to process the result if the link is clicked.

Continue using the user_row_actions filter to add your link. I'd suggest using an action hook like admin_notices to check if your link was submitted and then process it, since you need to use that hook to display a "success" message anyway. That way you can combine those two processes. That way, your processing of the clicked link will only be run once instead of 20 times.

Here's your original code modified as I described above. I've included comments to clarify what it's doing and why.

// Adds "Send verification email" action to Users page
add_filter('user_row_actions', 'send_verification_email_link', 10, 2);
function send_verification_email_link($actions, $user_object) {
    $actions['send_rejection'] = "<a class='send_verification_email' href='" . admin_url( "users.php?action=send_verification_email&amp;user_id=" . $user_object->ID ) . "'>" . __( 'Send Verification Email' ) . "</a>";
    return $actions;
}


add_action( 'admin_notices', 'send_verification_email' );
function send_verification_email() {

    // Get the current screen so you only move forward if this is the users.php screen.
    $screen = get_current_screen();
    if ( 'users' == $screen->id ) {

        // Make sure to check if the $_GET value is actually set before you compare the value, 
        // otherwise you may get errors if the page is loaded without it.
        if ( isset( $_GET['action'] ) && 'send_verification_email' == $_GET['action'] ) {

            // Check that the email was passed too.
            $user_id = ( isset( $_GET['user_id'] ) ) ? $_GET['user_id'] : false;

            // Get the user info object info using the user ID (you'll need 
            // this for the email address and other data like "first_name" you use in the email message.
            $user_object = get_user_by( 'ID', $user_id );

            // If you have a user with an email address.
            if ( $user_object->user_email ) {

                $my_logo = "<img src='https://example.com/' alt='logo' />";

                $subject = 'Your Example Account is not yet verified';
                $headers = array('Content-Type: text/html; charset=UTF-8');

                $message = '<p style="text-align: center;">'.$my_logo.'</p>

                    <div style="max-width: 600px; margin: 30px auto; padding: 15px; font-family: Roboto,Open Sans,Helvetica,Arial; border: 1px solid #e8e8e8; line-height: 1.6; text-align: center; background-color: white;">

                    <div style="text-align: left;">
                    <p>Hi '.$user_object->first_name.',</p>

                    <p>Thank you for registering your business on Example.com. Your account is not yet verified because you have not provided the verification information or the information you provided is invalid. Please provide the necessary information below to get verified:</p>

                    <p><strong>Private person:</strong></p>
                    <ul>
                    <li>Upload a profile photo.</li>
                    <li>Upload an identification document.</li>
                    </ul>

                    <p><strong>Company:</strong></p>
                    <ul>
                    <li>Upload a profile photo.</li>
                    <li>Upload an identification document.</li>
                    <li>Provide your registered company name.</li>
                    <li>Provide your company registration number.</li>
                    </ul>

                    <a style="text-align: center;" href="https://example.com/login/" rel="noopener noreferrer" target="_blank">Click here to login to your account.</a>

                    <p>When you are logged in, click the settings icon on your profile page and click edit profile. Scroll to the verification section to provide the verification information.</p>

                    <p>Please let us know if you have any questions.</p>

                    <p>Kind regards,<br>Example Team</p>

                    </div>        
                    </div>';

                // Send message.
                wp_mail( $user_object->user_email, $subject, $message, $headers );

                // Set up admin notice
                $class = 'updated notice'; 
                $admin_notice = 'Success! The verification email has been sent to ' . $user_object->user_email;

            } else {

                // Set up admin notice for error state.
                $class = 'notice notice-error';
                $admin_notice = "No email address was passed so no email was sent.";
            }

            // Display message.
            printf( '<div class="%s"><p>%s</p></div>', $class, $admin_notice );
        }
    }
}
3
  • Thank you very much for the detailed answer. Your code works and I learnt a lot from your answer. Best regards. Sadiq
    – Sadiq11111
    Commented Apr 18, 2019 at 9:39
  • I'm glad to hear that helped and worked out for you.
    – butlerblog
    Commented Apr 18, 2019 at 12:03
  • For anyone hitting 'this page has expired' when firing their admin notice action, I found this post on nonces and also this in the codex aided my solution. Commented Feb 21, 2020 at 11:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.