官方不提供现金交易,线下交易风险自担,请仔细鉴别!
xnx_need_avatar 默认头像发帖拦截
Xiuno BBS X 插件,对仍使用系统默认头像的用户拦截发帖与回帖操作,引导其先到个人中心设置自定义头像,从而提升社区内容质量与视觉一致性。通过多个 hook 在请求入口与提交前双重拦截,核心代码零硬编码插件名。
功能特性
默认头像判定:基于
user_read_cache($uid)读出的avatar_url字符串与default_avatar_url()严格比较,覆盖三种「实际仍是默认头像」的场景:
1. avatar==0(从未设置过头像)
2. avatar<0 且对应预设头像文件已被删除(user_format 回落默认) 3. avatar>0 但上传的物理文件丢失(user_format 回落默认)
双重拦截:GET 请求入口拦截(输出完整提示页)+ POST 提交前兜底拦截(输出 htmx 友好的 HTML 片段),绕过页面直连接口提交同样被拦
全场景覆盖:发新帖、回帖、帖子详情页快速回复表单三处入口均有拦截点
快速回复表单替换:命中拦截时用 CSS 隐藏原表单元素,改为显示「请先设置头像」提示卡 + 「去设置」链接,而非整体跳转
用户组豁免:管理员组(gid=1,2)默认豁免,可后台自定义豁免用户组列表(逗号分隔)
一键开关:后台可整体启用 / 禁用,禁用后所有 hook 调用
shouldBlock()立即返回 false多语言:内置简体中文、繁体中文、英文三套语言包
安装说明
将插件目录放入
plugin/xnx_need_avatar/进入后台「插件管理」找到「默认头像发帖拦截」点击安装
安装时自动写入默认配置:
enabled=1、exempt_gids='1,2'(即默认启用,管理员组豁免)卸载时自动删除
xnx_need_avatar配置项,不残留数据
插件仅使用 setting 表存储配置,不建任何附加数据表,安装 / 卸载零副作用。
使用指南
后台配置
访问 /admin/plugin-setting-xnx_need_avatar,仅管理员组(gid=1,2)可进入,POST 操作经 CsrfService::check() CSRF 校验。
| 配置项 | 字段名 | 说明 | |---|---|---| | 启用状态 | enabled | 1=启用拦截,0=禁用(默认启用) | | 豁免用户组 | exempt_gids | 逗号分隔的用户组 ID,命中即跳过拦截(默认 1,2) |
保存后通过 NeedAvatarService::saveSettings() 写入 setting 表,下次请求即时生效。
前台行为
普通用户未设置头像时,访问发帖页 / 回帖页会看到完整提示页(含 header/footer),引导跳转个人中心
直接 POST 提交发帖 / 回帖时,返回警告样式的 HTML 片段(含「去设置」链接),htmx 容器友好
帖子详情页的快速回复表单会被 CSS 隐藏,替换为「请先设置头像后再发帖」提示,并附「去设置」链接到
my_url()豁免用户组成员、已设置头像的用户无任何感知,流程与原生一致
技术细节
拦截点 hook 列表
| Hook 文件 | 触发位置 | 拦截方式 | |---|---|---| | thread_create_get_start.php | 发帖页 GET 入口 | renderBlockPage() 输出完整页并 exit | | thread_create_thread_before.php | 发帖 POST 提交前 | renderBlockHtml() 输出片段并 exit | | post_get_start.php | 回帖页 GET 入口 | renderBlockPage() 输出完整页并 exit | | post_post_start.php | 回帖 POST 提交前 | renderBlockHtml() 输出片段并 exit | | thread_quick_reply_message_before.htm | 帖子详情页快速回复表单渲染前 | CSS 隐藏表单 + 提示卡注入 | | model_inc_file.php | 核心加载模型时 | 将 NeedAvatarService.php 注册进全局 include 列表 | | lang_zh_cn_bbs.php / lang_zh_tw_bbs.php / lang_en_us_bbs.php | 语言包加载 | 注入简中 / 繁中 / 英文文案 |
所有 hook 在 conf.json 的 hooks_rank 中均设为 100,与其他插件无优先级冲突。
默认头像判定逻辑
NeedAvatarService::isDefaultAvatar($uid) 实现:
调用
user_read_cache($uid)读取用户缓存(含user_format处理后的avatar_url)若用户不存在直接返回
true(保守拦截)严格比较
$user['avatar_url'] === default_avatar_url(),相等即视为默认头像
这种基于「最终渲染 URL 字符串」的判定比直接读 avatar 字段数值更稳健,能覆盖 user_format 在文件缺失时回落默认头像的三种边界场景,避免误判或漏判。
拦截决策流程
NeedAvatarService::shouldBlock($uid, $gid) 按以下顺序判断:
读取配置,若
enabled为空 → 返回false(插件被禁用)解析
exempt_gids字符串为数组,若当前gid命中 → 返回false(豁免)否则返回
isDefaultAvatar($uid)结果
exempt_gids 解析支持任意空白与多余逗号容错(parseGids() 已做 trim 与空值过滤)。
GET vs POST 拦截的差异
GET 入口拦截(
renderBlockPage):输出包含view/htm/header.inc.htm与footer.inc.htm的完整页面,居中显示警告图标 + 提示文案 + 「去设置」按钮,调用exit终止后续流程POST 提交拦截(
renderBlockHtml):仅设置Content-Type: text/html; charset=utf-8头并输出alert alert-warning样式的 HTML 片段,适合 htmx 异步刷新容器直接渲染,同样exit终止
两套输出均通过 my_url() 生成跳转链接,指向用户个人中心。
快速回复表单处理
thread_quick_reply_message_before.htm hook 在帖子详情页快速回复表单渲染前执行:
通过
<style>#quick_reply_form > :not(.need-avatar-tip){display:none !important}</style>隐藏表单原有元素注入一个
.need-avatar-tip警告卡片,含「请先设置头像后再发帖」文案与「去设置」链接不调用
exit,允许页面其余部分正常渲染
配置兜底
NeedAvatarService::getSettings() 在 setting_get 返回空或字段缺失时,会自动补齐 enabled=1、exempt_gids='1,2',确保即使 setting 表异常也不会导致 shouldBlock() 报错。
兼容性
Xiuno BBS X 1.1+(
bbs_version: 1.1)PHP 8.x(对
isset兜底、intval严格比较、in_array第三参数true严格模式)Bootstrap 5(提示页与卡片使用
x-card、alert、btn等原生类)Tabler Icons(
ti ti-photo图标,跟随主题自带图标库)无 jQuery 依赖
依赖核心函数
default_avatar_url()、user_read_cache()、my_url(),需核心版本提供通过 hook 注入,核心代码无硬编码插件名,插件禁用后拦截行为自动失效
版本历史
1.0.0:首版发布,包含默认头像判定、发帖 / 回帖 GET+POST 双重拦截、快速回复表单替换、用户组豁免、后台启用开关、简中 / 繁中 / 英文三语言支持
版本 1.0.0 | 兼容 Xiuno 1.1+