diff --git a/app/Services/PluginManager.php b/app/Services/PluginManager.php index b867c474..bacf326d 100644 --- a/app/Services/PluginManager.php +++ b/app/Services/PluginManager.php @@ -111,6 +111,7 @@ class PluginManager $manifest['version'], $this->enabled->get($name)['version'] )) { + $this->enabled->put($name, $manifest['version']); $this->dispatcher->dispatch(new Events\PluginVersionChanged($plugin)); } } @@ -129,9 +130,7 @@ class PluginManager return; } - $enabled = $this->all()->filter(function ($plugin) { - return $plugin->isEnabled(); - }); + $enabled = $this->getEnabledPlugins(); $this->registerAutoload( $enabled->mapWithKeys(function ($plugin) { @@ -243,14 +242,11 @@ class PluginManager return $this->all()->get($name); } - /** - * @param string $name - */ - public function enable($name) + public function enable($plugin) { - $plugin = $this->get($name); - if (! $plugin->isEnabled($name)) { - $this->enabled->put($name, ['version' => $plugin->version]); + $plugin = is_string($plugin) ? $this->get($plugin) : $plugin; + if ($plugin && ! $plugin->isEnabled()) { + $this->enabled->put($plugin->name, ['version' => $plugin->version]); $this->saveEnabled(); $plugin->setEnabled(true); @@ -259,46 +255,32 @@ class PluginManager } } - /** - * @param string $name - */ - public function disable($name) + public function disable($plugin) { - if (is_null($this->enabled)) { - $this->convertPluginRecord(); - } - - $rejected = $this->enabled->reject(function ($item) use ($name) { - return is_string($item) ? $item == $name : $item['name'] == $name; - }); - - if ($rejected->count() !== $this->enabled->count()) { - $plugin = $this->getPlugin($name); - $plugin->setEnabled(false); - - $this->enabled = $rejected; + $plugin = is_string($plugin) ? $this->get($plugin) : $plugin; + if ($plugin && $plugin->isEnabled()) { + $this->enabled->pull($plugin->name); $this->saveEnabled(); + $plugin->setEnabled(false); + $this->dispatcher->dispatch(new Events\PluginWasDisabled($plugin)); } } - /** - * @param string $name - */ - public function delete($name) + public function delete($plugin) { - $plugin = $this->getPlugin($name); + $plugin = is_string($plugin) ? $this->get($plugin) : $plugin; + if ($plugin) { + $this->disable($plugin); - $this->disable($name); + // dispatch event before deleting plugin files + $this->dispatcher->dispatch(new Events\PluginWasDeleted($plugin)); - // dispatch event before deleting plugin files - $this->dispatcher->dispatch(new Events\PluginWasDeleted($plugin)); + $this->filesystem->deleteDirectory($plugin->getPath()); - $this->filesystem->deleteDirectory($plugin->getPath()); - - // refresh plugin list - $this->plugins = null; + $this->plugins->pull($plugin->name); + } } /** diff --git a/tests/ServicesTest/PluginManagerTest.php b/tests/ServicesTest/PluginManagerTest.php index c79c6da0..c4976cd9 100644 --- a/tests/ServicesTest/PluginManagerTest.php +++ b/tests/ServicesTest/PluginManagerTest.php @@ -3,6 +3,7 @@ namespace Tests; use Event; +use App\Events; use ReflectionClass; use App\Services\Plugin; use App\Services\PluginManager; @@ -374,4 +375,78 @@ class PluginManagerTest extends TestCase $plugin = new Plugin('', ['require' => ['another-plugin' => '^1.0.0']]); $this->assertFalse($manager->getUnsatisfied($plugin)->has('another-plugin')); } + + public function testEnable() + { + Event::fake(); + + $manager = app('plugins'); + $reflection = new ReflectionClass($manager); + $property = $reflection->getProperty('plugins'); + $property->setAccessible(true); + $plugin = new Plugin('', ['name' => 'fake']); + $property->setValue($manager, collect(['fake' => $plugin])); + + $manager->enable('fake'); + Event::assertDispatched(Events\PluginWasEnabled::class, function ($event) { + $this->assertEquals('fake', $event->plugin->name); + return true; + }); + $this->assertTrue($manager->getEnabledPlugins()->has('fake')); + $this->assertEquals( + 'fake', + json_decode(resolve(\App\Services\Option::class)->get('plugins_enabled'), true)[0]['name'] + ); + } + + public function testDisable() + { + Event::fake(); + + $manager = app('plugins'); + $reflection = new ReflectionClass($manager); + $property = $reflection->getProperty('plugins'); + $property->setAccessible(true); + $plugin = new Plugin('', ['name' => 'fake']); + $plugin->setEnabled(true); + $property->setValue($manager, collect(['fake' => $plugin])); + + $manager->disable('fake'); + Event::assertDispatched(Events\PluginWasDisabled::class, function ($event) { + $this->assertEquals('fake', $event->plugin->name); + return true; + }); + $this->assertFalse($manager->getEnabledPlugins()->has('fake')); + $this->assertCount(0, json_decode(resolve(\App\Services\Option::class)->get('plugins_enabled'), true)); + } + + public function testDelete() + { + Event::fake(); + $this->mock(Filesystem::class, function ($mock) { + $mock->shouldReceive('directories')->andReturn(collect([])); + $mock->shouldReceive('deleteDirectory')->with('/fake')->once(); + }); + + $manager = app('plugins'); + $reflection = new ReflectionClass($manager); + $property = $reflection->getProperty('plugins'); + $property->setAccessible(true); + $plugin = new Plugin('/fake', ['name' => 'fake']); + $plugin->setEnabled(true); + $property->setValue($manager, collect(['fake' => $plugin])); + + $manager->delete('fake'); + Event::assertDispatched(Events\PluginWasDisabled::class, function ($event) { + $this->assertEquals('fake', $event->plugin->name); + return true; + }); + Event::assertDispatched(Events\PluginWasDeleted::class, function ($event) { + $this->assertEquals('fake', $event->plugin->name); + return true; + }); + $this->assertFalse($manager->getEnabledPlugins()->has('fake')); + $this->assertCount(0, json_decode(resolve(\App\Services\Option::class)->get('plugins_enabled'), true)); + $this->assertTrue($manager->all()->isEmpty()); + } }