From bb5a2529dfa284f5b6bed03d2f0baef4cf4cf4e0 Mon Sep 17 00:00:00 2001 From: Stanislau Komar Date: Thu, 29 Dec 2022 01:04:52 +0400 Subject: [PATCH] v1.3: implements KernelInterface::loadPlugin method in runtime --- README.md | 25 ++++++---- composer.json | 4 +- phpdoc.xml | 33 ------------- src/Kernel.php | 22 ++++++--- src/KernelInterface.php | 60 +++++++++++++++++++++++- src/Plugin/PluginBootLoaderInterface.php | 15 ++++++ 6 files changed, 107 insertions(+), 52 deletions(-) delete mode 100644 phpdoc.xml diff --git a/README.md b/README.md index b70f01c..33e97c3 100644 --- a/README.md +++ b/README.md @@ -28,32 +28,39 @@ include 'vendor/autoload.php'; ```php +use Micro\Framework\Kernel\Configuration\DefaultApplicationConfiguration; +use Micro\Framework\Kernel\Plugin\PluginDependedInterface; +use Micro\Framework\Kernel\Plugin\ApplicationPluginInterface; +use Micro\Component\DependencyInjection\Container; +use Micro\Framework\Kernel\Plugin\PluginBootLoaderInterface; +use Micro\Framework\Kernel\KernelBuilder; + // Create simple plugin -class TestPlugin extends \Micro\Framework\Kernel\Plugin\AbstractPlugin +class TestPlugin implements PluginDependedInterface { - public function provideDependencies(\Micro\Component\DependencyInjection\Container $container): void + public function provideDependencies(Container $container): void { print_r('Provided dependencies'); } } // Create Dependency provider boot loader -class DependencyProviderLoader implements \Micro\Framework\Kernel\Plugin\PluginBootLoaderInterface +class DependencyProviderLoader implements PluginBootLoaderInterface { - public function __construct(private readonly \Micro\Component\DependencyInjection\Container $container) + public function __construct(private readonly Container $container) { } - public function boot(\Micro\Framework\Kernel\Plugin\ApplicationPluginInterface $applicationPlugin): void + public function boot(ApplicationPluginInterface $applicationPlugin): void { - $applicationPlugin->provideDependencies($this->container); + $applicationPlugin->getDependedPlugins($this->container); } } -$kernelBuilder = new \Micro\Framework\Kernel\KernelBuilder(); -$container = new \Micro\Component\DependencyInjection\Container(); -$configuration = new \Micro\Framework\Kernel\Configuration\DefaultApplicationConfiguration(['APP_ENV' => 'dev']); +$kernelBuilder = new KernelBuilder(); +$container = new Container(); +$configuration = new DefaultApplicationConfiguration(['APP_ENV' => 'dev']); $kernel = $kernelBuilder ->setApplicationConfiguration($configuration) ->setContainer($container) diff --git a/composer.json b/composer.json index 8fb32b9..b3b589a 100755 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "micro/kernel", "type": "library", "description": "", - "version": "1.2", + "version": "1.3", "license": "MIT", "autoload": { "psr-4": { @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=8.0", + "php": "^8.1|^8.2", "micro/dependency-injection": "^1" } } diff --git a/phpdoc.xml b/phpdoc.xml deleted file mode 100644 index 243df9d..0000000 --- a/phpdoc.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - Micro Framework: Kernel component - - docs/.build - - - - - src/ - - - - src/**/*Interface.php - - - - - - - php - - public - - - - \ No newline at end of file diff --git a/src/Kernel.php b/src/Kernel.php index c04fbaf..2461302 100755 --- a/src/Kernel.php +++ b/src/Kernel.php @@ -22,6 +22,11 @@ class Kernel implements KernelInterface */ private array $plugins; + /** + * @var string[] + */ + private array $pluginsLoaded; + /** * @param array $applicationPluginCollection * @param Container|null $container @@ -36,11 +41,12 @@ public function __construct( $this->isStarted = false; $this->isTerminated = false; + $this->pluginsLoaded = []; $this->plugins = []; } /** - * @return void + * {@inheritDoc} */ public function run(): void { @@ -53,7 +59,7 @@ public function run(): void } /** - * @return void + * {@inheritDoc} */ public function terminate(): void { @@ -65,7 +71,7 @@ public function terminate(): void } /** - * @return Container + * {@inheritDoc} */ public function container(): Container { @@ -73,11 +79,14 @@ public function container(): Container } /** - * @param string $applicationPluginClass - * @return void + * {@inheritDoc} */ - protected function loadPlugin(string $applicationPluginClass): void + public function loadPlugin(string $applicationPluginClass): void { + if (in_array($applicationPluginClass, $this->pluginsLoaded, true)) { + return; + } + $plugin = new $applicationPluginClass(); foreach ($this->pluginBootLoaderCollection as $bootLoader) { @@ -85,6 +94,7 @@ protected function loadPlugin(string $applicationPluginClass): void } $this->plugins[] = $plugin; + $this->pluginsLoaded[] = $applicationPluginClass; } /** diff --git a/src/KernelInterface.php b/src/KernelInterface.php index 9349b35..fe1293b 100755 --- a/src/KernelInterface.php +++ b/src/KernelInterface.php @@ -4,11 +4,52 @@ use Micro\Component\DependencyInjection\Container; +/** + * The kernel is needed for plugin management. A plugin can be any class object. + * + * Kernel implementation + * + * GitHub Docs + * + * Packagist Repo + * + * ```php + * interface SomePluginInterface + * { + * public function getName(): string; + * } + * + * $kernel = new Kernel( + * [ + * new class implements SomePluginInterface + * { + * public function getName(): string + * { + * return 'SomePluginName'; + * } + * } + * ], + * [] + * ); + * + * $kernel->run(); + * $iterator = $kernel->plugins(SomePluginInterface::class); + * foreach($iterator as $plugin) + * { + * print_r($plugin->getName() . "\r\n"); + * } + * + * ``` + * + * @api + */ interface KernelInterface { /** * Get service Dependency Injection Container * + * @api + * * @return Container */ public function container(): Container; @@ -16,6 +57,8 @@ public function container(): Container; /** * Run application * + * @api + * * @return void */ public function run(): void; @@ -23,14 +66,27 @@ public function run(): void; /** * Terminate application * + * @api + * * @return void */ public function terminate(): void; /** - * @param string|null $interfaceInherited + * @param string $applicationPluginClass + * + * @return void + */ + public function loadPlugin(string $applicationPluginClass): void; + + /** + * Iterate plugins with the specified type. + * + * @param string|null $interfaceInherited If empty, each connected plugin will be iterated. + * + * @api * - * @return iterable + * @return iterable Application plugins iterator */ public function plugins(string $interfaceInherited = null): iterable; } diff --git a/src/Plugin/PluginBootLoaderInterface.php b/src/Plugin/PluginBootLoaderInterface.php index 2017306..84da579 100755 --- a/src/Plugin/PluginBootLoaderInterface.php +++ b/src/Plugin/PluginBootLoaderInterface.php @@ -2,9 +2,24 @@ namespace Micro\Framework\Kernel\Plugin; +/** + * An interface that allows you to declare plugin loading behavior. Called when the plugin is initialized. + * + * Do not use this interface unless absolutely necessary. + * + * + * An example of the implementation of the loader to create an object with the plugin configuration. + * + * + * @api + */ interface PluginBootLoaderInterface { /** + * Immediately after creation, a pre-configuration plugin gets here. + * + * @api + * * @param object $applicationPlugin * * @return void