乌徒帮技术范儿WordPressWordPress开发 › 为wordpress添加回复时邮件通知功能剖析

为wordpress添加回复时邮件通知功能剖析

分类:WordPress开发

网上有很多关于给wordpress的评论添加在回复时用邮件通知被回复者的文章,而且都实现的无插件化,只需要不多的代码即可。乌徒帮之前也有一篇文章,不仅提供了代码,而且还提供了不能发送邮件的解决办法,你可以看这里温故知新。

而本文将带你较为详细的来剖析这一功能的实现。

一、了解wordpress发送邮件函数wp_mail

wp_mail函数是wordpress内置的邮件发送函数,基于php的mail()函数,因此需要你的主机有邮件发送功能,如果不支持mail函数,也可以使用wp-mail-smtp插件基本解决。

wp_mail函数用法

<?php?wp_mail(?$to,?$subject,?$message,?$headers,?$attachments?);??>

有五个参数,第一个是向哪个邮箱发送邮件,第二个是发送的邮件的标题,第三个是发送的内容。第四个是作为网页发送的邮件的网页头部信息,第五个是附件。例子如下

<?php
$attachments = array(WP_CONTENT_DIR . '/uploads/file_to_attach.zip');
$headers = 'From: My Name <myname@mydomain.com>' . "\r\n";
wp_mail('test@test.com', 'subject', 'message', $headers, $attachments);
?>
<?php
add_filter('wp_mail_content_type',create_function('', 'return "text/html";'));
wp_mail('me@example.net', 'The subject', '<p>The <em>HTML</em> message</p>');
?>

用法也很简单。更多的邮件发送功能,请参考php邮件发送函数。

二、判断在什么情况下发送邮件

在了解了我们可以用wordpress的wp_mail函数来向评论回复者发送邮件的之后,我们要判断在什么情况下发送这些邮件。

当一个新的用户对之前已经有的评论进行回复时,我们利用当前的回复动作进行邮件发送,我们先通过下面的一些判断,确定确实是要发送邮件,然后获取被回复那条评论的作者信息,向他的邮箱发送一条邮件信息。

1、管理员是否要接收邮件,管理员最好不要接收邮件,否则烦死你

$admin_notify = '0';//1为接收,0为不接收
$admin_email = get_bloginfo ('admin_email');//获取管理员的邮箱地址
$comment = get_comment($comment_id);
$comment_author_email = trim($comment->comment_author_email);//获取当前评论者的邮件地址
if($comment_author_email == $admin_email && $admin_notify == '1')//如果当前评论者是管理员,而且你愿意接收邮件,那么我们做一个记号,以让你可以接收到邮件,这将在文章最后的全部代码中给出

2、判断这条评论是否有parent值,如果这条评论是回复上面的某条评论的话,应该是有该值的,这时才进行邮件发送

$parent_id = $comment->comment_parent ? $comment->comment_parent : '';//获取当前回复的是哪条评论(ID值)
if($parent_id != '')//只有当这是在回复一条评论时才发送邮件

3、如果评论是垃圾评论,当然不要发送邮件

$spam_confirmed = $comment->comment_approved;//获取当前评论的状态,如果这条评论还是未被审核的评论,那么也不发送邮件;你需要注意的是,如果是一个新的访客,你在后台设置了,那么这条评论是需要审核的,评论没有被公布,被评论者自然收不到邮件
if($spam_confirmed != 'spam')//只有评论被公开了,才发送邮件

4、如果被回复的评论作者不勾选被评论时接收邮件,那么是不发送邮件的

(这里我们需要在comments表中增加一个字段,来记录之前的评论作者是否愿意接受邮件提示,而如果你希望所有用户都接受邮件,那么可以去除这一功能,并不给用户选择的余地。)

if($wpdb->query("Describe {$wpdb->comments} mail_to_comment") == '')$wpdb->query("ALTER TABLE {$wpdb->comments} ADD COLUMN mail_to_comment TINYINT NOT NULL DEFAULT 0;");// 在comments表中增加一个字段,用以保存是否已经发送了邮件的状态
if($comment_author_email != $admin_email && isset($_POST['mail_to_comment']))$wpdb->query("UPDATE {$wpdb->comments} SET mail_to_comment='1' WHERE comment_ID='$comment_id'");//如果接收到提交的内容用存在用户勾选了允许邮件提示的check框,那么将会把刚才增加的那个字段值设置为1,用在下面判断这条评论是否允许其他用户评论时邮件通知
$notify = $parent_id ? get_comment($parent_id)->mail_to_comment : '0';//判断评论是否能邮件通知的,由上一条得到
if($notify == '1')//只有当评论者允许接受邮件时才进行邮件发送

