# 插件相关

> LyMaster 除了支持 LyApi 本身的插件以外，还有自己独特的插件系统！

插件系统花费了大量时间进行开发，它可以给你任何你想要的功能哦！

安装时、卸载时、加载时、接口注册时、页面注册时、控制台生成时 等大量事件函数！

## 插件模板
```php
<?php

namespace Admin\plugin\Template;

use APP\DI;
use APP\program\CuteDB;
use APP\program\Resource;
use Plugin\LyMaster\plugin\Processor;

/**
 * 插件主程序
 */
class options
{

    // 插件基础设置
    const SIGN = "Template";                                   // 框架标志（与文件夹同名）
    const NAME = '插件开发模板';                                // 插件名称（展示名）
    const VERSION = "V1";                                    // 插件当前版本号
    const PATH = LyApi . '/admin/plugin/' . self::SIGN;     // 插件根目录路径
    const USABLE = false;                                   // 插件是否可用(本插件为模板，所以不允许注册)

    // 插件自定义变量
    const test = "Hello LyMaster";

    // 插件数据库列表
    public $tables = [];

    public $config = [];

    // 插件处理器对象
    private $processor;
    private $resources;

    // 本地 Cute 数据库处理程序
    private $_db;

    // 插件构造函数
    public function __construct()
    {
        // 初始化官方插件处理器程序
        $this->processor = new Processor();
        $this->resources = new Resource();

        $this->_db = new CuteDB();

        // 初始化插件配置程序
        $this->config = [
            'debug' => true // 配置插件是否开启 Debug 模式
        ];
    }

    /**
     * 插件注册事件：当插件被 Admin系统 检测并加载时所调用参数
     * !(本事件仅一次！请完成部分安装操作)
     */
    public function onInstall()
    {
        // 当插件被安装(检测) 是执行，可完成 数据库初始化、信息验证...
    }

    /**
     * 插件卸载事件：当插件被 Admin系统 卸载时所调用参数
     * !(本事件仅一次！请完成部分卸载操作)
     */
    public function onUninst()
    {
        // 当插件被删除时执行，可完成 数据库清理 等操作...
    }

    /**
     * 加载页面列表事件：当 Admin系统 管理页面列表被加载时执行
     * !(将注册页面程序写入本函数可有效减少资源消耗)
     */
    public function onLoadPages()
    {

        // 本函数将在 后台页面结构生成时被调用(请完成页面注册操作)

        $this->processor->title = self::NAME; // 建议不要修改
        $this->processor->icon = 'fa fa-support'; // 建议不要修改

        // $LyMaster = new LyMaster();

        // 注册插件在后台的管理页面 (如不需要后台管理页面，可不进行注册)
        $this->processor->registerSP($this, [
            'title' => "模板演示", // 选项标题显示
            'icon' => 'fa fa-cog', // 选项图标显示 (fontawesome)
            'context' => "<h1> Hello LyMaster </h1>" // 页面内容(建议读取 HTML 作为内容)
        ]);
    }

    /**
     * 注册接口事件：当LyApi注册接口时执行
     * !(可将插件需要单独注册的VIEW或API程序写入本处)
     */
    public function onRegisterApi()
    {
        // 由于下方的访问可包含 index 内容，所以需要优先注册 btool/index 路径
        $this->processor->registerAPI(function ($type, $args, $backval) {
            return 'OK'; // 匿名函数的返回值即为页面的内容 (类型为VIEW则支持HTML标签)
        }, [
            "type" => 'VIEW', // 注册的接口的类型(VIEW OR API)
            "path" => "btool/index" // 访问路径 (支持 * 匹配所有)
        ], []);

        $this->processor->registerAPI(function ($type, $args, $backval) {
            return '当前访问路径为：' . $backval['holder'][0];
            // $backval['holder'] 为 * 号的匹配，路径中第一个 * 则对应 $backval['holder'][0]
        }, [
            "type" => 'API', // API 类型会作为接口数据被返回！
            "path" => "btool/*" // 使用了通配符 * 访问任何 btool/xxx 都会被分配到此
        ], [
            // 本处为 backval 数据，即可将本处的一些数据传递到匿名函数中
            // PS: 匿名函数无法直接取得 onRegisterApi 的任何数据，但可从此处传入
        ]);
    }

    /**
     * 注册命令行指令事件：当LyMaster注册命令行插件指令时执行
     * !(可将插件需要单独注册的命令行指令程序写入本处)
     */
    public function onRegisterCmd()
    {
        // Cmder http://domain/admin/cmder 命令注册程序
        $this->processor->registerCommand(["tpl", "template"], function ($commands, $num) {
            // 参数: $commands 输入命令列表(为数组，使用空格分隔而成)
            // 参数: $num      $commands 数组长度
            if ($num > 1) {
                return "Hello " . $commands[1];
            } else {
                return "Hello LyMaster";
            }
        });
    }

    /**
     * 主页面渲染事件：当主页面管控程序为本插件时
     * !(可将插件需要单独注册的命令行指令程序写入本处)
     */
    public function indexPage()
    {
        // 当 index 页面被此插件接管后，此函数将处理页面渲染
        return "<h1>Welcome LyMaster Plugin Template</h1>";
    }

    // 回传 Processor (请勿删除本函数，否则出现运行错误！！)
    public function getProcessor()
    {
        return $this->processor;
    }
}
```
