Plugins are now updated according to their dependency definitions
This commit is contained in:
parent
eb886af176
commit
5c46dbec32
|
|
@ -9,7 +9,7 @@ use BackendAuth;
|
|||
use Backend\Models\User;
|
||||
use Backend\Models\AccessLog;
|
||||
use Backend\Classes\Controller;
|
||||
use System\Classes\VersionManager;
|
||||
use System\Classes\UpdateManager;
|
||||
use System\Classes\ApplicationException;
|
||||
use October\Rain\Support\ValidationException;
|
||||
use Exception;
|
||||
|
|
@ -75,7 +75,7 @@ class Auth extends Controller
|
|||
], true);
|
||||
|
||||
// Load version updates
|
||||
VersionManager::instance()->updateAll();
|
||||
UpdateManager::instance()->update();
|
||||
|
||||
// Log the sign in event
|
||||
AccessLog::add($user);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use Config;
|
|||
use RecursiveIteratorIterator;
|
||||
use RecursiveDirectoryIterator;
|
||||
use Illuminate\Container\Container;
|
||||
use ApplicationException;
|
||||
|
||||
/**
|
||||
* Plugin manager
|
||||
|
|
@ -105,34 +106,6 @@ class PluginManager
|
|||
return $this->plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cross checks all plugins and their dependancies, if not met plugins
|
||||
* are disabled and vice versa.
|
||||
*/
|
||||
protected function loadDependencies()
|
||||
{
|
||||
foreach ($this->plugins as $id => $plugin) {
|
||||
|
||||
if (!isset($plugin->require) || !$plugin->require)
|
||||
continue;
|
||||
|
||||
$required = is_array($plugin->require) ? $plugin->require : [$plugin->require];
|
||||
$disable = false;
|
||||
foreach ($required as $require) {
|
||||
if (!$this->hasPlugin($require))
|
||||
$disable = true;
|
||||
|
||||
elseif (($pluginObj = $this->findByIdentifier($require)) && $pluginObj->disabled)
|
||||
$disable = true;
|
||||
}
|
||||
|
||||
if ($disable)
|
||||
$this->disablePlugin($id);
|
||||
else
|
||||
$this->enablePlugin($id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the register() method on all plugins. Can only be called once.
|
||||
*/
|
||||
|
|
@ -227,6 +200,18 @@ class PluginManager
|
|||
return $this->pathMap[$classId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a plugin exists and is enabled.
|
||||
* @param string $id Plugin identifier, eg: Namespace.PluginName
|
||||
* @return boolean
|
||||
*/
|
||||
public function exists($id)
|
||||
{
|
||||
return (!$this->findByIdentifier($id) || $this->isDisabled($id))
|
||||
? false
|
||||
: true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with all registered plugins
|
||||
* The index is the plugin namespace, the value is the plugin information object.
|
||||
|
|
@ -446,17 +431,108 @@ class PluginManager
|
|||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Dependencies
|
||||
//
|
||||
|
||||
/**
|
||||
* Check if a plugin exists and is enabled.
|
||||
* @param string $id Plugin identifier, eg: Namespace.PluginName
|
||||
* @return boolean
|
||||
* Cross checks all plugins and their dependancies, if not met plugins
|
||||
* are disabled and vice versa.
|
||||
*/
|
||||
public static function pluginExists($id)
|
||||
protected function loadDependencies()
|
||||
{
|
||||
$instance = static::instance();
|
||||
return (!$instance->findByIdentifier($id) || $instance->isDisabled($id))
|
||||
? false
|
||||
: true;
|
||||
foreach ($this->plugins as $id => $plugin) {
|
||||
if (!$required = $this->getDependencies($plugin))
|
||||
continue;
|
||||
|
||||
$disable = false;
|
||||
foreach ($required as $require) {
|
||||
if (!$this->hasPlugin($require))
|
||||
$disable = true;
|
||||
|
||||
elseif (($pluginObj = $this->findByIdentifier($require)) && $pluginObj->disabled)
|
||||
$disable = true;
|
||||
}
|
||||
|
||||
if ($disable)
|
||||
$this->disablePlugin($id);
|
||||
else
|
||||
$this->enablePlugin($id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plugin identifiers that are required by the supplied plugin.
|
||||
* @param string $plugin Plugin identifier, object or class
|
||||
* @return array
|
||||
*/
|
||||
public function getDependencies($plugin)
|
||||
{
|
||||
if (is_string($plugin) && (!$plugin = $this->findByIdentifier($identifer)))
|
||||
return false;
|
||||
|
||||
if (!isset($plugin->require) || !$plugin->require)
|
||||
return null;
|
||||
|
||||
return is_array($plugin->require) ? $plugin->require : [$plugin->require];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts a collection of plugins, in the order that they should be actioned,
|
||||
* according to their given dependencies. Least dependent come first.
|
||||
* @param array $plugins Object collection to sort, or null to sort all.
|
||||
* @return array Collection of sorted plugin identifiers
|
||||
*/
|
||||
public function sortByDependencies($plugins = null)
|
||||
{
|
||||
if (!is_array($plugins))
|
||||
$plugins = $this->getPlugins();
|
||||
|
||||
$result = [];
|
||||
$checklist = $plugins;
|
||||
|
||||
$loopCount = 0;
|
||||
while (count($checklist)) {
|
||||
|
||||
if (++$loopCount > 999)
|
||||
throw new ApplicationException('Too much recursion');
|
||||
|
||||
foreach ($checklist as $code => $plugin) {
|
||||
|
||||
/*
|
||||
* Get dependencies and remove any aliens
|
||||
*/
|
||||
$depends = $this->getDependencies($plugin) ?: [];
|
||||
$depends = array_filter($depends, function($pluginCode) use ($plugins) {
|
||||
return isset($plugins[$pluginCode]);
|
||||
});
|
||||
|
||||
/*
|
||||
* No dependencies
|
||||
*/
|
||||
if (!$depends) {
|
||||
array_push($result, $code);
|
||||
unset($checklist[$code]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find dependencies that have not been checked
|
||||
*/
|
||||
$depends = array_diff($depends, $result);
|
||||
if (count($depends) > 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* All dependencies are checked
|
||||
*/
|
||||
array_push($result, $code);
|
||||
unset($checklist[$code]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -104,9 +104,9 @@ class UpdateManager
|
|||
/*
|
||||
* Update plugins
|
||||
*/
|
||||
$plugins = $this->pluginManager->getPlugins();
|
||||
foreach ($plugins as $name => $plugin) {
|
||||
$this->updatePlugin($name);
|
||||
$plugins = $this->pluginManager->sortByDependencies();
|
||||
foreach ($plugins as $plugin) {
|
||||
$this->updatePlugin($plugin);
|
||||
}
|
||||
|
||||
Parameters::set('system::update.count', 0);
|
||||
|
|
|
|||
|
|
@ -67,21 +67,6 @@ class VersionManager
|
|||
$this->pluginManager = PluginManager::instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the update for all plugins
|
||||
*/
|
||||
public function updateAll()
|
||||
{
|
||||
$plugins = $this->pluginManager->getPlugins();
|
||||
|
||||
foreach ($plugins as $code => $plugin) {
|
||||
if (!$this->hasVersionFile($code))
|
||||
continue;
|
||||
|
||||
$this->updatePlugin($code);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a single plugin by its code or object with it's latest changes.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue