Change AbstractPicoPlugin::$enabled's behavior

AbstractPicoPlugin::$enabled now defaults to NULL what leaves the decision whether a plugin should be enabled or disabled by default up to Pico (precisely AbstractPicoPlugin::triggerEvent()). If all dependencies of a plugin are fulfilled, Pico enables the plugin by default. Otherwise the plugin is silently disabled (this was the behavior when AbstractPicoPlugin::$enabled was set to TRUE previously).

If a plugin should never be disabled *silently* (e.g. when dealing with security-relevant stuff like access control, or similar), set AbstractPicoPlugin::$enabled to TRUE. If Pico can't fulfill all the plugin's dependencies, it will throw an RuntimeException.

If a plugin rather does some "crazy stuff" a user should really be aware of before using it, you can set AbstractPicoPlugin::$enabled to FALSE. The user will then have to enable the plugin manually. However, if another plugin depends on this plugin, it might get enabled silently nevertheless.

No matter what, the user can always explicitly enable or disable a plugin in Pico's config.
This commit is contained in:
Daniel Rudolf 2017-12-27 21:32:52 +01:00
parent 1ce1780a86
commit afd0a4d7a3
No known key found for this signature in database
GPG Key ID: A061F02CD8DE4538
4 changed files with 47 additions and 15 deletions

View File

@ -38,9 +38,9 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
*
* @see PicoPluginInterface::isEnabled()
* @see PicoPluginInterface::setEnabled()
* @var bool
* @var bool|null
*/
protected $enabled = true;
protected $enabled;
/**
* Boolean indicating if this plugin was ever enabled/disabled manually
@ -99,11 +99,12 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
if ($pluginEnabled !== null) {
$this->setEnabled($pluginEnabled);
} elseif ($this->enabled) {
$this->setEnabled($this->enabled, true, true);
} elseif ($this->enabled === null) {
// make sure dependencies are already fulfilled,
// otherwise the plugin needs to be enabled manually
try {
$this->checkCompatibility();
$this->checkDependencies(false);
$this->setEnabled(true, false, true);
} catch (RuntimeException $e) {
$this->enabled = false;
}

View File

@ -486,14 +486,18 @@ class Pico
*
* See {@see Pico::loadComposerPlugins()} for details about plugins loaded
* from `vendor/pico-plugin.php` (i.e. plugins that were installed using
* `composer`), and {@see Pico::loadLocalPlugins()} for details about
* plugins installed to {@see Pico::$pluginsDir}. Pico loads plugins from
* the filesystem only if {@see Pico::$enableLocalPlugins} is set to TRUE
* composer), and {@see Pico::loadLocalPlugins()} for details about plugins
* installed to {@see Pico::$pluginsDir}. Pico loads plugins from the
* filesystem only if {@see Pico::$enableLocalPlugins} is set to TRUE
* (this is the default).
*
* Pico always loads plugins from `vendor/pico-plugin.php` first and
* ignores conflicting plugins in {@see Pico::$pluginsDir}.
*
* The official PicoDeprecated plugin must be loaded when plugins that use
* an older API version than Pico's API version ({@see Pico::API_VERSION})
* are loaded.
*
* Please note that Pico will change the processing order when needed to
* incorporate plugin dependencies. See {@see Pico::sortPlugins()} for
* details.
@ -513,14 +517,21 @@ class Pico
if ($this->enableLocalPlugins) {
$this->loadLocalPlugins($composerPlugins);
}
if (!isset($this->plugins['PicoDeprecated']) && (count($this->plugins) !== count($this->nativePlugins))) {
throw new RuntimeException(
"Plugins using an older API than version " . static::API_VERSION . " found, "
. "but PicoDeprecated isn't loaded"
);
}
}
/**
* Loads plugins from vendor/pico-plugin.php
*
* This method loads all plugins installed using `composer` and Pico's
* `picocms/pico-installer` installer by reading the `pico-plugin.php` in
* composer's `vendor` dir.
* This method loads all plugins installed using composer and Pico's
* `picocms/composer-installer` installer by reading the `pico-plugin.php`
* in composer's `vendor` dir.
*
* @see Pico::loadPlugins()
* @see Pico::loadLocalPlugins()

View File

@ -70,11 +70,15 @@ interface PicoPluginInterface
public function setEnabled($enabled, $recursive = true, $auto = false);
/**
* Returns TRUE if this plugin is enabled, FALSE otherwise
* Returns a boolean indicating whether this plugin is enabled or not
*
* You musn't rely on the return value when Pico's `onConfigLoaded` event
* wasn't triggered on all plugins yet. This method might even return NULL
* then. The plugin's status might change later.
*
* @see PicoPluginInterface::setEnabled()
*
* @return bool plugin is enabled (TRUE) or disabled (FALSE)
* @return bool|null plugin is enabled (TRUE) or disabled (FALSE)
*/
public function isEnabled();

View File

@ -33,11 +33,27 @@ class DummyPlugin extends AbstractPicoPlugin
/**
* This plugin is disabled by default
*
* If you want to enable your plugin by default, simply remove this class
* property.
* Usually you should remove this class property (or set it to NULL) to
* leave the decision whether this plugin should be enabled or disabled by
* default up to Pico. If all the plugin's dependenies are fulfilled (see
* {@see self::$dependsOn}), Pico enables the plugin by default. Otherwise
* the plugin is silently disabled.
*
* If this plugin should never be disabled *silently* (e.g. when dealing
* with security-relevant stuff like access control, or similar), set this
* to TRUE. If Pico can't fulfill all the plugin's dependencies, it will
* throw an RuntimeException.
*
* If this plugin rather does some "crazy stuff" a user should really be
* aware of before using it, you can set this to FALSE. The user will then
* have to enable the plugin manually. However, if another plugin depends
* on this plugin, it might get enabled silently nevertheless.
*
* No matter what, the user can always explicitly enable or disable this
* plugin in Pico's config.
*
* @see AbstractPicoPlugin::$enabled
* @var bool
* @var bool|null
*/
protected $enabled = false;