From 329f4c86bccacf54413d1fc35a3fa2862bea13b0 Mon Sep 17 00:00:00 2001 From: printempw Date: Mon, 24 Oct 2016 22:32:07 +0800 Subject: [PATCH] add class autoloader for plugins --- app/Providers/PluginServiceProvider.php | 46 ++++++++++++++++++------- app/Services/Plugin.php | 42 ++++++++++++---------- app/Services/PluginManager.php | 39 ++++++++++----------- 3 files changed, 76 insertions(+), 51 deletions(-) diff --git a/app/Providers/PluginServiceProvider.php b/app/Providers/PluginServiceProvider.php index 3df1e26d..a2adaf24 100644 --- a/app/Providers/PluginServiceProvider.php +++ b/app/Providers/PluginServiceProvider.php @@ -2,6 +2,8 @@ namespace App\Providers; +use Illuminate\Support\Str; +use App\Services\PluginManager; use Illuminate\Support\ServiceProvider; class PluginServiceProvider extends ServiceProvider @@ -11,9 +13,38 @@ class PluginServiceProvider extends ServiceProvider * * @return void */ - public function boot() + public function boot(PluginManager $plugins) { - // + $namespaces = []; + + foreach ($plugins->getPlugins() as $plugin) { + $namespaces[$plugin->getNameSpace()] = $plugin->getPath()."/src"; + } + + // register class autoloader for plugins + spl_autoload_register(function($class) use ($namespaces) { + // traverse in registered plugin namespaces + foreach ((array) array_keys($namespaces) as $namespace) { + if ($namespace != '' && mb_strpos($class, $namespace) === 0) { + // parse real file path + $path = $namespaces[$namespace].Str::replaceFirst($namespace, '', $class).".php"; + $path = str_replace('\\', '/', $path); + + if (file_exists($path)) { + include $path; + } + } + } + }); + + $bootstrappers = $plugins->getEnabledBootstrappers(); + + foreach ($bootstrappers as $file) { + // bootstraper is a closure + $bootstrapper = require $file; + + $this->app->call($bootstrapper); + } } /** @@ -23,15 +54,6 @@ class PluginServiceProvider extends ServiceProvider */ public function register() { - $this->app->bind('plugins', 'App\Services\PluginManager'); - - $bootstrappers = $this->app->make('plugins')->getEnabledBootstrappers(); - - foreach ($bootstrappers as $file) { - // bootstraper is a closure - $bootstrapper = require $file; - - $this->app->call($bootstrapper); - } + $this->app->singleton('plugins', PluginManager::class); } } diff --git a/app/Services/Plugin.php b/app/Services/Plugin.php index 7e5ce819..876da0de 100644 --- a/app/Services/Plugin.php +++ b/app/Services/Plugin.php @@ -2,29 +2,15 @@ namespace App\Services; -use Illuminate\Contracts\Support\Arrayable; use Illuminate\Support\Arr; use Illuminate\Support\Str; +use Illuminate\Contracts\Support\Arrayable; /** * @property string $name * @property string $description - * @property string $type - * @property array $keywords - * @property string $homepage - * @property string $time - * @property string $license - * @property array $authors - * @property array $support - * @property array $require - * @property array $requireDev - * @property array $autoload - * @property array $autoloadDev - * @property array $conflict - * @property array $replace - * @property array $provide - * @property array $suggest - * @property array $extra + * @property string $title + * @property array $author */ class Plugin implements Arrayable { @@ -56,6 +42,13 @@ class Plugin implements Arrayable */ protected $version; + /** + * The namespace used by the plugin. + * + * @var string + */ + protected $namespace; + /** * Whether the plugin is enabled. * @@ -121,7 +114,20 @@ class Plugin implements Arrayable return $this->installed; } - public function getViewPath($name) { + public function getNameSpace() + { + return $this->namespace; + } + + public function setNameSpace($namespace) + { + $this->namespace = $namespace; + + return $this; + } + + public function getViewPath($name) + { return $this->path."/views/$name.tpl"; } diff --git a/app/Services/PluginManager.php b/app/Services/PluginManager.php index ddf7535b..468adc93 100644 --- a/app/Services/PluginManager.php +++ b/app/Services/PluginManager.php @@ -2,22 +2,28 @@ namespace App\Services; -use Illuminate\Contracts\Foundation\Application; -use Illuminate\Contracts\Events\Dispatcher; -use Illuminate\Filesystem\Filesystem; use Illuminate\Support\Arr; -use Illuminate\Support\Collection; -use App\Services\Repositories\OptionRepository; -use App\Events\PluginWasDisabled; use App\Events\PluginWasEnabled; +use App\Events\PluginWasDisabled; +use Illuminate\Support\Collection; use App\Events\PluginWasUninstalled; +use Illuminate\Filesystem\Filesystem; +use Illuminate\Contracts\Events\Dispatcher; +use App\Services\Repositories\OptionRepository; +use Illuminate\Contracts\Foundation\Application; class PluginManager { - protected $option; - + /** + * @var Application + */ protected $app; + /** + * @var OptionRepository + */ + protected $option; + /** * @var Dispatcher */ @@ -34,13 +40,13 @@ class PluginManager protected $plugins; public function __construct( - OptionRepository $option, Application $app, + OptionRepository $option, Dispatcher $dispatcher, Filesystem $filesystem ) { - $this->option = $option; - $this->app = $app; + $this->app = $app; + $this->option = $option; $this->dispatcher = $dispatcher; $this->filesystem = $filesystem; } @@ -80,6 +86,7 @@ class PluginManager // Per default all plugins are installed if they are registered in composer. $plugin->setInstalled(true); + $plugin->setNameSpace(Arr::get($package, 'namespace')); $plugin->setVersion(Arr::get($package, 'version')); $plugin->setEnabled($this->isEnabled($plugin->name)); @@ -119,10 +126,6 @@ class PluginManager $enabled[] = $name; - // $this->migrate($plugin); - - // $this->publishAssets($plugin); - $this->setEnabled($enabled); $plugin->setEnabled(true); @@ -164,12 +167,6 @@ class PluginManager $this->disable($name); - // $this->migrateDown($plugin); - - // $this->unpublishAssets($plugin); - - // $plugin->setInstalled(false); - $this->filesystem->deleteDirectory($plugin->getPath()); // refresh plugin list