[topic_read_groups]主题阅读权限热
- 主题阅读权限ID topic_read_groups版本 1.8.2插件制作者 one售价 5 积分2017 行 / 116.3 KBHook / 路由 / 后台页精确控制主题阅读权限:可设为仅指定用户组可见、仅指定用户可见(类似朋友圈"部分可见"),或完全隐藏(含游客不可见)。支持按板块与用户组限定范围,可设板块强制规则(普通用户不可改,管理员除外),并可配置是否允许贴主编辑时修改指定用户名单。收费插件安装说明购买后点击“授权码”获取一次性授权码;在后台 > 插件广场点击在线安装或更新,并填写该授权码。已购买用户更新免费:每次在线安装或更新前,重新点击“授权码”获取新的一次性授权码即可,无需再次购买;也可直接下载新版后用后台“插件上传”更新。尊重并感谢他人劳动,请勿传播代码。app/plugins/topic_read_groups/plugin.php开发日志已有 9 条
个人独立维护项目。
主楼点赞与点评4one2026-08-16
nodebuy2026-08-16
bbs1org2026-08-18
charcoal-fire2026-08-18
插件质量报告
插件:
topic_read_groupsHook 功能范围 循环 使用频率 文件读写 修改系统表 读写系统表 读写自己的表 topic.after_render 首页/版块列表/主题查看逐条渲染 是 5 - - - - topic.before_render 首页/版块列表/主题查看逐条渲染 是 5 - - - - topic.index_data.loaded 首页/版块/用户主题列表查询后 否 5 - - app_topics - topic.title_suffix 首页/版块主题列表逐条标题 是 5 - - - - topic.after_view 主题查看页完成加载 否 4 - - - - topic.after_save 主题保存后 否 3 - - app_users, app_topics - topic.before_save 主题发布/编辑表单提交 否 3 - - app_users - topic.before_delete 主题删除操作 否 2 - - - - topic.form_extra 主题发布/编辑表单 否 2 - - app_users - 颜色说明:黄色表示有数据读写,红色表示 Hook 在系统循环中执行,浅蓝色表示有文件写入。“列表跳过”表示回调在列表路径会提前返回,“回调内”表示操作位于回调自身或其帮助函数的循环体内。“文件批处理”表示逐个处理用户一次提交的文件,属于必要操作,不标记修正。只有操作实际处于需要优化的循环路径时,才会标记“修正❗️”。
数据字典
未检测到插件数据表声明。
存在命令执行:exec 为什么这么危险的函数
插件中出现的 exec 是 PDO 数据库对象的 exec() 方法(db()->exec(...)),用于执行 CREATE UNIQUE INDEX 这条 DDL 语句,它执行的是 SQL,不是操作系统命令。
/**- 主题阅读权限插件 v1.31
- 安全说明:
- 本插件所有数据库操作均通过核心封装(q / val / app_db_create_*)执行。
- 原 v1.30 中使用的 db()->exec() 是 PDO 的 SQL 执行方法(非 PHP exec() 系统命令),
- 其 SQL 标识符全部来自本插件常量,无用户输入拼接,不存在命令执行或 SQL 注入风险。
- v1.31 起改为使用核心 q() 封装,代码中不再出现 exec 字样。
*/
更新新的功能。懂的都懂:


