Plugin Development Documentation

Complete guide to creating powerful plugins for Edge Suite Plugin Manager

Quick Start

Get up and running with plugin development in minutes. Learn the basics and start creating.

Features

Discover all the powerful auto-registration features available in the plugin system.

Requirements

System requirements and dependencies needed for plugin development.

Welcome to Edge Suite Plugin Manager

The Edge Suite Plugin Manager is a powerful system that allows you to easily extend Edge Suite with custom plugins. It provides a complete solution for adding new functionality through modular, hot-swappable plugins.

Key Benefits

  • Easy plugin installation via ZIP upload
  • Hot-swappable plugins without downtime
  • Comprehensive configuration system with schemas
  • Built-in security and validation
  • Auto-discovery of routes, views, and assets
  • Admin menu integration
  • Event hooks and listeners
  • NEW: Lifecycle hooks for installation, activation, and cleanup
Note: Edge Suite Plugin Manager requires Laravel 10.0+ and PHP 8.1+. All plugins are installed in the plugins/ directory.

Auto-Registration Features

The Edge Suite Plugin Manager comes with powerful auto-registration capabilities:

🔧 Component Auto-Loading

Models, Controllers, Services, and Middleware are automatically discovered and registered with Laravel's systems.

⚙️ Configuration System

Each plugin can have its own configuration schema with validation, making setup straightforward.

🛣️ Route Registration

Plugin routes are automatically registered with custom middleware, prefixes, and domains.

📊 Admin Integration

Seamless integration with Edge Suite admin panel, including menu registration and permissions.

🔄 Lifecycle Management

Built-in lifecycle hooks allow plugins to perform setup, cleanup, and validation operations during install, activate, deactivate, and uninstall events.

System Requirements

Before developing plugins, ensure your system meets these requirements:

Minimum Requirements

  • Edge Suite: Latest version installed
  • PHP: 8.1 or higher
  • Laravel: 10.0 or higher
  • Extensions: ZIP, JSON, Fileinfo
  • Permissions: Write access to plugins/ directory
Important: Ensure your server has sufficient memory and execution time for plugin operations.

Plugin File Structure

Every plugin must follow this structure to be recognized by Edge Suite Plugin Manager:

YourPluginName/ ├── plugin.json # REQUIRED - Plugin manifest ├── Plugin.php # REQUIRED - Main plugin class ├── routes.php # OPTIONAL - Plugin routes ├── config.json # OPTIONAL - Plugin configuration ├── Controllers/ # OPTIONAL - Plugin controllers │ └── YourController.php ├── Models/ # OPTIONAL - Eloquent models (auto-registered) │ └── YourModel.php ├── Observers/ # OPTIONAL - Model observers (auto-registered) │ └── YourModelObserver.php ├── Middleware/ # OPTIONAL - Route middleware (auto-registered) │ └── YourMiddleware.php ├── Services/ # OPTIONAL - Service classes (auto-bound) │ └── YourService.php ├── views/ # OPTIONAL - Plugin views │ └── dashboard.blade.php ├── assets/ # OPTIONAL - CSS, JS, images │ ├── css/ │ ├── js/ │ └── images/ └── database/ # OPTIONAL - Database related files └── factories/ # OPTIONAL - Model factories (auto-loaded) └── YourModelFactory.php
Important: Only plugin.json and Plugin.php are required. All other files are optional but follow conventions for auto-loading.

Required Files

These two files must be present in every plugin:

  • plugin.json - Contains plugin metadata and configuration schema
  • Plugin.php - Main plugin class that handles initialization and lifecycle

Optional Files

These files are automatically loaded if present:

  • routes.php - Plugin routes (auto-registered with namespace and middleware)
  • config.json - Plugin configuration values
  • Controllers/ - Auto-loaded with plugin namespace
  • Models/ - Auto-registered with Eloquent and service container
  • Observers/ - Auto-associated with models (e.g., UserObserver → User model)
  • Middleware/ - Auto-registered as route middleware with plugin prefix
  • Services/ - Auto-bound to Laravel service container
  • views/ - Registered as view namespace (lowercase plugin name)
  • assets/ - Copied to public/plugins/{plugin-name}/
  • database/factories/ - Auto-loaded for testing and seeding
Auto-Registration: Models, Observers, Middleware, and Services are automatically registered with Laravel's container and systems. No manual registration needed!

Plugin Lifecycle Hooks

Edge Suite Plugin Manager provides powerful lifecycle hooks that allow your plugins to execute custom logic during important events like installation, activation, deactivation, and uninstallation.

