Plugins ======= Plugins let you extend LacePHP without touching the core. Drop third-party or custom code into `weave/Plugins`, and LacePHP will auto-discover, register routes, middleware or CLI commands for you—keeping your application modular and upgrade-safe. Why Plugins Matter ------------------ - **Modularity** Keep reusable features in separate packages or folders, not mixed with your app or framework. - **Discoverability** LacePHP auto-discovers any class implementing `PluginInterface` under `weave/Plugins`. - **Extensibility** Plugins can register routes, middleware, service providers or CLI commands at boot time. PluginManager Overview ---------------------- LacePHP’s `PluginManager` handles discovery and registration: .. code-block:: php use Lacebox\Sole\PluginManager; $pm = new PluginManager(); $pm->discoverFromFolder(__DIR__); // load PHP files under weave/Plugins $pm->discoverFromComposer('vendor'); // load composer packages with lace-plugin.json $pm->registerAll($router, $config); // let plugins add routes/middleware $pm->bootAll($config); // call plugin boot logic $commands = $pm->getCommands(); // pull in CLI commands Creating a Simple Plugin ------------------------ 1. **Implement** the `PluginInterface` in `weave/Plugins/MyFeature/MyPlugin.php`: .. code-block:: php addRoute( 'GET', '/hello-plugin', fn() => 'Hello from MyPlugin!' ); } public function boot(array $config): void { // run once at framework startup if (! empty($config['myfeature']['enabled'])) { // set up services, load configs, etc. } } } 2. **Enable** any config in `config/lace.php`: .. code-block:: php return [ 'myfeature' => [ 'enabled' => true, // other settings... ], ]; No further wiring is needed—LacePHP will discover and invoke your plugin automatically. Built-in ShoeAI Plugin ---------------------- LacePHP ships with an AI helper plugin under `weave/Plugins/ShoeAI`. It demonstrates: - **Implementing both** `PluginInterface` **and** `CommandProviderInterface` - **Registering multiple CLI commands** for AI features Review `weave/Plugins/ShoeAI/AiCommands.php`: .. code-block:: php register('ai:activate', 'Activate your AI license', fn($argv)=>Credentials::enable()); $cli->register('ai:status', 'Show AI subscription status', fn($argv)=>ShoeAIStatus::status()); $cli->register('ai:scaffold','Scaffold code from a prompt', fn($argv)=>ShoeGenie::scaffold($argv[2] ?? null)); $cli->register('ai:rollback','Rollback scaffolded code', fn($argv)=>ShoeGenie::rollback()); $cli->register('ai:buddy', 'AI peer-coding buddy', fn($argv)=>ShoeBuddy::ask($argv[2] ?? null, (int)($argv[3] ?? 0), $argv[4] ?? null)); } } When LacePHP starts, these commands become available: .. code-block:: text php lace ai:activate php lace ai:status php lace ai:scaffold "Build a REST API for posts" php lace ai:rollback php lace ai:buddy Controllers/MyController.php 10 "Why does this line fail?" Composer-Published Plugins -------------------------- Publish a plugin as a Composer package: 1. **Add** a `lace-plugin.json` alongside your `composer.json`: .. code-block:: json { "pluginClass": "Vendor\\MyPlugin\\MainPlugin" } 2. **Implement** `PluginInterface` (and/or `CommandProviderInterface`) in `MainPlugin`. 3. **Require** via composer: .. code-block:: bash composer require vendor/my-laceplugin LacePHP’s `discoverFromComposer()` will detect and load it automatically. Registering CLI Commands Manually --------------------------------- Plugins (or your app) can add commands at runtime: .. code-block:: php $pm->registerCommands([ \weave\Plugins\MyFeature\MyCommand::class, ]); LacePHP will include these classes when assembling the CLI. Best Practices -------------- - **Single responsibility:** per plugin group related features together. - **Namespace correctly:** follow PSR-4 under `weave/Plugins/YourPlugin/`. - **Use Composer:** for shareable plugins—others can install with `composer require`. - **Keep `boot()` light:** defer heavy work to services or on-demand hooks. .. warning:: - Plugin discovery loads **every** PHP file under `weave/Plugins`—avoid duplicate class names. - Ensure your `register()` logic does not override core routes or middleware unintentionally. - Sanitize configuration values before use in `boot()` to prevent runtime errors. By writing plugins, even a complex AI feature like ShoeAI, you can add or share functionality cleanly, without touching LacePHP’s core code. | |