立即注册 找回密码

QQ登录

只需一步,快速开始

查看: 4608|回复: 0

[Discuz 开发教程] Discuz x2 后台的邮件通知更新天数功能分析

[复制链接]

116

主题

13

回帖

563

积分

终身VIP会员

Rank: 7Rank: 7Rank: 7

积分
563

推广达人宣传达人突出贡献荣誉管理论坛元老

发表于 2015-1-12 21:43:41 | 显示全部楼层 |阅读模式
道勤网-数据www.daoqin.net

亲注册登录道勤网-可以查看更多帖子内容哦!(包涵精彩图片、文字详情等)请您及时注册登录-www.daoqin.net

您需要 登录 才可以下载或查看,没有账号?立即注册

x
邮件通知更新天数功能介绍:当用户多少天没有登录站点的时候才会给其发送邮件通知。


邮件通知更新天数的位置:后台-》全局-》空间设置-》基本设置下的邮件通知更新天数,如图。
设置为0则不启用该功能,单位为天。
222.jpg
功能分析:

比如用户A回复了用户B的帖子,这时候在用户A回复用户B帖子的同时会执行下面这个操作。
具体文件:sourceincludepostpost_newreply.php的98行附近。
  1. notification_add($post['authorid'], 'pcomment', 'comment_add', array(
  2.                         'tid' => $_G['tid'],
  3.                         'pid' => $_G['gp_pid'],
  4.                         'subject' => $thread['subject'],
  5.                         'commentmsg' => cutstr(str_replace(array('[b]', '[/b]', '[/color]'), '', preg_replace("/\[color=([#\w]+?)\]/i", "", stripslashes($comment))), 200)
  6.                 ));
