Added "extensions" attribute in plugin.yml with version checking (#903)

* Added "extensions" attribute in plugin.yml with version checking

* Renamed getExtensions() to getRequiredExtensions()

As per recommendation from @dktapps
This commit is contained in:
SOFe 2017-05-15 17:04:26 +08:00 committed by Dylan K. Taylor
parent 576702ffa9
commit c7c7a40899
2 changed files with 64 additions and 1 deletions

View File

@ -27,6 +27,7 @@ class PluginDescription{
private $name;
private $main;
private $api;
private $extensions = [];
private $depend = [];
private $softDepend = [];
private $loadBefore = [];
@ -75,6 +76,17 @@ class PluginDescription{
if(isset($plugin["depend"])){
$this->depend = (array) $plugin["depend"];
}
if(isset($plugin["extensions"])){
$extensions = (array) $plugin["extensions"];
$isLinear = $extensions === array_values($extensions);
foreach($extensions as $k => $v){
if($isLinear){
$k = $v;
$v = "*";
}
$this->extensions[$k] = is_array($v) ? $v : [$v];
}
}
if(isset($plugin["softdepend"])){
$this->softDepend = (array) $plugin["softdepend"];
}
@ -149,6 +161,50 @@ class PluginDescription{
return $this->commands;
}
/**
* @return array
*/
public function getRequiredExtensions(){
return $this->extensions;
}
/**
* Checks if the current PHP runtime has the extensions required by the plugin.
*
* @throws PluginException if there are required extensions missing or have incompatible version, or if the version constraint cannot be parsed
*/
public function checkRequiredExtensions(){
foreach($this->extensions as $name => $versionConstrs){
if(!extension_loaded($name)){
throw new PluginException("Required extension $name not loaded");
}
if(!is_array($versionConstrs)){
$versionConstrs = [$versionConstrs];
}
$gotVersion = phpversion($name);
foreach($versionConstrs as $constr){ // versionConstrs_loop
if($constr === "*"){
continue;
}
if($constr === ""){
throw new PluginException("One of the extension version constraints of $name is empty. Consider quoting the version string in plugin.yml");
}
foreach(["<=", "le", "<>", "!=", "ne", "<", "lt", "==", "=", "eq", ">=", "ge", ">", "gt"] as $comparator){
// warning: the > character should be quoted in YAML
if(substr($constr, 0, strlen($comparator)) === $comparator){
$version = substr($constr, strlen($comparator));
if(!version_compare($gotVersion, $version, $comparator)){
throw new PluginException("Required extension $name has an incompatible version ($gotVersion not $constr)");
}
continue 2; // versionConstrs_loop
}
}
throw new PluginException("Error parsing version constraint: $constr");
}
}
}
/**
* @return array
*/
@ -218,4 +274,4 @@ class PluginDescription{
public function getWebsite(){
return $this->website;
}
}
}

View File

@ -147,6 +147,13 @@ class PluginManager{
if(preg_match($loader->getPluginFilters(), basename($path)) > 0){
$description = $loader->getPluginDescription($path);
if($description instanceof PluginDescription){
try{
$description->checkRequiredExtensions();
}catch(PluginException $ex){
$this->server->getLogger()->error($ex->getMessage());
return null;
}
if(($plugin = $loader->loadPlugin($path)) instanceof Plugin){
$this->plugins[$plugin->getDescription()->getName()] = $plugin;