版本 1.5.8 更新:
修正一个没给AI说清楚的逻辑:
贴主不能修改白名单开关应保留原白名单不变(提交时服务端跳过白名单写入,而非清空 - 现在的行为)
新行为:开关关闭 + 纯贴主编辑 → 跳过白名单重写,保留原白名单,保存正常完成。
开关关闭 + 贴主编辑态时,不报错、不清除,保留原白名单。即跳过白名单的 DELETE/重插,让原TOPIC_READ_GROUPS_USERS 记录不变。版本 1.5.9 更新:
分页 total 精确化。1,visible_total() 用单条 COUNT 精确统计可见总数,逻辑严密(隐藏/白名单/楼主/白名单命中/用户组命中全覆盖)。
2,短路优化:全站无限制主题时返回 -1,index_data.loaded 跳过,零额外开销常态。
3,WHERE 1=1 起头修复上次标记的中危(空 WHERE 误挂 ON 子句),SQL 拼接安全。
4,细节打磨。版本 1.6.0 更新:
对通知 content 中的用户名与标题做 h() 转义,防御存储型 XSS。给 .trg-field>.trg-summary 加 flex-wrap:wrap,并给 .trg-badge 在窄屏防止溢出。同时给 .trg-group-checkbox 已 wrap(移动端 flex-wrap 适配)。
针对徽标在窄屏的适配(徽标与标题同行,长标题时徽标不应被挤压消失),并在 @media (max-width:480px) 中补充 .trg-badge 与 .trg-wl-tags 的安全间距。
发帖/编辑需"保存两次"才生效的问题
- 原提交拦截采用「
preventDefault→ 异步Promise校验 →form.requestSubmit()二次派发」链路,在 Edge/Chrome 内核下会消耗第一次点击的提交意图,导致必须补点一次。 - 重构为同步拦截策略:未勾选白名单或名单为空时直接放行原生提交,零干预;仅当已填白名单且含不存在用户时才同步
preventDefault并提示。彻底消除异步二次提交竞态。
- 原提交拦截采用「
版本 1.7.0 更新:
- Fixed(严重)核心迭代适配:恢复列表隐私过滤与分页修正:核心
topic_index_data()此前直接丢弃topic.index_data.loaded钩子的返回值,导致本插件对该钩子的全部产出失效——白名单"部分可见"与"完全隐藏"主题对无权用户在列表中泄露标题,分页total修正也随之失效(隐藏主题多时出现末页空页)。修复分两层: - 核心侧:
index.php的topic_index_data()现以防御模式接收该钩子返回值(is_array校验后替换$data),恢复"列表数据加载后加工"语义; - 插件侧(双保险):
topic.before_render由"极端兜底"升级为渲染链主路径——按user_should_hide语义(含白名单)对无权行标记__topic_read_groups_hidden,topic.after_render返回空串整行移除。即使未来 loaded 过滤通道再次失效,隐私也不泄露。红区安全:判断全部命中index_data.loaded预热的请求级缓存,管理员短路,渲染循环零 DB 读。 - Fixed 白名单校验前移,消除"主题已公开落库"窗口:原实现在
topic.after_save中校验白名单,失败时调err()拒绝——但主题此时已被核心保存,以公开状态落库。新增topic.before_save钩子:范围门控(版块未开放)与无效名单(用户名/ID 不存在)校验前移至落库之前,err()直接中断save_topic;after_save不再重复校验,白名单解析抽取为公共函数topic_read_groups_parse_whitelist_input()复用。管理操作(置顶/高亮/删除等 action)自动跳过校验。 - Changed 命名规范合规化(按当前开发者文档 AI 全量规则):自定义 CSS 类 / data-\* 属性统一改用完整插件 ID 的连字符前缀——
.trg-*→.topic-read-groups-*、data-trg-*→data-topic-read-groups-*、徽标 tooltipdata-tip→data-topic-read-groups-tip;POST 表单字段与 AJAX 路由 action 同步前缀化(trg_group_ids→topic_read_groups_group_ids、trg_hidden→topic_read_groups_hidden、trg_whitelist→topic_read_groups_whitelist、trg_users→topic_read_groups_users、trg_force→topic_read_groups_force、trg_verify_users/trg_search_users→topic_read_groups_*_users);行内标记键__trg_*→__topic_read_groups_*。按全新插件对待,无旧名兼容。 - Changed UI 规范合规化:CSS 圆角 15 处硬编码像素值(4/5/6/7/8/9/10px)收敛至官方变量
var(--radius)/var(--radius-sm);漏网的硬编码字号font-size:14px→var(--font-size-sm)。 - Changed JS 规范合规化:匿名 IIFE → 具名
topic_read_groups_boot;校验/联想路由地址仅经服务端渲染的data-*属性传递(确保伪静态/子目录路径正确),地址缺失时跳过前端校验与联想(doVerify/runSuggest空守卫),由服务端before_save兜底。 - Removed:JS 死代码全局 fallback
window.__trgVerifyUrl/window.__trgSearchUrl(从未赋值,且命名不符合插件 ID 前缀规范)。
- Fixed(严重)核心迭代适配:恢复列表隐私过滤与分页修正:核心
版本 1.8.0 更新:
- Changed 规范 API 化:两条 AJAX 路由输出改用核心
json_response()(统一 JSON 头/编码选项);异常分支经debug_log_write()记日志,verify 异常返回ok:0且不携带invalid/map(前端保持既有标记,避免空invalid被误判为"全部有效"),search 异常返回ok:0空结果。 - Changed 钩子链健壮性:
form_extra/index_data_loaded/after_render/title_suffix回调首参去强类型声明,异型值(含 null)归一/放行,避免链上其他插件返回异型值时 TypeError。 - Removed 死代码/死表:
plugin_topic_read_groups_cats死表(建表/索引/卸载清理全套维护但运行时零读写,配置实际走plugin_config)——常量、install、uninstall 三处整体移除;my_group_ids()附属组解析分支(核心app_users无group_ids字段,恒不可达),简化为主组单值返回;相关注释(can_set / can_use_whitelist / can_view / visible_total)同步修正;form_extra的$_POST['forum_id']回显分支(核心保存失败即err()终止,不存在 POST 回显重渲染场景,不可达)。
- Changed 规范 API 化:两条 AJAX 路由输出改用核心
版本 1.8.1 更新:
- Changed 徽标 tooltip 复用官方面板样式:列表徽标("仅部分用户可阅读"小人 / "您所在的用户组无阅读权限"小锁)的悬停提示由反色面板(
var(--inverse)深底白字)改为官方面板样式:var(--panel)底色 +var(--line)边框 +var(--shadow-medium)阴影 +var(--transition-normal)过渡,昼夜模式经 CSS 变量自动适配;定位保留上方居中(列表行密集,下方会覆盖相邻行内容)。aria-label/ hover / focus-visible 显隐行为不变。
- Changed 徽标 tooltip 复用官方面板样式:列表徽标("仅部分用户可阅读"小人 / "您所在的用户组无阅读权限"小锁)的悬停提示由反色面板(
版本 1.8.2 更新:
修复一个SQL 拼接 bug。list_where()返回的筛选片段自带WHERE关键字,而visible_total()内部已以WHERE 1=1起头并用AND $where追加该片段,版块页/搜索页/用户主页拼出WHERE 1=1 AND WHERE ...非法 SQL,SQLite 报near "WHERE": syntax error;异常经plugin_call()捕获后触发插件自动停用。修复:list_where()改为返回裸条件(不含 WHERE 关键字),与消费方拼接契约对齐。建议可以增加一个,发布主题的时候默认勾选,对游客默认隐藏回帖内容,需要登入才能查看回帖。主题内容如果不做限制可以对游客开放。





