diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml
index f86851d..9130c1b 100644
--- a/.github/workflows/moodle-ci.yml
+++ b/.github/workflows/moodle-ci.yml
@@ -1,6 +1,6 @@
name: Moodle Plugin CI
-on: [ push, pull_request ]
+on: [push, pull_request]
jobs:
static:
@@ -8,16 +8,16 @@ jobs:
strategy:
matrix:
- php: [ '8.1' ]
- moodle-branch: [ 'MOODLE_402_STABLE' ]
- database: [ 'pgsql' ]
+ php: ['8.2']
+ moodle-branch: ['main']
+ database: ['pgsql']
steps:
- name: Start PostgreSQL
run: docker run -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_HOST_AUTH_METHOD=trust -d postgres:14
- name: Check out repository code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
path: plugin
@@ -28,29 +28,9 @@ jobs:
ini-values: max_input_vars=5000
coverage: none
- - name: Get composer cache directory
- id: composer-cache
- run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
-
- - name: Composer cache
- uses: actions/cache@v3
- with:
- path: ${{ steps.composer-cache.outputs.dir }}
- key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
- restore-keys: |
- ${{ runner.os }}-composer-
-
- - name: npm cache
- uses: actions/cache@v3
- with:
- path: ~/.npm
- key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
- restore-keys: |
- ${{ runner.os }}-node-
-
- name: Initialise moodle-plugin-ci
run: |
- composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^3
+ composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^4
echo $(cd ci/bin; pwd) >> $GITHUB_PATH
echo $(cd ci/vendor/bin; pwd) >> $GITHUB_PATH
sudo locale-gen en_AU.UTF-8
@@ -58,7 +38,6 @@ jobs:
- name: Install moodle-plugin-ci
run: |
- moodle-plugin-ci add-plugin learnweb/moodle-tool_lifecycle
moodle-plugin-ci install --plugin ./plugin --db-host=127.0.0.1 --no-init
env:
DB: ${{ matrix.database }}
@@ -83,7 +62,6 @@ jobs:
- name: Moodle PHPDoc Checker
if: ${{ always() }}
run: moodle-plugin-ci phpdoc
- continue-on-error: true
- name: Validating
if: ${{ always() }}
@@ -109,28 +87,21 @@ jobs:
strategy:
fail-fast: false
matrix:
- php: [ '8.0', '8.1' ]
- moodle-branch: [ 'MOODLE_401_STABLE', 'MOODLE_402_STABLE' ]
- database: [ 'mariadb', 'pgsql' ]
+ php: ['8.0', '8.1', '8.2']
+ moodle-branch: ['MOODLE_401_STABLE', 'MOODLE_402_STABLE', 'MOODLE_403_STABLE', 'main']
+ database: ['mariadb', 'pgsql']
+ exclude:
+ - php: '8.0'
+ moodle-branch: 'main'
+ - php: '8.2'
+ moodle-branch: 'MOODLE_401_STABLE'
include:
- php: '7.4'
- moodle-branch: 'MOODLE_39_STABLE'
- database: 'mariadb'
- - php: '7.4'
- moodle-branch: 'MOODLE_39_STABLE'
+ moodle-branch: 'MOODLE_401_STABLE'
database: 'pgsql'
- - php: '8.0'
- moodle-branch: 'MOODLE_311_STABLE'
- database: 'mariadb'
- - php: '8.0'
- moodle-branch: 'MOODLE_311_STABLE'
- database: 'pgsql'
- - php: '8.0'
- moodle-branch: 'MOODLE_400_STABLE'
+ - php: '7.4'
+ moodle-branch: 'MOODLE_401_STABLE'
database: 'mariadb'
- - php: '8.0'
- moodle-branch: 'MOODLE_400_STABLE'
- database: 'pgsql'
steps:
- name: Start MariaDB
@@ -142,7 +113,7 @@ jobs:
run: docker run -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_HOST_AUTH_METHOD=trust -d postgres:14
- name: Check out repository code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
path: plugin
@@ -153,24 +124,6 @@ jobs:
ini-values: max_input_vars=5000
coverage: none
- - name: Get composer cache directory
- id: composer-cache
- run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- - name: Composer cache
- uses: actions/cache@v3
- with:
- path: ${{ steps.composer-cache.outputs.dir }}
- key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
- restore-keys: |
- ${{ runner.os }}-composer-
- - name: npm cache
- uses: actions/cache@v3
- with:
- path: ~/.npm
- key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
- restore-keys: |
- ${{ runner.os }}-node-
-
- name: Initialise moodle-plugin-ci
run: |
composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^3
@@ -181,7 +134,6 @@ jobs:
- name: Install moodle-plugin-ci
run: |
- moodle-plugin-ci add-plugin learnweb/moodle-tool_lifecycle
moodle-plugin-ci install --plugin ./plugin --db-host=127.0.0.1
env:
DB: ${{ matrix.database }}
@@ -194,3 +146,15 @@ jobs:
- name: Behat features
if: ${{ always() }}
run: moodle-plugin-ci behat --profile chrome --auto-rerun 0
+
+ # This step allows to upload Behat faildump (screenshots) as workflow artifact,
+ # so it can be downloaded and inspected. You don't need this step if you
+ # are not running Behat test. Artifact will be retained for 7 days.
+ - name: Upload Behat Faildump
+ if: ${{ failure() && steps.behat.outcome == 'failure' }}
+ uses: actions/upload-artifact@v4
+ with:
+ name: Behat Faildump (${{ join(matrix.*, ', ') }})
+ path: ${{ github.workspace }}/moodledata/behat_dump
+ retention-days: 7
+ if-no-files-found: ignore
diff --git a/approvestep.php b/approvestep.php
index 2918dba..bd81051 100644
--- a/approvestep.php
+++ b/approvestep.php
@@ -32,7 +32,7 @@
admin_externalpage_setup('lifecyclestep_adminapprove_manage');
$action = optional_param('act', null, PARAM_ALPHA);
-$ids = optional_param_array('c', array(), PARAM_INT);
+$ids = optional_param_array('c', [], PARAM_INT);
$stepid = required_param('stepid', PARAM_INT);
$step = \tool_lifecycle\local\manager\step_manager::get_step_instance($stepid);
@@ -139,13 +139,13 @@
$hasrecords = $DB->record_exists_sql('SELECT a.id FROM {lifecyclestep_adminapprove} a ' .
'JOIN {tool_lifecycle_process} p ON p.id = a.processid ' .
'JOIN {tool_lifecycle_step} s ON s.workflowid = p.workflowid AND s.sortindex = p.stepindex ' .
- 'WHERE s.id = :sid AND a.status = 0', array('sid' => $stepid));
+ 'WHERE s.id = :sid AND a.status = 0', ['sid' => $stepid]);
if ($hasrecords) {
$mform->display();
echo get_string('courses_waiting', 'lifecyclestep_adminapprove',
- array('step' => $step->instancename, 'workflow' => $workflow->title));
+ ['step' => $step->instancename, 'workflow' => $workflow->title]);
echo "
";
echo '
';
echo '';
- $button = new \single_button(new moodle_url($PAGE->url, array('act' => PROCEED_ALL)),
+ $button = new \single_button(new moodle_url($PAGE->url, ['act' => PROCEED_ALL]),
get_string(PROCEED_ALL, 'lifecyclestep_adminapprove'));
echo $OUTPUT->render($button);
- $button = new \single_button(new moodle_url($PAGE->url, array('act' => ROLLBACK_ALL)),
+ $button = new \single_button(new moodle_url($PAGE->url, ['act' => ROLLBACK_ALL]),
get_string(ROLLBACK_ALL, 'lifecyclestep_adminapprove'));
echo $OUTPUT->render($button);
echo '
';
- $PAGE->requires->js_call_amd('lifecyclestep_adminapprove/init', 'init', array(sesskey(), $PAGE->url->out()));
+ $PAGE->requires->js_call_amd('lifecyclestep_adminapprove/init', 'init', [sesskey(), $PAGE->url->out()]);
} else {
echo get_string('no_courses_waiting', 'lifecyclestep_adminapprove',
- array('step' => $step->instancename, 'workflow' => $workflow->title));
+ ['step' => $step->instancename, 'workflow' => $workflow->title]);
}
echo $OUTPUT->footer();
diff --git a/classes/decision_table.php b/classes/decision_table.php
index bfa2d53..2b81106 100644
--- a/classes/decision_table.php
+++ b/classes/decision_table.php
@@ -40,7 +40,7 @@ class decision_table extends \table_sql {
private $category;
/**
- * @var String pattern for the coursename.
+ * @var string pattern for the coursename.
*/
private $coursename;
@@ -60,13 +60,13 @@ public function __construct($stepid, $courseid, $category, $coursename) {
$this->define_baseurl("/admin/tool/lifecycle/step/adminapprove/approvestep.php?stepid=$stepid");
$this->define_columns(['checkbox', 'courseid', 'course', 'category', 'startdate', 'tools']);
$this->define_headers(
- array(\html_writer::checkbox('checkall', null, false),
+ [\html_writer::checkbox('checkall', null, false),
get_string('courseid', 'lifecyclestep_adminapprove'),
get_string('course'),
get_string('category'),
get_string('startdate'),
- get_string('tools', 'lifecyclestep_adminapprove')));
- $this->column_nosort = array('checkbox', 'tools');
+ get_string('tools', 'lifecyclestep_adminapprove')]);
+ $this->column_nosort = ['checkbox', 'tools'];
$fields = 'm.id, w.displaytitle as workflow, c.id as courseid, c.fullname as course, cc.name as category,
c.startdate, m.status';
$from = '{lifecyclestep_adminapprove} m ' .
@@ -76,7 +76,7 @@ public function __construct($stepid, $courseid, $category, $coursename) {
'LEFT JOIN {tool_lifecycle_workflow} w ON w.id = p.workflowid ' .
'LEFT JOIN {tool_lifecycle_step} s ON s.workflowid = p.workflowid AND s.sortindex = p.stepindex';
$where = 'm.status = 0 AND s.id = :sid ';
- $params = array('sid' => $stepid);
+ $params = ['sid' => $stepid];
if ($courseid) {
$where .= 'AND c.id = :cid ';
$params['cid'] = $courseid;
@@ -154,13 +154,13 @@ public function col_startdate($row) {
public function col_tools($row) {
$output = \html_writer::start_div('singlebutton mr-1');
$output .= \html_writer::tag('button', get_string('proceed', 'lifecyclestep_adminapprove'),
- array('class' => 'btn btn-secondary adminapprove-action', 'data-action' => 'proceed', 'data-content' => $row->id,
- 'type' => 'button'));
+ ['class' => 'btn btn-secondary adminapprove-action', 'data-action' => 'proceed', 'data-content' => $row->id,
+ 'type' => 'button']);
$output .= \html_writer::end_div();
$output .= \html_writer::start_div('singlebutton mr-1 ml-0 mt-1');
$output .= \html_writer::tag('button', get_string('rollback', 'lifecyclestep_adminapprove'),
- array('class' => 'btn btn-secondary adminapprove-action', 'data-action' => 'rollback', 'data-content' => $row->id,
- 'type' => 'button'));
+ ['class' => 'btn btn-secondary adminapprove-action', 'data-action' => 'rollback', 'data-content' => $row->id,
+ 'type' => 'button']);
$output .= \html_writer::end_div();
return $output;
}
diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php
index 9f946d6..e0538b2 100644
--- a/classes/privacy/provider.php
+++ b/classes/privacy/provider.php
@@ -34,7 +34,7 @@ class provider implements null_provider {
*
* @return string the reason
*/
- public static function get_reason() : string {
+ public static function get_reason(): string {
return 'privacy:metadata';
}
}
diff --git a/classes/step_table.php b/classes/step_table.php
index 83815bc..afd91e3 100644
--- a/classes/step_table.php
+++ b/classes/step_table.php
@@ -43,8 +43,8 @@ public function __construct() {
$this->define_baseurl("/admin/tool/lifecycle/step/adminapprove/index.php");
$this->define_columns(['stepname', 'workflowname', 'courses']);
$this->define_headers(
- array(get_string('step', 'tool_lifecycle'), get_string('workflow', 'lifecyclestep_adminapprove'),
- get_string('amount_courses', 'lifecyclestep_adminapprove')));
+ [get_string('step', 'tool_lifecycle'), get_string('workflow', 'lifecyclestep_adminapprove'),
+ get_string('amount_courses', 'lifecyclestep_adminapprove')]);
$this->set_attribute('id', 'adminapprove-steptable');
$this->sortable(false);
$fields = 's.id as id, s.instancename as stepname, w.title as workflowname, b.courses as courses';
diff --git a/db/caches.php b/db/caches.php
index 5f277d8..11825df 100644
--- a/db/caches.php
+++ b/db/caches.php
@@ -24,8 +24,8 @@
defined('MOODLE_INTERNAL') || die();
-$definitions = array(
- 'mformdata' => array(
- 'mode' => cache_store::MODE_SESSION
- )
-);
+$definitions = [
+ 'mformdata' => [
+ 'mode' => cache_store::MODE_SESSION,
+ ],
+];
diff --git a/lang/de/lifecyclestep_adminapprove.php b/lang/de/lifecyclestep_adminapprove.php
index 860f6c0..35c1886 100644
--- a/lang/de/lifecyclestep_adminapprove.php
+++ b/lang/de/lifecyclestep_adminapprove.php
@@ -23,27 +23,27 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-$string['pluginname'] = 'Adminbestätigungs-Schritt';
-$string['privacy:metadata'] = 'Dieses Subplugin speichert keine persönlichen Daten.';
-$string['emailsubject'] = 'Kurs-Lebenszyklus: Es gibt neue Kurse, die auf Bestätigung warten.';
-$string['emailcontent'] = 'Es gibt {$a->amount} neue Kurse, die auf Bestätigung warten. Bitte besuchen Sie {$a->url}.';
-$string['emailcontenthtml'] = 'Es gibt {$a->amount} neue Kurse, die auf Bestätigung warten. Bitte klicken Sie auf diesen Link.';
+$string['amount_courses'] = 'Anzahl wartender Kurse';
+$string['bulkactions'] = 'Massenaktionen';
$string['courseid'] = 'Kurs-ID';
-$string['workflow'] = 'Workflow';
-$string['proceedselected'] = 'Ausgewählte fortführen';
-$string['rollbackselected'] = 'Ausgewählte zurücksetzten';
-$string['tools'] = 'Aktionen';
$string['courses_waiting'] = 'Diese Kurse warten derzeit auf Bestätigung im "{$a->step}"-Schritt in dem "{$a->workflow}"-Workflow.';
-$string['no_courses_waiting'] = 'Es gibt derzeit keine Kurse, die im "{$a->step}"-Schritt in dem "{$a->workflow}"-Workflow auf Bestätigung warten.';
-$string['proceed'] = 'Fortführen';
-$string['rollback'] = 'Zurücksetzten';
-$string['amount_courses'] = 'Anzahl wartender Kurse';
-$string['only_number'] = 'Es sind nur Ziffern erlaubt!';
-$string['nothingtodisplay'] = 'Es gibt keine auf Bestätigung wartenden Kurse, die auf diese Filter passen.';
+$string['emailcontent'] = 'Es gibt {$a->amount} neue Kurse, die auf Bestätigung warten. Bitte besuchen Sie {$a->url}.';
+$string['emailcontenthtml'] = 'Es gibt {$a->amount} neue Kurse, die auf Bestätigung warten. Bitte klicken Sie auf diesen Link.';
+$string['emailsubject'] = 'Kurs-Lebenszyklus: Es gibt neue Kurse, die auf Bestätigung warten.';
$string['manage-adminapprove'] = 'Adminbestätigungs-Schritte verwalten';
+$string['no_courses_waiting'] = 'Es gibt derzeit keine Kurse, die im "{$a->step}"-Schritt in dem "{$a->workflow}"-Workflow auf Bestätigung warten.';
$string['nostepstodisplay'] = 'Es gibt derzeit keine Kurse in Adminbestätigungs-Schritten, die auf Bestätigung warten.';
-$string['bulkactions'] = 'Massenaktionen';
+$string['nothingtodisplay'] = 'Es gibt keine auf Bestätigung wartenden Kurse, die auf diese Filter passen.';
+$string['only_number'] = 'Es sind nur Ziffern erlaubt!';
+$string['pluginname'] = 'Adminbestätigungs-Schritt';
+$string['privacy:metadata'] = 'Dieses Subplugin speichert keine persönlichen Daten.';
+$string['proceed'] = 'Fortführen';
$string['proceedall'] = 'Alle fortführen';
+$string['proceedselected'] = 'Ausgewählte fortführen';
+$string['rollback'] = 'Zurücksetzten';
$string['rollbackall'] = 'Alle zurücksetzten';
+$string['rollbackselected'] = 'Ausgewählte zurücksetzten';
$string['statusmessage'] = 'Statusnachricht';
$string['statusmessage_help'] = 'Statusnachricht, welche dem Lehrer angezeigt wird, wenn ein Prozess eines Kurses den Adminbestätigungs-Schritt bearbeitet.';
+$string['tools'] = 'Aktionen';
+$string['workflow'] = 'Workflow';
diff --git a/lang/en/lifecyclestep_adminapprove.php b/lang/en/lifecyclestep_adminapprove.php
index 178cda4..ce4354a 100644
--- a/lang/en/lifecyclestep_adminapprove.php
+++ b/lang/en/lifecyclestep_adminapprove.php
@@ -22,28 +22,28 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-$string['pluginname'] = 'Admin Approve Step';
-$string['privacy:metadata'] = 'This subplugin does not store any personal data.';
+$string['amount_courses'] = 'Remaining waiting courses';
+$string['bulkactions'] = 'Bulk actions';
$string['cachedef_mformdata'] = 'Caches the mform data';
-$string['emailsubject'] = 'Lifecycle: There are new courses waiting for confirmation.';
-$string['emailcontent'] = 'There are {$a->amount} new courses waiting for confirmation. Please visit {$a->url}.';
-$string['emailcontenthtml'] = 'There are {$a->amount} new courses waiting for confirmation. Please visit this link.';
$string['courseid'] = 'Course id';
-$string['workflow'] = 'Workflow';
-$string['proceedselected'] = 'Proceed selected';
-$string['rollbackselected'] = 'Rollback selected';
-$string['tools'] = 'Tools';
$string['courses_waiting'] = 'These courses are currently waiting for approval in the "{$a->step}" Step in the "{$a->workflow}" Workflow.';
-$string['no_courses_waiting'] = 'There are currently no courses waiting for approval in the "{$a->step}" Step in the "{$a->workflow}" Workflow.';
-$string['proceed'] = 'Proceed';
-$string['rollback'] = 'Rollback';
-$string['amount_courses'] = 'Remaining waiting courses';
-$string['only_number'] = 'Only numeric characters allowed!';
-$string['nothingtodisplay'] = 'There are no courses waiting for approval matching your current filters.';
+$string['emailcontent'] = 'There are {$a->amount} new courses waiting for confirmation. Please visit {$a->url}.';
+$string['emailcontenthtml'] = 'There are {$a->amount} new courses waiting for confirmation. Please visit this link.';
+$string['emailsubject'] = 'Lifecycle: There are new courses waiting for confirmation.';
$string['manage-adminapprove'] = 'Manage Admin Approve Steps';
+$string['no_courses_waiting'] = 'There are currently no courses waiting for approval in the "{$a->step}" Step in the "{$a->workflow}" Workflow.';
$string['nostepstodisplay'] = 'There are currently no courses waiting for interaction in any Admin Approve step.';
-$string['bulkactions'] = 'Bulk actions';
+$string['nothingtodisplay'] = 'There are no courses waiting for approval matching your current filters.';
+$string['only_number'] = 'Only numeric characters allowed!';
+$string['pluginname'] = 'Admin Approve Step';
+$string['privacy:metadata'] = 'This subplugin does not store any personal data.';
+$string['proceed'] = 'Proceed';
$string['proceedall'] = 'Proceed all';
+$string['proceedselected'] = 'Proceed selected';
+$string['rollback'] = 'Rollback';
$string['rollbackall'] = 'Rollback all';
+$string['rollbackselected'] = 'Rollback selected';
$string['statusmessage'] = 'Status message';
$string['statusmessage_help'] = 'Status message, which is displayed to a teacher, if a process of a course is at this admin approve step.';
+$string['tools'] = 'Tools';
+$string['workflow'] = 'Workflow';
diff --git a/lib.php b/lib.php
index 3c5b388..8862fe5 100644
--- a/lib.php
+++ b/lib.php
@@ -70,7 +70,7 @@ public function process_course($processid, $instanceid, $course) {
*/
public function rollback_course($processid, $instanceid, $course) {
global $DB;
- $DB->delete_records('lifecyclestep_adminapprove', array('processid' => $processid));
+ $DB->delete_records('lifecyclestep_adminapprove', ['processid' => $processid]);
}
/**
@@ -91,13 +91,13 @@ public function get_subpluginname() {
*/
public function process_waiting_course($processid, $instanceid, $course) {
global $DB;
- $record = $DB->get_record('lifecyclestep_adminapprove', array('processid' => $processid));
+ $record = $DB->get_record('lifecyclestep_adminapprove', ['processid' => $processid]);
switch ($record->status) {
case 1:
- $DB->delete_records('lifecyclestep_adminapprove', array('processid' => $processid));
+ $DB->delete_records('lifecyclestep_adminapprove', ['processid' => $processid]);
return step_response::proceed();
case 2:
- $DB->delete_records('lifecyclestep_adminapprove', array('processid' => $processid));
+ $DB->delete_records('lifecyclestep_adminapprove', ['processid' => $processid]);
return step_response::rollback();
default:
return step_response::waiting();
@@ -136,9 +136,9 @@ public function post_processing_bulk_operation() {
* @return instance_setting[]
*/
public function instance_settings() {
- return array(
+ return [
new instance_setting('statusmessage', PARAM_TEXT),
- );
+ ];
}
/**
@@ -161,6 +161,6 @@ public function extend_add_instance_form_definition($mform) {
*/
public function abort_course($process) {
global $DB;
- $DB->delete_records('lifecyclestep_adminapprove', array('processid' => $process->id));
+ $DB->delete_records('lifecyclestep_adminapprove', ['processid' => $process->id]);
}
}
diff --git a/tests/admin_approve_test.php b/tests/admin_approve_test.php
index ee6744a..9836870 100644
--- a/tests/admin_approve_test.php
+++ b/tests/admin_approve_test.php
@@ -35,7 +35,7 @@
* @copyright 2019 Justus Dieckmann
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-class admin_approve_test extends \advanced_testcase {
+final class admin_approve_test extends \advanced_testcase {
/**
* Starts a manual trigger and checks that one mail is send.
@@ -46,7 +46,7 @@ class admin_approve_test extends \advanced_testcase {
* @throws dml_transaction_exception
* @throws moodle_exception
*/
- public function test_admin_mail() {
+ public function test_admin_mail(): void {
$this->resetAfterTest(true);
$generator = $this->getDataGenerator()->get_plugin_generator('tool_lifecycle');
$workflow = $generator->create_workflow([], []);
diff --git a/version.php b/version.php
index e118d20..2f6b804 100644
--- a/version.php
+++ b/version.php
@@ -26,9 +26,9 @@
$plugin->version = 2023052300;
$plugin->component = 'lifecyclestep_adminapprove';
-$plugin->dependencies = array(
- 'tool_lifecycle' => 2022112400
-);
+$plugin->dependencies = [
+ 'tool_lifecycle' => 2022112400,
+];
$plugin->requires = 2020061500; // Requires Moodle 3.9+.
$plugin->release = 'v4.2-r1';
$plugin->maturity = MATURITY_STABLE;