定制 saeedvir/laravel-pluginable 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

saeedvir/laravel-pluginable

最新稳定版本:v2.2

Composer 安装命令:

composer require saeedvir/laravel-pluginable

包简介

An extensive Laravel plugin system that provides automatic registration of routes, controllers, services, views, and configurations for modular application development.

README 文档

README

An extensive Laravel plugin system that provides automatic registration of routes, controllers, services, views, and configurations for modular application development.

banner

Note

Laravel Pluginable Forked From paramientos/laravel-plugin-system

Note

Chat With AI About This Package

Features

  • Automatic Plugin Discovery - Automatically scans and registers plugins
  • Route Registration - Auto-registers plugin routes with customizable prefixes
  • Controller Binding - Automatically binds plugin controllers to the service container
  • Service Registration - Registers services as singletons with interface binding support
  • View Integration - Seamless integration with Laravel views and Livewire Volt
  • Config Management - Automatic configuration loading and merging
  • Plugin Generator - Artisan command to create new plugins with boilerplate code
  • Component Generator - Create commands, controllers, listeners, events, and views within plugins (v1.5)
  • Component Management - Add components to existing plugins with duplicate detection (v1.5)
  • 🚀 Performance Cache - Cache plugin manifest for production speed (v2.0)
  • 🛠️ Plugin Facade - Easy programmatic access to plugin data (v2.0)
  • 🪝 Blade Hooks - Inject content into views from plugins (v2.0)
  • 🛡️ Middleware Support - Auto-register plugin middleware (v2.0)
  • 🌍 Localization & Migrations - Auto-load translations and database migrations (v2.0)

Installation

Install the package via Composer:

composer require saeedvir/laravel-pluginable

Publish the configuration file:

php artisan vendor:publish --tag=laravel-pluginable-config

Key Features (v1.5)

Smart Plugin Management

  • Existing Plugin Detection: Automatically detects if a plugin already exists
  • Component Addition: Add new components to existing plugins without recreation
  • Duplicate Prevention: Warns and skips if component already exists
  • Flexible Component Creation: Create individual or multiple components at once

Supported Components

  • Commands: Custom Artisan commands with proper signatures
  • Controllers: RESTful controllers with CRUD operations (extends Laravel Controller)
  • Events: Broadcastable events with proper structure
  • Listeners: Queue-enabled listeners with error handling
  • Views: Blade templates or Livewire Volt components
  • Routes: RESTful route definitions with proper namespacing (v1.5)
  • Enums: PHP 8.1+ enums with string backing type
  • Traits: Reusable trait classes (concerns) for shared functionality
  • Providers: Service providers automatically created for each plugin

Configuration

The configuration file config/laravel-pluginable.php allows you to customize:

return [
    // Path where plugins are stored
    'plugins_path' => app_path('Plugins'),
    
    // Base namespace for plugins
    'plugin_namespace' => 'App\\Plugins',
    
    // Whether to prefix routes with 'plugins/'
    'use_plugins_prefix_in_routes' => false,
    
    // Default view type for new plugins
    'default_view_type' => 'volt', // 'volt' or 'blade'
    
    // Enable/disable Volt support
    'enable_volt_support' => true,
];

Usage

Creating a Plugin

Use the Artisan command to create a new plugin:

# Create plugin with default view type (configured in config)
php artisan make:plugin MyAwesomePlugin

# Create plugin with Volt views
php artisan make:plugin MyAwesomePlugin --view-type=volt

# Create plugin with traditional Blade views
php artisan make:plugin MyAwesomePlugin --view-type=blade

# Auto-detect best view type based on configuration and availability
php artisan make:plugin MyAwesomePlugin --view-type=auto

Creating Plugin Components (v1.5)

Generate specific components within your plugin:

# Create a command within the plugin
php artisan make:plugin MyAwesomePlugin --command=ProcessDataCommand

# Create a controller within the plugin
php artisan make:plugin MyAwesomePlugin --controller=ApiController

# Create an event within the plugin
php artisan make:plugin MyAwesomePlugin --event=DataProcessedEvent

# Create a listener within the plugin
php artisan make:plugin MyAwesomePlugin --listener=SendNotificationListener

# Create a view within the plugin
php artisan make:plugin MyAwesomePlugin --view=dashboard

# Create routes for the plugin (v1.5)
php artisan make:plugin MyAwesomePlugin --route

