=== 子比多平台文章同步 (zibll-post-sync) ===

作者：阿晨
网站：https://navigation.hoarfall.com/
适用于：WordPress + 子比主题（zibll）；同步核心也兼容普通 WordPress。

== 功能 ==
- 在主站点发布 / 编辑文章时，自动把文章推送同步到其它站点。
- 同步范围包含：分类目录（category）、标签（post_tag）、专题（topics），以及标题、正文、摘要、别名、发布时间、评论状态、作者（按邮箱匹配）、特色图。
- 可选「删除也同步」：主站删除文章时，同步删除其它站对应的同步文章（仅删除同步来的文章，不会误删对方原创内容）。
- 提供「立即同步全部已发布文章」与「测试目标站连通性」按钮。
- HMAC-SHA256 签名 + 时间戳防重放鉴权，密钥不随请求明文比对。

== 安装 ==
1. 把 zibll-post-sync 目录上传到每个参与站点的 /wp-content/plugins/。
2. 在 WordPress 后台「插件」中启用「子比多平台文章同步」。
3. 依赖子比主题时，后台会出现「文章同步」菜单（基于 Codestar Framework）。普通 WordPress 下同步核心仍可用，只是设置页需要子比主题才能显示。

== 配置（典型：一个主站 + 多个接收站）==
主站点（推送）：
- 角色：主站点（仅推送，不接收）
- 推送设置 → 目标站点：逐个添加
    * 站点地址：其它站点的完整地址，如 https://other-site.com
    * 接收密钥：填写对方在「接收设置」里配置的接收密钥（两端必须一致）
- 勾选需要同步的文章类型与分类法（默认已含 分类/标签/专题）
- 可选开启「删除也同步」
- 点「测试所有目标站连通性」确认配置正确

接收站（接收）：
- 角色：接收站（仅接收，不推送）
- 接收设置 → 接收密钥：生成一段复杂字符串（如 openssl rand -hex 16），保存
- 把这段密钥填回主站对应目标站的「接收密钥」
- 可选：来源白名单（只允许特定主站地址）、默认作者（邮箱匹配失败时的归属）、允许接收的分类法

双端模式：如需要在多个站点之间互相同步，可把角色设为「双端」。插件会为每篇同步来的文章记录来源标记，
不会对同步来的文章再次回推，从而避免回环。

== 工作原理 ==
- 主站监听 save_post：文章变为/保持 publish 状态时，构建 payload（标题、正文、分类法按 slug、特色图 URL、作者邮箱等），
  逐目标站以 POST 请求发送到 /wp-json/zibll-post-sync/v1/receive，并附带签名与时间戳。
- 接收站校验签名、时间戳（±300 秒）与可选来源白名单后：按 source_site + source_post_id 查找是否已存在对应文章；
  不存在则新建，存在则更新。分类法按 slug 在本地创建/更新后挂载，特色图下载到媒体库并设为缩略图。
- 防止回环：接收端写入期间设置导入标记，且不会把“同步来的文章”反向推送。

== 注意事项 ==
- 所有站点需使用 https 且证书有效（图片下载已放宽 sslverify 以兼容内网/自签证书）。
- 文章正文会经过 wp_kses_post 过滤，普通图文内容不受影响；内嵌脚本/iframe 等可能被过滤。
- 分类法按 slug 同步：主站新增/重命名分类（slug 不变）会在接收站同步创建或更新；若主站修改了 slug，接收站会新建一个分类。
- 调试：在「基础设置」开启调试日志，异常会写入 PHP error_log。

== 目录结构 ==
zibll-post-sync/
├── zibll-post-sync.php    入口：常量、选项读取、加载调度
├── includes/
│   ├── functions.php      通用函数（签名/校验/分类法映射/图片导入/来源查找）
│   ├── sender.php         发送端（save_post / 删除 钩子 + 推送）
│   ├── receiver.php       接收端（REST 接口）
│   ├── ajax.php           手动同步 / 连通性测试
│   └── admin-options.php  CSF 设置页
└── assets/js/admin.js     后台按钮交互
