立即注册 登录
彼岸网 返回首页

天香公主的个人空间 http://www.bian-wang.com/discuz/?10005 [收藏] [复制] [分享] [RSS] txgz999@yahoo.com

日志

Discuz功能改进:如何用@来发通知

热度 8已有 4276 次阅读2014-11-20 11:30 PM |个人分类:Discuz|系统分类:社交网理论与实践

在一些论坛里,用户可以在贴子里写上另一个用户的用户名,并加一个@前缀,这样对方就会收到通知来看这个帖子。

下面是虎扑论坛里的一个例子:






下面我们尝试在Discuz系统的记录里加上这个功能。

1。 在source/language/lang_notification.php加入: 'doing_mention' => '{actor} 在 < a href="{url}" target="_blank">记录</a> 中提到了您', 2。 在source/include/spacecp/spacecp_doing.php里下面一段: if($updo['uid'] != $_G['uid']) { notification_add($updo['uid'], 'doing', 'doing_reply', array( 'url'=>"home.php?mod=space&uid=$updo[uid]&do=doing&view=me&doid=$updo[doid]&highlight=$newid", 'from_id'=>$updo['doid'], 'from_idtype'=>'doid')); updatecreditbyaction('comment', 0, array(), 'doing'.$updo['doid']); } 之后加入: if (preg_match_all("/(&nbsp;|\s|^)@(\S+)(&nbsp;|\s|$)/", $message, $matches)) { $result = array_unique($matches[2]); foreach($result as $ausername) { if(($auid = C::t('common_member')->fetch_uid_by_username($ausername))) { if (($auid != $_G['uid']) && ($auid != $updo['uid'])) { if (!isblacklist($auid)) notification_add($auid, 'comment', 'doing_mention', array( 'url'=>"home.php?mod=space&uid=$auid&do=doing&view=me&doid=$updo[doid]&highlight=$newid", 'from_id'=>$updo['doid'], 'from_idtype'=>'doid')); } } } } 下面是效果图:





以上只是讨论下做法,不足为据。 类似的可以将这个功能引入日志及其评论中,在这里就不讨论了。

注:本文中的代码里的某些<符号后人为加了一个不应该有的空格,以避免Discuz在保存日志时自动改变日志内容。

