- 定时发布ID scheduled_post版本 1.0.0插件制作者 cxk123售价 30 积分1400 行 / 82.1 KBHook / 路由 / 后台页写好主题、指定一个发布时间,到点由计划任务自动替你发出去(时间按**站点时区**解释,最长可排 90 天,收费插件安装说明购买后点击“授权码”获取一次性授权码;在后台 > 插件广场点击在线安装或更新,并填写该授权码。已购买用户更新免费:每次在线安装或更新前,重新点击“授权码”获取新的一次性授权码即可,无需再次购买;也可直接下载新版后用后台“插件上传”更新。尊重并感谢他人劳动,请勿传播代码。app/plugins/scheduled_post/plugin.php插件预览6 张开发日志已有 1 条
此项目接受所有登录用户协助维护和提交更新。
主楼 版本 1.0.0 更新:
首次上架(1.0.0)。市场里 排期 / 待发布 / 自动发布 / 预约发布 / schedul 此前 0 命中;核心
app_topics只有created_at,
发出来就是发出来了,没有任何「未来时间」的概念 —— 想「早上写好、上班时间自动发」只能靠人守着点。
这一款补的就是这件事:写好主题、指定一个发布时间,到点由计划任务自动替你发出去。- 发帖页原生的「定时发布」区块:就在核心那张发帖表单里,选一个时间点「加入排期」即可(
formaction交给排期路由,
不复制核心表单的任何输入框、不改变「保存」立即发帖的行为);带附件时页面明确提示并在服务端拒绝
(附件与会话上传时序绑定,跨请求延迟发布不可靠)。- 我的排期:待发布 / 发布中 / 已发布 / 发布失败 / 已取消 五种状态,状态页签带计数;每条能改时间、
取消、立即发;失败的那条把失败原因直接印在行里,已发布的给「查看主题 #N」直达链接;
每条排期都有审计留痕(create / reschedule / cancel / defer / publish / fail / retry / immediate)。- 到点自动发布走的是与手动发帖完全同一条核心写路径(
save_topic()):同样的版块与用户组校验、
同样的标题正文长度、同样的发帖间隔、同样的全文索引与全部钩子(
topic.before_save/
topic.after_save都照常触发,别的插件的写路径钩子看到的就是一次正常发帖)。
所以作者到点被禁言 / 封禁 / 删号时,这条排期会发布失败并留痕,绝不绕过校验偷偷发出去。- 并发只发一次:用 CAS(
UPDATE … WHERE status='pending'+rowCount())抢发,两个管理员同时点「立即检查并发布」
也只会建出 1 篇主题;被核心校验或别的插件的策略钩子
err()中断时,由 shutdown 兜底把那条留痕成失败,
不会留下停在「发布中」的黑洞条目(超时残行会自动复位重排)。- 同一作者的连续排期逐条错开:发帖间隔没过的那条顺延到间隔之后(保持待发布、记
defer审计),
不丢内容、也不误报失败。
- 匿名版块 fail-closed:站点装了匿名区时,定时发布默认在所有版块关闭,由站长在后台逐版块确认后开放,
开放后一律以匿名身份发出(匿名登记由匿名区在核心保存钩子里自己落地,本插件不碰它的表、不调它的函数);
配置在排期之后被改窄,发布时复核守卫 → 该条失败留痕,不做「猜着发」。- 后台一个 Tab:排期总数 / 待发布(含 24 小时内到期)/ 发布中 / 已发布 / 发布失败 / 已取消 / 最近一条待发
+ 队列(按状态筛选,作者 / 版块 / 定时 / 状态 / 尝试次数 / 结果 / 强制取消·重试)
+ 「立即检查并发布到期条目」(计划任务租约被占住时的兜底)
+ 设置(总开关、允许普通用户、每人待发布上限、最长可排天数、开放版块白名单、匿名区逐版块白名单、每页条数)
+ 最近审计流。审计只记topic_id与时间,正文与标题不进审计表。- 时间一律按站点时区解释(本站
Asia/Shanghai,页面上写明):datetime-local输入经
DateTimeImmutable::createFromFormat()解析,跨日 / 跨月 / 夏令时边界交给 PHP 时区库;过去的时间、
超过上限的时间、非法时间一律拒绝(服务端为准,不猜)。查询预算(实测):首页 0 条(不挂首页槽位,启用=停用)、发帖页 0 条(区块只读配置与插件缓存)、
「我的排期」≤4 条、后台 ≤6 条;计划任务固定条数、按到期条数一次取回、每条到期条目的边际成本恒定。
核心app_*表一列都不加,自有表全部plugin_scheduled_post_前缀。验收:
tools/lab_verify_scheduled_post.sh543 项通过 / 0 失败(私有站点副本 + 独占端口;
含 CAS 并发三组、失败留痕、时区逐秒比对、查询预算、卸载重装);七道静态门禁全绿。
已知边界(1.0.0 首版,如实写明):① 排期不支持附件(页面提示 + 服务端拒绝);
② 到点发布是跨请求动作,作者那一刻的禁言 / 封禁会让这条失败(这是设计,不是缺陷);
③ 被err()中断的那一轮会提前结束,其余到期条目留到下一轮(后台有「立即检查并发布」兜底);
④v1.0.0只支持改时间 / 取消 / 重试 / 立即发,不支持改已排期的正文(要改就取消重排)。- 发帖页原生的「定时发布」区块:就在核心那张发帖表单里,选一个时间点「加入排期」即可(
插件质量报告
插件:
scheduled_postHook 功能范围 循环 使用频率 文件读写 修改系统表 读写系统表 读写自己的表 app.boot 全站请求启动 否 5 - - - 写 plugin_scheduled_post_queue, plugin_scheduled_post_audit sidebar.feature_links 首页/侧栏快捷功能 否 5 - - - - user.menu_links 个人卡片/移动端我的菜单(展示位置:个人卡片) 否 4 - - - - topic.form_extra 主题发布/编辑表单 否 2 - - - - 颜色说明:黄色表示有数据读写,红色表示 Hook 在系统循环中执行,浅蓝色表示有文件写入。“列表跳过”表示回调在列表路径会提前返回,“回调内”表示操作位于回调自身或其帮助函数的循环体内。“文件批处理”表示逐个处理用户一次提交的文件,属于必要操作,不标记修正。只有操作实际处于需要优化的循环路径时,才会标记“修正❗️”。
数据字典
plugin_scheduled_post_queue字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_scheduled_post_audit字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析