Available Lifecycle Hooks

Your Plugin.php class can implement any of these optional hook methods:

<?php namespace Plugins\YourPluginName; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; class Plugin { protected $pluginPath; protected $manifest; public function __construct($pluginPath, $manifest) { $this->pluginPath = $pluginPath; $this->manifest = $manifest; } // Called when plugin is first installed public function onInstall() { Log::info('Plugin installed: Creating database tables...'); // Create database tables Schema::create('your_plugin_table', function (Blueprint $table) { $table->id(); $table->string('name'); $table->timestamps(); }); // Copy default configuration files // Set up initial data return true; } // Called when plugin is activated public function onActivate() { Log::info('Plugin activated: Registering services...'); // Register event listeners // Schedule tasks // Enable features // Return false to cancel activation return true; } // Called when plugin is deactivated public function onDeactivate() { Log::info('Plugin deactivated: Cleaning up...'); // Remove event listeners // Cancel scheduled tasks // Disable features } // Called before plugin is uninstalled public function onUninstall() { Log::info('Plugin uninstalling: Removing data...'); // Drop database tables Schema::dropIfExists('your_plugin_table'); // Remove configuration files // Clean up any remaining data } }

Hook Execution Order

Understanding when each hook is called:

🟢 Installation Process

  1. Plugin files are extracted and validated
  2. onInstall() hook is called
  3. Plugin is registered but remains inactive

🟢 Activation Process

  1. Plugin validation checks pass
  2. Plugin is loaded (classes, routes, views registered)
  3. onActivate() hook is called
  4. If hook returns false, activation is cancelled
  5. Admin menus are registered
  6. Caches are refreshed

🔴 Deactivation Process

  1. onDeactivate() hook is called
  2. Plugin models are cleared
  3. Admin menus are removed
  4. Caches are refreshed

🔴 Uninstallation Process

  1. onUninstall() hook is called
  2. Plugin is deactivated (if active)
  3. All plugin files are removed
  4. Public assets are removed
  5. Caches are cleared
Pro Tip: Use onActivate() to return false if your plugin requirements aren't met, preventing activation until issues are resolved.

Hook Best Practices

  • Keep hooks fast: Avoid long-running operations that could timeout
  • Use transactions: Wrap database operations in transactions for safety
  • Handle errors gracefully: Use try-catch blocks and return appropriate values
  • Log important actions: Help administrators troubleshoot issues
  • Check dependencies: Validate requirements before proceeding
  • Clean up thoroughly: Remove all traces during uninstall
Warning: Lifecycle hooks run with elevated privileges. Always validate input and sanitize data to prevent security issues.

Development Guide

Learn how to create plugins with proper configuration and structure.

1. Creating plugin.json (REQUIRED)

The manifest file defines your plugin's metadata and configuration schema:

{ // REQUIRED FIELDS "name": "YourPluginName", "version": "1.0.0", // OPTIONAL FIELDS "display_name": "Your Plugin Display Name", "description": "What your plugin does", "author": "Your Name", "namespace": "Plugins\\YourPluginName", // ROUTE CONFIGURATION "routes": { "prefix": "your-plugin", "middleware": ["web", "auth"] }, // CONFIGURATION SCHEMA "config_schema": { "enabled": { "type": "boolean", "default": true, "label": "Enable Plugin" } } }

2. Creating Plugin.php (REQUIRED)

The main plugin class handles initialization and lifecycle events:

<?php namespace Plugins\YourPluginName; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Schema; class Plugin { protected $pluginPath; protected $manifest; protected $config; // REQUIRED - Constructor called on plugin load public function __construct($pluginPath, $manifest) { $this->pluginPath = $pluginPath; $this->manifest = $manifest; $this->config = $this->loadConfig(); $this->init(); } // Initialize your plugin protected function init() { Log::info('Your Plugin initialized'); } // OPTIONAL - Load plugin configuration protected function loadConfig() { $configPath = $this->pluginPath . '/config.json'; if (file_exists($configPath)) { return json_decode(file_get_contents($configPath), true) ?: []; } return ['enabled' => true]; } // LIFECYCLE HOOKS - All optional public function onInstall() { Log::info('Setting up database tables...'); // Create tables, copy files, etc. return true; } public function onActivate() { Log::info('Plugin activated successfully'); // Register services, enable features return true; // Return false to cancel activation } public function onDeactivate() { Log::info('Plugin deactivated'); // Clean up, disable features } public function onUninstall() { Log::info('Removing plugin data...'); // Drop tables, remove files } }

3. Advanced Features

Take advantage of auto-registration features:

Models (Auto-Registered)

Create models in Models/ directory - they're automatically registered with Laravel's service container:

// Models/YourModel.php <?php namespace Plugins\YourPluginName\Models; use Illuminate\Database\Eloquent\Model; class YourModel extends Model { protected $table = 'your_plugin_table'; protected $fillable = ['name', 'description']; }

Controllers (Auto-Loaded)

Controllers are automatically loaded with your plugin's namespace:

// Controllers/DashboardController.php <?php namespace Plugins\YourPluginName\Controllers; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class DashboardController extends Controller { public function index() { return view('yourpluginname::dashboard'); } }

Routes (Auto-Registered)

Create routes.php and they're automatically registered with your namespace:

// routes.php <?php use Illuminate\Support\Facades\Route; Route::get('/', 'DashboardController@index')->name('dashboard'); Route::get('/settings', 'DashboardController@settings')->name('settings');

Plugin Examples

Real-world examples to help you get started with plugin development.

Live Examples: Check out complete working examples in our GitHub repository.

Example 1: Database Plugin with Lifecycle Hooks

A plugin that creates its own database table and manages data:

// Plugin.php <?php namespace Plugins\TaskManager; use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Log; class Plugin { protected $pluginPath; protected $manifest; public function __construct($pluginPath, $manifest) { $this->pluginPath = $pluginPath; $this->manifest = $manifest; } public function onInstall() { // Create tasks table on install Schema::create('plugin_tasks', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('description')->nullable(); $table->boolean('completed')->default(false); $table->timestamps(); }); Log::info('Task Manager: Database table created'); return true; } public function onActivate() { // Check if table exists before activation if (!Schema::hasTable('plugin_tasks')) { Log::error('Task Manager: Required table missing'); return false; // Cancel activation } Log::info('Task Manager: Plugin activated'); return true; } public function onDeactivate() { Log::info('Task Manager: Plugin deactivated'); } public function onUninstall() { // Clean up: drop table on uninstall Schema::dropIfExists('plugin_tasks'); Log::info('Task Manager: Database table removed'); } }

Example 2: API Integration with Configuration

A weather plugin that uses external APIs and configuration:

{ "name": "WeatherWidget", "version": "1.0.0", "display_name": "Weather Widget", "description": "Displays weather information from external API", "config_schema": { "api_key": { "type": "string", "label": "Weather API Key", "required": true }, "location": { "type": "string", "default": "London", "label": "Default Location" }, "cache_duration": { "type": "integer", "default": 300, "label": "Cache Duration (seconds)" } } }
// Plugin.php <?php namespace Plugins\WeatherWidget; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; class Plugin { protected $pluginPath; protected $manifest; protected $config; public function __construct($pluginPath, $manifest) { $this->pluginPath = $pluginPath; $this->manifest = $manifest; $this->config = $this->loadConfig(); } protected function loadConfig() { $configPath = $this->pluginPath . '/config.json'; if (file_exists($configPath)) { return json_decode(file_get_contents($configPath), true) ?: []; } return []; } public function onActivate() { // Validate API key before activation if (empty($this->config['api_key'])) { Log::error('Weather Widget: API key required'); return false; } // Test API connection try { $response = Http::get('https://api.openweathermap.org/data/2.5/weather', [ 'q' => $this->config['location'] ?? 'London', 'appid' => $this->config['api_key'] ]); if ($response->failed()) { Log::error('Weather Widget: API connection failed'); return false; } } catch (\Exception $e) { Log::error('Weather Widget: ' . $e->getMessage()); return false; } Log::info('Weather Widget: Successfully activated'); return true; } public function onDeactivate() { Log::info('Weather Widget: Deactivated'); } }

Installation Process

To install and test your plugins:

  1. Create your plugin folder with the required files
  2. Test locally in your Edge Suite development environment
  3. Zip the entire plugin folder
  4. Upload via Edge Suite admin panel
  5. Configure plugin settings (if required)
  6. Activate and test your plugin
Best Practice: Use lifecycle hooks to validate requirements and fail gracefully if conditions aren't met. This prevents broken activations!

Next Steps

Ready to start building? Here are some resources:

  • Browse example plugins for inspiration
  • Check the Edge Suite community for plugin ideas
  • Join our Discord for development support
  • Share your plugins with the Edge Suite community