- 内容修订留痕ID edit_history版本 1.1.0插件制作者 cxk123售价 30 积分1856 行 / 102.4 KBHook / 路由 / 后台页把「先发违规内容、被举报后偷偷改成无害内容」这条原本无法举证的逃逸路径堵死:每条主题与回帖都保留完整修订链收费插件安装说明购买后点击“授权码”获取一次性授权码;在后台 > 插件广场点击在线安装或更新,并填写该授权码。已购买用户更新免费:每次在线安装或更新前,重新点击“授权码”获取新的一次性授权码即可,无需再次购买;也可直接下载新版后用后台“插件上传”更新。尊重并感谢他人劳动,请勿传播代码。app/plugins/edit_history/plugin.php插件预览5 张开发日志已有 2 条
此项目接受所有登录用户协助维护和提交更新。
主楼 版本 1.0.0 更新:
1.0.0 首次上架:主题与回帖的「内容修订留痕」(可查 · 可对比 · 可回滚 · 可留档)【为什么需要它】
本站核心改主题/回帖时是直接覆盖旧正文(UPDATE app_topics SET …body=?/UPDATE app_replies SET body=?),
唯一的台账app_topics_del只有墓碑坐标、不含正文,且只记删除不记修改。
于是「先发违规内容、被举报后偷偷改成无害内容」在技术上无法举证。
本插件把改前正文留痕,处置争议的举证成本从「无法举证」降到「一条 diff」。【新能力】
- 修订落库:改前正文在
topic.before_save/reply.before_save捕获,写成功之后(after_save)才提交
—— 被拒绝的编辑(无权限、内容非法、置顶/高亮这类管理动作)一律不留痕,绝不产生「内容没变却多一条修订」的假账。
正文前后值、标题前后值、字数与逐行差异摘要、编辑人、时间、编辑器类型全部入库;内容一字没改则一条不写。- 合并窗口:同一个人连续编辑同一楼,窗口内(默认 10 分钟,可配 0 = 关闭)合并成一条修订,
并且「改前」始终是这一串改动最开始的那一版,不会越合越糊。
- 前台对比视图:
?a=edit_history&kind=topic|reply&id=内容id—— 时间线 + 纯 PHP 逐行 diff(自写 LCS,
无任何外部库、无 JS 依赖,
<details>原生折叠)+ 改前/改后原文 + 当前正文。
楼层操作区有一个「修订 N 次」入口(管理团队看总数,普通用户只看得到自己改过的次数)。- 一键回滚(管理团队):POST + 必填理由 + 二次确认,可「撤销这次修改(恢复改前)」或「恢复到这里(改后)」;
回滚前把当前正文另存为一条新修订,历史只增不减;标题一并回滚(不留「标题是新的、正文是旧的」这种半吊子状态)。
- 保留策略与存储控制:按天 / 按条数(按内容计)集合式清理,每条内容的最新一版永远保留;
后台可看存储占用(行数 / 字节 / 最早最新时间)、清理记录与审计台账,也可以按内容清空历史(必填理由 + 审计)。
- 后台一个 Tab:全局开关 / 保留策略 / 最近修订流(按类型、内容 id、主题 id、编辑人用户名等值筛选)/ 存储占用 /
清理记录 / 按内容清空历史 / 审计台账(append-only)。
【隐私口径(本插件最硬的一条)】
落库期与展示期各过一次 anon_board 的批量遮蔽契约:匿名内容的修订里editor_id与author_id一律写 0,
只留遮蔽后的显示名;版主代改匿名内容也只写通用匿名名,不给「哪个匿名号动了这条内容」留任何解匿侧信道。
契约缺字段 / 抛异常一律 fail-closed(整批按匿名渲染并显式提示),绝不降级成真名。【查询预算】
主题页 +1(整页一次 IN 批查,含「我改过几条」);逐楼入口 0 查询;对比视图 2;后台 Tab 5;
回滚 POST ≤6。站点上一条修订都没有时主题页 0 查询(站点标记短路);所有批查用IN (0)占位保证条数恒定。【兼容】
· 只加自己的两张表(plugin_edit_history_revisions/plugin_edit_history_audit),**不改任何 app_* 既有列**;
· 依赖的钩子全部是核心既有扩展点,未装别的插件也能单独工作;未装匿名区时遮蔽契约零查询降级;
· 卸载(保留数据关)会把两张表与全部站点标记清干净,重装幂等。- 修订落库:改前正文在
插件质量报告
插件:
edit_historyHook 功能范围 循环 使用频率 文件读写 修改系统表 读写系统表 读写自己的表 topic.replies_data.loaded 主题查看页回帖查询后 否 4 - - - 读 plugin_edit_history_revisions reply.after_save 回帖保存后 否 3 - - - 写 plugin_edit_history_revisions reply.before_save 回帖发布/编辑表单提交 否 3 - - app_replies, app_topics - topic.after_save 主题保存后 否 3 - - - 写 plugin_edit_history_revisions topic.before_save 主题发布/编辑表单提交 否 3 - - app_topics - post.ops_actions 非系统hook 否 1 - - - - 颜色说明:黄色表示有数据读写,红色表示 Hook 在系统循环中执行,浅蓝色表示有文件写入。“列表跳过”表示回调在列表路径会提前返回,“回调内”表示操作位于回调自身或其帮助函数的循环体内。“文件批处理”表示逐个处理用户一次提交的文件,属于必要操作,不标记修正。只有操作实际处于需要优化的循环路径时,才会标记“修正❗️”。
数据字典
plugin_edit_history_revisions字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_edit_history_audit字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 版本 1.1.0 更新:
1.1.0 · 留痕页可见性- 修复(越权读):前台留痕页此前只要求登录,没有版本块可见性判定 —— 任何登录用户按连续的主题/回帖 id 就能读到「仅指定用户组可见」版块里内容的当前标题与全文。现在补上与核心同一口径的可见性判定,无权时按「不存在」处理(避免被用来枚举内容是否存在);版块信息缺失时同样按拒绝处理。
- 无数据结构变更。