通过上面的判断,我们接下来可以发送邮件了。

三、发送邮件的内容

在发出的邮件中,你最好需要写一些不错的语句,尽量让用户能够返回你的网站进行新的互动。

$wp_email = 'no-reply@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME']));
$to = trim(get_comment($parent_id)->comment_author_email);
$subject = '您在 [' . get_option("blogname") . '] 的评论有了回复';
$message = '
    <div style="background-color:#eef2fa; border:1px solid #d8e3e8; color:#111; padding:0 15px; -moz-border-radius:5px; -webkit-border-radius:5px; -khtml-border-radius:5px; border-radius:5px;">
    <p>' . trim(get_comment($parent_id)->comment_author) . ', 您好!</p>
    <p>您曾在《' . get_the_title($comment->comment_post_ID) . '》的评论: <br />'
    . wpautop(get_comment($parent_id)->comment_content) . '</p>
    <p>' . trim($comment->comment_author) . ' 给您的回复:<br />'
    . wpautop($comment->comment_content) . '<br /></p>
    <p>您可以点击 <a href="' . htmlspecialchars(get_comment_link($parent_id, array('type' => 'comment'))) . '">查看完整内容</a></p>
    <p>欢迎再次光临 <a href="' . get_option('home') . '">' . get_option('blogname') . '</a></p>
    <p>(此邮件由系统自动发出, 请勿回复.)</p>
    </div>';
$from = "来自: \"" . get_option('blogname') . "\" <$wp_email>";
$headers = "$from\nContent-Type: text/html; charset=" . get_option('blog_charset') . "\n";
wp_mail( $to, $subject, $message, $headers );

四、让你的博客拥有此功能

即使你将所有的代码增加到functions.php文件中,也需要一个勾子触发此事件,如果我们命名一个函数mail_to_comment来实现这一功能的话,你仍然需要增加下面的一个事件来实现当用户提交评论时触发函数,从而实现发送邮件

add_action('comment_post', 'mail_to_comment');

五、延伸:在评论框附近增加是否邮件通知的选项

在上文中第二点的第4种情况中,我们谈到了作为评论者是否愿意接收这种有人回复我的评论时得到邮件提示的功能,那么我们需要在我们的提交按钮附近增加一个复选框,让用户勾选它,从而可以记录用户的意愿。而上文中我们已经为comments表增加了一个字段,正是这个字段记录了用户的意向。

如果你自己设计评论列表和评论框,那么可以直接将这个复选框放在你的评论提交按钮附近即可,只要name值和上文中$_POST得到的值相同即可。

但如果你并没有设计自己的评论列表,那么你也可以通过勾子的方式增加一个复选框,代码如下:

function add_mail_to_comment_checkbox() {
     echo '<label for="mail_to_comment"><input type="checkbox" name="mail_to_comment" id="mail_to_comment" value="mail_to_comment" checked="checked" style="margin-left:20px;" />有人回复时邮件通知我</label>';
}
add_action('comment_form', 'add_mail_to_comment_checkbox');

经过frustigor的自己制作评论列表页面的经验发现,这个动作将发生在评论代码的<?php do_action('comment_form', $post->ID); ?>地方,所以即使你自己设计自己的评论列表和复选框,也可以将<?php do_action('comment_form', $post->ID); ?>放在你想要的位置,将上面的代码写入functions.php中,以此来实现增加一个复选框。

六、完整的代码

通过上述的讲解,或许你有了大概的思路了,但我还是将所有的代码都贴出来,以供大家参考。同时,我还加入了新的功能,即如果你发布了文章,同时也可以收到评论。这样我们就可以关闭后台的邮件评论通知了,因为wordpress的邮件通知无关信息太多。好吧,下面就是代码。

[payfor price="2"]/**
* 本函数实现了在评论框附近添加是否需要在别人回复时邮件通知的功能
*/

include_once(ABSPATH.'/wp-includes/pluggable.php');