5/1/2016补充:经网友sesemule提醒,发现原来的代码只处理了记录里的回复部分,没处理记录本身。要支持记录本身的话,还要做下面的改动:
3。 在source/include/spacecp/spacecp_doing.php里下面一句: C::t('common_member_field_home')->update($_G['uid'], $setarr); 之后加入: if (preg_match_all("/(&nbsp;|\s|^)@(\S+)(&nbsp;|\s|$)/", $message, $matches)) { $result = array_unique($matches[2]); foreach($result as $ausername) { if(($auid = C::t('common_member')->fetch_uid_by_username($ausername))) { if ($auid != $_G['uid']) { if (!isblacklist($auid)) notification_add($auid, 'comment', 'doing_mention', array( 'url'=>"home.php?mod=space&uid=$auid&do=doing&view=me&doid=$newdoid&highlightdoing=$newdoid", 'from_id'=>$updo['doid'], 'from_idtype'=>'doid')); } } } } 4。 在source/include/space/space_doing.php里将下面这句 $uids = $_GET['highlight'] ? array() : array($space['uid']); 改成: $uids = ($_GET['highlight'] || $_GET['highlightdoing']) ? array() : array($space['uid']); 5。 在source/include/space/space_doing.php里下面这段: $query = C::t('home_doing')->fetch_all_search($start, $perpage, 1, $uids, '', $searchkey, '', '' ,'', 1, $doid, $f_index); foreach($query as $value) { 之后加入: if($_GET['highlightdoing'] && $value['doid'] == $_GET['highlightdoing']) { $value['style'] .= 'color:#F60;'; } 6。在template/default/home/space_doing.htm里将下面这句 <dd class="{if empty($diymode)}ptm{else}ptw{/if} xs2"> 改成: <dd class="{if empty($diymode)}ptm{else}ptw{/if} xs2" style="$dv[style]">
相关代码下载: http://www.bian-wang.com/upload/txgz_doing_at_notification_160502a.zip

5/16/2016补充:应网友sesemule的要求,把这个功能扩展到日志及其评论:
1)加汉字:在文件 source/language/lang_notification.php 中加入:
'blog_mention' => '{actor} 在 < a href="{url}" target="_blank">日志</a> 中提到了您', 'blogcomment_mention' => '{actor} 在 < a href="{url}" target="_blank">日志评论</a> 中提到了您', 2)日志的通知:在文件 source/include/spacecp/spacecp_blog.php 里的下面这段
if($newblog = blog_post($_POST, $blog)) { if(empty($blog) && $newblog['topicid']) { $url = 'home.php?mod=space&uid='.$_G['uid'].'&do=topic&topicid='.$newblog['topicid'].'&view=blog&quickforward=1'; } else { $url = 'home.php?mod=space&uid='.$newblog['uid'].'&do=blog&quickforward=1&id='.$newblog['blogid']; } 后加入 if (preg_match_all("/(&nbsp;|\s|^)@(\S+)(&nbsp;|\s|$)/", $_POST['message'], $matches)) { $n_url = 'home.php?mod=space&uid='.$newblog['uid'].'&do=blog&id='.$newblog['blogid']; $result = array_unique($matches[2]); foreach($result as $ausername) { if(($auid = C::t('common_member')->fetch_uid_by_username($ausername))) { if ($auid != $_G['uid']) { if (!isblacklist($auid)) notification_add($auid, 'comment', 'blog_mention', array('url'=>$n_url)); } } } } 3)日志评论的通知:
3a)新评论:在文件 source/include/spacecp/spacecp_comment.php 里的下面这段
$cidarr = add_comment($message, $id, $idtype, $cid); 后加入 if ($idtype == 'blogid') { if (preg_match_all("/(&nbsp;|\s|^)@(\S+)(&nbsp;|\s|$)/", $message, $matches)) { if($cidarr['cid'] != 0 && $comment = C::t('home_comment')->fetch($cidarr['cid'], $_G['uid'])) { $n_url = "home.php?mod=space&uid=$comment[uid]&do=blog&id=$id&cid=$cidarr[cid]"; $result = array_unique($matches[2]); foreach($result as $ausername) { if(($auid = C::t('common_member')->fetch_uid_by_username($ausername))) { if ($auid != $_G['uid']) { if (!isblacklist($auid)) notification_add($auid, 'comment', 'blogcomment_mention', array('url'=>$n_url)); } } } } } } 3b)修改评论: 在文件 source/include/spacecp/spacecp_comment.php 里的下面这段
C::t('home_comment')->update($comment['cid'], array('message'=>$message, 'status'=>$comment_status)); 后加入 if ($comment['idtype'] == 'blogid') { if (preg_match_all("/(&nbsp;|\s|^)@(\S+)(&nbsp;|\s|$)/", $message, $matches)) { $n_url = "home.php?mod=space&uid=$comment[uid]&do=blog&id=$comment[id]&cid=$cid"; $result = array_unique($matches[2]); foreach($result as $ausername) { if(($auid = C::t('common_member')->fetch_uid_by_username($ausername))) { if ($auid != $_G['uid']) { if (!isblacklist($auid)) notification_add($auid, 'comment', 'blogcomment_mention', array('url'=>$n_url)); } } } } }

发表评论 评论 (174 个评论)

