Skip to content

Commit 5f62d5a

Browse files
committedMar 28, 2024
MDL-81084 core: Move standard plugins to plugins.json
1 parent 2c57fc4 commit 5f62d5a

File tree

5 files changed

+881
-355
lines changed

5 files changed

+881
-355
lines changed
 

‎lib/classes/plugin_manager.php

+71-355
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ class core_plugin_manager {
6969

7070
/** @var core_plugin_manager holds the singleton instance */
7171
protected static $singletoninstance;
72+
/** @var \stdClass cache of standard plugins */
73+
protected static ?\stdClass $standardplugincache = null;
7274
/** @var array of raw plugins information */
7375
protected $pluginsinfo = null;
7476
/** @var array of raw subplugins information */
@@ -119,6 +121,7 @@ public static function instance() {
119121
* @param bool $phpunitreset
120122
*/
121123
public static function reset_caches($phpunitreset = false) {
124+
static::$standardplugincache = null;
122125
if ($phpunitreset) {
123126
static::$singletoninstance = null;
124127
} else {
@@ -327,6 +330,20 @@ protected function load_present_plugins() {
327330
}
328331
}
329332

333+
/**
334+
* Load the standard plugin data from the plugins.json file.
335+
*
336+
* @return \stdClass
337+
*/
338+
protected static function load_standard_plugins(): \stdClass {
339+
if (static::$standardplugincache === null) {
340+
$data = file_get_contents(dirname(__DIR__) . '/plugins.json');
341+
static::$standardplugincache = json_decode($data, false);
342+
}
343+
344+
return static::$standardplugincache;
345+
}
346+
330347
/**
331348
* Get list of present plugins of given type.
332349
*
@@ -1702,379 +1719,78 @@ public function get_plugintype_root($plugintype) {
17021719
* @param string $name plugin name
17031720
* @return bool
17041721
*/
1705-
public static function is_deleted_standard_plugin($type, $name) {
1722+
public static function is_deleted_standard_plugin(
1723+
string $type,
1724+
string $name,
1725+
): bool {
17061726
// Do not include plugins that were removed during upgrades to versions that are
17071727
// not supported as source versions for upgrade any more. For example, at MOODLE_23_STABLE
17081728
// branch, listed should be no plugins that were removed at 1.9.x - 2.1.x versions as
17091729
// Moodle 2.3 supports upgrades from 2.2.x only.
1710-
$plugins = [
1711-
'assignment' => ['offline', 'online', 'upload', 'uploadsingle'],
1712-
'auth' => ['radius', 'fc', 'nntp', 'pam', 'pop3', 'imap'],
1713-
'block' => ['course_overview', 'messages', 'community', 'participants', 'quiz_results'],
1714-
'cachestore' => ['memcache', 'memcached', 'mongodb'],
1715-
'editor' => ['tinymce'],
1716-
'enrol' => ['authorize'],
1717-
'filter' => ['censor'],
1718-
'h5plib' => ['v124'],
1719-
'media' => ['swf'],
1720-
'portfolio' => ['picasa', 'boxnet'],
1721-
'qformat' => ['blackboard', 'learnwise', 'examview', 'webct'],
1722-
'message' => ['jabber'],
1723-
'mod' => ['assignment'],
1724-
'quizaccess' => ['safebrowser'],
1725-
'report' => ['search'],
1726-
'repository' => ['alfresco', 'picasa', 'skydrive', 'boxnet'],
1727-
'tinymce' => ['dragmath', 'ctrlhelp', 'managefiles', 'moodleemoticon', 'moodleimage',
1728-
'moodlemedia', 'moodlenolink', 'pdw', 'spellchecker', 'wrap',
1729-
],
1730-
1731-
'tool' => ['bloglevelupgrade', 'qeupgradehelper', 'timezoneimport', 'assignmentupgrade', 'health'],
1732-
'theme' => ['bootstrapbase', 'clean', 'more', 'afterburner', 'anomaly', 'arialist', 'base',
1733-
'binarius', 'boxxie', 'brick', 'canvas', 'formal_white', 'formfactor', 'fusion', 'leatherbound',
1734-
'magazine', 'mymobile', 'nimble', 'nonzero', 'overlay', 'serenity', 'sky_high', 'splash',
1735-
'standard', 'standardold',
1736-
],
1737-
'logstore' => ['legacy'],
1738-
'webservice' => ['amf', 'xmlrpc'],
1739-
];
1730+
$plugins = static::load_standard_plugins()->deleted;
17401731

1741-
if (!isset($plugins[$type])) {
1742-
return false;
1732+
if (property_exists($plugins, $type)) {
1733+
return in_array($name, $plugins->$type);
17431734
}
1744-
return in_array($name, $plugins[$type]);
1735+
1736+
return false;
17451737
}
17461738

17471739
/**
1748-
* Defines a white list of all plugins shipped in the standard Moodle distribution
1740+
* Fetches a list of all plugins shipped in the standard Moodle distribution.
17491741
*
1750-
* @param string $type
1742+
* If a type is specified but does not exist, a false value is returned.
1743+
* Otherwise an array of the plugins of the specified type is returned.
1744+
*
1745+
* @param null|string $type
17511746
* @return false|array array of standard plugins or false if the type is unknown
17521747
*/
1753-
public static function standard_plugins_list($type) {
1754-
1755-
$standardplugins = [
1756-
1757-
'antivirus' => [
1758-
'clamav',
1759-
],
1760-
1761-
'atto' => [
1762-
'accessibilitychecker', 'accessibilityhelper', 'align',
1763-
'backcolor', 'bold', 'charmap', 'clear', 'collapse', 'emoticon',
1764-
'equation', 'fontcolor', 'html', 'image', 'indent', 'italic',
1765-
'link', 'managefiles', 'media', 'noautolink', 'orderedlist',
1766-
'recordrtc', 'rtl', 'strike', 'subscript', 'superscript', 'table',
1767-
'title', 'underline', 'undo', 'unorderedlist', 'h5p', 'emojipicker',
1768-
],
1769-
1770-
'assignsubmission' => [
1771-
'comments', 'file', 'onlinetext',
1772-
],
1773-
1774-
'assignfeedback' => [
1775-
'comments', 'file', 'offline', 'editpdf',
1776-
],
1777-
1778-
'auth' => [
1779-
'cas', 'db', 'email', 'ldap', 'lti', 'manual', 'mnet',
1780-
'nologin', 'none', 'oauth2', 'shibboleth', 'webservice',
1781-
],
1782-
1783-
'availability' => [
1784-
'completion', 'date', 'grade', 'group', 'grouping', 'profile',
1785-
],
1786-
1787-
'block' => [
1788-
'accessreview', 'activity_modules', 'activity_results', 'admin_bookmarks', 'badges',
1789-
'blog_menu', 'blog_recent', 'blog_tags', 'calendar_month',
1790-
'calendar_upcoming', 'comments',
1791-
'completionstatus', 'course_list', 'course_summary',
1792-
'feedback', 'globalsearch', 'glossary_random', 'html',
1793-
'login', 'lp', 'mentees', 'mnet_hosts', 'myoverview', 'myprofile',
1794-
'navigation', 'news_items', 'online_users',
1795-
'private_files', 'recent_activity', 'recentlyaccesseditems',
1796-
'recentlyaccessedcourses', 'rss_client', 'search_forums', 'section_links',
1797-
'selfcompletion', 'settings', 'site_main_menu',
1798-
'social_activities', 'starredcourses', 'tag_flickr', 'tag_youtube', 'tags', 'timeline',
1799-
],
1800-
1801-
'booktool' => [
1802-
'exportimscp', 'importhtml', 'print',
1803-
],
1804-
1805-
'cachelock' => [
1806-
'file',
1807-
],
1808-
1809-
'cachestore' => [
1810-
'file', 'session', 'static', 'apcu', 'redis',
1811-
],
1812-
1813-
'calendartype' => [
1814-
'gregorian',
1815-
],
1816-
1817-
'communication' => [
1818-
'customlink',
1819-
'matrix',
1820-
],
1821-
1822-
'contenttype' => [
1823-
'h5p',
1824-
],
1825-
1826-
'customfield' => [
1827-
'checkbox', 'date', 'select', 'text', 'textarea',
1828-
],
1829-
1830-
'coursereport' => [
1831-
// Deprecated!
1832-
],
1833-
1834-
'datafield' => [
1835-
'checkbox', 'date', 'file', 'latlong', 'menu', 'multimenu',
1836-
'number', 'picture', 'radiobutton', 'text', 'textarea', 'url',
1837-
],
1838-
1839-
'dataformat' => [
1840-
'html', 'csv', 'json', 'excel', 'ods', 'pdf',
1841-
],
1842-
1843-
'datapreset' => [
1844-
'imagegallery',
1845-
'journal',
1846-
'proposals',
1847-
'resources',
1848-
],
1849-
1850-
'fileconverter' => [
1851-
'unoconv', 'googledrive',
1852-
],
1853-
1854-
'editor' => [
1855-
'atto', 'textarea', 'tiny',
1856-
],
1857-
1858-
'enrol' => [
1859-
'category', 'cohort', 'database', 'flatfile',
1860-
'guest', 'imsenterprise', 'ldap', 'lti', 'manual', 'meta', 'mnet',
1861-
'paypal', 'self', 'fee',
1862-
],
1863-
1864-
'factor' => [
1865-
'admin', 'auth', 'capability', 'cohort', 'email', 'grace', 'iprange', 'nosetup', 'role',
1866-
'token', 'totp', 'webauthn', 'sms',
1867-
],
1868-
1869-
'filter' => [
1870-
'activitynames', 'algebra', 'emailprotect',
1871-
'emoticon', 'displayh5p', 'mathjaxloader', 'mediaplugin', 'multilang', 'tex', 'tidy',
1872-
'urltolink', 'data', 'glossary', 'codehighlighter',
1873-
],
1874-
1875-
'format' => [
1876-
'singleactivity', 'social', 'topics', 'weeks',
1877-
],
1878-
1879-
'forumreport' => [
1880-
'summary',
1881-
],
1882-
1883-
'gradeexport' => [
1884-
'ods', 'txt', 'xls', 'xml',
1885-
],
1886-
1887-
'gradeimport' => [
1888-
'csv', 'direct', 'xml',
1889-
],
1890-
1891-
'gradereport' => [
1892-
'grader', 'history', 'outcomes', 'overview', 'user', 'singleview', 'summary',
1893-
],
1894-
1895-
'gradingform' => [
1896-
'rubric', 'guide',
1897-
],
1898-
1899-
'h5plib' => [
1900-
'v126',
1901-
],
1902-
1903-
'local' => [
1904-
],
1905-
1906-
'logstore' => [
1907-
'database', 'standard',
1908-
],
1909-
1910-
'ltiservice' => [
1911-
'gradebookservices', 'memberships', 'profile', 'toolproxy', 'toolsettings', 'basicoutcomes',
1912-
],
1913-
1914-
'mlbackend' => [
1915-
'php', 'python',
1916-
],
1917-
1918-
'media' => [
1919-
'html5audio', 'html5video', 'videojs', 'vimeo', 'youtube',
1920-
],
1921-
1922-
'message' => [
1923-
'airnotifier', 'email', 'popup',
1924-
],
1925-
1926-
'mnetservice' => [
1927-
'enrol',
1928-
],
1929-
1930-
'mod' => [
1931-
'assign', 'bigbluebuttonbn', 'book', 'chat', 'choice', 'data', 'feedback', 'folder',
1932-
'forum', 'glossary', 'h5pactivity', 'imscp', 'label', 'lesson', 'lti', 'page',
1933-
'quiz', 'resource', 'scorm', 'survey', 'url', 'wiki', 'workshop',
1934-
],
1935-
1936-
'paygw' => [
1937-
'paypal',
1938-
],
1939-
1940-
'plagiarism' => [
1941-
],
1942-
1943-
'portfolio' => [
1944-
'download', 'flickr', 'googledocs', 'mahara',
1945-
],
1946-
1947-
'profilefield' => [
1948-
'checkbox', 'datetime', 'menu', 'social', 'text', 'textarea',
1949-
],
1950-
1951-
'qbank' => [
1952-
'bulkmove',
1953-
'columnsortorder',
1954-
'comment',
1955-
'customfields',
1956-
'deletequestion',
1957-
'editquestion',
1958-
'exporttoxml',
1959-
'exportquestions',
1960-
'history',
1961-
'importquestions',
1962-
'managecategories',
1963-
'previewquestion',
1964-
'statistics',
1965-
'tagquestion',
1966-
'usage',
1967-
'viewcreator',
1968-
'viewquestionname',
1969-
'viewquestiontext',
1970-
'viewquestiontype',
1971-
],
1972-
1973-
'qbehaviour' => [
1974-
'adaptive', 'adaptivenopenalty', 'deferredcbm',
1975-
'deferredfeedback', 'immediatecbm', 'immediatefeedback',
1976-
'informationitem', 'interactive', 'interactivecountback',
1977-
'manualgraded', 'missing',
1978-
],
1979-
1980-
'qformat' => [
1981-
'aiken', 'blackboard_six', 'gift',
1982-
'missingword', 'multianswer',
1983-
'xhtml', 'xml',
1984-
],
1985-
1986-
'qtype' => [
1987-
'calculated', 'calculatedmulti', 'calculatedsimple',
1988-
'ddimageortext', 'ddmarker', 'ddwtos', 'description',
1989-
'essay', 'gapselect', 'match', 'missingtype', 'multianswer',
1990-
'multichoice', 'numerical', 'random', 'randomsamatch',
1991-
'shortanswer', 'truefalse',
1992-
],
1993-
1994-
'quiz' => [
1995-
'grading', 'overview', 'responses', 'statistics',
1996-
],
1997-
1998-
'quizaccess' => [
1999-
'delaybetweenattempts', 'ipaddress', 'numattempts', 'offlineattempts', 'openclosedate',
2000-
'password', 'seb', 'securewindow', 'timelimit',
2001-
],
2002-
2003-
'report' => [
2004-
'backups', 'competency', 'completion', 'configlog', 'courseoverview', 'eventlist',
2005-
'infectedfiles', 'insights', 'log', 'loglive', 'outline', 'participation', 'progress',
2006-
'questioninstances', 'security', 'stats', 'status', 'performance', 'usersessions',
2007-
'themeusage',
2008-
],
2009-
2010-
'repository' => [
2011-
'areafiles', 'contentbank', 'coursefiles', 'dropbox', 'equella', 'filesystem',
2012-
'flickr', 'flickr_public', 'googledocs', 'local', 'merlot', 'nextcloud',
2013-
'onedrive', 'recent', 's3', 'upload', 'url', 'user', 'webdav',
2014-
'wikimedia', 'youtube',
2015-
],
2016-
2017-
'search' => [
2018-
'simpledb', 'solr',
2019-
],
2020-
2021-
'scormreport' => [
2022-
'basic',
2023-
'interactions',
2024-
'graphs',
2025-
'objectives',
2026-
],
2027-
2028-
'tiny' => [
2029-
'accessibilitychecker',
2030-
'autosave',
2031-
'equation',
2032-
'h5p',
2033-
'media',
2034-
'recordrtc',
2035-
'link',
2036-
'html',
2037-
'noautolink',
2038-
'premium',
2039-
],
2040-
2041-
'theme' => [
2042-
'boost', 'classic',
2043-
],
2044-
2045-
'tool' => [
2046-
'admin_presets', 'analytics', 'availabilityconditions', 'behat', 'brickfield', 'capability', 'cohortroles',
2047-
'componentlibrary', 'customlang', 'dataprivacy', 'dbtransfer', 'filetypes', 'generator', 'httpsreplace', 'innodb',
2048-
'installaddon', 'langimport', 'licensemanager', 'log', 'lp', 'lpimportcsv', 'lpmigrate', 'messageinbound',
2049-
'mobile', 'moodlenet', 'multilangupgrade', 'monitor', 'oauth2', 'phpunit', 'policy', 'profiling', 'recyclebin',
2050-
'replace', 'spamcleaner', 'task', 'templatelibrary', 'uploadcourse', 'uploaduser', 'unsuproles',
2051-
'usertours', 'xmldb', 'mfa',
2052-
],
2053-
2054-
'webservice' => [
2055-
'rest', 'soap',
2056-
],
2057-
2058-
'workshopallocation' => [
2059-
'manual', 'random', 'scheduled',
2060-
],
2061-
2062-
'workshopeval' => [
2063-
'best',
2064-
],
2065-
2066-
'workshopform' => [
2067-
'accumulative', 'comments', 'numerrors', 'rubric',
2068-
],
2069-
];
1748+
public static function standard_plugins_list(string $type): array|false {
1749+
$plugins = static::load_standard_plugins()->standard;
20701750

2071-
if (isset($standardplugins[$type])) {
2072-
return $standardplugins[$type];
1751+
if (property_exists($plugins, $type)) {
1752+
return (array) $plugins->$type;
20731753
} else {
20741754
return false;
20751755
}
20761756
}
20771757

1758+
/**
1759+
* Get all standard plugins by their component name.
1760+
*
1761+
* @return array
1762+
*/
1763+
public static function get_standard_plugins(): array {
1764+
$plugins = static::load_standard_plugins()->standard;
1765+
1766+
$result = [];
1767+
foreach ($plugins as $type => $list) {
1768+
foreach ($list as $plugin) {
1769+
$result[] = "{$type}_{$plugin}";
1770+
}
1771+
}
1772+
1773+
return $result;
1774+
}
1775+
1776+
/**
1777+
* Get all deleted standard plugins by their component name.
1778+
*
1779+
* @return array
1780+
*/
1781+
public static function get_deleted_plugins(): array {
1782+
$plugins = static::load_standard_plugins()->deleted;
1783+
1784+
$result = [];
1785+
foreach ($plugins as $type => $list) {
1786+
foreach ($list as $plugin) {
1787+
$result[] = "{$type}_{$plugin}";
1788+
}
1789+
}
1790+
1791+
return $result;
1792+
}
1793+
20781794
/**
20791795
* Remove the current plugin code from the dirroot.
20801796
*

‎lib/plugins.json

+684
Large diffs are not rendered by default.

‎lib/plugins.schema.json

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "https://moodle.org/apis.schema.json",
4+
"title": "Standard Plugins",
5+
"description": "Moodle standard and removed plugins",
6+
"type": "object",
7+
"properties": {
8+
"standard": {
9+
"description": "The list of plugins installed with a standard Moodle install",
10+
"$ref": "#/$defs/plugintypes"
11+
},
12+
"deleted": {
13+
"description": "The list of plugins that were previously inlcuded as standard with a Moodle install",
14+
"$ref": "#/$defs/plugintypes"
15+
}
16+
},
17+
"required": [
18+
"standard",
19+
"deleted"
20+
],
21+
"$defs": {
22+
"plugintypes": {
23+
"description": "A list of Moodle plugin types",
24+
"type": "object",
25+
"patternProperties": {
26+
"^[a-z][a-z0-9]*$": {
27+
"$ref": "#/$defs/plugintype"
28+
}
29+
}
30+
},
31+
"plugintype": {
32+
"description": "A list of Moodle plugins in a plugin type",
33+
"type": "array",
34+
"items": {
35+
"$ref": "#/$defs/pluginname"
36+
}
37+
},
38+
"pluginname": {
39+
"type": "string",
40+
"pattern": "^([a-z][a-z0-9_]*)?[a-z0-9]+$"
41+
}
42+
}
43+
}

‎lib/tests/plugin_manager_test.php

+82
Original file line numberDiff line numberDiff line change
@@ -702,4 +702,86 @@ public static function check_explicitly_supported_provider(): array {
702702
],
703703
];
704704
}
705+
706+
/**
707+
* @dataProvider is_deleted_standard_plugin_provider
708+
*/
709+
public function test_is_deleted_standard_plugin(
710+
mixed $type,
711+
mixed $name,
712+
bool $expected,
713+
): void {
714+
$this->assertEquals(
715+
$expected,
716+
\core_plugin_manager::is_deleted_standard_plugin($type, $name),
717+
);
718+
}
719+
720+
public static function is_deleted_standard_plugin_provider(): array {
721+
return [
722+
// Valid deleted plugin.
723+
['h5plib', 'v124', true],
724+
// Valid type, but not a valid plugin.
725+
['h5plib', 'v99', false],
726+
// Invalid type.
727+
['marmelade', 'paddington', false],
728+
];
729+
}
730+
731+
public function test_get_deleted_plugins(): void {
732+
$plugins = core_plugin_manager::get_deleted_plugins();
733+
$this->assertIsArray($plugins);
734+
735+
// Pick a couple we know should be there.
736+
$this->assertContains('h5plib_v124', $plugins);
737+
$this->assertNotContains('h5plib_v99', $plugins);
738+
739+
$this->assertContains('editor_tinymce', $plugins);
740+
$this->assertNotContains('editor_tiny', $plugins);
741+
}
742+
743+
public function test_standard_plugins_list_no_type(): void {
744+
$plugins = core_plugin_manager::standard_plugins_list('typo');
745+
$this->assertFalse($plugins);
746+
}
747+
748+
/**
749+
* @dataProvider standard_plugins_list_provider
750+
*/
751+
public function test_standard_plugins_list(
752+
string $type,
753+
array $expectedplugins,
754+
): void {
755+
$plugins = core_plugin_manager::standard_plugins_list($type);
756+
$this->assertIsArray($plugins);
757+
foreach ($expectedplugins as $expected) {
758+
$this->assertContains($expected, $plugins);
759+
}
760+
}
761+
762+
public static function standard_plugins_list_provider(): array {
763+
return [
764+
[
765+
'mod',
766+
['forum', 'assign', 'book', 'choice'],
767+
],
768+
[
769+
'block',
770+
['starredcourses', 'badges'],
771+
],
772+
[
773+
'tiny',
774+
['autosave', 'h5p'],
775+
],
776+
];
777+
}
778+
779+
public function test_get_standard_plugins(): void {
780+
$plugins = core_plugin_manager::get_standard_plugins();
781+
$this->assertIsArray($plugins);
782+
783+
$this->assertContains('mod_forum', $plugins);
784+
$this->assertContains('block_badges', $plugins);
785+
$this->assertNotContains('marmelade_paddington', $plugins);
786+
}
705787
}

‎lib/upgrade.txt

+1
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ information provided here is intended especially for developers.
137137
because there aren't cases in core.
138138
- Deprecation: Cannot use the "Test" suffix on abstract test case classes. Proceed to
139139
rename them to end with "TestCase" instead.
140+
* The list of standard, and deleted, plugins is now located as JSON at lib/plugins.json.
140141

141142
=== 4.3 ===
142143

0 commit comments

Comments
 (0)
Please sign in to comment.