V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lml12377
V2EX  ›  程序员

Discuz 如何通过插件实现发帖内容过滤?

  •  1
     
  •   lml12377 · 2016-04-26 17:11:01 +08:00 · 5180 次点击
    这是一个创建于 2892 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题是这样的:

    在发帖页面,当我内容都输入好,点击发帖按钮,在数据写入数据库之前这一段处理过程,我能不能通过插件实现对这个处理过程的介入,比如把帖子内容处理一下再返回过去,最后存入数据库是处理过的数据?

    其实直接改原先 discuz 的处理逻辑是肯定能实现的,但是做插件目的就是为了脱离核心代码,这样升级的时候不至于覆盖乱了套,也不要 Discuz 自己的防水墙或者啥啥过滤,我就是要自己实现插件修改他发帖的内容~

    搞了一天快疯了,求大神指路!

    16 条回复    2016-04-27 13:42:57 +08:00
    oyxhm
        1
    oyxhm  
       2016-04-26 17:17:28 +08:00   ❤️ 1
    那你没有必要在过程中处理啊,你直接写个插件,从数据库取数据进行一次过滤再更新数据库不就好了。
    lml12377
        2
    lml12377  
    OP
       2016-04-26 17:22:01 +08:00
    @oyxhm 其实我的需求是这样的: emoji 表情会影响发帖内容, emoji 后的文字内容包括 emoji 都无法存入数据库,我想要做的是发帖的时候通过正则过滤掉 emoji ,保留其它的部分,但是直接该系统逻辑又不合适,插件又不知道有没有在发帖的处理过程中埋入钩子点...
    branchzero
        3
    branchzero  
       2016-04-26 17:28:22 +08:00   ❤️ 1
    Discuz 的插件嵌入点只能在处理完成后进行。
    这个的话,我建议你 post 页面里面嵌入一个 js 去监听表单提交事件, js 处理完数据之后再进行提交。
    lml12377
        4
    lml12377  
    OP
       2016-04-26 17:43:21 +08:00
    @branchzero 我看了半天好像也只有一个 discuzcode() 挂钩点沾点边,但是这个居然是展示帖子的时候过滤的,我数据库里都没内容了,这时候也没啥用了。。。实在不行就按你的方法试一下~
    branchzero
        5
    branchzero  
       2016-04-26 17:45:10 +08:00   ❤️ 1
    @lml12377 post_message 有一个钩子,不过也是在入库之后提示发送成功的时候触发的。。。记得发帖操作完成前是没有钩子的,只能迂回解决了。
    lml12377
        6
    lml12377  
    OP
       2016-04-26 17:51:18 +08:00
    @branchzero 好纠结,我觉得官方有必要考虑让插件可以接入发帖流程,好纠结啊!!!
    kookxiang
        7
    kookxiang  
       2016-04-26 17:53:55 +08:00   ❤️ 1
    你可以直接改 $_GET 里的值啊
    lml12377
        8
    lml12377  
    OP
       2016-04-26 17:57:46 +08:00
    @kookxiang 你说的是 $_G 这个全局变量吗?
    kookxiang
        9
    kookxiang  
       2016-04-26 20:26:41 +08:00   ❤️ 1
    @lml12377 最新版是用的 $_GET 吧(魔改过的 $_GET + $_POST )
    Gn
        10
    Gn  
       2016-04-27 01:16:41 +08:00   ❤️ 1
    可以的, hook 的方法名写 `post()` 就行,会在发帖处理前触发,这时候修改表单值就可以了。

    Discuz! 的钩子是按当前的模块名拼接之后调用的,很多东西文档里没写,但其实可用,需要自己摸索。
    lml12377
        11
    lml12377  
    OP
       2016-04-27 08:38:43 +08:00
    @Gn 赶紧试一下,谢哥!
    lml12377
        12
    lml12377  
    OP
       2016-04-27 11:02:57 +08:00
    @kookxiang 我在插件里定义了 common() ,属于全局嵌入点,加了判断 $_GET['action'] === 'newthread' && $_GET['topicsubmit'] === 'yes',代表发帖那个 form 表单提交的 url ,验证了点击发帖后是可以触发的!但是蛋疼的问题来了:官方定义 common 是“所有模块执行前被调用”,但是我这样 $_POST['subject'] = 'xxx',发完贴之后标题并没有想象中变为 xxx ,这是为何。。。
    lml12377
        13
    lml12377  
    OP
       2016-04-27 12:22:32 +08:00
    @kookxiang 已解决,给 discuz 程序员献上膝盖,服!猿哥们在 $_POST['subject'] 和 $_POST['message'] 接收到之后又往 $_GET['subject'] 和 $_POST['message'] 里存了一份... 最终入库的是 $_GET 里的数据...
    lml12377
        14
    lml12377  
    OP
       2016-04-27 12:25:51 +08:00
    @kookxiang 满屏的代码连一行注释都不给,官方文档 common() 钩子也没有说明,好在最终在 source/module/forum/forum_post.php 里面发现了猫腻:$_GET['subject'] ...
    kookxiang
        15
    kookxiang  
       2016-04-27 12:36:40 +08:00 via Android   ❤️ 1
    @lml12377 所以我叫你用 $_GET 了…这是一个坑
    lml12377
        16
    lml12377  
    OP
       2016-04-27 13:42:57 +08:00
    @kookxiang (ง •̀_•́)ง
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5492 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 08:14 · PVG 16:14 · LAX 01:14 · JFK 04:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.