回复 天香公主 2017-6-24 07:59 PM
a1980: 好棒的功能,想請問天香,像Discuz X3.2的notification要怎麼寫,我參考了這個寫法,但似乎都沒有成功,我是希望如果有新的文章,只要開啟瀏覽器,不論有沒有進 ...
我发了篇新博文讨论这个问题 http://www.bian-wang.com/discuz/home.php?mod=space&uid=10005&do=blog&id=1754,感觉这是个满有意思的话题,希望多听到您的见解
回复 a1980 2017-6-19 09:31 PM
天香公主: 我正在看相关的介绍。这本小书 https://web-push-book.gauntface.com/downloads/web-push-book.pdf 看上去不错,建议读读。在浏览器里要注册一个service worker  ...
感謝天香,我會好好研究一下
回复 天香公主 2017-6-14 09:37 PM
a1980: 謝謝天香抽空回覆,目前我是參考了這個網站用他們的方式是會跳出同意通知,但點選同意通知之後就不知道該如何呼叫新帖通知出來了。

https://developer.mozilla. ...
我正在看相关的介绍。这本小书 https://web-push-book.gauntface.com/downloads/web-push-book.pdf 看上去不错,建议读读。在浏览器里要注册一个service worker 来订阅网站发的消息。在网站数据库里要记载那些订阅者。然后在适当的时候(如你说的是发表新文章时)网站就可以给这些订阅者发消息。那个 service worker 会接收和显示消息。发消息时不是网站向各个订阅者直接发,而是网站将消息发给各个订阅者客户端认定的一个 push service,这个push service会保存这个要发的消息。当它发现那个客户端在运行时就会把消息发过去。
回复 a1980 2017-6-14 09:16 PM
天香公主: 谢谢,我看了你给的链接,它用的是html5里的Notification API。要想通知用户有新文章,估计还要用到Push API。我过去没用过这些东西,等周末试试再和你讨论吧。 ...
謝謝天香抽空回覆,目前我是參考了這個網站用他們的方式是會跳出同意通知,但點選同意通知之後就不知道該如何呼叫新帖通知出來了。

https://developer.mozilla.org/en-US/docs/Web/API/notification
回复 天香公主 2017-6-14 06:12 AM
a1980: 好棒的功能,想請問天香,像Discuz X3.2的notification要怎麼寫,我參考了這個寫法,但似乎都沒有成功,我是希望如果有新的文章,只要開啟瀏覽器,不論有沒有進 ...
谢谢,我看了你给的链接,它用的是html5里的Notification API。要想通知用户有新文章,估计还要用到Push API。我过去没用过这些东西,等周末试试再和你讨论吧。
回复 a1980 2017-6-14 02:38 AM
天香公主: 嗯,在2)里少了句 $lastipDate = dgmdate($lastipDate);
我把它加在前一个评论里了。
好棒的功能,想請問天香,像Discuz X3.2的notification要怎麼寫,我參考了這個寫法,但似乎都沒有成功,我是希望如果有新的文章,只要開啟瀏覽器,不論有沒有進到我們的網站,他都會在右下角通知讀者有新文章
http://www.75271.com/3375.html
回复 a1980 2017-6-13 03:48 AM
好棒的功能,想請問天香,像Discuz X3.2的notification要怎麼寫,我參考了這個寫法,但似乎都沒有成功,我是希望如果有新的文章,只要開啟瀏覽器,不論有沒有進到我們的網站,他都會在右下角通知讀者有新文章
http://www.75271.com/3375.html
回复 天香公主粉丝 2017-5-28 07:21 AM
公主,这个功能真的很棒,
回复 sesemule 2017-4-17 09:09 AM
天香公主: 嗯,在2)里少了句 $lastipDate = dgmdate($lastipDate);
我把它加在前一个评论里了。
完美!

另外,怎么设置只有groupid是1、2、3的用户组可以使用这个安全提醒?
回复 天香公主 2017-4-17 08:28 AM
sesemule: 安全提醒正常出现。

唯一的问题是:上次登录时间显示不正常,显示为1492424688,大概对应2017年4月17日18:32。
嗯,在2)里少了句 $lastipDate = dgmdate($lastipDate);
我把它加在前一个评论里了。
回复 sesemule 2017-4-17 06:53 AM
天香公主: 我把代码改了下,你再试试吧。把上次的改动都去掉后,加入下面的修改:

1)修改语言包文件 source/language/lang_notification.php,在末端加入

    'ipnotic ...
安全提醒正常出现。

唯一的问题是:上次登录时间显示不正常,显示为1492424688,大概对应2017年4月17日18:32。
回复 天香公主 2017-4-17 12:12 AM
sesemule: 好像……并没有起作用? 等我有空再核对下,是不是哪里代码复制错了……
我把代码改了下,你再试试吧。把上次的改动都去掉后,加入下面的修改:

1)修改语言包文件 source/language/lang_notification.php,在末端加入

    'ipnotice' => '<div class="bm"><h2>安全提醒</h2><div class="bm_c" style="width: 400px;">
<dl class="xld cl bbda">
<dd>本次登录位置 {nowip} {nowipConvert}<br />上次登录位置 {lastip} {lastipConvert}<br />上次登录时间 {lastipDate}</dd>
</dl>
<p class="ptn cl"><a href="home.php?mod=spacecp&ac=profile&op=password" class="xi2 y">登录地点异常,建议立即更改密码 &raquo;</a></p>
</div>',

2)修改函数库文件 source/function/function_misc.php,在末端加入

function ipnotice($lastip, $lastipDate, $nowip) {
    global $_G;
    if (!$_G['setting']['bbclosed'] && !$_G['member']['freeze'] && !$_G['member']['groupexpiry'] && $_G['setting']['disableipnotice'] != 1 && $_G['uid'] && $_G['adminid'] == 1)
    {
                $lastipConvert = convertip($lastip);
                $lastipDate = dgmdate($lastipDate);
                $nowipConvert = convertip($nowip);

                $lastipConvert = process_ipnotice($lastipConvert);
                $nowipConvert = process_ipnotice($nowipConvert);

                if($lastipConvert != $nowipConvert && stripos($lastipConvert, $nowipConvert) == false && stripos($nowipConvert, $lastipConvert) == false) {
                        notification_add($_G['uid'], 'system', 'ipnotice', array(
                'nowip' => $nowip,
                'nowipConvert' => $nowipConvert,
                'lastip' => $lastip,
                'lastipConvert' => $lastipConvert,
                'lastipDate' => $lastipDate
            ),1);
                }
    }
}

3)修改类文件 source/class/class_member.php,在函数 on_login 的定义里的下面一句

dsetcookie('lip', $_G['member']['lastip'].','.$_G['member']['lastvisit']);

后加入:

require_once libfile('function/misc');
ipnotice($_G['member']['lastip'], $_G['member']['lastvisit'], $_G['clientip']);

4)修改类文件 source/class/discuz/discuz_application.php,在函数 _init_session 的定义里的下面一句

dsetcookie('lip', $this->var['member']['lastip'].','.$this->var['member']['lastvisit']);

后加入:

require_once libfile('function/misc');
ipnotice($this->var['member']['lastip'], $this->var['member']['lastvisit'], $this->var['clientip']);

注意:
A) 在2)中有个条件 $_G['adminid'] == 1,所以暂时只有管理员会有这个系统提醒,便于你测试。如果你要对全站用户开放这个功能,就把这个条件去掉。
B)在2)中还有个条件 $_G['setting']['disableipnotice'] != 1,即只有“关闭登录安全提醒”选择否时才会有系统提醒。如果你觉得这个安全提醒应该与这个设置值无关,比如你不想有弹窗所以要在“关闭登录安全提醒”选择是而又要这个系统提醒,那就把这个条件去掉。
回复 天香公主 2017-4-16 11:45 PM
sesemule: 哪个最后刷新,哪个就会有安全提醒的弹窗。
哈,我认为是先登录的那个会有弹窗,你认为是最后刷新的那个会有弹窗,这我还得试试再确认,但至少我们都同意不是两个都有弹窗。而如果改用通知的话,两个都会收到通知,因为通知是发给用户的而不是设备的。所以这是弹窗机制和通知机制的一个不同点。我刚把通知的代码改了下,马上贴上来,你再试试,希望除前述的不同点外,其它效果类似。

