• one
    主题阅读权限
    ID topic_read_groups版本 1.8.2插件制作者 one售价 5 积分2017 行 / 116.3 KBHook / 路由 / 后台页
    精确控制主题阅读权限:可设为仅指定用户组可见、仅指定用户可见(类似朋友圈"部分可见"),或完全隐藏(含游客不可见)。支持按板块与用户组限定范围,可设板块强制规则(普通用户不可改,管理员除外),并可配置是否允许贴主编辑时修改指定用户名单。
    收费插件安装说明购买后点击“授权码”获取一次性授权码;在后台 > 插件广场点击在线安装或更新,并填写该授权码。已购买用户更新免费:每次在线安装或更新前,重新点击“授权码”获取新的一次性授权码即可,无需再次购买;也可直接下载新版后用后台“插件上传”更新。尊重并感谢他人劳动,请勿传播代码。
    app/plugins/topic_read_groups/plugin.php
    开发日志已有 9 条

    个人独立维护项目。

    • one
      one
      版本 1.8.2 d9dbe3924c61 更新:修复一个SQL 拼接 bug。 `list_where()` 返回的筛选片段自带 `WHERE` 关键字,而 `visible_total()` 内部已以 `WHERE 1=1` 起头并用 ` AND $where` 追加该片段,版块页/搜索页/用户主页拼出 `WHERE 1=1 AND WHERE ...` 非法 SQL,SQLite 报 `near "WHERE": syntax error`release
    • one
      one
      版本 1.8.1 93fb0eea832e 更新:- **Changed 徽标 tooltip 复用官方面板样式**:列表徽标("仅部分用户可阅读"小人 / "您所在的用户组无阅读权限"小锁)的悬停提示由反色面板(`var(--inverse)` 深底白字)改为官方面板样式:`var(--panel)` 底色 + `var(--line)` 边框 + `var(--shadow-medium)` 阴影 + `var(--transition-no
    • one
      one
      版本 1.8.0 73fc38b7629f 更新:- **Changed 规范 API 化**:两条 AJAX 路由输出改用核心 `json_response()`(统一 JSON 头/编码选项);异常分支经 `debug_log_write()` 记日志,verify 异常返回 `ok:0` 且不携带 `invalid/map`(前端保持既有标记,避免空 `invalid` 被误判为"全部有效"),search 异常返回 `ok:0` 空结果。
    • one
      one
      版本 1.7.0 8c099c5dae03 更新:- **Fixed(严重)核心迭代适配:恢复列表隐私过滤与分页修正**:核心 `topic_index_data()` 此前直接丢弃 `topic.index_data.loaded` 钩子的返回值,导致本插件对该钩子的全部产出失效——白名单"部分可见"与"完全隐藏"主题对无权用户在列表中泄露标题,分页 `total` 修正也随之失效(隐藏主题多时出现末页空页)。修复分两层: - 核心侧:`ind
    • one
      one
      版本 1.6.1 9155ec99d81d 更新:1、细节优化 2、再次按 .ai-rules.md AI开发规则对代码做最严格的全量审查,并做修复。@350 再次帮检查
    • one
      one
      版本 1.6.0 534ce0e038f2 更新:对通知 content 中的用户名与标题做 h() 转义,防御存储型 XSS。 给 .trg-field>.trg-summary 加 flex-wrap:wrap,并给 .trg-badge 在窄屏防止溢出。同时给 .trg-group-checkbox 已 wrap(移动端 flex-wrap 适配)。 针对徽标在窄屏的适配(徽标与标题同行,长标题时徽标不应被挤压消失),并在 @media (
    • one
      one
      版本 1.5.9 3ea4d3fa47e7 更新:分页 total 精确化。 1,visible_total() 用单条 COUNT 精确统计可见总数,逻辑严密(隐藏/白名单/楼主/白名单命中/用户组命中全覆盖)。 2,短路优化:全站无限制主题时返回 -1,index_data.loaded 跳过,零额外开销常态。 3,WHERE 1=1 起头修复上次标记的中危(空 WHERE 误挂 ON 子句),SQL 拼接安全。 4,细节打磨。
    • one
      one
      版本 1.5.8 a818e930f837 更新:修正一个没给AI说清楚的逻辑: 贴主不能修改白名单开关应保留原白名单不变(提交时服务端跳过白名单写入,而非清空 - 现在的行为) 新行为:开关关闭 + 纯贴主编辑 → 跳过白名单重写,保留原白名单,保存正常完成。 开关关闭 + 贴主编辑态时,不报错、不清除,保留原白名单。即跳过白名单的 DELETE/重插,让原TOPIC_READ_GROUPS_USERS 记录不变。
    • one
      one
      版本 1.5.6 0436bca320e9 更新:1.5.6修正: 1、权限控制增强 2、用户名前缀模糊查询 3、其他细节打磨
    主楼
  • 质量报告

    插件质量报告

    插件:topic_read_groups

    Hook功能范围循环使用频率文件读写修改系统表读写系统表读写自己的表
    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 在系统循环中执行,浅蓝色表示有文件写入。“列表跳过”表示回调在列表路径会提前返回,“回调内”表示操作位于回调自身或其帮助函数的循环体内。“文件批处理”表示逐个处理用户一次提交的文件,属于必要操作,不标记修正。只有操作实际处于需要优化的循环路径时,才会标记“修正❗️”。

    数据字典

    未检测到插件数据表声明。

    #1
  • bbs1org

    存在命令执行:exec 为什么这么危险的函数

    #2
  • one

    插件中出现的 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 字样。

    */

    #3
  • one

    更新新的功能。懂的都懂:
    PixPin_2026-08-13_22-32-27.png
    PixPin_2026-08-13_22-33-17.png

    #4
  • bbs1org

    @one 那就再丰富下,加上只有指定用户名单可看。参考微信朋友圈权限

    #5
  • one

    已测试OK,但你这是要准备干嘛?

    PixPin_2026-08-13_23-33-58.png

    PixPin_2026-08-13_23-34-28.png

    #6
  • bbs1org

    可以群聊

    #7
  • one

    正在修复如果输入了不存在的用户。从400多行搞了1400行了
    PixPin_2026-08-13_23-49-51.png

    #8
  • one

    版本 1.5.6 更新:
    1.5.6修正:

    1、权限控制增强
    2、用户名前缀模糊查询
    3、其他细节打磨

    01.png
    02.png
    03.png

    最后由 one 编辑于 2026-08-16 12:11
    #9
  • one

    版本 1.5.8 更新:
    修正一个没给AI说清楚的逻辑:
    贴主不能修改白名单开关应保留原白名单不变(提交时服务端跳过白名单写入,而非清空 - 现在的行为)
    新行为:开关关闭 + 纯贴主编辑 → 跳过白名单重写,保留原白名单,保存正常完成。
    开关关闭 + 贴主编辑态时,不报错、不清除,保留原白名单。即跳过白名单的 DELETE/重插,让原TOPIC_READ_GROUPS_USERS 记录不变。

    #10
  • one

    版本 1.5.9 更新:
    分页 total 精确化。

    1,visible_total() 用单条 COUNT 精确统计可见总数,逻辑严密(隐藏/白名单/楼主/白名单命中/用户组命中全覆盖)。
    2,短路优化:全站无限制主题时返回 -1,index_data.loaded 跳过,零额外开销常态。
    3,WHERE 1=1 起头修复上次标记的中危(空 WHERE 误挂 ON 子句),SQL 拼接安全。
    4,细节打磨。

    #11
  • one

    版本 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 并提示。彻底消除异步二次提交竞态。
    #12
  • one

    版本 1.6.1 更新:
    1、细节优化
    2、再次按 .ai-rules.md AI开发规则对代码做最严格的全量审查,并做修复。@350 再次帮检查

    #13
  • one

    版本 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-*、徽标 tooltip data-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 前缀规范)。
    #14
  • one

    版本 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 回显重渲染场景,不可达)。
    #15
  • one

    版本 1.8.1 更新:

    • Changed 徽标 tooltip 复用官方面板样式:列表徽标("仅部分用户可阅读"小人 / "您所在的用户组无阅读权限"小锁)的悬停提示由反色面板(var(--inverse) 深底白字)改为官方面板样式:var(--panel) 底色 + var(--line) 边框 + var(--shadow-medium) 阴影 + var(--transition-normal) 过渡,昼夜模式经 CSS 变量自动适配;定位保留上方居中(列表行密集,下方会覆盖相邻行内容)。aria-label / hover / focus-visible 显隐行为不变。
    #16
  • one

    版本 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 关键字),与消费方拼接契约对齐。

    #17
  • zaiwai

    建议可以增加一个,发布主题的时候默认勾选,对游客默认隐藏回帖内容,需要登入才能查看回帖。主题内容如果不做限制可以对游客开放。

    #18
  • one

    其实你的这个功能这个插件已经可以实现曲线救国了(让游客吸能看到主题,点击后提示无权限)。

    #19

发表回复

登录后回复