Refactor plugin system (part 11)

This commit is contained in:
Pig Fang 2019-08-15 16:54:12 +08:00
parent d871af1906
commit 560ed2c2fd
2 changed files with 96 additions and 39 deletions

View File

@ -111,6 +111,7 @@ class PluginManager
$manifest['version'], $manifest['version'],
$this->enabled->get($name)['version'] $this->enabled->get($name)['version']
)) { )) {
$this->enabled->put($name, $manifest['version']);
$this->dispatcher->dispatch(new Events\PluginVersionChanged($plugin)); $this->dispatcher->dispatch(new Events\PluginVersionChanged($plugin));
} }
} }
@ -129,9 +130,7 @@ class PluginManager
return; return;
} }
$enabled = $this->all()->filter(function ($plugin) { $enabled = $this->getEnabledPlugins();
return $plugin->isEnabled();
});
$this->registerAutoload( $this->registerAutoload(
$enabled->mapWithKeys(function ($plugin) { $enabled->mapWithKeys(function ($plugin) {
@ -243,14 +242,11 @@ class PluginManager
return $this->all()->get($name); return $this->all()->get($name);
} }
/** public function enable($plugin)
* @param string $name
*/
public function enable($name)
{ {
$plugin = $this->get($name); $plugin = is_string($plugin) ? $this->get($plugin) : $plugin;
if (! $plugin->isEnabled($name)) { if ($plugin && ! $plugin->isEnabled()) {
$this->enabled->put($name, ['version' => $plugin->version]); $this->enabled->put($plugin->name, ['version' => $plugin->version]);
$this->saveEnabled(); $this->saveEnabled();
$plugin->setEnabled(true); $plugin->setEnabled(true);
@ -259,46 +255,32 @@ class PluginManager
} }
} }
/** public function disable($plugin)
* @param string $name
*/
public function disable($name)
{ {
if (is_null($this->enabled)) { $plugin = is_string($plugin) ? $this->get($plugin) : $plugin;
$this->convertPluginRecord(); if ($plugin && $plugin->isEnabled()) {
} $this->enabled->pull($plugin->name);
$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;
$this->saveEnabled(); $this->saveEnabled();
$plugin->setEnabled(false);
$this->dispatcher->dispatch(new Events\PluginWasDisabled($plugin)); $this->dispatcher->dispatch(new Events\PluginWasDisabled($plugin));
} }
} }
/** public function delete($plugin)
* @param string $name
*/
public function delete($name)
{ {
$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->filesystem->deleteDirectory($plugin->getPath());
$this->dispatcher->dispatch(new Events\PluginWasDeleted($plugin));
$this->filesystem->deleteDirectory($plugin->getPath()); $this->plugins->pull($plugin->name);
}
// refresh plugin list
$this->plugins = null;
} }
/** /**

View File

@ -3,6 +3,7 @@
namespace Tests; namespace Tests;
use Event; use Event;
use App\Events;
use ReflectionClass; use ReflectionClass;
use App\Services\Plugin; use App\Services\Plugin;
use App\Services\PluginManager; use App\Services\PluginManager;
@ -374,4 +375,78 @@ class PluginManagerTest extends TestCase
$plugin = new Plugin('', ['require' => ['another-plugin' => '^1.0.0']]); $plugin = new Plugin('', ['require' => ['another-plugin' => '^1.0.0']]);
$this->assertFalse($manager->getUnsatisfied($plugin)->has('another-plugin')); $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());
}
} }