laravel modules 使用数据库进行模块管理以及 filement modules 自定义模块管理器 | laravel china 社区-大发黄金版app下载

laravel modules 使用数据库进行模块管理

laravel modules 默认是使用文件系统进行进行模块管理的,如果本地开发是没有问题的,但是如果放到线上,由于模块信息默认是在项目根目录的,那么就要把根目录的这个文件进行权限配置。背离了我们只放开 public/storage 目录权限的目标(这里描述的的可能不准确),所以下面只有两个选择

  1. 把模块信息文件放到 public 或者 storage 下。
  2. 采用数据库进行模块管理

在这里我选择使用数据库进行模块管理的操作,创建 model 和迁移文件 php artisan make:model moduleactivator -m
编辑迁移文件


use illuminate\database\migrations\migration;
use illuminate\database\schema\blueprint;
use illuminate\support\facades\schema;
return new class extends migration
{
    /**
     * run the migrations.
     */
    public function up(): void
    {
        schema::create('module_activators', function (blueprint $table) {
            $table->id();
            $table->string('module_name')->unique();
            $table->boolean('module_status');
            $table->timestamps();
        });
    }
    /**
     * reverse the migrations.
     */
    public function down(): void
    {
        schema::dropifexists('module_activators');
    }
};

增加两个字段 module_namemodule_status 分别表示模块名称和模块状态
执行迁移 php artisan migrate
接下来修改配置文件modules.php 如果没有文件,记得 publish 一下就可以了

'activators' => [
    'file' => [
        'class' => fileactivator::class,
        'statuses-file' => base_path('modules_statuses.json'),
    ],
    'database' => [
        'class' => databaseactivator::class,
        'model' => moduleactivator::class,
    ]
],
'activator' => 'database',

activators 增加 database 配置,activator 修改为 database
database 配置中的 model 就是刚才创建的 moduleactivator 模型。
database 配置中的 classdatabaseactivator 数据库管理器,我们自己创建,代码如下


namespace app\activators;
use nwidart\modules\contracts\activatorinterface;
use nwidart\modules\module;
use illuminate\container\container;
use illuminate\database\eloquent\model;
class databaseactivator implements activatorinterface
{
    /**
     * 模块管理的模型
     * @var class-string $modelclass
     */
    private string $modelclass;
    public function __construct(container $app)
    {
        $this->modelclass = $app['config']['modules.activators.database.model'];
    }
    /**
     * enables a module
     */
    public function enable(module $module): void
    {
        $this->setactivebyname($module->getname(), true);
    }
    /**
     * disables a module
     */
    public function disable(module $module): void
    {
        $this->setactivebyname($module->getname(), false);
    }
    /**
     * determine whether the given status same with a module status.
     */
    public function hasstatus(module|string $module, bool $status): bool
    {
        $name = $module instanceof module ? $module->getname() : $module;
        $modulerecord = $this->modelclass::where('module_name', $name)->first();
        if ($modulerecord) {
            return boolval($modulerecord['module_status']) === $status;
        } else {
            return $status === false;
        }
    }
    /**
     * set active state for a module.
     */
    public function setactive(module $module, bool $active): void
    {
        $this->setactivebyname($module->getname(), $active);
    }
    /**
     * sets a module status by its name
     */
    public function setactivebyname(string $name, bool $active): void
    {
        $this->modelclass::upsert(['module_name' => $name, 'module_status' => $active], ['module_name'], ['module_status']);
    }
    /**
     * deletes a module activation status
     */
    public function delete(module $module): void
    {
        $modulerecord = $this->modelclass::where('module_name', $module->getname())->first();
        if ($modulerecord) {
            $modulerecord->delete();
        }
    }
    /**
     * deletes any module activation statuses created by this class.
     */
    public function reset(): void
    {
        $this->modelclass::truncate();
    }
}

database 配置中的 model, 就是为了可以更换为你自己的模块状态管理模型。
这个类实现了 activatorinterface 接口。

这样模块的激活状态就会存储在数据库中了。可以使用 laravel modulesartisan 命令来测试模块的激活状态。

filament-module 自动注册模块,只激活启用模块中的 plugin

filament 中的一个插件,可以搭配 laravel modules 来进行开发,每一个模块都是一个 filament 插件。方便我们模块化的组织系统。

但是默认的配置filament-modules.auto-register-plugins 存在一个问题,如果打开这个配置,那么所有的模块中的 plugin 都会被注册到 filament 中,即使这个模块没有被激活。
这显然不是我们想要的,我们只希望激活的模块中的 plugin 被注册到 filament 中。
但是如果把这个配置设置为 false 又得自己手动注册管理,会更麻烦。
所以我们需要一个自定义的模块管理器,来管理模块的激活状态,并且根据模块的激活状态来注册 plugin


namespace app\plugin;
use coolsam\modules\facades\filamentmodules;
use coolsam\modules\modulesplugin as basemodulesplugin;
use nwidart\modules\facades\module;
class modulesplugin extends basemodulesplugin
{
    protected function getmoduleplugins(): array
    {
        if (! config('filament-modules.auto-register-plugins', false)) {
            return [];
        }
        $enabledmodules = module::allenabled();
        $pluginpaths = [];
        foreach ($enabledmodules as $module) {
            $path = $module->getpath() . directory_separator . 'app' . directory_separator . 'filament' . directory_separator . '*plugin.php';
            $modulepluginpaths = glob($path);
            if(is_array($modulepluginpaths)) {
                $pluginpaths = array_merge($pluginpaths, $modulepluginpaths);
            }
        }
        return collect($pluginpaths)
            ->map(fn ($path) => filamentmodules::convertpathtonamespace($path))
            ->filter()->toarray();
        // return collect($enabledmodules)->map(function ($module) {
        //     $path = $module->getpath() . directory_separator . 'app' . directory_separator . 'filament' . directory_separator . $module->getname() . 'plugin.php';
        //     if(file_exists($path)) {
        //         return filamentmodules::convertpathtonamespace($path);
        //     }
        //     return null;
        // })->filter()->toarray();
    }
}

注意我注释的部分,一般我个人都会使用我注释部分的代码。因为我的规划是每个模块都只有一个插件,且插件名跟模块名称统一(这样略显死板)。这样注释部分的速度会更快。未注释的部分,单纯是为了防止模块有多个插件的情况。喜欢用哪个就自己开放关闭就可以了。
这个类继承了 use coolsam\modules\modulesplugin ,并重写了 getplugins 方法。这个方法用于获取所有激活模块的插件类。

这样修改panelprovider 中的 plugin 方法 ->plugin(modulesplugin::make()), 参数设定为上面那个自定义类就可以了,这样就可以自动注册已激活模块的插件了。

本作品采用《cc 协议》,转载必须注明作者和本文链接
从零开发一个电商项目,功能包括电商后台、商品 & sku 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
以构建论坛项目 larabbs 为线索,展开对 laravel 框架的全面学习。应用程序架构思路贴近 laravel 框架的设计哲学。
讨论数量: 1

这头像我以为是超哥

4天前

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