add class autoloader for plugins

This commit is contained in:
printempw 2016-10-24 22:32:07 +08:00
parent 84e4d97f00
commit 329f4c86bc
3 changed files with 76 additions and 51 deletions

View File

@ -2,6 +2,8 @@
namespace App\Providers; namespace App\Providers;
use Illuminate\Support\Str;
use App\Services\PluginManager;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
class PluginServiceProvider extends ServiceProvider class PluginServiceProvider extends ServiceProvider
@ -11,9 +13,38 @@ class PluginServiceProvider extends ServiceProvider
* *
* @return void * @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() public function register()
{ {
$this->app->bind('plugins', 'App\Services\PluginManager'); $this->app->singleton('plugins', PluginManager::class);
$bootstrappers = $this->app->make('plugins')->getEnabledBootstrappers();
foreach ($bootstrappers as $file) {
// bootstraper is a closure
$bootstrapper = require $file;
$this->app->call($bootstrapper);
}
} }
} }

View File

@ -2,29 +2,15 @@
namespace App\Services; namespace App\Services;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Illuminate\Contracts\Support\Arrayable;
/** /**
* @property string $name * @property string $name
* @property string $description * @property string $description
* @property string $type * @property string $title
* @property array $keywords * @property array $author
* @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
*/ */
class Plugin implements Arrayable class Plugin implements Arrayable
{ {
@ -56,6 +42,13 @@ class Plugin implements Arrayable
*/ */
protected $version; protected $version;
/**
* The namespace used by the plugin.
*
* @var string
*/
protected $namespace;
/** /**
* Whether the plugin is enabled. * Whether the plugin is enabled.
* *
@ -121,7 +114,20 @@ class Plugin implements Arrayable
return $this->installed; 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"; return $this->path."/views/$name.tpl";
} }

View File

@ -2,22 +2,28 @@
namespace App\Services; namespace App\Services;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use App\Services\Repositories\OptionRepository;
use App\Events\PluginWasDisabled;
use App\Events\PluginWasEnabled; use App\Events\PluginWasEnabled;
use App\Events\PluginWasDisabled;
use Illuminate\Support\Collection;
use App\Events\PluginWasUninstalled; 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 class PluginManager
{ {
protected $option; /**
* @var Application
*/
protected $app; protected $app;
/**
* @var OptionRepository
*/
protected $option;
/** /**
* @var Dispatcher * @var Dispatcher
*/ */
@ -34,13 +40,13 @@ class PluginManager
protected $plugins; protected $plugins;
public function __construct( public function __construct(
OptionRepository $option,
Application $app, Application $app,
OptionRepository $option,
Dispatcher $dispatcher, Dispatcher $dispatcher,
Filesystem $filesystem Filesystem $filesystem
) { ) {
$this->option = $option; $this->app = $app;
$this->app = $app; $this->option = $option;
$this->dispatcher = $dispatcher; $this->dispatcher = $dispatcher;
$this->filesystem = $filesystem; $this->filesystem = $filesystem;
} }
@ -80,6 +86,7 @@ class PluginManager
// Per default all plugins are installed if they are registered in composer. // Per default all plugins are installed if they are registered in composer.
$plugin->setInstalled(true); $plugin->setInstalled(true);
$plugin->setNameSpace(Arr::get($package, 'namespace'));
$plugin->setVersion(Arr::get($package, 'version')); $plugin->setVersion(Arr::get($package, 'version'));
$plugin->setEnabled($this->isEnabled($plugin->name)); $plugin->setEnabled($this->isEnabled($plugin->name));
@ -119,10 +126,6 @@ class PluginManager
$enabled[] = $name; $enabled[] = $name;
// $this->migrate($plugin);
// $this->publishAssets($plugin);
$this->setEnabled($enabled); $this->setEnabled($enabled);
$plugin->setEnabled(true); $plugin->setEnabled(true);
@ -164,12 +167,6 @@ class PluginManager
$this->disable($name); $this->disable($name);
// $this->migrateDown($plugin);
// $this->unpublishAssets($plugin);
// $plugin->setInstalled(false);
$this->filesystem->deleteDirectory($plugin->getPath()); $this->filesystem->deleteDirectory($plugin->getPath());
// refresh plugin list // refresh plugin list