Files
laralog/docs/plugins.md
T

120 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 插件开发指南
## 目录结构
```
plugins/{vendor}.{name}/
├── plugin.json # 插件清单(必填)
├── src/
│ ├── ServiceProvider.php # 插件入口(继承基类)
│ ├── ... # 业务代码
│ └── Filament/ # 可选:后台页面/资源
├── routes/web.php # 可选:前台路由(boot 时自动加载)
├── database/migrations/ # 可选:迁移(migrate 时自动加载)
└── views/ # 可选:视图(命名空间 plugin.{vendor}.{name}
```
## plugin.json
```json
{
"title": "插件标题",
"version": "1.0.0",
"description": "插件描述",
"author": "作者",
"type": "core",
"provider": "Plugins\\Vendor\\Name\\ServiceProvider",
"requires": ["neatstudio.payment"],
"filament_pages": ["Plugins\\Vendor\\Name\\Filament\\Pages\\SettingsPage"],
"filament_resources": ["Plugins\\Vendor\\Name\\Filament\\Resources\\OrderResource"]
}
```
| 字段 | 说明 |
|------|------|
| `provider` | 入口类 FQCN;缺省时自动推断 `src/ServiceProvider.php` |
| `requires` | 依赖的其他插件(如会员依赖支付),按 `vendor.name` 引用 |
| `filament_pages` / `filament_resources` | 注册到后台的页面/资源(由 `PluginPages` 汇总) |
## ServiceProvider
```php
<?php
declare(strict_types=1);
namespace Plugins\Vendor\Name;
use App\Blog\Support\PluginManager;
use App\Blog\Support\PluginServiceProvider;
class ServiceProvider extends PluginServiceProvider
{
protected function boot(PluginManager $manager): void
{
// 加载前台路由(可选)
$this->loadRoutes(__DIR__.'/../routes/web.php');
// 注册视图命名空间(可选)
$this->loadViews(__DIR__.'/../views', 'plugin.vendor.name');
// 注册动作/过滤器
$manager->addAction('comment.created', function ($comment) { ... }, 10);
$manager->addFilter('post.rendered', fn (string $html, $post) => $html, 10);
}
}
```
> 注意:插件入口类**不要**命名为 `PluginServiceProvider`(与基类短名冲突会导致 PHP 声明错误),统一用 `ServiceProvider`。
## 钩子系统
### addAction(hook, callback, priority) — 无返回值
| Hook | 参数 | 用途 |
|------|------|------|
| `comment.created` | `Comment` | 新评论创建(AI 审核在此监听) |
| `payment.paid` | `Payment` | 支付成功(订阅激活/解锁在此监听) |
### addFilter(hook, callback, priority) — 返回值传给下一个过滤器
| Hook | 签名 | 用途 |
|------|------|------|
| `post.rendered` | `(string $html, Post $post): string` | 文章渲染后处理(付费内容过滤) |
| `seo.structured_data` | `(array $data): array` | 扩展 JSON-LD 结构化数据 |
| `payment.gateway` | `(array $gateways): array` | 注册支付渠道 |
## 迁移
插件迁移放在 `database/migrations/``app/Providers/AppServiceProvider` 启动时自动注册,`php artisan migrate` 会一并执行(无需手动 --path)。
## 打包与安装
- 将插件目录打成 ZIP(根目录含 plugin.json
- 后台「插件管理」→ 上传 ZIP 安装,或配置远程市场 `MARKET_URL`
- 内置插件(config/plugins.php enabled 列表)不可卸载,只能停用
## 异步任务(配合 Workerman
实现 `App\Blog\Jobs\AiJob` 接口并在 Workerman 常驻进程执行:
```php
use App\Blog\Jobs\AiJob;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
class MyAiJob implements AiJob, ShouldQueue
{
use Queueable;
public function __construct(public int $id) {}
public function handle(\App\Blog\Services\LlmClient $llm): void
{
// LlmClient 由容器自动注入
}
}
```
入队:`dispatch(new MyAiJob($id))->onQueue('ai')`Workerman 默认消费 `default,ai` 队列)。