Add Pico::API_VERSION

This commit is contained in:
Daniel Rudolf 2017-05-10 17:00:48 +02:00
parent 36b3aef1c7
commit 7b222b03e4
No known key found for this signature in database
GPG key ID: A061F02CD8DE4538
3 changed files with 84 additions and 11 deletions

View file

@ -37,6 +37,14 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
*/
protected $statusChanged = false;
/**
* Boolean indicating whether this plugin matches Pico's API version
*
* @see AbstractPicoPlugin::checkCompatibility()
* @var boolean|null
*/
protected $nativePlugin;
/**
* List of plugins which this plugin depends on
*
@ -81,6 +89,7 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
// make sure dependencies are already fulfilled,
// otherwise the plugin needs to be enabled manually
try {
$this->checkCompatibility();
$this->checkDependencies(false);
} catch (RuntimeException $e) {
$this->enabled = false;
@ -105,6 +114,7 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
$this->enabled = (bool) $enabled;
if ($enabled) {
$this->checkCompatibility();
$this->checkDependencies($recursive);
} else {
$this->checkDependants($recursive);
@ -283,4 +293,35 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
return $this->dependants;
}
/**
* Checks compatibility with Pico's API version
*
* Pico automatically adds a dependency to {@see PicoDeprecated} when the
* plugin's API is older than Pico's API. {@see PicoDeprecated} furthermore
* throws a exception when it can't provide compatibility in such cases.
* However, we still have to decide whether this plugin is compatible to
* newer API versions, what defaults to "no" by default.
*
* @return void
* @throws RuntimeException thrown when the plugin's and Pico's API
* aren't compatible
*/
protected function checkCompatibility()
{
if ($this->nativePlugin === null) {
$picoClassName = get_class($this->pico);
$picoApiVersion = defined($picoClassName . '::API_VERSION') ? $picoClassName::API_VERSION : 1;
$pluginApiVersion = defined('static::API_VERSION') ? static::API_VERSION : 1;
$this->nativePlugin = ($pluginApiVersion === $picoApiVersion);
if (!$this->nativePlugin && ($pluginApiVersion > $picoApiVersion)) {
throw new RuntimeException(
"Unable to enable plugin '" . get_called_class() . "': The plugin's API (version "
. $pluginApiVersion . ") isn't compatible with Pico's API (version " . $picoApiVersion . ")"
);
}
}
}
}

View file

@ -42,6 +42,13 @@ class Pico
*/
const VERSION_ID = 20000;
/**
* Pico API version
*
* @var int
*/
const API_VERSION = 2;
/**
* Sort files in alphabetical ascending order
*
@ -121,6 +128,13 @@ class Pico
*/
protected $plugins = array();
/**
* List of loaded plugins using the current API version
*
* @var object[]
*/
protected $nativePlugins = array();
/**
* Current configuration of this Pico instance
*
@ -523,6 +537,12 @@ class Pico
}
$this->plugins[$className] = $plugin;
if ($plugin instanceof PicoPluginInterface) {
if (defined($className . '::API_VERSION') && ($className::API_VERSION >= static::API_VERSION)) {
$this->nativePlugins[$className] = $plugin;
}
}
} else {
throw new RuntimeException(
"Unable to load plugin '" . $className . "' "
@ -567,6 +587,10 @@ class Pico
$this->plugins[$className] = $plugin;
if (defined($className . '::API_VERSION') && ($className::API_VERSION >= static::API_VERSION)) {
$this->nativePlugins[$className] = $plugin;
}
return $plugin;
}
@ -613,8 +637,9 @@ class Pico
$dependencies = array();
if ($plugin instanceof PicoPluginInterface) {
$dependencies = $plugin->getDependencies();
} else {
$dependencies = array('PicoDeprecated');
}
if (!isset($this->nativePlugins[$pluginName])) {
$dependencies[] = 'PicoDeprecated';
}
foreach ($dependencies as $dependency) {
@ -1996,10 +2021,14 @@ class Pico
}
/**
* Triggers events on plugins which implement PicoPluginInterface
* Triggers events on plugins using the current API version
*
* Plugins using older API versions are handled by {@see PicoDeprecated}.
* Please note that {@see PicoDeprecated} also triggers custom events on
* plugins using older API versions, thus you can safely use this method
* to trigger custom events on all loaded plugins, no matter what API
* version - the event will be triggered in any case
*
* Deprecated events (as used by plugins not implementing
* {@link PicoPluginInterface}) are triggered by {@link PicoDeprecated}.
* You MUST NOT trigger events of Pico's core with a plugin!
*
* @see PicoPluginInterface
@ -2011,12 +2040,8 @@ class Pico
*/
public function triggerEvent($eventName, array $params = array())
{
foreach ($this->plugins as $plugin) {
// only trigger events for plugins that implement PicoPluginInterface
// deprecated events (plugins for Pico 0.9 and older) will be triggered by `PicoDeprecated`
if ($plugin instanceof PicoPluginInterface) {
$plugin->handleEvent($eventName, $params);
}
foreach ($this->nativePlugins as $plugin) {
$plugin->handleEvent($eventName, $params);
}
}
}

View file

@ -13,6 +13,13 @@
*/
class DummyPlugin extends AbstractPicoPlugin
{
/**
* API version used by this plugin
*
* @var int
*/
const API_VERSION = 2;
/**
* This plugin is disabled by default
*