diff --git a/docs/apis/plugintypes/index.md b/docs/apis/plugintypes/index.md index 49d939ee4..02a8e3e49 100644 --- a/docs/apis/plugintypes/index.md +++ b/docs/apis/plugintypes/index.md @@ -132,6 +132,166 @@ foreach ($pluginman->get_plugin_types() as $type => $dir) { +## Plugin type deprecation + + + +When a plugin or subplugin type is no longer needed or is replaced by another plugin type, it should be deprecated. +Using `components.json` or `subplugins.json` plugin types and subplugin types, respectively, can be marked as deprecated. + +The process for plugin and subplugin type deprecation differs slightly to the normal [Deprecation](/general/development/policies/deprecation) process. +Unlike with code deprecation, where the deprecated class or method is usually expected to remain functional during the deprecation window, deprecated plugin/subplugin types are treated as end-of-life as soon as they are deprecated. + +Once deprecated, core will exclude plugins of the respective plugin type when performing common core-plugin communication, such as with hooks, callbacks, events, and-so-on. +In the case of subplugins, the subplugin owner (the component which the subplugin belongs to), **must** have been updated to remove or replace all references to the subplugins before the time of deprecation. + +Class autoloading and string resolution is still supported during the deprecation window, to assist with any plugin migration scripts that may be required. + +:::info limitations + +Whilst both plugin and subplugin types can be deprecated, only those plugin types which do _not_ support subplugins can be deprecated. + +::: + +### Deprecation process + +Deprecation follows a 3 stage process: + +1. The plugin/subplugin type is marked as deprecated (a core version bump is also required). +2. The plugin/subplugin type is marked as deleted (a core version bump is also required). +3. Final removal of the plugin/subplugin type from the respective config file. + +#### First stage deprecation + +During first stage deprecation, plugins of the respective type may remain installed, but are deemed end-of-life. + +This stage gives administrators time to remove the affected plugins from the site, or migrate them to their replacement plugins. + +#### Second stage deprecation + +The second stage deprecation is the deletion phase. + +If any affected plugins are still present (that is any which have not been uninstalled or migrated yet), the site upgrade will be blocked. + +These plugins **must** be removed before continuing with site upgrade. + +#### Final deprecation + +In the final deprecation stage the relevant configuration changes supporting first and second stage deprecation can be removed from the respective config files. This removes the last reference to these plugin/subplugin types. + +### Deprecating a plugin type + +The first phase of plugin type deprecation involves describing the plugin in the `deprecatedplugintypes` configuration in `lib/components.json`. The plugin type must also be removed from the `plugintypes` object. + +The second phase of plugin type deprecation involves moving the entry from the `deprecatedplugintypes` object to the `deletedplugintypes` object. + +:::info Remember + +Don't forget to increment the core version number when marking a plugin/subplugin type for either deprecation or deletion. A version bump isn't needed for final removal. + +::: + +:::tip Example of plugin type deprecation config values + +To mark a plugin type as deprecated in `components.json`, the plugin type should be removed from the `plugintypes` object, and added to a new `deprecatedplugintypes` object. + +```json title="lib/components.json demonstrating first stage deprecation of a plugin type" +{ + "plugintypes": { + ... + }, + "subsystems": { + ... + }, + "deprecatedplugintypes": { + "aiplacement": "ai/placement" + } +} +``` + +To mark a plugin type as deleted in `components.json`, the plugin type should be removed from the `deprecatedplugintypes` object, and added to a new `deletedplugintypes` object. If the `deprecatedplugintypes` object is now empty, it may be removed entirely from config. + +```json title="lib/components.json demonstrating second stage deprecation (deletion) of a plugin type" +{ + "plugintypes": { + ... + }, + "subsystems": { + ... + }, + "deletedplugintypes": { + "aiplacement": "ai/placement" + } +} +``` + +Third stage deprecation just removes the plugin type from the `deletedplugintypes` object. If the `deletedplugintypes` object is now empty, it may be removed entirely from config. + +```json title="lib/components.json demonstrating final stage deprecation of a plugin type. The process is the same for subplugin types." +{ + "plugintypes": { + ... + }, + "subsystems": { + ... + }, +} +``` + +::: + +### Deprecating a subplugin type + +To mark a subplugin type as deprecated, edit the component's `subplugins.json` file, remove the subplugin type from the `subplugintypes` object and add it to the `deprecatedsubplugintypes` object. The mark a subplugin type for stage 2 deprecation (deletion), edit the same file and move the subplugin type from the `deprecatedsubplugintypes` object to the `deletedsubplugintypes` object. + +Following deletion, the plugin/subplugin type can be removed from the respective JSON entirely. + +:::info Remember + +Don't forget to increment the core version number when marking a plugin/subplugin type for either deprecation or deletion. A version bump isn't needed for final removal. + +::: + +:::tip Example of subplugin type deprecation config values + +To mark a subplugin type as deprecated in a component's `subplugins.json`, the subplugin type should be removed from the `subplugintypes` object, and added to a new `deprecatedsubplugintypes` object. + +```json title="mod/lti/db/subplugins.json demonstrating first stage deprecation of a subplugin type" +{ + "subplugintypes": { + "ltiservice": "service" + }, + "deprecatedsubplugintypes": { + "ltisource": "source" + } +} +``` + +To mark a subplugin type as deleted in a component's `subplugins.json`, the subplugin type should be removed from the `deprecatedsubplugintypes` object, and added to a new `deletedsubplugintypes` object. If the `deprecatedsubplugintypes` object is now empty, it may be removed entirely from config. + +```json title="mod/lti/db/subplugins.json demonstrating second stage deprecation (deletion) of a subplugin type" +{ + "subplugintypes": { + "ltiservice": "service" + }, + "deletedsubplugintypes": { + "ltisource": "source" + } +} +``` + +Third stage deprecation just removes the subplugin type from the `deletedsubplugintypes` object. If this object is then empty, it may be removed entirely from config. + +```json title="mod/lti/db/subplugins.json demonstrating final stage deprecation of a subplugin type." +{ + "subplugintypes": { + "ltiservice": "service" + } +} +``` + +::: + ## See also - [Guidelines for contributing code](https://docs.moodle.org/dev/Guidelines_for_contributed_code) diff --git a/docs/devupdate.md b/docs/devupdate.md index ad4d87ab6..d27eefac8 100644 --- a/docs/devupdate.md +++ b/docs/devupdate.md @@ -113,3 +113,11 @@ $activity-icon-interactivecontent-bg: #c70827; Moodle has updated the version of PHPUnit used in core to version 11.4. Some tests may encounter issues as a result. Please see the [PHPUnit 11 Upgrade Guide](/general/development/tools/phpunit/upgrading-11) for assistance in updating any broken tests. + +::: + +## Plugin type deprecation + + + +A new process for plugin type and subplugin type deprecation has been introduced. See [the Plugin Type deprecation](./apis/plugintypes/index.md#deprecating-a-plugin-type) and [Subplugin deprecation](./apis/plugintypes/index.md#deprecating-a-subplugin-type) documentation for further information. diff --git a/general/development/policies/deprecation/index.md b/general/development/policies/deprecation/index.md index 447077bae..ce23fb0a6 100644 --- a/general/development/policies/deprecation/index.md +++ b/general/development/policies/deprecation/index.md @@ -290,6 +290,7 @@ Named parameter arguments are available from PHP 8.0 onwards. - [Deprecation attributes](/docs/apis/core/deprecation/) - [External functions deprecation](/docs/apis/subsystems/external/writing-a-service#deprecation) - [Capabilities deprecation](/docs/apis/subsystems/access#deprecating-a-capability) +- [Plugin type deprecation](/docs/apis/plugintypes#plugin-type-deprecation) - [Icon deprecation](./icon-deprecation.md) - [SCSS deprecation](./scss-deprecation.md) - [Behat step definition deprecation](../../tools/behat/writing.md#deprecating-a-step-definition) diff --git a/general/development/tools/metadata/index.md b/general/development/tools/metadata/index.md index a4704c428..f724b3466 100644 --- a/general/development/tools/metadata/index.md +++ b/general/development/tools/metadata/index.md @@ -39,6 +39,8 @@ The name and location on disk of every plugin type, and subsystem is described i +Plugin types may also be marked as deprecated in this metadata. For more information, see [Plugin type deprecation](/docs/apis/plugintypes#plugin-type-deprecation). + ## Subplugins Any plugin which supports subplugins must describe its subplugin types by name and path in that plugins `db/subplugins.json` location. @@ -48,6 +50,8 @@ This file requires that subplugins be specified as a set of key and value pairs - The name is the used as a prefix for all namespaces. - The path is the path that the plugins exist within. +Subplugin types may also be marked as deprecated in this metadata. For more information, see [Plugin type deprecation](/docs/apis/plugintypes#plugin-type-deprecation). + In the following example the subplugins used in `mod_quiz` are described. The Quiz activity module is located in `mod/quiz`. It has two subplugin types, `quiz`, and `quizaccess` which are located in `mod/quiz/report`, and `mod/quiz/accessrule` respectively.