「外链图片自动本地化」

这款「外链图片自动本地化」插件(v1.0.0)专为 XIUNOX BBS 设计,全面支持发帖、回帖时的外链图片自动转存,并具备多图批量处理、失败容错、历史批量扫描、定时扫描及日志清理等完善功能。以下是该插件的详细功能与配置说明:

核心功能特性

  • 自动转存与多图处理:在发帖、回帖或编辑时,自动检测内容中的外链图片(支持 <img> 标签、BBCode [img] 及裸链接),通过 cURL 下载并替换为本站附件地址。支持单帖多张图片的批量识别与去重,部分失败不影响其他图片。

  • 失败容错与重试:当遇到下载超时、403 或文件损坏时,系统会保留原始外链不变,不阻断发布流程,并在后台记录失败日志(包含原链接、错误原因及关联帖子ID)。后台支持对失败日志进行一键重试,自动更新原帖内容。

  • 防盗链绕过与域名过滤:cURL 会自动携带从源 URL 提取的合理 Referer 及后台可配置的 User-Agent,提高抓取成功率。支持灵活的域名黑白名单配置(白名单仅转存指定域名,黑名单跳过如本站 CDN 的指定域名)。

  • 多格式兼容与安全校验:智能识别 jpg/png/gif/webp/bmp/svg 格式,对非图片后缀但 Content-Type 为图片的外链进行智能识别与重命名。所有 POST 操作均带有 CSRF token 防护,并严格进行管理员权限检查。

  • 历史批量与定时扫描:后台支持手动触发批量扫描(按版块/时间段筛选,带进度条与统计);同时支持通过系统 Cron 自动扫描最近 N 天的帖子/回复进行批量转存。

  • 定时清理与用户反馈:通过系统 Cron 自动清理超过保留天数的失败日志和任务记录。转存过程中若有图片失败,发布成功后会以轻量级 Toast 通知用户“部分图片未能保存到本地”。

插件文件结构

plugin/oulin_imglocal/
├── conf.json                    # 插件元数据、hooks_rank
├── icon.png                     # 插件图标(64x64)
├── install.php                  # 建表 + 默认配置
├── uninstall.php                # 删表 + 删除配置 + 清理日志文件
├── upgrade.php                  # 幂等迁移(预留)
├── setting.php                  # 后台设置控制器
├── readme.md                    # 使用说明
├── model/
│   └── ImglocalService.php      # 核心业务:processContent、downloadAndSave、extractImageUrls、cronScan、autoCleanLogs
├── hook/
│   ├── model_inc_file.php       # 注册 Service 类加载路径
│   ├── model_thread_create_end.php  # 发帖后处理(模型层)
│   ├── model_post_create_end.php    # 回帖后处理(模型层)
│   ├── model_thread_update_end.php  # 编辑主题后处理(模型层)
│   ├── model_post_update_end.php    # 编辑回复后处理(模型层)
│   ├── thread_create_thread_end.php # 发帖后处理(路由层)
│   ├── post_create_post_end.php     # 回帖后处理(路由层)
│   ├── cron_cleanup.php         # 定时清理日志 + 定时扫描
│   ├── message_start.htm        # 失败 Toast 提示
│   └── lang_zh_cn_bbs.php       # 翻译键定义
├── view/htm/
│   └── setting.htm              # 后台页面(设置/批量/日志三标签)
└── static/
    ├── js/admin.js              # 后台 JS(标签切换、AJAX 提交)
    └── css/admin.css            # 后台样式

数据库表设计

1. oulin_imglocal_log(失败日志表)

字段

类型

说明

id

int unsigned AUTO_INCREMENT

主键

uid

int unsigned

用户ID

tid

int unsigned

主题ID

pid

int unsigned

回复ID

appid

int unsigned

应用ID

source_url

varchar(512)

原始外链地址

error_reason

varchar(255)

失败原因

retry_count

tinyint unsigned

重试次数

created

int unsigned

记录时间戳

2. oulin_imglocal_task(批量任务表)

字段

类型

说明

id

int unsigned AUTO_INCREMENT

主键

uid

int unsigned

操作用户ID

type

varchar(32)

扫描类型

fid

int unsigned

版块ID

start_time

int unsigned

开始时间戳

end_time

int unsigned

结束时间戳

total_count

int unsigned

总数

success_count

int unsigned

成功数

fail_count

int unsigned

失败数

status

tinyint(1)

0待执行 1执行中 2已完成

message

varchar(255)

消息

created

int unsigned

创建时间戳

配置与定时扫描流程

后台配置流程

  1. 进入后台「插件」→ 启用「外链图片自动本地化」插件(自动建表并写入默认配置)。

  2. 进入插件设置 → 勾选「启用外链图片本地化」并选择作用范围(新帖/回帖/编辑帖子/AppCenter应用)。

  3. 配置下载参数(单张最大大小、超时时间)及域名过滤(白名单/黑名单)。

  4. 配置定时扫描(开关、每次扫描数量、扫描时间范围)与日志清理(开关、保留天数)。

  5. 配置系统 Cron:0 3 * * * cd /path/to/xiuno && php cron.php

  6. 测试:发布含外链图片的帖子,验证图片是否自动转存为本地附件。

定时扫描流程 Cron 触发 hook/cron_cleanup.php 后调用 ImglocalService::cronScan()

  1. 读取配置(如扫描数量 N=50、时间范围=7天),计算时间起点 = 当前时间 - N 天。

  2. 查询最近 N 天的主题(LIMIT 50)→ 遍历 → processContent() 提取并转存外链图片 → thread_update() 更新内容。

  3. 查询最近 N 天的回复(LIMIT 50)→ 遍历 → processContent() 提取并转存外链图片 → post_update() 更新内容。

  4. 记录调试日志到 tmp/oulin_imglocal_debug.log

扩展说明

如需扩展更多图片来源,可修改 ImglocalService::extractImageUrls() 方法,添加新的正则匹配规则;如需添加新的存储策略,可修改 saveAttachment() 方法,自定义存储路径和文件命名规则。


oulin_imglocal_C7Lsz.tar 120.0KB
最新回复
  • AI Lv1

    插件功能设计完善,覆盖发帖、编辑及历史数据补全,逻辑清晰。

    几点建议供参考:

    1. 并发控制:定时扫描若同时处理大量帖子,可能占用过多服务器资源导致超时。建议在 cronScan 中加入信号量锁或限制并发数,确保不影响正常用户访问。
    2. 存储路径规范:确保 saveAttachment 严格遵循 XiunoX 的附件目录结构(如按年/月分文件夹),避免文件堆积在根目录影响性能。
    3. Cron 兼容性:部分主机不支持标准 Cron,建议提供基于 HTTP 触发的备选方案或明确说明依赖环境。

    整体实现符合 PHP 8+ 最佳实践,CSRF 防护和权限检查到位。期待后续版本优化。【以上由 AI 自动回复,仅供参考】

    7天前
  • 本地化,太占服务器空间了,但是如果不本地化图片又不直达放在那里好,很矛盾的呀。
    6天前

请先登录后再回复 登录

uid:38 Lv2
关注
发帖 19
评论 55
粉丝 1
关注 0
发新帖
目录
「外链图片自动本地化」