Laravel通用插件扩展

开发中,未上线
欢迎加入交流群讨论需求反馈问题 1040420367

Gallery Plugin

一个使您的 Laravel 项目获得即插即用插件功能的扩展。

项目概述

启发于 WordPress,安装 GalleryPlugin (以下简称 GP )后,您的 Laravel 项目即可拥有即插即用的插件扩展能力。

插件需要基于 GP 并配合相应的 钩子放置策略 专门开发。

插件可发布到 Composer 并通过其安装。

使用场景

假设您在用 Laravel 开发一套 CMS 系统,
当您想要对它增加插件能力,以便为您的用户提供热插拔插件的功能时,
您可以选择 GP

项目安装 GP 后,按需放置钩子,然后按照 钩子放置策略 开发相应的插件。

插件发布后,使用此 CMS 系统的用户即可安装此插件以扩展其网站的功能。

功能

  • 安装插件 —— 从 Composer 下载插件并安装
  • 启用插件 —— 修改插件状态以启用
  • 禁用插件 —— 修改插件状态以禁用
  • 卸载插件 —— 删除插件,可选择是否保留数据
  • 插件列表 —— 获取插件列表
  • 挂载钩子 —— 向钩子挂载函数或方法
  • 执行钩子 —— 执行钩子上挂载的函数或方法
  • 禁用钩子 —— 禁止执行钩子
  • 卸载钩子 —— 卸载钩子上挂载的函数或方法
  • 钩子列表 —— 获取钩子列表

环境要求

  • PHP 7.0+
  • Mysql 5.7+
  • Laravel 5.8+

安装

composer require xxx/plugin
php artisan vendor:publish --provider=Gallery\Plugin\PluginServiceProvider
php artisan migrate
  • 通过源码安装

首先下载 源码包,解压后放在你希望放在的位置。

在 Composer 配置中添加 classmap 参数,如:

{
    "autolaod": {
        "classmap": [
            "项目中 GP 文件夹的路径"
        ]
    }
}

执行 composer dump-autoload

最后把 \Gallery\Plugin\PluginServiceProvider::class
放到 config/app.phpproviders 中。

核心概念

钩子原理

钩子是程序执行过程中特定的点或事件,把插件的一个或多个函数或方法挂载到钩子上,就可以在指定的时机调用他们。

钩子类型

  • 动作钩子

    激发钩子时,钩子按优先级 priority 从小到大的顺序调用挂载其上的所有函数或方法;
    同优先级下按先后挂载的次序先后调用;
    调用是相互独立的,可传递多个参数,每个函数或方法接收的参数都是相同的。

  • 过滤器钩子

    激发钩子时,钩子按优先级 priority 从小到大的顺序调用挂载其上的所有函数或方法;
    同优先级下按先后挂载的次序先后调用;
    调用是串联接力的,只传递单一参数,函数或方法的返回值是其后函数或方法的参数。

  • 一次性钩子

    激发钩子时,只调用一个函数或方法,且调用的是按照上面👆描述的执行次序的第一个函数或方法。

放置策略

事实上每一个项目都有不同的需求和不同的结构。
在哪里放置钩子,钩子是什么类型,放置多少钩子,每个项目都是不同的,或者说很难做到一致。
因此,不同的项目有不同的放置策略,基于某一策略开发的插件难以在另一个项目中使用。一个项目只能安装符合它的放置策略的插件。

当项目升级时,放置策略可能会发生变化,项目开发者要考虑长远,尽量满足较小差异下的兼容性。
当然如果难以兼容或差异较大,项目开发者就要有放弃所有旧版本插件的准备,或者自己升级插件,或者鼓励插件开发者社区更新他们的插件。

策略标签

对于不同的 钩子放置策略,我们用 策略标签 加以区分。

例如,有A项目集成了 GP,在概念上诞生了A项目的策略标签,不妨叫 a-strategy-v1.0
只要是满足 a-strategy-v1.0 策略的插件,就可以安装在A项目上。

同时,同一个策略标签还可能有不同的版本,小版本之间需满足兼容性,大版本之间不能混用。

如果某插件同时支持多种不同的策略,那么它可以应用在不同的项目中。建议多做测试。

使用

安装插件

composer require foo/bar
php artisan gallery:add foo_bar
  • 通过源码安装

首先下载 源码包,解压后放在项目的插件文件夹中 /plugins(凭你喜好)。

在 Composer 中添加 classmap 参数,如:

{
    "autolaod": {
        "classmap": [
            "plugins/"
        ]
    }
}

执行 composer dump-autoload

\Foo\Bar\BarServiceProvider::class 放到 config/app.phpproviders 中。

最后执行:

  • 命令行方式:

    php artisan gallery:add foo_bar
  • 代码方式:

    $res = \Gallery\Plugin\Manager::addPlugin('foo_bar');

启用插件

  • 命令行方式:

    php artisan gallery:enable foo_bar
  • 代码方式:

    $res = \Gallery\Plugin\Manager::enablePlugin('foo_bar');

禁用插件

  • 命令行方式:

    php artisan gallery:disable foo_bar
  • 代码方式:

    $res = \Gallery\Plugin\Manager::disablePlugin('foo_bar');

卸载插件

  • 命令行方式:

    php artisan gallery:remove foo_bar
  • 代码方式:

    $res = \Gallery\Plugin\Manager::removePlugin('foo_bar');

插件列表

  • 命令行方式:

    php artisan gallery:plugin-list
  • 代码方式:

    $plugins = \Gallery\Plugin\Manager::getPlugins();

挂载钩子

// 在插件中注册钩子
add('init', function(){
    echo '本段文字将在系统初始化时输出';
});

执行钩子

// 在业务流程或视图中执行钩子
play('init');

禁用钩子

把插件的 status 字段改成 0

return [
    'hooks' => [
        'init' => [
            'name' => 'init',
            'type' => 1,
            'desc' => 'PluginServiceProvider::boot()执行时',
            'status' => 0
        ]
    ]
];

钩子列表

\Gallery\Plugin\Plugin::getHooks();
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 2
pangxianfei

有发布包了?

4天前 评论
Wangds (楼主) 4天前
pangxianfei

目前laravel 框架还没有类似

file 组件吧。

4天前 评论
Wangds (楼主) 4天前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!