[开发]SKILL: SoSite 插件开发助手

👑Lv.11 元老 🌞 骨干会员
2026-10-25 00:51:08

本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:8月13日备份/sosite-plugin-dev/SKILL.md。

SKILL: SoSite 插件开发助手

本 Skill/Rule 包用于指导 SoSite(自研 MVC 社区系统,PHP 8.2 / MySQL 5.7-8.0,零 Composer 依赖) 的插件开发。

挂载到 AI 编程工具后,当任务涉及"写一个 SoSite 插件 / 加 hook / 加后台设置页 / 插件路由 / 插件视图"时,自动参考本包规范,避免写出白屏、数据错乱、不合规范或踩中已知坑的代码。

一、触发条件(命中即加载本 Skill)

  • 用户要求编写/修改 SoSite 插件(前台功能插件、后台管理插件、钩子插件)
  • 用户要求新增/修改 hook(如 init_after、route_register、nav_plugin_links 等)
  • 用户要求新增插件后台设置页 / 后台路由 / 侧边栏入口
  • 用户要求新增插件路由(前台页)或插件视图/静态资源
  • 涉及 plugins/ 目录、plugin.json、Plugin\xxx 命名空间、Plugin::hook 的改动

二、硬规则(违反即返工)

R1 目录与命名

  • 插件必须位于 plugins/{dir}/,{dir} 用小写下划线(如 daily_checkin、friend_links)
  • 命名空间 = Plugin\{Dir}(目录名转 StudlyCase,如 Plugin\DailyCheckin),Autoloader 已支持 Plugin\ 前缀映射
  • 视图必须放 plugins/{dir}/views/(A+ 后 resolveTemplate 插件目录优先,控制器 view('plugins/{dir}/xxx') 自动解析到此处;不得再往 app/Views/plugins/ 放模板)
  • 静态资源放 plugins/{dir}/assets/,页面引用直接写 /plugins/{dir}/assets/xxx(经 $this->url()),不要用 asset()——asset() 会解析到 assets/plugins/ 发布目录,造成双份漂移(已知坑)

R2 plugin.json

  • 必须包含:name(中文名)、version(如 1.0.0)、author、description、hooks(hook名 => 相对路径)、activated
  • activated 默认 false(安装后默认停用,需后台手动启用,防未审查代码立即执行)
  • hooks 路径以 hook/ 开头,如 "init_after": "hook/init_after.php"

R3 生命周期

  • 可选 plugins/{dir}/Plugin.php:namespace Plugin\{Dir}; class Plugin { static activate(): bool; static deactivate(): bool; static uninstall(): void; }
  • activate() 返回 false 会回滚启用;uninstall() 内自行清理建表/数据(框架只负责删注册与缓存)

R4 控制器与路由

  • 前台控制器 extends \app\Core\Controller;后台控制器 必须 extends \app\Controllers\Admin\BaseController(自带 isAdmin + 二次密码验证)
  • 路由注册写在 hook 文件:前台 hook/route_register.php 用 $router->get/post('/path', ['\Plugin\Xxx\XxxController', 'method']);后台 hook/admin_route_register.php 同样注册(URL 不带 /admin 前缀,由后台容器鉴权)
  • hook 文件内 if (!isset($router)) return; 防御性开头

R5 视图与安全

  • 输出一律 $this->e(...) 转义(XSS);POST 表单必须带 csrf 并 Csrf::verifyOrDie($_POST['csrf'] ?? '')
  • 模板编译器 {if} 内禁止函数调用(仅放行 isset/empty,safeExpr 黑名单,白屏即查此)
  • 数据库 SQL:PDO native prepare 两条铁律(全局 ATTR_EMULATE_PREPARES=false):
  1. 同一命名占位符不能复用(:now,:now 会 HY093)——需要两次就拆成 :created_at/:last_active_at
  2. SHOW 语句不能有占位符(1064)——SHOW TABLES LIKE :x 必须 $conn->quote() 内联

R6 其他

  • 改动 plugin.json 后必须 Plugin::refresh() 重建缓存(plugins/plugins_cache.php),否则后台/前台读旧配置
  • 导航/下拉入口:nav_plugin_links 钩子中 $view = $GLOBALS['__view'] ?? null; 后 echo '<a href="...">' . $view->icon('xxx', 16) . '名称</a>'
  • 插件内建表不要放 initDatabaseSchema();在 Plugin::activate()/uninstall() 里建/删(或懒建)

三、工作流(标准开发顺序)

  1. 需求拆解:功能是前台页面 / 后台管理 / 纯钩子?需要哪些 hook?是否建表?
  2. 搭骨架:创建 plugins/{dir}/ + plugin.json(activated:false)+ Plugin.php(如需要)+ hook/ + views/ + assets/
  3. 写路由:hook/route_register.php(前台)或 hook/admin_route_register.php(后台),require 控制器
  4. 写控制器:继承正确基类;方法内取数据 → $this->view('plugins/{dir}/xxx', [...])
  5. 写视图:plugins/{dir}/views/xxx.php,用 $this->section('title'/'content') + $this->e() 转义;资源用 $this->url('/plugins/{dir}/assets/...')
  6. 写 hook 逻辑:按需在 hook/*.php 中实现(导航、注入 CSS/JS、数据联动)
  7. 验证:php -l 全部新文件 → 后台启用插件 → 页面实测(白屏查 safeExpr/PDO,样式丢失查资源路径)
  8. 清理:确认不破坏其他插件;卸载测试 uninstall() 能清数据

四、速查手册索引(references/)

文件内容
references/01-plugin-structure.md插件目录结构、plugin.json 字段、生命周期、最小示例(抄即用)
references/02-hooks-catalog.md全部 hook 名称、触发点、可用变量与参数
references/03-api-cheatsheet.md控制器/模型/工具类 API 速查(Database、Settings、Points、AuditLog、Csrf、Upload、Search、Plugin)
references/04-security.md安全规范与已知坑(XSS/CSRF/路径穿越/PDO 铁律/白名单)
references/05-ui-templates.md模板语法、图标、资源引用、样式约定(含双份 CSS 坑)
references/06-troubleshooting.md排错清单(白屏/404/样式丢失/计数错乱等根因速查)
references/07-plugin-patterns.md典型插件模式与实现模板:场景→母版插件速查表、13 类模式代码骨架(后台 CRUD/审核流/签到积分/游戏/纯 hook/提交审核/注册拦截/收藏关注/业务子系统/并发防重/纯工具/设置页注入)
plugin-system.md插件系统介绍:架构、加载流程、生命周期、核心 21 个 hook 总表(含触发文件/参数)、14 插件注册分布、hook 使用统计、已知坑

五、给 AI 的协作约定

  • 开发新插件先查 references/07-plugin-patterns.md 场景速查表,找到最接近的现有插件作母版,在其结构上改(勿从零写)
  • 动手前先 php -l 目标文件;改动插件后按 R6 提示用户 Plugin::refresh()
  • 遇到"模板改了没生效":先确认文件在 plugins/{dir}/views/(不是 app/Views/plugins)、资源不是 asset()
  • 涉及新表:DDL 与 activate()/uninstall() 成对出现,幂等(CREATE TABLE IF NOT EXISTS)
  • 涉及数据库查询:先判断是否有 SHOW / 复用占位符场景,再写 SQL
  • 涉及后台页:继承 Admin\BaseController,别忘了 CSRF 与 __nav_active 高亮
轻量级、高性能、零 MySQL 依赖的PHP社区系统。
| 浏览 1 次 | 回复 0 次

全部回复 (0)

暂无回复

请 登录