插件管理
插件管理是 Yuan-ICP 系统的扩展功能模块,允许开发者通过插件系统扩展系统功能,实现模块化开发和功能定制。
📋 功能概览
插件管理模块提供以下核心功能:
- 插件安装:安装新的功能插件
- 插件启用/禁用:控制插件的运行状态
- 插件配置:管理插件的配置参数
- 插件更新:更新插件到最新版本
- 插件开发:支持自定义插件开发
🔌 插件系统架构
插件目录结构
plugins/
├── index.php # 插件管理入口
├── example-plugin/ # 示例插件
│ ├── plugin.json # 插件配置文件
│ ├── main.php # 插件主文件
│ ├── install.php # 安装脚本
│ ├── uninstall.php # 卸载脚本
│ ├── config.php # 配置页面
│ └── assets/ # 插件资源文件
│ ├── css/ # 样式文件
│ ├── js/ # JavaScript文件
│ └── images/ # 图片资源
└── system/ # 系统内置插件
├── backup/ # 备份插件
├── logs/ # 日志插件
└── themes/ # 主题管理插件
插件配置文件 (plugin.json)
每个插件都包含一个 plugin.json
配置文件,定义插件的基本信息:
json
{
"name": "示例插件",
"version": "1.0.0",
"description": "这是一个示例插件,展示插件开发的基本结构",
"author": "开发者姓名",
"license": "MIT",
"requires": {
"system_version": "1.0.0",
"php_version": "7.4"
},
"hooks": [
"admin_menu",
"frontend_header",
"after_application_submit"
],
"permissions": [
"plugin_manage",
"plugin_config"
]
}
📦 插件管理功能
访问插件管理
- 登录后台管理系统
- 点击侧边栏"插件管理"
- 查看已安装插件列表
插件状态说明
- 已启用:插件正在运行,功能可用
- 已禁用:插件已安装但未启用
- 需要更新:有新版本可用
- 安装失败:插件安装过程中出现问题
插件操作
- 启用插件:激活插件功能
- 禁用插件:停用插件功能
- 配置插件:设置插件参数
- 卸载插件:完全移除插件
- 更新插件:升级到最新版本
🛠️ 插件开发指南
创建新插件
- 创建插件目录:在
plugins/
目录下创建新文件夹 - 编写配置文件:创建
plugin.json
配置文件 - 开发主文件:创建
main.php
主文件 - 添加安装脚本:创建
install.php
安装脚本 - 添加卸载脚本:创建
uninstall.php
卸载脚本
插件主文件 (main.php)
插件主文件包含插件的核心逻辑:
php
<?php
/**
* 示例插件主文件
*/
// 防止直接访问
if (!defined('YUAN_ICP_SYSTEM')) {
die('Direct access not allowed');
}
class ExamplePlugin {
private $plugin_name = 'example-plugin';
private $plugin_version = '1.0.0';
public function __construct() {
$this->init_hooks();
}
/**
* 初始化钩子
*/
private function init_hooks() {
// 注册钩子函数
add_hook('admin_menu', [$this, 'add_admin_menu']);
add_hook('frontend_header', [$this, 'add_frontend_header']);
add_hook('after_application_submit', [$this, 'handle_application_submit']);
}
/**
* 添加后台菜单
*/
public function add_admin_menu() {
// 在后台菜单中添加插件菜单项
echo '<li><a href="plugins.php?plugin=' . $this->plugin_name . '">示例插件</a></li>';
}
/**
* 添加前台头部
*/
public function add_frontend_header() {
// 在前台页面头部添加内容
echo '<meta name="example-plugin" content="enabled">';
}
/**
* 处理备案申请提交后的事件
*/
public function handle_application_submit($application_data) {
// 在备案申请提交后执行自定义逻辑
$this->log_application($application_data);
}
/**
* 记录申请日志
*/
private function log_application($data) {
// 记录申请信息到日志
error_log('Example Plugin: New application submitted - ' . json_encode($data));
}
}
// 初始化插件
new ExamplePlugin();
安装脚本 (install.php)
安装脚本在插件安装时执行:
php
<?php
/**
* 示例插件安装脚本
*/
// 防止直接访问
if (!defined('YUAN_ICP_SYSTEM')) {
die('Direct access not allowed');
}
class ExamplePluginInstaller {
/**
* 安装插件
*/
public function install() {
try {
// 创建插件数据表
$this->create_tables();
// 插入默认配置
$this->insert_default_config();
// 创建必要的目录
$this->create_directories();
return ['success' => true, 'message' => '插件安装成功'];
} catch (Exception $e) {
return ['success' => false, 'message' => '插件安装失败: ' . $e->getMessage()];
}
}
/**
* 创建数据表
*/
private function create_tables() {
$db = db();
$sql = "CREATE TABLE IF NOT EXISTS example_plugin_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
message TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)";
$db->exec($sql);
}
/**
* 插入默认配置
*/
private function insert_default_config() {
$db = db();
$stmt = $db->prepare("INSERT OR IGNORE INTO system_config (config_key, config_value) VALUES (?, ?)");
$stmt->execute(['example_plugin_enabled', '1']);
$stmt->execute(['example_plugin_log_level', 'info']);
}
/**
* 创建必要目录
*/
private function create_directories() {
$plugin_dir = __DIR__;
$directories = [
$plugin_dir . '/logs',
$plugin_dir . '/cache',
$plugin_dir . '/uploads'
];
foreach ($directories as $dir) {
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
}
}
}
// 执行安装
if (isset($_POST['install'])) {
$installer = new ExamplePluginInstaller();
$result = $installer->install();
if ($result['success']) {
echo '<div class="alert alert-success">' . $result['message'] . '</div>';
} else {
echo '<div class="alert alert-danger">' . $result['message'] . '</div>';
}
}
?>
卸载脚本 (uninstall.php)
卸载脚本在插件卸载时执行:
php
<?php
/**
* 示例插件卸载脚本
*/
// 防止直接访问
if (!defined('YUAN_ICP_SYSTEM')) {
die('Direct access not allowed');
}
class ExamplePluginUninstaller {
/**
* 卸载插件
*/
public function uninstall() {
try {
// 删除插件数据表
$this->drop_tables();
// 删除插件配置
$this->remove_config();
// 清理插件文件
$this->cleanup_files();
return ['success' => true, 'message' => '插件卸载成功'];
} catch (Exception $e) {
return ['success' => false, 'message' => '插件卸载失败: ' . $e->getMessage()];
}
}
/**
* 删除数据表
*/
private function drop_tables() {
$db = db();
$db->exec("DROP TABLE IF EXISTS example_plugin_logs");
}
/**
* 删除配置
*/
private function remove_config() {
$db = db();
$stmt = $db->prepare("DELETE FROM system_config WHERE config_key LIKE 'example_plugin_%'");
$stmt->execute();
}
/**
* 清理文件
*/
private function cleanup_files() {
$plugin_dir = __DIR__;
$directories = [
$plugin_dir . '/logs',
$plugin_dir . '/cache',
$plugin_dir . '/uploads'
];
foreach ($directories as $dir) {
if (is_dir($dir)) {
$this->remove_directory($dir);
}
}
}
/**
* 递归删除目录
*/
private function remove_directory($dir) {
if (is_dir($dir)) {
$files = scandir($dir);
foreach ($files as $file) {
if ($file != "." && $file != "..") {
$path = $dir . '/' . $file;
if (is_dir($path)) {
$this->remove_directory($path);
} else {
unlink($path);
}
}
}
rmdir($dir);
}
}
}
// 执行卸载
if (isset($_POST['uninstall'])) {
$uninstaller = new ExamplePluginUninstaller();
$result = $uninstaller->uninstall();
if ($result['success']) {
echo '<div class="alert alert-success">' . $result['message'] . '</div>';
} else {
echo '<div class="alert alert-danger">' . $result['message'] . '</div>';
}
}
?>
🔗 钩子系统
可用钩子列表
系统提供以下钩子点供插件使用:
后台钩子
- admin_menu:后台菜单渲染时
- admin_header:后台页面头部
- admin_footer:后台页面底部
- dashboard_stats:仪表盘统计信息
- application_list:备案申请列表
前台钩子
- frontend_header:前台页面头部
- frontend_footer:前台页面底部
- home_content:首页内容
- apply_form:申请表单
- query_result:查询结果
事件钩子
- after_application_submit:备案申请提交后
- after_application_approve:备案申请审核通过后
- after_application_reject:备案申请被驳回后
- user_login:用户登录后
- user_logout:用户登出后
钩子使用示例
php
// 注册钩子函数
add_hook('admin_menu', 'my_plugin_menu_function');
// 钩子函数实现
function my_plugin_menu_function() {
echo '<li><a href="my_plugin.php">我的插件</a></li>';
}
// 移除钩子
remove_hook('admin_menu', 'my_plugin_menu_function');
⚙️ 插件配置
配置页面 (config.php)
插件可以有自己的配置页面:
php
<?php
/**
* 示例插件配置页面
*/
require_once __DIR__.'/../includes/auth.php';
require_once __DIR__.'/../includes/functions.php';
require_login();
$db = db();
$message = '';
$error = '';
// 处理配置保存
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$enabled = isset($_POST['enabled']) ? 1 : 0;
$log_level = trim($_POST['log_level'] ?? 'info');
try {
$stmt = $db->prepare("REPLACE INTO system_config (config_key, config_value) VALUES (?, ?)");
$stmt->execute(['example_plugin_enabled', $enabled]);
$stmt->execute(['example_plugin_log_level', $log_level]);
$message = '配置保存成功!';
} catch (Exception $e) {
$error = '配置保存失败: ' . $e->getMessage();
}
}
// 获取当前配置
$stmt = $db->query("SELECT config_key, config_value FROM system_config WHERE config_key LIKE 'example_plugin_%'");
$config = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
$enabled = $config['example_plugin_enabled'] ?? 0;
$log_level = $config['example_plugin_log_level'] ?? 'info';
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>示例插件配置 - Yuan-ICP</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-4">
<h1>示例插件配置</h1>
<?php if ($message): ?>
<div class="alert alert-success"><?= htmlspecialchars($message) ?></div>
<?php endif; ?>
<?php if ($error): ?>
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
<?php endif; ?>
<form method="POST">
<div class="mb-3">
<label class="form-label">启用插件</label>
<div class="form-check">
<input type="checkbox" class="form-check-input" name="enabled" value="1" <?= $enabled ? 'checked' : '' ?>>
<label class="form-check-label">启用示例插件功能</label>
</div>
</div>
<div class="mb-3">
<label class="form-label">日志级别</label>
<select class="form-select" name="log_level">
<option value="debug" <?= $log_level === 'debug' ? 'selected' : '' ?>>调试</option>
<option value="info" <?= $log_level === 'info' ? 'selected' : '' ?>>信息</option>
<option value="warning" <?= $log_level === 'warning' ? 'selected' : '' ?>>警告</option>
<option value="error" <?= $log_level === 'error' ? 'selected' : '' ?>>错误</option>
</select>
</div>
<button type="submit" class="btn btn-primary">保存配置</button>
<a href="plugins.php" class="btn btn-secondary">返回插件列表</a>
</form>
</div>
</body>
</html>
📊 插件管理操作
插件安装
- 上传插件文件:将插件文件上传到
plugins/
目录 - 检查兼容性:系统自动检查插件兼容性
- 运行安装脚本:执行插件的安装脚本
- 启用插件:安装完成后可以启用插件
插件更新
- 检查更新:系统自动检查插件更新
- 下载更新:下载最新版本的插件文件
- 备份当前:自动备份当前插件配置
- 应用更新:应用更新到最新版本
插件卸载
- 选择插件:在插件列表中选择要卸载的插件
- 确认卸载:点击"卸载"按钮
- 备份数据:系统自动备份插件配置
- 完成卸载:插件文件被完全移除
🚨 故障排除
常见问题
1. 插件安装失败
问题:插件无法正常安装 解决方案:
- 检查插件文件是否完整
- 确认插件兼容性
- 检查文件权限设置
- 查看系统错误日志
2. 插件功能异常
问题:插件功能不工作或出错 解决方案:
- 检查插件是否正确启用
- 确认插件配置是否正确
- 查看插件错误日志
- 检查钩子注册
3. 插件冲突
问题:多个插件之间产生冲突 解决方案:
- 逐个禁用插件找出冲突源
- 检查插件钩子使用
- 更新插件到最新版本
- 联系插件开发者
4. 性能问题
问题:插件影响系统性能 解决方案:
- 检查插件资源使用
- 优化插件代码
- 使用缓存机制
- 定期清理插件数据
💡 最佳实践
插件开发原则
- 模块化设计:将功能分解为独立模块
- 错误处理:完善的错误处理和日志记录
- 性能优化:优化资源使用和响应时间
- 安全考虑:防止安全漏洞和恶意代码
开发建议
- 遵循规范:遵循插件的开发规范
- 充分测试:在不同环境下测试插件
- 文档完善:为插件提供详细文档
- 版本控制:使用版本控制系统管理代码
维护建议
- 定期更新:保持插件与系统同步
- 用户反馈:收集用户反馈并持续改进
- 性能监控:监控插件性能指标
- 安全更新:及时修复安全漏洞
📋 插件检查清单
功能检查
- [ ] 插件安装功能正常
- [ ] 插件启用/禁用正常
- [ ] 插件配置功能正常
- [ ] 插件卸载功能正常
- [ ] 钩子系统正常工作
兼容性检查
- [ ] 与系统版本兼容
- [ ] 与PHP版本兼容
- [ ] 与其他插件兼容
- [ ] 数据库兼容性
- [ ] 主题系统兼容
性能检查
- [ ] 插件加载速度合理
- [ ] 资源使用合理
- [ ] 缓存机制正常
- [ ] 错误处理完善
- [ ] 日志记录正常
📚 相关文档
🎯 总结
插件管理系统为 Yuan-ICP 提供了强大的扩展能力:
- 功能扩展:通过插件系统扩展系统功能
- 模块化开发:支持独立的模块开发
- 灵活配置:每个插件可以有自己的配置
- 易于管理:简单的插件安装和管理操作
通过合理使用插件系统,您可以根据实际需求定制系统功能,提升系统的灵活性和可扩展性。