# Create an enum within the plugin
php artisan make:plugin MyAwesomePlugin --enum=Status

# Create a trait within the plugin
php artisan make:plugin MyAwesomePlugin --trait=Cacheable

# Create a middleware within the plugin
php artisan make:plugin MyAwesomePlugin --middleware=AdminMiddleware

# Create a language file within the plugin
php artisan make:plugin MyAwesomePlugin --lang=messages

# Combine multiple components
php artisan make:plugin MyAwesomePlugin --command=ProcessCommand --controller=ProcessController --event=ProcessedEvent --enum=Status --trait=Cacheable --middleware=AdminMiddleware --lang=messages --route

Adding Components to Existing Plugins (v1.5)

You can add new components to existing plugins without recreating them:

# Add a command to existing plugin
php artisan make:plugin ExistingPlugin --command=NewCommand

# Add multiple components to existing plugin
php artisan make:plugin ExistingPlugin --controller=ApiController --event=UserRegistered --enum=Status --trait=Cacheable --middleware=AdminMiddleware --lang=messages --route

# If component already exists, it will be skipped with a warning
php artisan make:plugin ExistingPlugin --command=ExistingCommand
# Output: Command file 'ExistingCommand.php' already exists in plugin 'ExistingPlugin'. Skipping...

Listing Plugins

Display all discovered plugins and their current status:

php artisan plugin:list

This creates the following structure:

app/Plugins/MyAwesomePlugin/
├── config.php                          # Plugin configuration
├── routes.php                          # Plugin routes
├── MyAwesomePluginProvider.php         # Service provider (auto-created)
├── Controllers/
│   └── MyAwesomePluginController.php   # Plugin controller
├── Services/
│   ├── MyAwesomePluginService.php      # Plugin service
│   └── MyAwesomePluginServiceInterface.php # Service interface
├── Middleware/                         # Generated middleware
│   └── AdminMiddleware.php
├── Lang/                               # Generated language files
│   └── messages.php
├── Commands/                           # Generated commands (v1.5)
│   └── ProcessDataCommand.php
├── Events/                             # Generated events (v1.5)
│   └── DataProcessedEvent.php
├── Listeners/                          # Generated listeners (v1.5)
│   └── SendNotificationListener.php
├── Status.php                          # Generated enum
├── Cacheable.php                       # Generated trait
└── Views/
    └── index.blade.php                 # Livewire Volt component or Blade view

Plugin Structure

Config File (config.php)

<?php
return [
    'name' => 'MyAwesomePlugin',
    'version' => '1.0.0',
    'description' => 'MyAwesomePlugin plugin',
    'enabled' => true,
];

Routes File (routes.php)

<?php
use Livewire\Volt\Volt;

Volt::route('/', 'index');

Controller

<?php
namespace App\Plugins\MyAwesomePlugin\Controllers;

use App\Http\Controllers\Controller;

class MyAwesomePluginController extends Controller
{
    public function index()
    {
        // Controller logic
    }
}

Service & Interface

<?php
namespace App\Plugins\MyAwesomePlugin\Services;

interface MyAwesomePluginServiceInterface
{
    public function handle(): array;
}

class MyAwesomePluginService implements MyAwesomePluginServiceInterface
{
    public function handle(): array
    {
        return [
            'message' => 'MyAwesomePlugin service is working!',
            'timestamp' => now()->toISOString(),
        ];
    }
}

Service Provider

<?php
namespace App\Plugins\MyAwesomePlugin;

use Illuminate\Support\ServiceProvider;

class MyAwesomePluginProvider extends ServiceProvider
{
    public function register(): void
    {
        // Register plugin services here
    }

    public function boot(): void
    {
        // Boot plugin services here
    }
}

Enum

<?php
namespace App\Plugins\MyAwesomePlugin;

enum Status: string
{
    case ACTIVE = 'active';
    case INACTIVE = 'inactive';
    case PENDING = 'pending';
}

Trait

<?php
namespace App\Plugins\MyAwesomePlugin;

trait Cacheable
{
    protected int $cacheTimeout = 3600;

    public function getCacheKey(string $suffix = ''): string
    {
        return static::class . ($suffix ? ":{$suffix}" : '');
    }

    public function clearCache(string $suffix = ''): void
    {
        cache()->forget($this->getCacheKey($suffix));
    }
}

Views

The plugin system supports both Livewire Volt and traditional Blade views:

