5

For example, I write a new post with content "Today I'm happy, because I finally met the girl that @David told me about bla blah..." Once the post is published, there should be an email notification sent to David about this post that mentions him. Is there already such plugin? If not please help me with my implementation. Thanks a million time! :)

The script needs to first parse the content of this new post. Find names after '@', then go to database to match commenter's name in order to get his/her email address (Assuming the person that I @ must have comment on my blog before)

The basic send email part is below.

function email_friend()  {

    $postTitle = get_the_title($id);
    $post_permalink = get_permalink( $id );
    $to = '[email protected]';
    $subject = 'Arch!tect mentioned you in his new post《'.$postTitle .'》';
    $from = "[email protected]";
    $headers = "From:" . $from;

    $message = "Arch!tect mentioned you in his new post《".$postTitle . 
    "》 check it out?\n\n"  ."Post link:".$post_permalink
    ."\n\n\nPlease don't reply this email.\r\n";

    mail($to, $subject, $message, $headers);
}

add_action ( 'publish post', 'email_friend' );

Done with simple part!

Now please help me with the hard part...parsing name in post and fetching email address in database.


P.S.

Thank you all for helping! I managed to finish the code and it's working fine now (tested). To mention people with name that has space in it, I'm using underscore first then change it back to space. It now send email to all people that I mention in my post and after doing that it will send a summary to myself with the result. I'll paste the complete code below please have a look and tell me what I need to improve.

function email_friend()  {

    // get post object
    $post = get_post($id);
    // get post content
    $content = $post->post_content;
    // get how many people is mentioned in this post
    //$mentionCount = preg_match_all('/(@(\w)+)/', $content, $matches);
    $mentionCount = preg_match_all('/(@[^\s]+)/', $content, $matches);//support other lang


    // if there is at least one @ with a name after it
    if (0 !== $mentionCount) {

        $friendList = array();//for storing correct names

        for ($mentionIndex=0; $mentionIndex < $mentionCount; $mentionIndex++) {

            $mentionName = $matches[0][$mentionIndex];  

            $mentionName = str_replace('_',' ',$mentionName); //change _ back to space

            $mentionName = substr($mentionName, 1); //get rid of @
            //for security and add wildcard
            $friend_display_name_like = '%' . like_escape($mentionName) . '%'; 

            global $wpdb;

            // get correct name first
            $friendCorrectName = $wpdb->get_var( $wpdb->prepare( "

                                                           SELECT comment_author
                                                           FROM $wpdb->comments
                                                           WHERE comment_author
                                                           LIKE %s ",
                                                           $friend_display_name_like
                                                           )) ;

            // get friend email by comment author name
            $friend_email = $wpdb->get_var( $wpdb->prepare( "

                                                           SELECT comment_author_email
                                                           FROM $wpdb->comments
                                                           WHERE comment_author
                                                           LIKE %s ",
                                                           $friendCorrectName
                                                           )) ;


            if($friend_email) {// if found email address then email

                $postTitle = get_the_title($id);
                $post_permalink = get_permalink( $id );
                $to =   $friend_email;
                $subject =   'Arch!tect mentioned you in his new post 《'.$postTitle . 

                '》';

                $from = "[email protected]";

                $headers = "From:" . $from;

                $message = "Arch!tect mentioned you in his new post《".$postTitle . 
                "》 check it out?\n\n"  ."Post link:".$post_permalink
                ."\n\n\nPlease don't reply this email.\r\n";

                if(mail($to, $subject, $message, $headers)) {
                    //if send successfully put his/her name in my list
                    array_push($friendList, $friendCorrectName);
                   //array_push($friendList, $friend_email);
                }


            } 



        } 
 $comma_separated = implode(",", $friendList); //friend list array to string 

        // now send an email to myself about the result
        $postTitle = get_the_title($id);
        $post_permalink = get_permalink( $id );
        $to =    '[email protected]';
        $subject =   "Your new post《".$postTitle . 
        "》has notified ".count($friendList)."friends successfully";
        $from = "[email protected]";
        $headers = "From:" . $from;
        //list all friends that received my email
        $message = "Your new post《".$postTitle . 
        "》has notified ".count($friendList)."friends successfully:\n\n".$comma_separated ;

        mail($to, $subject, $message, $headers);


    }





}//end of email_friend function


add_action ( 'publish_post', 'email_friend' );

Edit: changed (\w)+ to [^\s]+ so it supports more languages. (Chinese tested)

1 Answer 1

3

Twice edited according to kaiser's suggestions, unsecure version removed.

<?php
function my_email_friend($post_id = '') {
    // get post object
    $post = get_post($post_id);
    // get post content
    $content = $post->post_content;
    // if @David exists
    if( 0 !== preg_match('/(@\w)/', $content, $matches) )
        $friend_display_name_like = '%' . like_escape($matches[0]) . '%';
    else
        return; // do nothing if no matches
    global $wpdb;
    // get friend email by 'display_name'
    $friend_email = $wpdb->get_var( $wpdb->prepare( "
        SELECT user_email
        FROM $wpdb->users
        WHERE display_name
        LIKE %s ",
        $friend_display_name_like
    )) ;
    if($friend_email) {
        /* Your  code here, 'mail()' can use '$friend_email' */
    }
}
add_action('publish_post', 'my_email_friend');

Use it only as starting point because:

  • the code is partially tested (read: untested);
  • you can mention many friends in the post, the first mentioned will be notified (could be enhanced);
  • you can have something like [email protected] in the post content. The script will try to find 'example' user;
  • only one John from both John Doe and John Roe will be e-mailed.

Everything to be enhanced, but seems like ready to test.

3
  • 2
    Some notes: First, you should use $wpdb->prepare() as $friend_first_name could also be an attempt to hijack your database: It's no trusted value. Second, you should use the display_name. It's not more unique, but mostly used to display user names. At least it's what the user chooses to "be" on that page. Third, there should imho also be a like_escape() in use to get similar names in case of a typo. And fourth, you could simply use the WP_User_Query for this.
    – kaiser
    Mar 2, 2013 at 13:12
  • 1
    If you allow me another suggestion, don't leave the old/unsecure code in the Answer.
    – brasofilo
    Mar 2, 2013 at 18:12
  • @brasofilo,thanks a lot for all suggestions. Unfortunately I was unable to get WP_User_Query to work in this case. I know, built-in is better than regular.
    – Max Yudin
    Mar 2, 2013 at 18:53

Your Answer

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

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