From 750208684574ec951c7e17d3307958ad3942146d Mon Sep 17 00:00:00 2001 From: Tomo Tsuyuki Date: Tue, 7 May 2024 16:01:45 +1000 Subject: [PATCH 1/8] Issue #121 Update old records from system context to cm context. --- db/upgrade.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/db/upgrade.php b/db/upgrade.php index a584342..cb7d4c0 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -341,5 +341,35 @@ function xmldb_cms_upgrade($oldversion) { upgrade_mod_savepoint(true, 2023112100, 'cms'); } + if ($oldversion < 2024090301) { + // Update query for setting. + $sql = "UPDATE {customfield_data} mcd1 + SET contextid = sub.mcid + FROM ( + SELECT mcd.id mcdid, mcd.contextid mcdcontextid, mc.id mcid + FROM {customfield_data} mcd + JOIN {customfield_field} mcf ON mcf.id = mcd.fieldid + JOIN {customfield_category} mcc ON mcc.id = mcf.categoryid + JOIN {course_modules} mcm ON mcm.instance = mcd.instanceid AND mcm.module = ( + SELECT id FROM {modules} WHERE name = 'cms' + ) + JOIN {context} mc ON mc.instanceid = mcm.id AND contextlevel = 70 + WHERE mcd.id IN ( + SELECT mcd.id + FROM {customfield_data} mcd + JOIN {customfield_field} mcf ON mcf.id = mcd.fieldid + JOIN {customfield_category} mcc ON mcc.id = mcf.categoryid + JOIN {course_modules} mcm ON mcm.instance = mcd.instanceid AND mcm.module = ( + SELECT id FROM {modules} WHERE name = 'cms' + ) + JOIN {context} mc ON mc.instanceid = mcm.id AND contextlevel = 70 + WHERE mcf.type = 'textarea' AND mcc.component = 'mod_cms' AND mcd.contextid != mc.id + ) + ) sub + WHERE mcd1.id = sub.mcdid"; + $DB->execute($sql); + upgrade_mod_savepoint(true, 2024090301, 'cms'); + } + return true; } From a065dc267b7700c281d04909294e7f9ebdadd6fd Mon Sep 17 00:00:00 2001 From: Tomo Tsuyuki Date: Fri, 10 May 2024 12:09:36 +1000 Subject: [PATCH 2/8] Issue #121 Use Moodle db function to update the records. --- db/upgrade.php | 41 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/db/upgrade.php b/db/upgrade.php index cb7d4c0..12207b1 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -342,32 +342,21 @@ function xmldb_cms_upgrade($oldversion) { } if ($oldversion < 2024090301) { - // Update query for setting. - $sql = "UPDATE {customfield_data} mcd1 - SET contextid = sub.mcid - FROM ( - SELECT mcd.id mcdid, mcd.contextid mcdcontextid, mc.id mcid - FROM {customfield_data} mcd - JOIN {customfield_field} mcf ON mcf.id = mcd.fieldid - JOIN {customfield_category} mcc ON mcc.id = mcf.categoryid - JOIN {course_modules} mcm ON mcm.instance = mcd.instanceid AND mcm.module = ( - SELECT id FROM {modules} WHERE name = 'cms' - ) - JOIN {context} mc ON mc.instanceid = mcm.id AND contextlevel = 70 - WHERE mcd.id IN ( - SELECT mcd.id - FROM {customfield_data} mcd - JOIN {customfield_field} mcf ON mcf.id = mcd.fieldid - JOIN {customfield_category} mcc ON mcc.id = mcf.categoryid - JOIN {course_modules} mcm ON mcm.instance = mcd.instanceid AND mcm.module = ( - SELECT id FROM {modules} WHERE name = 'cms' - ) - JOIN {context} mc ON mc.instanceid = mcm.id AND contextlevel = 70 - WHERE mcf.type = 'textarea' AND mcc.component = 'mod_cms' AND mcd.contextid != mc.id - ) - ) sub - WHERE mcd1.id = sub.mcdid"; - $DB->execute($sql); + // Collect records which have wrong contextid in the customfield data. + $sql = "SELECT mcd.id mcdid, mcd.contextid mcdcontextid, mc.id mcid + FROM {customfield_data} mcd + JOIN {customfield_field} mcf ON mcf.id = mcd.fieldid + JOIN {customfield_category} mcc ON mcc.id = mcf.categoryid + JOIN {course_modules} mcm ON mcm.instance = mcd.instanceid AND mcm.module = ( + SELECT id FROM mdl_modules WHERE name = 'cms' + ) + JOIN {context} mc ON mc.instanceid = mcm.id AND contextlevel = " . CONTEXT_MODULE . " + WHERE mcc.component = 'mod_cms' AND mcd.contextid != mc.id"; + $records = $DB->get_records_sql($sql); + // Update records with correct contextid. + foreach ($records as $record) { + $DB->set_field('customfield_data', 'contextid', $record->mcid, ['id' => $record->mcdid]); + } upgrade_mod_savepoint(true, 2024090301, 'cms'); } From 83163545449af5c6ef1190aba151aef26de81f94 Mon Sep 17 00:00:00 2001 From: Tomo Tsuyuki Date: Mon, 20 May 2024 18:43:53 +1000 Subject: [PATCH 3/8] Issue #121 Move upgrade script to adhoc task. --- classes/task/update_customfield_context.php | 55 +++++++++++++++++++++ db/upgrade.php | 19 ++----- 2 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 classes/task/update_customfield_context.php diff --git a/classes/task/update_customfield_context.php b/classes/task/update_customfield_context.php new file mode 100644 index 0000000..7560d15 --- /dev/null +++ b/classes/task/update_customfield_context.php @@ -0,0 +1,55 @@ +. + +namespace mod_cms\task; + +use core\task\adhoc_task; + +/** + * Runs customfield context update. + * + * @package mod_cms + * @author Tomo Tsuyuki + * @copyright 2023 Catalyst IT + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class update_customfield_context extends adhoc_task { + + /** + * Run the task. + * + * @return void + */ + public function execute() { + global $DB; + + // Collect records which have wrong contextid in the customfield data. + $sql = "SELECT mcd.id mcdid, mcd.contextid mcdcontextid, mc.id mcid + FROM {customfield_data} mcd + JOIN {customfield_field} mcf ON mcf.id = mcd.fieldid + JOIN {customfield_category} mcc ON mcc.id = mcf.categoryid + JOIN {course_modules} mcm ON mcm.instance = mcd.instanceid AND mcm.module = ( + SELECT id FROM {modules} WHERE name = 'cms' + ) + JOIN {context} mc ON mc.instanceid = mcm.id AND contextlevel = " . CONTEXT_MODULE . " + WHERE mcc.component = 'mod_cms' AND mcd.contextid != mc.id"; + $records = $DB->get_records_sql($sql); + // Update records with correct contextid. + foreach ($records as $record) { + $DB->set_field('customfield_data', 'contextid', $record->mcid, ['id' => $record->mcdid]); + } + } +} diff --git a/db/upgrade.php b/db/upgrade.php index 12207b1..a32986e 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -23,11 +23,13 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use core\task\manager; use mod_cms\local\lib; use mod_cms\local\model\cms_types; use mod_cms\local\model\cms; use mod_cms\local\datasource\fields; use mod_cms\local\datasource\userlist; +use mod_cms\task\update_customfield_context; /** * Function to upgrade mod_cms database @@ -342,21 +344,8 @@ function xmldb_cms_upgrade($oldversion) { } if ($oldversion < 2024090301) { - // Collect records which have wrong contextid in the customfield data. - $sql = "SELECT mcd.id mcdid, mcd.contextid mcdcontextid, mc.id mcid - FROM {customfield_data} mcd - JOIN {customfield_field} mcf ON mcf.id = mcd.fieldid - JOIN {customfield_category} mcc ON mcc.id = mcf.categoryid - JOIN {course_modules} mcm ON mcm.instance = mcd.instanceid AND mcm.module = ( - SELECT id FROM mdl_modules WHERE name = 'cms' - ) - JOIN {context} mc ON mc.instanceid = mcm.id AND contextlevel = " . CONTEXT_MODULE . " - WHERE mcc.component = 'mod_cms' AND mcd.contextid != mc.id"; - $records = $DB->get_records_sql($sql); - // Update records with correct contextid. - foreach ($records as $record) { - $DB->set_field('customfield_data', 'contextid', $record->mcid, ['id' => $record->mcdid]); - } + // Add adhoc task to update contextid in customfield records. + manager::queue_adhoc_task(new update_customfield_context()); upgrade_mod_savepoint(true, 2024090301, 'cms'); } From fa95b45a1ba74265f31b0a4e46e56afaf0ea1d20 Mon Sep 17 00:00:00 2001 From: Tomo Tsuyuki Date: Tue, 4 Jun 2024 19:18:27 +1000 Subject: [PATCH 4/8] Issue #121 Update valuetrust if exists. --- db/upgrade.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/db/upgrade.php b/db/upgrade.php index a32986e..723599d 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -349,5 +349,25 @@ function xmldb_cms_upgrade($oldversion) { upgrade_mod_savepoint(true, 2024090301, 'cms'); } + if ($oldversion < 2023120102) { + $dbman = $DB->get_manager(); + // Conditionally launch add field valuetrust. + if ($dbman->field_exists('customfield_data', 'valuetrust')) { + $sql = "SELECT mcd.id mcdid + FROM {customfield_data} mcd + JOIN {customfield_field} mcf ON mcf.id = mcd.fieldid + JOIN {customfield_category} mcc ON mcc.id = mcf.categoryid + WHERE mcc.component = 'mod_cms' AND mcd.valuetrust = 0"; + $records = $DB->get_records_sql($sql); + $mcdids = array_keys($records); + foreach (array_chunk($mcdids, 100) as $ids) { + [$sql, $params] = $DB->get_in_or_equal($ids); + $sql = 'UPDATE {customfield_data} SET valuetrust = 1 WHERE id ' . $sql; + $DB->execute($sql, $params); + } + } + upgrade_mod_savepoint(true, 2023120102, 'cms'); + } + return true; } From 32e67518e4be3c0b3115737a70f841d081fbf25c Mon Sep 17 00:00:00 2001 From: Tomo Tsuyuki Date: Fri, 7 Jun 2024 12:07:39 +1000 Subject: [PATCH 5/8] Issue #121 Update contextid for userlist customfield records. --- classes/task/update_customfield_context.php | 5 +- db/upgrade.php | 52 +++++++++++++++++++-- version.php | 2 +- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/classes/task/update_customfield_context.php b/classes/task/update_customfield_context.php index 7560d15..cf0bac8 100644 --- a/classes/task/update_customfield_context.php +++ b/classes/task/update_customfield_context.php @@ -36,6 +36,9 @@ class update_customfield_context extends adhoc_task { public function execute() { global $DB; + // Record {customfield_data}.instanceid is from {cms}.id. + // Record {customfield_data}.contextid is from contextid of {course_modules}, which is linked to {cms}. + // Collect records which have wrong contextid in the customfield data. $sql = "SELECT mcd.id mcdid, mcd.contextid mcdcontextid, mc.id mcid FROM {customfield_data} mcd @@ -45,7 +48,7 @@ public function execute() { SELECT id FROM {modules} WHERE name = 'cms' ) JOIN {context} mc ON mc.instanceid = mcm.id AND contextlevel = " . CONTEXT_MODULE . " - WHERE mcc.component = 'mod_cms' AND mcd.contextid != mc.id"; + WHERE mcc.component = 'mod_cms' AND mcc.area = 'cmsfield' AND mcd.contextid != mc.id"; $records = $DB->get_records_sql($sql); // Update records with correct contextid. foreach ($records as $record) { diff --git a/db/upgrade.php b/db/upgrade.php index 723599d..3823cc1 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -344,14 +344,14 @@ function xmldb_cms_upgrade($oldversion) { } if ($oldversion < 2024090301) { - // Add adhoc task to update contextid in customfield records. + // Add adhoc task to update contextid in customfield records for 'cmsfield' type. manager::queue_adhoc_task(new update_customfield_context()); upgrade_mod_savepoint(true, 2024090301, 'cms'); } - if ($oldversion < 2023120102) { + if ($oldversion < 2024090302) { $dbman = $DB->get_manager(); - // Conditionally launch add field valuetrust. + // Update valuetrust if exists for mod_cms (both 'cmsfield' and 'cmsuserlist'). if ($dbman->field_exists('customfield_data', 'valuetrust')) { $sql = "SELECT mcd.id mcdid FROM {customfield_data} mcd @@ -366,7 +366,51 @@ function xmldb_cms_upgrade($oldversion) { $DB->execute($sql, $params); } } - upgrade_mod_savepoint(true, 2023120102, 'cms'); + upgrade_mod_savepoint(true, 2024090302, 'cms'); + } + + if ($oldversion < 2024090303) { + // Update contextid in customfield records for 'cmsuserlist' type. + // {customfield_data}.instanceid" is from one of id from userlistinstanceids which is JSON encoded in {cms}.customdata. + // "userlistinstanceids" is a unique id for the customfield_data. + // New ID is from userlistmaxinstanceid which is JSON encoded in the {cms_types}.customdata" and add 1 to use. + $sql = "SELECT mc.id, mc.customdata, mcx.id contextid + FROM {cms} mc + JOIN {course_modules} mcm ON mc.id = mcm.instance AND mcm.module = ( + SELECT id FROM {modules} WHERE name = 'cms' + ) + JOIN {context} mcx ON mcx.instanceid = mcm.id AND mcx.contextlevel = " . CONTEXT_MODULE . " + WHERE mc.customdata LIKE '%userlistinstanceids%'"; + $cmsrecords = $DB->get_records_sql($sql); + + // Load userlist from customfield_data and set to array. + $userlist = []; + foreach ($cmsrecords as $cmsrecord) { + $customdata = json_decode($cmsrecord->customdata); + foreach ($customdata->userlistinstanceids as $instanceid) { + $userlist[$instanceid] = [ + 'id' => $cmsrecord->id, + 'contextid' => $cmsrecord->contextid, + ]; + } + } + + // Check cmsuserlist records and set correct contextid if it's different one. + $sql = "SELECT mcd.id, mcd.instanceid, mcd.contextid + FROM {customfield_data} mcd + JOIN {customfield_field} mcf ON mcf.id = mcd.fieldid + JOIN {customfield_category} mcc ON mcc.id = mcf.categoryid + WHERE mcc.component = 'mod_cms' AND mcc.area = 'cmsuserlist'"; + $cmsuserlistdata = $DB->get_records_sql($sql); + foreach ($cmsuserlistdata as $cmsuserlist) { + if (!empty($userlist[$cmsuserlist->instanceid])) { + if ($userlist[$cmsuserlist->instanceid]['contextid'] != $cmsuserlist->contextid) { + $DB->set_field('customfield_data', 'contextid', $userlist[$cmsuserlist->instanceid]['contextid'], + ['id' => $cmsuserlist->id]); + } + } + } + upgrade_mod_savepoint(true, 2024090303, 'cms'); } return true; diff --git a/version.php b/version.php index a23e888..6ee8741 100644 --- a/version.php +++ b/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2024090301; +$plugin->version = 2024090303; $plugin->requires = 2022112800; // Moodle 4.1 and above. $plugin->supported = [401, 401]; // Moodle 4.1. $plugin->component = 'mod_cms'; From eaadb9fc30855918b89b94e1cf65e3e26c77dcd8 Mon Sep 17 00:00:00 2001 From: Tomo Tsuyuki Date: Tue, 11 Jun 2024 10:20:17 +1000 Subject: [PATCH 6/8] Issue #121 Increase chunk from 100 to 1000. --- db/upgrade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/upgrade.php b/db/upgrade.php index 3823cc1..b56cb62 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -360,7 +360,7 @@ function xmldb_cms_upgrade($oldversion) { WHERE mcc.component = 'mod_cms' AND mcd.valuetrust = 0"; $records = $DB->get_records_sql($sql); $mcdids = array_keys($records); - foreach (array_chunk($mcdids, 100) as $ids) { + foreach (array_chunk($mcdids, 1000) as $ids) { [$sql, $params] = $DB->get_in_or_equal($ids); $sql = 'UPDATE {customfield_data} SET valuetrust = 1 WHERE id ' . $sql; $DB->execute($sql, $params); From 878ad9f69410acb681a35c94075fb660a4f1dfa8 Mon Sep 17 00:00:00 2001 From: Alexander Van der Bellen Date: Tue, 12 Nov 2024 23:19:29 +0800 Subject: [PATCH 7/8] Rune files table upgrade in ad hoc task --- classes/task/update_files_context.php | 155 ++++++++++++++++++++++++++ db/upgrade.php | 8 ++ 2 files changed, 163 insertions(+) create mode 100644 classes/task/update_files_context.php diff --git a/classes/task/update_files_context.php b/classes/task/update_files_context.php new file mode 100644 index 0000000..ede158f --- /dev/null +++ b/classes/task/update_files_context.php @@ -0,0 +1,155 @@ +. + +namespace mod_cms\task; + +use core\task\adhoc_task; +use csv_export_writer; +use file_storage; +use moodle_exception; + +/** + * Update the context of embedded files to match the context of the mod_cms module instance. + * + * @package mod_cms + * @author Alexander Van der Bellen + * @copyright 2024 Catalyst IT Australia + * @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class update_files_context extends adhoc_task { + + /** + * Factory method to create a new update_files_context task. + * + * @param int|null $courseid Limit the task to a specific course or all courses if null. + * @param bool $dryrun Whether to run the task without making database changes. + * @return update_files_context The task instance. + */ + public static function instance(?int $courseid = null, bool $dryrun = true): update_files_context { + $task = new self(); + $task->set_custom_data((object) ['courseid' => $courseid, 'dryrun' => $dryrun]); + return $task; + } + + /** + * Run the task to delete course results for a user. + */ + public function execute(): void { + global $CFG; + $data = $this->get_custom_data(); + $csv = self::update_contexts($data->courseid, $data->dryrun); + file_put_contents($CFG->dataroot . '/' . $csv->filename, $csv->print_csv_data(true)); + } + + /** + * Update mod_cms customfield_textarea embedded file contexts to match the context of the mod_cms module instance. + * @param int|null $courseid Limit the task to a specific course or all courses if null. + * @param bool $dryrun Whether to run the task without making database changes. + * @return csv_export_writer The CSV export writer containing the results of the task. + */ + private static function update_contexts(?int $courseid, bool $dryrun): csv_export_writer { + global $DB; + + $sql = "SELECT f.*, ctx.id AS ctxid, cms.course AS courseid + FROM {files} f + JOIN {customfield_data} cfd ON cfd.id = f.itemid + JOIN {customfield_field} cff ON cff.id = cfd.fieldid + JOIN {cms} cms ON cms.id = cfd.instanceid + JOIN {cms_types} cmst ON cmst.id = cms.typeid AND cmst.datasources LIKE '%fields%' + JOIN {course_modules} cm ON cm.instance = cms.id + JOIN {modules} m ON m.id = cm.module AND m.name = 'cms' + JOIN {context} ctx ON ctx.instanceid = cm.id AND ctx.contextlevel = :modulecontextlevel + WHERE f.contextid = 1 AND f.component = 'customfield_textarea' AND f.filearea = 'value'"; + + $params = ['modulecontextlevel' => CONTEXT_MODULE]; + + if (!empty($courseid)) { + $sql .= " AND cms.course = :courseid"; + $params['courseid'] = $courseid; + } + + $csv = new csv_export_writer(); + $csv->set_filename('mod_cms_update_files_context'); + $csv->add_data([ + 'courseid', + 'newpathnamehash', + 'newcontextid', + 'id', + 'contenthash', + 'pathnamehash', + 'contextid', + 'component', + 'filearea', + 'itemid', + 'filepath', + 'filename', + 'timecreated', + 'timemodified', + ]); + + $records = $DB->get_recordset_sql($sql, $params); + foreach ($records as $record) { + $newcontextid = $record->ctxid; + + $newpathnamehash = file_storage::get_pathname_hash( + $newcontextid, + $record->component, + $record->filearea, + $record->itemid, + $record->filepath, + $record->filename + ); + + $csv->add_data([ + $record->courseid, + $newpathnamehash, + $newcontextid, + $record->id, + $record->contenthash, + $record->pathnamehash, + $record->contextid, + $record->component, + $record->filearea, + $record->itemid, + $record->filepath, + $record->filename, + $record->timecreated, + $record->timemodified, + ]); + + // Update the record with the new context id and path name hash. + $record->contextid = $newcontextid; + $record->pathnamehash = $newpathnamehash; + + if (!$dryrun) { + // Remove the ctxid and courseid fields. + unset($record->ctxid); + unset($record->courseid); + + // Update the record in the database. + try { + $DB->update_record('files', $record); + } catch (moodle_exception $e) { + debugging('Failed to insert record into files table: ' . $e->getMessage(), DEBUG_DEVELOPER); + } + } + } + + $records->close(); + + return $csv; + } +} diff --git a/db/upgrade.php b/db/upgrade.php index b56cb62..8c243e0 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -413,5 +413,13 @@ function xmldb_cms_upgrade($oldversion) { upgrade_mod_savepoint(true, 2024090303, 'cms'); } + if ($oldversion < 2024090304) { + // Run ad hoc task for updating contextid in the files table. + $task = \mod_cms\task\update_files_context::instance(null, false); + manager::queue_adhoc_task($task); + + upgrade_mod_savepoint(true, 2024090304, 'cms'); + } + return true; } From c4971efd6c978767bfd32b38a98743e1d001a8bc Mon Sep 17 00:00:00 2001 From: Alexander Van der Bellen Date: Mon, 18 Nov 2024 16:22:30 +0800 Subject: [PATCH 8/8] Fix Adhoc task failed: mod_cms\task\update_files_context,Class 'csv_export_writer' not found --- classes/task/update_files_context.php | 4 +++- db/upgrade.php | 4 ++-- version.php | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/classes/task/update_files_context.php b/classes/task/update_files_context.php index ede158f..e2d675f 100644 --- a/classes/task/update_files_context.php +++ b/classes/task/update_files_context.php @@ -61,7 +61,9 @@ public function execute(): void { * @return csv_export_writer The CSV export writer containing the results of the task. */ private static function update_contexts(?int $courseid, bool $dryrun): csv_export_writer { - global $DB; + global $CFG, $DB; + + require_once($CFG->libdir . '/csvlib.class.php'); $sql = "SELECT f.*, ctx.id AS ctxid, cms.course AS courseid FROM {files} f diff --git a/db/upgrade.php b/db/upgrade.php index 8c243e0..d691e2b 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -413,12 +413,12 @@ function xmldb_cms_upgrade($oldversion) { upgrade_mod_savepoint(true, 2024090303, 'cms'); } - if ($oldversion < 2024090304) { + if ($oldversion < 2024090305) { // Run ad hoc task for updating contextid in the files table. $task = \mod_cms\task\update_files_context::instance(null, false); manager::queue_adhoc_task($task); - upgrade_mod_savepoint(true, 2024090304, 'cms'); + upgrade_mod_savepoint(true, 2024090305, 'cms'); } return true; diff --git a/version.php b/version.php index 6ee8741..9f811c3 100644 --- a/version.php +++ b/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2024090303; +$plugin->version = 2024090305; $plugin->requires = 2022112800; // Moodle 4.1 and above. $plugin->supported = [401, 401]; // Moodle 4.1. $plugin->component = 'mod_cms';