还有不知你注意到没有,不是IP变了就会有提醒,而是IP所在的地区变了才会有提醒。
回复 sesemule 2017-4-16 10:44 PM
天香公主: 我对你说的过程有点疑问。比如你有A和B两个设备,先在A上登录网站,再在B上登录网站,然后你在这两个设备上刷新网页后是都能看到弹窗,还是只在A上看到弹窗? ...
哪个最后刷新,哪个就会有安全提醒的弹窗。
回复 天香公主 2017-4-16 05:55 PM
sesemule: 按天香说的试了一下退出和重新登录,发现了挺奇怪的现象。

如果两个不同IP的设备都在登录状态下刷新网页,就会正常出现右下角的安全提醒弹窗;但是如果一个设备 ...
我对你说的过程有点疑问。比如你有A和B两个设备,先在A上登录网站,再在B上登录网站,然后你在这两个设备上刷新网页后是都能看到弹窗,还是只在A上看到弹窗?
回复 sesemule 2017-4-16 03:31 AM
天香公主: 忘了问你是不是关闭了“关闭登录安全提醒”?还有你希望我添加的这个提醒功能是否要依赖这个设置值?
没有关闭——也就是说,如果使用不同IP地址登录,是会在右下角弹出安全提醒的。

嗯,是否与这个设置值有关联倒不太重要,我倒是想起来:”特定用户组才有安全提醒“比较重要。也就是说,对于大多数普通会员来说,并不会关注自己的帐号有没有安全隐患,给予提醒反而是一种打扰;积分较多的高级会员以及网站管理人员却会非常在意安全问题,每次不同IP的登录都值得关注。

对了,今天中午终于收到了一条系统发送的安全提醒,到目前为止的唯一一条;右下角弹窗的安全提醒收到好多次了。是不是您做的这个安全提醒和DZ自带的右下角弹窗的触发机制不同?
回复 天香公主 2017-4-15 11:38 PM
sesemule: 好像……并没有起作用? 等我有空再核对下,是不是哪里代码复制错了……
忘了问你是不是关闭了“关闭登录安全提醒”?还有你希望我添加的这个提醒功能是否要依赖这个设置值?
回复 sesemule 2017-4-15 09:22 AM
天香公主: 我再看看。你测试看到右下角的登录安全提醒弹窗了吗?还有有没有退出和重新登录?
按天香说的试了一下退出和重新登录,发现了挺奇怪的现象。

如果两个不同IP的设备都在登录状态下刷新网页,就会正常出现右下角的安全提醒弹窗;但是如果一个设备登录后退出,然后用另一个设备登录,就不会出现安全提醒弹窗。——这是说明,DZ本身的安全提醒机制就是不完善的吗?
回复 天香公主 2017-4-15 07:45 AM
sesemule: 好像……并没有起作用? 等我有空再核对下,是不是哪里代码复制错了……
我再看看。你测试看到右下角的登录安全提醒弹窗了吗?还有有没有退出和重新登录?
回复 sesemule 2017-4-15 06:30 AM
天香公主: 嗯,这个主意不错。我想可以这样做,你试试吧:
1)修改语言包文件 source/language/lang_notification.php,在末端加入

    'ipnotice' => '<div class=&quot ...
好像……并没有起作用? 等我有空再核对下,是不是哪里代码复制错了……

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 立即注册

小黑屋|Archiver|彼岸网  

Powered by Discuz! X3.1 © 2001-2014 Comsenz Inc.
GMT-4, 2017-10-20 06:34 AM , Processed in 0.067348 second(s), 22 queries.

返回顶部