Skip to content

Commit

Permalink
Add plugin system
Browse files Browse the repository at this point in the history
  • Loading branch information
MrMicky-FR committed Oct 24, 2019
1 parent 5fa134c commit 74a78b5
Show file tree
Hide file tree
Showing 23 changed files with 1,101 additions and 71 deletions.
46 changes: 46 additions & 0 deletions app/Console/Commands/PluginCacheCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace Azuriom\Console\Commands;

use Azuriom\Extensions\ExtensionsManager;
use Illuminate\Console\Command;

class PluginCacheCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'plugin:cache';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Cache the plugins service providers';

/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}

/**
* Execute the console command.
*
* @param \Azuriom\Extensions\ExtensionsManager $extensions
* @return mixed
*/
public function handle(ExtensionsManager $extensions)
{
$extensions->cachePlugins();

$this->info('Cached plugins files generated successfully.');
}
}
50 changes: 50 additions & 0 deletions app/Console/Commands/PluginClearCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace Azuriom\Console\Commands;

use Azuriom\Extensions\ExtensionsManager;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;

class PluginClearCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'plugin:clear';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Cache the plugins service providers';

/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}

/**
* Execute the console command.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param \Azuriom\Extensions\ExtensionsManager $extensions
* @return mixed
*/
public function handle(Filesystem $files, ExtensionsManager $extensions)
{
if ($files->exists($extensions->getCachedPluginsPath())) {
$files->delete($extensions->getCachedPluginsPath());
}

$this->info('Cached plugins files removed');
}
}
4 changes: 2 additions & 2 deletions app/Console/Commands/ThemeCreateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ class ThemeCreateCommand extends Command
*
* @var string
*/
protected $description = 'Create a new theme folder';
protected $description = 'Create a new Azuriom theme';

/**
* Create a new command instance.
*
* @param Filesystem $files
* @param \Illuminate\Filesystem\Filesystem $files
* @return void
*/
public function __construct(Filesystem $files)
Expand Down
240 changes: 240 additions & 0 deletions app/Extensions/ExtensionsManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
<?php

namespace Azuriom\Extensions;

use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Composer;

class ExtensionsManager
{
/**
* The application instance.
*
* @var \Illuminate\Contracts\Foundation\Application
*/
private $app;

/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
private $files;

/**
* The composer instance.
*
* @var \Illuminate\Support\Composer $composer
*/
private $composer;

/**
* The loaded and enabled plugins
*
* @var \Illuminate\Support\Collection
*/
private $loadedPlugins;

/**
* Create a new ExtensionsManager instance.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @param \Illuminate\Filesystem\Filesystem $files
* @param \Illuminate\Support\Composer $composer
*/
public function __construct(Application $app, Filesystem $files, Composer $composer)
{
$this->app = $app;
$this->files = $files;
$this->composer = $composer;
}

/**
* Get the current active theme.
*
* @return string|null
*/
public function getCurrentTheme()
{
return setting('theme');
}

/**
* Get the loaded plugins.
*
* @return \Illuminate\Support\Collection
*/
public function getLoadedPlugins()
{
return $this->loadedPlugins;
}

public function isPluginLoaded($plugin)
{
return $this->loadedPlugins->contains($plugin);
}

/**
* Get the plugins descriptions
*
* @return \Illuminate\Support\Collection
*/
public function getPluginsDescriptions()
{
return $this->findPlugins()->mapWithKeys(function ($path) {
$info = $this->getPluginDescription($path);

return $info ? [$path => $info] : [];
});
}

/**
* Get the themes descriptions
*
* @return \Illuminate\Support\Collection
*/
public function getThemesDescriptions()
{
return $this->findThemes()->mapWithKeys(function ($path) {
$info = $this->getThemeDescription($path);

return $info ? [$path => $info] : [];
});
}

/**
* Discover the plugins names from the plugins directory
*
* @return \Illuminate\Support\Collection
*/
public function findPlugins()
{
return collect($this->files->directories(plugin_path()))->map(function ($path) {
return $this->files->name($path);
});
}

/**
* Discover the themes names from the themes folder
*
* @return \Illuminate\Support\Collection
*/
public function findThemes()
{
return collect($this->files->directories(theme_path()))->map(function ($path) {
return $this->files->name($path);
});
}

/**
* Get the content of the plugin.json of the plugin
*
* @param string $plugin
* @return mixed|null
*/
public function getPluginDescription(string $plugin)
{
$json = $this->getJson(plugin_path($plugin.'/plugin.json'));

if ($json !== null && ! isset($json->enabled)) {
$json->enabled = true;
}

return $json;
}

/**
* Get the content of the theme.json of the theme
*
* @param string $theme
* @return mixed|null
*/
public function getThemeDescription(string $theme)
{
return $this->getJson(theme_path($theme.'/theme.json'));
}

/**
* Read the content of a json
*
* @param string $path
* @return mixed|null
*/
protected function getJson(string $path)
{
if (! $this->files->isFile($path)) {
return null;
}

try {
return json_decode($this->files->get($path));
} catch (FileNotFoundException $e) {
return null;
}
}

public function loadPlugins()
{
if ($this->files->isFile($this->getCachedPluginsPath())) {
$plugins = collect($this->files->getRequire($this->getCachedPluginsPath()));
} else {
$plugins = $this->cachePlugins();
}

$this->loadedPlugins = $plugins->values();

return $plugins;
}

public function cachePlugins()
{
$plugins = $this->findPlugins()->mapWithKeys(function ($path) {
$info = $this->getPluginDescription($path);

return $info && $info->enabled ? [$path => $info] : [];
});

$this->files->put($this->getCachedPluginsPath(), '<?php return '.var_export($plugins->toArray(), true).';');

return $plugins;
}

public function setPluginEnabled(string $plugin, bool $enabled)
{
$description = $this->getPluginDescription($plugin);

if ($description === null) {
return false;
}

$description->enabled = $enabled;

$json = json_encode($description, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

$this->files->put(plugin_path($plugin.'/plugin.json'), $json);
$this->cachePlugins();

return true;
}

/**
* Get the path to the cached plugins.php file.
*
* @return string
*/
public function getCachedPluginsPath()
{
return $this->app->bootstrapPath('/cache/plugins.php');
}

public function dumpAutoload()
{
if ($this->app->isProduction()) {
$this->composer->dumpOptimized();
} else {
$this->composer->dumpAutoloads();
}
}
}
Loading

0 comments on commit 74a78b5

Please sign in to comment.