Skip to content

插件管理

插件管理是 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"
    ]
}

📦 插件管理功能

访问插件管理

  1. 登录后台管理系统
  2. 点击侧边栏"插件管理"
  3. 查看已安装插件列表

插件状态说明

  • 已启用:插件正在运行,功能可用
  • 已禁用:插件已安装但未启用
  • 需要更新:有新版本可用
  • 安装失败:插件安装过程中出现问题

插件操作

  • 启用插件:激活插件功能
  • 禁用插件:停用插件功能
  • 配置插件:设置插件参数
  • 卸载插件:完全移除插件
  • 更新插件:升级到最新版本

🛠️ 插件开发指南

创建新插件

  1. 创建插件目录:在 plugins/ 目录下创建新文件夹
  2. 编写配置文件:创建 plugin.json 配置文件
  3. 开发主文件:创建 main.php 主文件
  4. 添加安装脚本:创建 install.php 安装脚本
  5. 添加卸载脚本:创建 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>

📊 插件管理操作

插件安装

  1. 上传插件文件:将插件文件上传到 plugins/ 目录
  2. 检查兼容性:系统自动检查插件兼容性
  3. 运行安装脚本:执行插件的安装脚本
  4. 启用插件:安装完成后可以启用插件

插件更新

  1. 检查更新:系统自动检查插件更新
  2. 下载更新:下载最新版本的插件文件
  3. 备份当前:自动备份当前插件配置
  4. 应用更新:应用更新到最新版本

插件卸载

  1. 选择插件:在插件列表中选择要卸载的插件
  2. 确认卸载:点击"卸载"按钮
  3. 备份数据:系统自动备份插件配置
  4. 完成卸载:插件文件被完全移除

🚨 故障排除

常见问题

1. 插件安装失败

问题:插件无法正常安装 解决方案

  • 检查插件文件是否完整
  • 确认插件兼容性
  • 检查文件权限设置
  • 查看系统错误日志

2. 插件功能异常

问题:插件功能不工作或出错 解决方案

  • 检查插件是否正确启用
  • 确认插件配置是否正确
  • 查看插件错误日志
  • 检查钩子注册

3. 插件冲突

问题:多个插件之间产生冲突 解决方案

  • 逐个禁用插件找出冲突源
  • 检查插件钩子使用
  • 更新插件到最新版本
  • 联系插件开发者

4. 性能问题

问题:插件影响系统性能 解决方案

  • 检查插件资源使用
  • 优化插件代码
  • 使用缓存机制
  • 定期清理插件数据

💡 最佳实践

插件开发原则

  1. 模块化设计:将功能分解为独立模块
  2. 错误处理:完善的错误处理和日志记录
  3. 性能优化:优化资源使用和响应时间
  4. 安全考虑:防止安全漏洞和恶意代码

开发建议

  1. 遵循规范:遵循插件的开发规范
  2. 充分测试:在不同环境下测试插件
  3. 文档完善:为插件提供详细文档
  4. 版本控制:使用版本控制系统管理代码

维护建议

  1. 定期更新:保持插件与系统同步
  2. 用户反馈:收集用户反馈并持续改进
  3. 性能监控:监控插件性能指标
  4. 安全更新:及时修复安全漏洞

📋 插件检查清单

功能检查

  • [ ] 插件安装功能正常
  • [ ] 插件启用/禁用正常
  • [ ] 插件配置功能正常
  • [ ] 插件卸载功能正常
  • [ ] 钩子系统正常工作

兼容性检查

  • [ ] 与系统版本兼容
  • [ ] 与PHP版本兼容
  • [ ] 与其他插件兼容
  • [ ] 数据库兼容性
  • [ ] 主题系统兼容

性能检查

  • [ ] 插件加载速度合理
  • [ ] 资源使用合理
  • [ ] 缓存机制正常
  • [ ] 错误处理完善
  • [ ] 日志记录正常

📚 相关文档

🎯 总结

插件管理系统为 Yuan-ICP 提供了强大的扩展能力:

  1. 功能扩展:通过插件系统扩展系统功能
  2. 模块化开发:支持独立的模块开发
  3. 灵活配置:每个插件可以有自己的配置
  4. 易于管理:简单的插件安装和管理操作

通过合理使用插件系统,您可以根据实际需求定制系统功能,提升系统的灵活性和可扩展性。

基于 MIT 协议发布