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'],
$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);
$this->disable($name);
$plugin = is_string($plugin) ? $this->get($plugin) : $plugin;
if ($plugin) {
$this->disable($plugin);
// dispatch event before deleting plugin files
$this->dispatcher->dispatch(new Events\PluginWasDeleted($plugin));
$this->filesystem->deleteDirectory($plugin->getPath());
// refresh plugin list
$this->plugins = null;
$this->plugins->pull($plugin->name);
}
}
/**

View File

@ -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());
}
}