Volt Component (default):

<?php
new class extends \Livewire\Volt\Component
{
    public string $message = 'Welcome to MyAwesomePlugin Plugin!';

    public function mount(): void
    {
        $this->message = 'Hello from MyAwesomePlugin!';
    }
}
?>

<div class="p-6 bg-white rounded-lg shadow-md">
    <h1 class="text-2xl font-bold text-gray-800 mb-4">MyAwesomePlugin Plugin</h1>
    <p class="text-gray-600 mb-4">{{ $message }}</p>
</div>

Traditional Blade View:

@extends('layouts.app')

@section('content')
<div class="p-6 bg-white rounded-lg shadow-md">
    <h1 class="text-2xl font-bold text-gray-800 mb-4">MyAwesomePlugin Plugin</h1>
    <p class="text-gray-600 mb-4">Welcome to MyAwesomePlugin Plugin!</p>
    
    <div class="bg-blue-50 border border-blue-200 rounded-lg p-4">
        <h2 class="text-lg font-semibold text-blue-800 mb-2">Plugin Information</h2>
        <ul class="text-blue-700 space-y-1">
            <li><strong>View Type:</strong> Traditional Blade</li>
        </ul>
    </div>
</div>
@endsection

Accessing Plugins

Once created, your plugin will be automatically registered and accessible via:

  • Routes: http://your-app.com/myawesomeplugin/ (or /plugins/myawesomeplugin/ if prefix is enabled)
  • Config: config('MyAwesomePlugin.name')
  • Services: Injected via dependency injection or app(MyAwesomePluginServiceInterface::class)

Service Injection

Plugin services are automatically registered and can be injected:

class SomeController extends Controller
{
    public function __construct(
        private MyAwesomePluginServiceInterface $pluginService
    ) {}

    public function index()
    {
        $result = $this->pluginService->handle();
        return response()->json($result);
    }
}

Advanced Configuration

Custom Plugin Path

You can change the default plugin path in the configuration:

'plugins_path' => base_path('custom/plugins'),

Custom Namespace

Change the base namespace for plugins:

'plugin_namespace' => 'Custom\\Plugins',

Route Prefixing

Enable route prefixing to add 'plugins/' to all plugin routes:

'use_plugins_prefix_in_routes' => true,

Advanced Features (v2.0)

Performance Optimization

In production, you should cache the plugin manifest to avoid filesystem scans on every request.

# detailed
php artisan plugin:cache

To clear the cache:

php artisan plugin:clear

Plugin Facade

The Plugin facade provides a convenient way to interact with the plugin system.

use SaeedVir\LaravelPluginable\Facades\Plugin;

// Get all plugins
$plugins = Plugin::all();

// Find a specific plugin
$myPlugin = Plugin::find('MyAwesomePlugin');

// Check if a plugin is enabled
if (Plugin::enabled('MyAwesomePlugin')) {
    // ...
}

Middleware Support

You can define middleware in your plugin's Middleware directory. They are automatically aliased as pluginname.middlewarename.

Example: Plugins/MyPlugin/Middleware/AdminCheck.php

// In your route file
Route::get('/admin', 'AdminController@index')
    ->middleware('myplugin.adminCheck');

Blade Hooks

Plugins can inject content into your application's views using Blade Hooks.

1. Define the hook in your layout:

<!-- resources/views/layouts/app.blade.php -->
<body>
    @pluginHook('body_start')
    
    @yield('content')
</body>

2. Register content from your plugin:

// Plugins/MyPlugin/MyPluginProvider.php
use SaeedVir\LaravelPluginable\Facades\Plugin;

public function boot()
{
    Plugin::registerHook('body_start', view('myplugin::banner'));
    // or
    Plugin::registerHook('body_start', '<div class="alert">Warning!</div>');
}

Migrations & Translations

  • Migrations: Place your migrations in Plugins/MyPlugin/database/migrations. They will be automatically registered.
  • Translations: Place your language files in Plugins/MyPlugin/lang. You can access them via trans('MyPlugin::file.key').

Requirements

  • PHP 8.1+
  • Laravel 10.0+ or 11.0+
  • Livewire Volt 1.0+ (for view components)

License

This package is open-sourced software licensed under the MIT license.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

If you discover any security vulnerabilities or bugs, please send an e-mail to saeed.es91@gmail.com

统计信息

  • 总下载量: 6
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-12-27