diff --git a/app/Services/PluginManager.php b/app/Services/PluginManager.php index ca79699d..0c63c0f5 100644 --- a/app/Services/PluginManager.php +++ b/app/Services/PluginManager.php @@ -121,6 +121,7 @@ class PluginManager $this->loadVendor($enabled); $this->loadViewsAndTranslations($enabled); $this->loadBootstrapper($enabled); + $this->registerLifecycleHooks(); $this->booted = true; } @@ -195,6 +196,25 @@ class PluginManager }); } + protected function registerLifecycleHooks() + { + $this->dispatcher->listen([ + Events\PluginWasEnabled::class, + Events\PluginWasDisabled::class, + Events\PluginWasDeleted::class, + ], function ($event) { + $plugin = $event->plugin; + $path = $plugin->getPath().'/callbacks.php'; + if ($this->filesystem->exists($path)) { + $callbacks = $this->filesystem->getRequire($path); + $callback = Arr::get($callbacks, get_class($event)); + if ($callback) { + return $this->app->call($callback, [$plugin]); + } + } + }); + } + /** * @return Collection */ diff --git a/tests/ServicesTest/PluginManagerTest.php b/tests/ServicesTest/PluginManagerTest.php index b602a3e9..f4f66758 100644 --- a/tests/ServicesTest/PluginManagerTest.php +++ b/tests/ServicesTest/PluginManagerTest.php @@ -4,6 +4,7 @@ namespace Tests; use Event; use ReflectionClass; +use App\Services\Plugin; use App\Services\PluginManager; use Illuminate\Filesystem\Filesystem; @@ -260,6 +261,48 @@ class PluginManagerTest extends TestCase option(['plugins_enabled' => '[]']); } + public function testLifecycleHooks() + { + $this->mock(Filesystem::class, function ($mock) { + $mock->shouldReceive('directories') + ->with(base_path('plugins')) + ->once() + ->andReturn(collect(['/mayaka'])); + + $mock->shouldReceive('exists') + ->with('/mayaka'.DIRECTORY_SEPARATOR.'package.json') + ->once() + ->andReturn(true); + + $mock->shouldReceive('get') + ->with('/mayaka'.DIRECTORY_SEPARATOR.'package.json') + ->once() + ->andReturn(json_encode([ + 'name' => 'mayaka', + 'version' => '0.0.0', + 'namespace' => 'Mayaka', + ])); + + $mock->shouldReceive('exists') + ->with('/mayaka/callbacks.php') + ->once() + ->andReturn(true); + + $mock->shouldReceive('getRequire') + ->with('/mayaka/callbacks.php') + ->once() + ->andReturn([ + \App\Events\PluginWasDeleted::class => function ($plugin) { + $this->assertInstanceOf(Plugin::class, $plugin); + $this->assertEquals('mayaka', $plugin->name); + }, + ]); + }); + + $manager = $this->rebootPluginManager(app('plugins')); + event(new \App\Events\PluginWasDeleted(new Plugin('/mayaka', ['name' => 'mayaka']))); + } + public function testRegisterAutoload() { $dir = config('plugins.directory');