A flexible and powerful plugin system for Laravel applications.
- Plugin discovery and registration
- Enable/disable plugins
- Plugin dependencies
- Console commands for plugin management
- Event-driven architecture
- Easy to extend
- Install the package via Composer:
composer require whilesmart/laravel-plugin-engine- Publish the configuration file (optional):
php artisan vendor:publish --provider="WhileSmart\LaravelPluginEngine\Providers\PluginServiceProvider" --tag=configPublish the configuration file:
php artisan vendor:publish --provider="WhileSmart\LaravelPluginEngine\Providers\PluginServiceProvider" --tag=configEdit the config/plugins.php file to configure the plugin system:
return [
'path' => base_path('plugins'), // Path where plugins are stored
'namespace' => 'Plugins', // Root namespace for plugins
'log_channel' => env('PLUGIN_ENGINE_LOG_CHANNEL'), // Log channel, null = app default
'log_level' => env('PLUGIN_ENGINE_LOG_LEVEL', 'warning'), // Minimum level the engine logs at
];The engine logs through its own configurable channel and minimum level, independent of the application's logging:
PLUGIN_ENGINE_LOG_CHANNEL: any channel fromconfig/logging.php. Leave unset to use the application's default channel.PLUGIN_ENGINE_LOG_LEVEL: messages below this level are dropped. Defaults towarning, so routine discovery output stays out of production logs. Set todebugto trace plugin discovery and registration.
plugin:list- List all available pluginsplugin:info {id}- Show information about a pluginplugin:enable {id}- Enable a pluginplugin:disable {id}- Disable a pluginplugin:install {package}- Install a plugin from a Composer package, a repository URL, or a local pathplugin:discover- Discover and register all available pluginsplugin:cache- Compile discovered plugins into a cache fileplugin:clear- Remove the plugin cache file
When a plugin is installed from a URL or a local path, the engine reads the
plugin's own composer.json and installs its require dependencies into the
host application, so the plugin's classes are available at runtime.
For hosts that embed several plugins, enable
wikimedia/composer-merge-plugin
so each plugin keeps owning its dependencies while Composer resolves them
together into the single host vendor/:
With this configured, installing a plugin runs a targeted composer update;
otherwise the engine falls back to composer require for the plugin's
dependencies.
By default, plugins are discovered by scanning the plugins directory and parsing each manifest on every boot. In production, compile the result to a cache file instead, alongside the framework's other caches:
php artisan plugin:cacheThe compiled file is loaded on boot and the filesystem scan is skipped.
Run this on every deploy, next to config:cache and route:cache.
plugin:enable, plugin:disable, and plugin:discover refresh an existing
cache automatically. To return to live discovery:
php artisan plugin:clear- Create a new directory in the
pluginsdirectory (or your configured path) - Create a
plugin.jsonfile with the following structure:
{
"id": "example-plugin",
"name": "Example Plugin",
"description": "A sample plugin",
"version": "1.0.0",
"namespace": "Plugins\\Example",
"provider": "Plugins\\Example\\ExampleServiceProvider",
"enabled": true,
"requires": {
"php": ">=8.1",
"laravel/framework": "^10.0"
}
}- Create a service provider for your plugin:
<?php
namespace Plugins\Example;
use Illuminate\Support\ServiceProvider;
class ExampleServiceProvider extends ServiceProvider
{
public function register()
{
// Register bindings
}
public function boot()
{
// Boot logic
$this->loadRoutesFrom(__DIR__.'/routes/web.php');
$this->loadViewsFrom(__DIR__.'/resources/views', 'example');
$this->loadMigrationsFrom(__DIR__.'/database/migrations');
}
}plugins/
example-plugin/
src/
Http/
Controllers/
Models/
Providers/
ExampleServiceProvider.php
resources/
views/
routes/
web.php
database/
migrations/
plugin.json
README.md
The plugin system dispatches several events that you can listen for:
WhileSmart\PluginEngine\Events\PluginEnabling- Fired before a plugin is enabledWhileSmart\PluginEngine\Events\PluginEnabled- Fired after a plugin is enabledWhileSmart\PluginEngine\Events\PluginDisabling- Fired before a plugin is disabledWhileSmart\PluginEngine\Events\PluginDisabled- Fired after a plugin is disabledWhileSmart\PluginEngine\Events\PluginInstalled- Fired after a plugin is installedWhileSmart\PluginEngine\Events\PluginDiscovered- Fired when a plugin is discovered
The repository ships a dockerized environment, so PHP and Composer are not required on the host:
make install # build the container and install dependencies
make test # run the test suite
make pint # fix code style
make check # run style check and tests
make shell # open a shell in the containerThis project is open-source and licensed under the MIT License.