复制代码
notification_add()函数是在source/function/function_core.php文件定义的,1897行附近,具体代码如下:
  1. function notification_add($touid, $type, $note, $notevars = array(), $system = 0) {
  2.         global $_G;

  3.         $tospace = array('uid'=>$touid);
  4.         space_merge($tospace, 'field_home');
  5.         $filter = empty($tospace['privacy']['filter_note'])?array():array_keys($tospace['privacy']['filter_note']);

  6.         if($filter && (in_array($type.'|0', $filter) || in_array($type.'|'.$_G['uid'], $filter))) {
  7.                 return false;
  8.         }

  9.         $notevars['actor'] = "<a href="home.php?mod=space&uid=$_G[uid]">".$_G['member']['username']."</a>";
  10.         if(!is_numeric($type)) {
  11.                 $vars = explode(':', $note);
  12.                 if(count($vars) == 2) {
  13.                         $notestring = lang('plugin/'.$vars[0], $vars[1], $notevars);
  14.                 } else {
  15.                         $notestring = lang('notification', $note, $notevars);
  16.                 }
  17.                 $frommyapp = false;
  18.         } else {
  19.                 $frommyapp = true;
  20.                 $notestring = $note;
  21.         }

  22.         $oldnote = array();
  23.         if($notevars['from_id'] && $notevars['from_idtype']) {
  24.                 $oldnote = DB::fetch_first("SELECT * FROM ".DB::table('home_notification')."
  25.                         WHERE uid='$touid' AND from_id='$notevars[from_id]' AND from_idtype='$notevars[from_idtype]'");
  26.         }
  27.         if(empty($oldnote['from_num'])) $oldnote['from_num'] = 0;
  28.         $notevars['from_num'] = $notevars['from_num'] ? $notevars['from_num'] : 1;
  29.         $setarr = array(
  30.                 'uid' => $touid,
  31.                 'type' => $type,
  32.                 'new' => 1,
  33.                 'authorid' => $_G['uid'],
  34.                 'author' => $_G['username'],
  35.                 'note' => addslashes($notestring),
  36.                 'dateline' => $_G['timestamp'],
  37.                 'from_id' => $notevars['from_id'],
  38.                 'from_idtype' => $notevars['from_idtype'],
  39.                 'from_num' => ($oldnote['from_num']+$notevars['from_num'])
  40.         );
  41.         if($system) {
  42.                 $setarr['authorid'] = 0;
  43.                 $setarr['author'] = '';
  44.         }

  45.         if($oldnote['id']) {
  46.                 DB::update('home_notification', $setarr, array('id'=>$oldnote['id']));
  47.         } else {
  48.                 $oldnote['new'] = 0;
  49.                 DB::insert('home_notification', $setarr);
  50.         }

  51.         if(empty($oldnote['new'])) {
  52.                 DB::query("UPDATE ".DB::table('common_member')." SET newprompt=newprompt+1 WHERE uid='$touid'");

  53.                 require_once libfile('function/mail');
  54.                 $mail_subject = lang('notification', 'mail_to_user');
  55.                 sendmail_touser($touid, $mail_subject, $notestring, $frommyapp ? 'myapp' : $type);
  56.         }

  57.         if(!$system && $_G['uid'] && $touid != $_G['uid']) {
  58.                 DB::query("UPDATE ".DB::table('home_friend')." SET num=num+1 WHERE uid='$_G[uid]' AND fuid='$touid'");
  59.         }
  60. }
复制代码
前面都是给相应用户发送提醒操作,具体不再此处进行分析,单独看发送邮件代码,如下:
  1. require_once libfile('function/mail');
  2.                 $mail_subject = lang('notification', 'mail_to_user');
  3.                 sendmail_touser($touid, $mail_subject, $notestring, $frommyapp ? 'myapp' : $type);
复制代码
这里会执行sendmail_touser()函数,$mail_subject是邮件标题,$notestring是提醒的内容,$frommyapp是操作的类型。
sendmail_touser()函数是在source\function\function_mail.php文件里定义的,204行附近,具体代码如下:
  1. function sendmail_touser($touid, $subject, $message, $mailtype='') {
  2.         global $_G;

  3.         if(empty($_G['setting']['sendmailday'])) return false;

  4.         require_once libfile('function/home');
  5.         $tospace = getspace($touid);
  6.         if(empty($tospace['email'])) return false;

  7.         space_merge($tospace, 'field_home');
  8.         space_merge($tospace, 'status');

  9.         $acceptemail = $tospace['acceptemail'];
  10.         if(!empty($acceptemail[$mailtype]) && $_G['timestamp'] - $tospace['lastvisit'] > $_G['setting']['sendmailday']*86400) {
  11.                 if(empty($tospace['lastsendmail'])) {
  12.                         $tospace['lastsendmail'] = $_G['timestamp'];
  13.                 }
  14.                 $sendtime = $tospace['lastsendmail'] + $acceptemail['frequency'];

  15.                 $query = DB::query("SELECT * FROM ".DB::table('common_mailcron')." WHERE touid='$touid' LIMIT 1");
  16.                 if($value = DB::fetch($query)) {
  17.                         $cid = $value['cid'];
  18.                         if($value['sendtime'] < $sendtime) $sendtime = $value['sendtime'];
  19.                         DB::update('common_mailcron', array('email'=>addslashes($tospace['email']), 'sendtime'=>$sendtime), array('cid'=>$cid));
  20.                 } else {
  21.                         $cid = DB::insert('common_mailcron', array('touid'=>$touid, 'email'=>addslashes($tospace['email']), 'sendtime'=>$sendtime), 1);
  22.                 }
  23.                 $message = preg_replace("/href\="(?!http\:\/\/)(.+?)"/i", 'href="'.$_G['siteurl'].'\\1"', $message);
  24.                 $setarr = array(
  25.                         'cid' => $cid,
  26.                         'subject' => addslashes($subject),
  27.                         'message' => addslashes($message),
  28.                         'dateline' => $_G['timestamp']
  29.                 );
  30.                 DB::insert('common_mailqueue', $setarr);
  31.                 return true;
  32.         }
  33.         return false;
  34. }
复制代码
下面具体分析代码的执行过程:
  1. if(empty($_G['setting']['sendmailday'])) return false;
复制代码
首先会判断$_G['setting']['sendmailday']变量是否存在,如果不存在则直接返回false。$_G['setting']['sendmailday']就是后台设置的邮件通知更新天数。
  1. require_once libfile('function/home');
  2.         $tospace = getspace($touid);
  3.         if(empty($tospace['email'])) return false;
复制代码
getspace($touid)是要获取发送对象的详细信息,如果该用户没有设置邮箱,就直接返回false。
  1. space_merge($tospace, 'field_home');
  2.         space_merge($tospace, 'status');

  3.         $acceptemail = $tospace['acceptemail'];
复制代码
前两句是查询该用户的相关信息。
$tospace['acceptemail']是该用户设置的邮件提醒。邮件提醒设置的具体位置在家园的设置-》邮件提醒。
  1. if(!empty($acceptemail[$mailtype]) && $_G['timestamp'] - $tospace['lastvisit'] > $_G['setting']['sendmailday']*86400) {
复制代码
首先判断该类型的操作是否进行邮件提醒(判断$acceptemail[$mailtype]变量是否存在),同时判断当前时间(TIMESTAMP)- 用户上一次的活动时间($tospace['lastvisit']) > 后台设置的邮件通知更新天数($_G['setting']['sendmailday'])*86400。不满足则跳出if判断,返回false。
  1. if(empty($tospace['lastsendmail'])) {
  2. $tospace['lastsendmail'] = $_G['timestamp'];
  3. }
复制代码
如果用户上一次发送邮件的时间不存在,那么就赋予当前时间给$tospace['lastsendmail']。
  1. $sendtime = $tospace['lastsendmail'] + $acceptemail['frequency'];
复制代码
计算发送邮件的时间,$acceptemail['frequency']为邮件提醒里的发送频率设置。
  1. $query = DB::query("SELECT * FROM ".DB::table('common_mailcron')." WHERE touid='$touid' LIMIT 1");
  2.                 if($value = DB::fetch($query)) {
  3.                         $cid = $value['cid'];
  4.                         if($value['sendtime'] < $sendtime) $sendtime = $value['sendtime'];
  5.                         DB::update('common_mailcron', array('email'=>addslashes($tospace['email']), 'sendtime'=>$sendtime), array('cid'=>$cid));
  6.                 } else {
  7.                         $cid = DB::insert('common_mailcron', array('touid'=>$touid, 'email'=>addslashes($tospace['email']), 'sendtime'=>$sendtime), 1);
  8.                 }
复制代码
首先到common_mailcron表里查询是否有向该用户发送邮件的邮件任务。如果存在就更新任务,如果不存在就往表里新插入一条任务。
  1. $message = preg_replace("/href\="(?!http\:\/\/)(.+?)"/i", 'href="'.$_G['siteurl'].'\\1"', $message);
  2.                 $setarr = array(
  3.                         'cid' => $cid,
  4.                         'subject' => addslashes($subject),
  5.                         'message' => addslashes($message),
  6.                         'dateline' => $_G['timestamp']
  7.                 );
  8.                 DB::insert('common_mailqueue', $setarr);
  9.                 return true;
复制代码
前面是对内容进行处理,然后往common_mailqueue表里插入一条数据,返回true。
至此,相应的邮件任务已经添加,但是邮件还没有发送。下面看下邮件任务是如何触发处理的。

在template\default\common\footer.htm文件,79行附近,找到如下代码。
  1. <!--{if !isset($_G['cookie']['sendmail'])}-->
  2.         <script type="text/javascript" src="home.php?mod=misc&ac=sendmail&rand=$_G[timestamp]"></script>
  3.         <!--{/if}-->
复制代码
如果不存在$_G['cookie']['sendmail'],那么就会输出一个js。
看js的src地址,是进入到了source\include\misc\misc_sendmail.php文件中,下面只分析重点,其他不做分析。
  1. $query = DB::query("SELECT * FROM ".DB::table('common_mailcron')." WHERE sendtime<='$_G[timestamp]' ORDER BY sendtime LIMIT 0,$pernum");
  2. while ($value = DB::fetch($query)) {
  3.         if($value['touid']) $touids[$value['touid']] = $value['touid'];
  4.         $cids[] = $value['cid'];
  5.         $list[$value['cid']] = $value;
  6. }

  7. if(empty($cids)) exit();

  8. $query = DB::query("SELECT * FROM ".DB::table('common_mailqueue')." WHERE cid IN (".dimplode($cids).")");
  9. while ($value = DB::fetch($query)) {
  10.         $sublist[$value['cid']][] = $value;
  11. }
复制代码
从common_mailcron和common_mailqueue表分别查询数据然后赋值。
  1. if($touids) {
  2.         DB::query("UPDATE ".DB::table('common_member_status')." SET lastsendmail='$_G[timestamp]' WHERE uid IN (".dimplode($touids).")");
  3. }
复制代码
更新common_member_status表里用户的最后发送邮件时间。
  1. DB::query("DELETE FROM ".DB::table('common_mailcron')." WHERE cid IN (".dimplode($cids).")");
  2. DB::query("DELETE FROM ".DB::table('common_mailqueue')." WHERE cid IN (".dimplode($cids).")");
复制代码
删除common_mailcron表里跟common_mailqueue表里删除相应的任务。
  1. require_once libfile('function/mail');

  2. foreach ($list as $cid => $value) {
  3.         $mlist = $sublist[$cid];
  4.         if($value['email'] && $mlist) {
  5.                 $subject = getstr($mlist[0]['subject'], 80, 0, 0, 0, -1);
  6.                 $message = '';
  7.                 foreach ($mlist as $subvalue) {
  8.                         if($subvalue['message']) {
  9.                                 $message .= "<br><strong>$subvalue[subject]</strong><br>$subvalue[message]<br>";
  10.                         } else {
  11.                                 $message .= $subvalue['subject'].'<br>';
  12.                         }
  13.                 }
  14.                 if(!sendmail($value['email'], $subject, $message)) {
  15.                         runlog('sendmail', "$value[email] sendmail failed.");
  16.                 }
  17.         }
  18. }
复制代码
执行相应的发送邮件操作。
至此邮件就发送出去了。
道勤主机提供365天*24小时全年全天无休、实时在线、零等待的售后技术支持。竭力为您免费处理您在使用道勤主机过程中所遇到的一切问题! 如果您是道勤主机用户,那么您可以通过QQ【792472177】、售后QQ【59133755】、旺旺【诠释意念】、微信:q792472177免费电话、后台提交工单这些方式联系道勤主机客服! 如果您不是我们的客户也没问题,点击页面最右边的企业QQ在线咨询图标联系我们并购买后,我们为您免费进行无缝搬家服务,让您享受网站零访问延迟的迁移到道勤主机的服务!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

道勤网- 推荐内容!上一条 /2 下一条

!jz_fbzt! !jz_sgzt! !jz_xgzt! 快速回复 !jz_fhlb! !jz_lxwm! !jz_gfqqq!

关于我们|手机版|小黑屋|地图|【道勤网】-www.daoqin.net 软件视频自学教程|免费教程|自学电脑|3D教程|平面教程|影视动画教程|办公教程|机械设计教程|网站设计教程【道勤网】 ( 皖ICP备15000319号-1 )

GMT+8, 2024-11-15 14:44

Powered by DaoQin! X3.4 © 2016-2063 Dao Qin & 道勤科技

快速回复 返回顶部 返回列表