function mail_to_comment($comment_id) {
?? ?
?? ?$comment = get_comment($comment_id);
?? ?$comment_author = $comment->comment_author;
?? ?$comment_author_url = $comment->comment_author_url ? '(Url:'.$comment->comment_author_url.')' : '';
?? ?$comment_author_email = trim($comment->comment_author_email);
?? ?$comment_content = $comment->comment_content;
?? ?
?? ?$comment_parent_id = $comment->comment_parent;
?? ?$comment_parent = get_comment($comment_parent_id);
?? ?$comment_parent_link = get_comment_link($comment_parent_id,array('type' => 'comment'));
?? ?
?? ?$comment_post_id = $comment->comment_post_ID;
?? ?$comment_post_link = get_permalink($comment_post_id);
?? ?$comment_post = get_post($comment_post_id);
?? ?$comment_post_title = $comment_post->post_title;
?? ?$comment_post_author = get_userdata($comment_post->post_author);
?? ?$blogDomain = $_SERVER['SERVER_NAME'];
?? ?$blogName = get_bloginfo('name');
?? ??? ?
?? ?if(isset($_POST['allow_mail_reply']) && $_POST['allow_mail_reply'] == 1){
?? ??? ?update_comment_meta($comment_id,'allow_mail_reply',1) or add_comment_meta($comment_id,'allow_mail_reply',1,true);
?? ?}
?? ?$allow_mail_reply = get_comment_meta($comment_parent_id,'allow_mail_reply',true);
?? ?if(!$allow_mail_reply)$allow_mail_reply = 0;
?? ?if($comment_parent_id == 0)$allow_mail_reply = 1;
?? ?
?? ?// 0:不同意接收邮件提示;1:同意只要有邮件就提示;
?? ?if(!$allow_mail_reply || $comment->comment_approved == 'spam' || $comment->comment_type == 'pingback')return;
?? ?
?? ?if($comment_parent_id == 0) :
?? ??? ?$mail_to = trim($comment_post_author->user_email);
?? ??? ?$mail_content = "{$comment_post_author->display_name},您好!"
?? ??? ??? ?."\n您的在{$blogName}上发表的文章“{$comment_post_title}”被{$comment_author}{$comment_author_url}评论,请及时回复他。"
?? ??? ??? ?."\n链接:{$comment_post_link}"
?? ??? ??? ?."\n内容:{$comment_content}";
?? ?else :
?? ??? ?$mail_to = $comment_parent->comment_author_email;
?? ??? ?$mail_content = "{$comment_parent->comment_author},您好!"
?? ??? ??? ?."\n您的在{$blogName}的文章“{$comment_post_title}”上发表的评论被{$comment_author}{$comment_author_url}回复,请及时回复他。"
?? ??? ??? ?."\n链接:{$comment_parent_link}"
?? ??? ??? ?."\n内容:{$comment_content}";
?? ?endif;
?? ?$mail_subject = "您在“{$blogName}{$blogDomain}”有了新的评论动态";
?? ?$mail_headers = "From: {$blogName} <no-reply@{$blogDomain}>\r\n";
?? ?
?? ?wp_mail($mail_to,$mail_subject,$mail_content,$mail_headers);
}
add_action('comment_post','mail_to_comment');


function add_mail_to_comment_checkbox() {
? echo '<p id="add-mail-comment-checkbox"><label><input type="checkbox" name="allow_mail_reply" value="1" checked="checked" />有人回复时邮件通知我</label></p>';
}
add_action('comment_form', 'add_mail_to_comment_checkbox');

// -- END ----------------------------------------[/payfor]

七、存在的一些问题

1、一条评论只能接受一条邮件提示,然而有时候一条评论会有多条回复来进行回复,那么只有第一条回复的内容能被显示在邮件中,其实我们希望不同的用户对一条评论进行回复时,被回复者都能收到起码一条他们之间的讨论邮件。

2、当新的访客进行回复时,开始是没有被审核的,当管理员在后台进行审核时,post_comment的action已经不生效了,也就说这条被审核的回复对应的被评论者并不能在它被审核时收到邮件提示(待证)。

3、更多的情况有待大家思考

已有2条评论 快速评论
  1. 免费部落 #4173楼 2013/10/30 14:23:00 回复

    正在考虑换个样式,原来的邮件 样式太难看了!

  2. FengFree #1097楼 2012/04/29 18:28:31 回复

    很好,收藏备用

填写个人信息,赶快回复吧!