Refactor plugin system (part 4)

This commit is contained in:
Pig Fang 2019-08-12 15:21:50 +08:00
parent 18019d85e6
commit d15fd0b36d
6 changed files with 138 additions and 1 deletions

View File

@ -0,0 +1,21 @@
<?php
namespace App\Events;
use App\Services\Plugin;
class PluginVersionChanged extends Event
{
public $plugin;
/**
* Create a new event instance.
*
* @param Plugin $plugin
* @return void
*/
public function __construct(Plugin $plugin)
{
$this->plugin = $plugin;
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace App\Listeners;
use Illuminate\Filesystem\Filesystem;
class CopyPluginAssets
{
/**
* @var Filesystem
*/
protected $filesystem;
public function __construct(Filesystem $filesystem)
{
$this->filesystem = $filesystem;
}
public function handle(\App\Events\PluginVersionChanged $event)
{
$plugin = $event->plugin;
$dir = public_path('plugins/'.$plugin->name);
$this->filesystem->deleteDirectory($dir);
$this->filesystem->copyDirectory(
$plugin->getPath().DIRECTORY_SEPARATOR.'assets',
$dir.'/assets'
);
$this->filesystem->copyDirectory(
$plugin->getPath().DIRECTORY_SEPARATOR.'lang',
$dir.'/lang'
);
}
}

View File

@ -21,6 +21,12 @@ class EventServiceProvider extends ServiceProvider
'App\Events\TextureDeleting' => [
'App\Listeners\TextureRemoved',
],
'App\Events\PluginWasEnabled' => [
'App\Listeners\CopyPluginAssets',
],
'App\Events\PluginVersionChanged' => [
'App\Listeners\CopyPluginAssets',
],
];
/**

View File

@ -97,6 +97,12 @@ class PluginManager
$plugin = new Plugin($directory, $manifest);
if ($this->enabled->contains('name', $name)) {
$plugin->setEnabled(true);
if (Comparator::notEqualTo(
$manifest['version'],
$this->enabled->firstWhere('name', $name)['version']
)) {
$this->dispatcher->dispatch(new Events\PluginVersionChanged($plugin));
}
}
$plugins->put($name, $plugin);
});

View File

@ -0,0 +1,28 @@
<?php
namespace Tests;
class CopyPluginAssetsTest extends TestCase
{
public function testHandle()
{
$plugin = new \App\Services\Plugin('/path', ['name' => 'fake']);
$this->mock(\Illuminate\Filesystem\Filesystem::class, function ($mock) {
$dir = public_path('plugins/fake');
$mock->shouldReceive('deleteDirectory')
->with($dir)
->once();
$mock->shouldReceive('copyDirectory')
->withArgs(['/path'.DIRECTORY_SEPARATOR.'assets', $dir.'/assets'])
->once();
$mock->shouldReceive('copyDirectory')
->withArgs(['/path'.DIRECTORY_SEPARATOR.'lang', $dir.'/lang'])
->once();
});
event(new \App\Events\PluginVersionChanged($plugin));
}
}

View File

@ -2,6 +2,7 @@
namespace Tests;
use Event;
use ReflectionClass;
use App\Services\PluginManager;
use Illuminate\Filesystem\Filesystem;
@ -82,6 +83,48 @@ class PluginManagerTest extends TestCase
$manager = $this->rebootPluginManager(app('plugins'));
}
public function testDetectVersionChanged()
{
option(['plugins_enabled' => json_encode([['name' => 'mayaka', 'version' => '0.0.0']])]);
Event::fake();
$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.1.0',
]));
$mock->shouldReceive('exists')
->with('/mayaka/vendor/autoload.php')
->once()
->andReturn(false);
$mock->shouldReceive('exists')
->with('/mayaka/bootstrap.php')
->once()
->andReturn(false);
});
$manager = $this->rebootPluginManager(app('plugins'));
Event::assertDispatched(\App\Events\PluginVersionChanged::class, function ($event) {
$this->assertEquals('0.1.0', $event->plugin->version);
return true;
});
option(['plugins_enabled' => '[]']);
}
public function testLoadComposer()
{
option(['plugins_enabled' => json_encode([['name' => 'mayaka', 'version' => '0.0.0']])]);
@ -151,7 +194,6 @@ class PluginManagerTest extends TestCase
->with('/mayaka/vendor/autoload.php')
->once()
->andReturn(false);
$mock->shouldReceive('exists')
->with('/mayaka/bootstrap.php')
->once()