jforum二次开发——添加内容过滤

java 编写的论坛中, jforum 算是比较多人用的一个,因为有 sso 功能,所以能很好的跟其他系统进行整合。 jforum 还有针对某个版块设置发帖审核的功能,当然,任何一个帖子都要进行审核的话,就缺乏消息的即时性,同时也增加了管理员的负担。
为了符合中国国情,我们在使用 jforum 过程中,可以给它添加一个内容过滤功能。我的实现出发点很简单,在原来审核功能的基础上,针对某一组用户,发现他们发布的内容包含有某些敏感词的时候,把这些内容添加到审核列表中,只有版主和管理员审核后,才显示这些内容。

一、实现分析

jforum-2.1.8 这个版本中,论坛发新帖、回复都是由类 net.jforum.view.forum. PostAction 来完成的。更具体一点,发表新帖和发表回复都是由 PostAction. insertSave() 方法实现。发表新帖的时候,会保存一个 Topic 和一个 Post 对象;发表回复的时候,只保存一个 Post 对象。
对于新帖是否要审核, jforum 是这样判断的:
//  Moderators and admins don't need to have their messages moderated
boolean  moderate  =  (forum.isModerated() &&
             ! pc.canAccess(SecurityConstants.PERM_MODERATION) &&
            ! pc.canAccess(SecurityConstants.PERM_ADMINISTRATION));

 
就是判断发布内容的版块是否需要审核,同时发布内容的用户不是版主或者管理员之类的。然后,对于回复内容, jforum 是这样判断的:

if (!firstPost && pc.canAccess(SecurityConstants.PERM_REPLY_WITHOUT_MODERATION, 
        Integer.toString(t.getForumId()))){
                          moderate 
= false;
 }

既判断该用户是否存在回复审核这种权限,如果用户的回复不需要审核,那么 post 对象的 moderate 状态被设置为 false 。最后, post 对象保存:
                    //  Save the remaining stuff
                   p.setModerate(moderate);
                   
int  postId  =  postDao.addNew(p);


二、利用审核状态位添加过滤



我在
post 保存前,再对其内容进行关键字判断(暂时也找不到其他更智能的方法)。
              
//设置是否被过滤,true说明发布的内容包含了关键字,放到审核列表中
    boolean filtered = false;     
        //如果该组启用了过滤
    if(!moderate && pc.canAccess(SecurityConstants.PERM_POST_FILTER)){
    ContextFilter cf = ContextFilter.getInstance();
    filtered 
= cf.filter(this.request.getParameter("subject")); //过滤标题
         //过滤帖子内容
        if(!filtered) {                                                                                                    
            filtered = cf.filter(p.getText());
         }
                         
        moderate 
= moderate || filtered ;  //更改审核状态
    }

    p.setModerate(moderate);
    
int postId = postDao.addNew(p);
   

    SecurityConstants.PERM_POST_FILTER是我在
SecurityConstants中添加的静态变量:

public   static   final  String PERM_POST_FILTER  =   " perm_post_filter " ;

还要给/WEB-INF/config/permissions.xml添加相应的选项,这样就可以针对某一组用户开启内容过滤功能:

         <!--  Lock and Unlock topics  -->
        
< permission  id ="perm_moderation_topic_lockUnlock"
             title
="Permissions.canLockUnlock"  type ="single" >
            
< option  value ="deny"  description ="No" />
            
< option  value ="allow"  description ="Yes" />
        
</ permission >
        <!--
内容过滤 -->
        
< permission  id ="perm_post_filter"
                title
="Permissions.filterPost"  type ="single" >
            
< option  value ="deny"  description ="No" />
            
< option  value ="allow"  description ="Yes" />
        
</ permission >
在国际化资源文件中添加Permissions.filterPost的描述。这样,在jforum的组权限管理里面,可以看到这个下拉单选项。

        这样,发布内容的过滤核心代码就完成了。
ContextFilter是我自己定义的一个负责内容过滤的类。当然,仅用这段代码的话,发布内容的人在发布了某些包含敏感词的时候,看到的提示信息是,该版块需要审核,请您耐心等待之类的,如果希望告诉用户,他发布的内容含有敏感词的话,需要修改一下waitingModeration()方法。首先看jforum原来重定向到需要审核页面的代码:
else   {

                          JForumExecutionContext.setRedirect(
this.request.getContextPath()

                                 
+ "/posts/waitingModeration/"

                                 
+ (firstPost ? 0 : t.getId())

                                 
+ "/" + t.getForumId()

                                 
+ SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION));
                   }

我在这基础上添加了一段:
// 内容被过滤了
                
  else   if (filtered) {
    JForumExecutionContext.setRedirect(
this.request.getContextPath()
         
+ "/posts/waitingModeration/"
         
+ (firstPost ? 0 : t.getId())
         
+ "/" + t.getForumId()
         
+ SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION)+"?filtered=true");                         
  }
else {
        JForumExecutionContext.setRedirect(
this.request.getContextPath()
        
+ "/posts/waitingModeration/"
        
+ (firstPost ? 0 : t.getId())
        
+ "/" + t.getForumId()
        
+ SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION));
}
waitingModeration() 方法中,给用户的提示信息是这样的:
this .context.put( " message " , I18n.getMessage( " PostShow.waitingModeration " ,

                          
new  String[]  { path + SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION) } ));

 
可以改成这样:
        
// TODO 添加被过滤的说明 BEGIN
if ( this .request.getParameter( " filtered " ) != null ) {
    
this.context.put("message"
        I18n.getMessage(
"PostShow.filtered.waitingModeration"
        
new String[] { path + 
        SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION) }
));
}
else
// TODO 添加被过滤的说明 END
this .context.put( " message "
I18n.getMessage(
" PostShow.waitingModeration "
    
new  String[]  { path + 
    SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION) }
));

 
当然,要在国际化资源文件中添加 PostShow.waitingModeration 这个信息的描述。
 
以上就能实现对用户发布内容的过滤,当然,用户编辑可以使用类似的方法,但实现起来需要修改的细节就多了很多。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值