diff --git a/README.md b/README.md
index 1c92813..fcb4918 100644
--- a/README.md
+++ b/README.md
@@ -12,9 +12,9 @@ PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see .
-@copyright 2021 coactum GmbH
+@copyright 2022 coactum GmbH
-# Discourse #
+# DisCourse #
## Description ##
@@ -27,7 +27,7 @@ In this way, the DisCourse enables the participants to work together to develop
On the overview page teachers can …
* See all phases and their deadlines and hints specified when the activity was created
-* See a brief summary of all DisCourse groups and their submission states and open the group pages for * each of these groups
+* See a brief summary of all DisCourse groups and their submission states and open the group pages for each of these groups
* Switch phases (phases can also be switched automatically by Moodle at the specified deadline)
Students can …
@@ -57,3 +57,23 @@ Students can additionally hand in a submission for the group if the phase of the
## Dependencies ##
No dependencies.
+
+## Incompatibilities ##
+- Incompatible with 3rd party plugin block_sharing_cart (https://moodle.org/plugins/block_sharing_cart). If you try to copy a DisCourse with the Sharing-Cart it may create an incomplete and unusable DisCourse.
+
+## Changelog ##
+- [1.2.0]:
+ - [Bugfix]: Deleting expired contexts via Moodle privacy mechanism now deletes all groups and groupings of a DisCourse (the grouping wich id is stored for the instance in the table mod_discourse and its groups).
+ - [Bugfix]: Deleting the whole plugin now removes all groupings connected with DisCourses (and all groups in this groupings).
+ - [Bugfix]: Renaming a DisCourse (in the edit settings, not via the quick edit option in the course) now renames groups and groupings connected with the DisCourse to its new name.
+ - [Bugfix]: Manual renaming of groups wont break the display of the shortened group names anymore.
+ - [Bugfix]: For DisCourse groups messaging is now enabled by default.
+ - [Bugfix]: If an invalid groupingid is stored for a DisCourse or the grouping stored for a DisCourse is deleted, other course groups are not displayed in the DisCourse anymore.
+ - [Feature]: Added possibility to backup and restore DisCourses via Moodle backup api.
+ - [Note]: If you restore a DisCourse within its original course Moodle does not create new groupings and groups. So no grouping is assigned with the new DisCourse and no participants or submissions are recreated.
+ - [Note]: Incompatible with 3rd party plugin block_sharing_cart (https://moodle.org/plugins/block_sharing_cart). If you try to copy a DisCourse with the Sharing-Cart it may create an incomplete and unusable DisCourse.
+ - [Feature]: DisCourses can now be included in the course reset.
+ - [Versions]: Tested for Moodle 3.9, 3.10, 3.11 and 4.0
+ - [Note]: Still uses old icon in Moodle 4.0
+ - [Known issue]: Minor display issues with some themes in Moodle 4.0 if sidebars are open and display is too small
+ - [Known issue]: After duplicating an activity in Moodle 4.0 Moodle returns the wrong activity allowed groups (for the original activity). In this case no groups but an error message is shown and the activity cant be used correctly. Teachers may just wait a few minutes, rename an activity in the course or contact the moodle administrator to clear the moodle cache to fix this issue.
diff --git a/amd/build/groupview.min.js.map b/amd/build/groupview.min.js.map
index 6d01ef0..6bb8b6e 100644
--- a/amd/build/groupview.min.js.map
+++ b/amd/build/groupview.min.js.map
@@ -1 +1 @@
-{"version":3,"sources":["../src/groupview.js"],"names":["define","$","init","click","e","preventDefault","each","hasClass","removeClass","addClass"],"mappings":"AAuBCA,OAAM,2BAAC,CAAC,QAAD,CAAD,CAAa,SAASC,CAAT,CAAY,CAC5B,MAAO,CACHC,IAAI,CAAE,eAAW,CACfD,CAAC,CAAC,YAAD,CAAD,CAAgBE,KAAhB,CAAsB,SAASC,CAAT,CAAY,CAChCA,CAAC,CAACC,cAAF,GACAJ,CAAC,CAAC,yBAAD,CAAD,CAA6BK,IAA7B,CAAkC,UAAW,CACzC,GAAIL,CAAC,CAAC,IAAD,CAAD,CAAQM,QAAR,CAAiB,MAAjB,CAAJ,CAA8B,CAC1BN,CAAC,CAAC,IAAD,CAAD,CAAQO,WAAR,CAAoB,MAApB,CACH,CAFD,IAEO,CACHP,CAAC,CAAC,IAAD,CAAD,CAAQQ,QAAR,CAAiB,MAAjB,CACH,CACJ,CAND,CAOD,CATD,CAUD,CAZE,CAcV,CAfM,CAAN","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Module for the group view a discourse.\n *\n * @module mod_discourse/group_view\n * @copyright 2021 coactum GmbH\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n define(['jquery'], function($) {\n return {\n init: function() {\n $('#id_cancel').click(function(e) {\n e.preventDefault();\n $('.collapseSubmissionForm').each(function() {\n if ($(this).hasClass('show')) {\n $(this).removeClass('show');\n } else {\n $(this).addClass('show');\n }\n });\n });\n }\n };\n});"],"file":"groupview.min.js"}
\ No newline at end of file
+{"version":3,"sources":["../src/groupview.js"],"names":["define","$","init","click","e","preventDefault","each","hasClass","removeClass","addClass"],"mappings":"AAuBCA,OAAM,2BAAC,CAAC,QAAD,CAAD,CAAa,SAASC,CAAT,CAAY,CAC5B,MAAO,CACHC,IAAI,CAAE,eAAW,CACfD,CAAC,CAAC,YAAD,CAAD,CAAgBE,KAAhB,CAAsB,SAASC,CAAT,CAAY,CAChCA,CAAC,CAACC,cAAF,GACAJ,CAAC,CAAC,yBAAD,CAAD,CAA6BK,IAA7B,CAAkC,UAAW,CACzC,GAAIL,CAAC,CAAC,IAAD,CAAD,CAAQM,QAAR,CAAiB,MAAjB,CAAJ,CAA8B,CAC1BN,CAAC,CAAC,IAAD,CAAD,CAAQO,WAAR,CAAoB,MAApB,CACH,CAFD,IAEO,CACHP,CAAC,CAAC,IAAD,CAAD,CAAQQ,QAAR,CAAiB,MAAjB,CACH,CACJ,CAND,CAOD,CATD,CAUD,CAZE,CAcV,CAfM,CAAN","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Module for the group view a discourse.\n *\n * @module mod_discourse/group_view\n * @copyright 2022 coactum GmbH\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n define(['jquery'], function($) {\n return {\n init: function() {\n $('#id_cancel').click(function(e) {\n e.preventDefault();\n $('.collapseSubmissionForm').each(function() {\n if ($(this).hasClass('show')) {\n $(this).removeClass('show');\n } else {\n $(this).addClass('show');\n }\n });\n });\n }\n };\n});"],"file":"groupview.min.js"}
\ No newline at end of file
diff --git a/amd/src/groupview.js b/amd/src/groupview.js
index 3a6e8e3..75ca85e 100644
--- a/amd/src/groupview.js
+++ b/amd/src/groupview.js
@@ -17,7 +17,7 @@
* Module for the group view a discourse.
*
* @module mod_discourse/group_view
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
diff --git a/backup/moodle2/backup_discourse_activity_task.class.php b/backup/moodle2/backup_discourse_activity_task.class.php
new file mode 100644
index 0000000..ed9b4ca
--- /dev/null
+++ b/backup/moodle2/backup_discourse_activity_task.class.php
@@ -0,0 +1,74 @@
+.
+
+/**
+ * The task that provides all the steps to perform a complete backup is defined here.
+ *
+ * @package mod_discourse
+ * @category backup
+ * @copyright 2022 coactum GmbH
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once($CFG->dirroot.'/mod/discourse/backup/moodle2/backup_discourse_stepslib.php');
+
+/**
+ * The class provides all the settings and steps to perform one complete backup of mod_discourse.
+ */
+class backup_discourse_activity_task extends backup_activity_task {
+
+ /**
+ * Defines particular settings for the plugin.
+ */
+ protected function define_my_settings() {
+ // No particular settings for this activity.
+ }
+
+ /**
+ * Defines particular steps for the backup process.
+ */
+ protected function define_my_steps() {
+ $this->add_step(new backup_discourse_activity_structure_step('discourse_structure', 'discourse.xml'));
+ }
+
+ /**
+ * Codes the transformations to perform in the activity in order to get transportable (encoded) links.
+ *
+ * @param string $content content.
+ * @return string $content content.
+ */
+ public static function encode_content_links($content) {
+ global $CFG;
+
+ $base = preg_quote($CFG->wwwroot, "/");
+
+ // Link to the list of discourses.
+ $search = "/(".$base."\/mod\/discourse\/index.php\?id\=)([0-9]+)/";
+ $content = preg_replace($search, '$@DISCOURSEINDEX*$2@$', $content);
+
+ // Link to discourse view by moduleid.
+ $search = "/(".$base."\/mod\/discourse\/view.php\?id\=)([0-9]+)/";
+ $content = preg_replace($search, '$@DISCOURSEVIEWBYID*$2@$', $content);
+
+ // Link to discourse group view by moduleid, group and userid.
+ $search = "/(".$base."\/mod\/discourse\/groupview.php\?id\=)([0-9]+)(&|&)group=([0-9]+)(&|&)userid=([0-9]+)/";
+ $content = preg_replace($search, '$@DISCOURSEGROUPVIEW*$2*$4*$6@$', $content);
+
+ return $content;
+ }
+}
diff --git a/backup/moodle2/backup_discourse_stepslib.php b/backup/moodle2/backup_discourse_stepslib.php
new file mode 100644
index 0000000..50735bd
--- /dev/null
+++ b/backup/moodle2/backup_discourse_stepslib.php
@@ -0,0 +1,89 @@
+.
+
+/**
+ * Backup steps for mod_discourse are defined here.
+ *
+ * @package mod_discourse
+ * @category backup
+ * @copyright 2022 coactum GmbH
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Define the complete structure for backup, with file and id annotations.
+ */
+class backup_discourse_activity_structure_step extends backup_activity_structure_step {
+
+ /**
+ * Defines the structure of the resulting xml file.
+ *
+ * @return backup_nested_element The structure wrapped by the common 'activity' element.
+ */
+ protected function define_structure() {
+ $userinfo = $this->get_setting_value('userinfo');
+ $groupinfo = $this->get_setting_value('groups');
+
+ // Replace with the attributes and final elements that the element will handle.
+ $discourse = new backup_nested_element('discourse', array('id'), array(
+ 'name', 'intro', 'introformat', 'timecreated', 'timemodified',
+ 'autoswitch', 'activephase', 'hintphaseone', 'hintphasetwo',
+ 'hintphasethree', 'hintphasefour', 'deadlinephaseone', 'deadlinephasetwo',
+ 'deadlinephasethree', 'deadlinephasefour', 'groupingid'));
+
+ $participants = new backup_nested_element('participants');
+
+ $participant = new backup_nested_element('participant', array('id'), array('userid', 'groupids'));
+
+ $submissions = new backup_nested_element('submissions');
+
+ $submission = new backup_nested_element('submission', array('id'), array(
+ 'groupid', 'submission', 'currentversion', 'format', 'timecreated', 'timemodified'));
+
+ // Build the tree with these elements with $discourse as the root of the backup tree.
+
+ $discourse->add_child($participants);
+ $participants->add_child($participant);
+
+ $discourse->add_child($submissions);
+ $submissions->add_child($submission);
+
+ // Define the source tables for the elements.
+
+ $discourse->set_source_table('discourse', array('id' => backup::VAR_ACTIVITYID));
+
+ if ($userinfo && $groupinfo) {
+ $participant->set_source_table('discourse_participants', array('discourse' => backup::VAR_PARENTID));
+
+ $submission->set_source_table('discourse_submissions', array('discourse' => backup::VAR_PARENTID));
+ }
+
+ // Define id annotations.
+
+ $discourse->annotate_ids('grouping', 'groupingid');
+
+ if ($userinfo && $groupinfo) {
+ $participant->annotate_ids('user', 'userid');
+ $submission->annotate_ids('group', 'groupid');
+ }
+
+ // Define file annotations.
+
+ $discourse->annotate_files('mod_discourse', 'intro', null); // This file area has no itemid.
+
+ return $this->prepare_activity_structure($discourse);
+ }
+}
diff --git a/backup/moodle2/restore_discourse_activity_task.class.php b/backup/moodle2/restore_discourse_activity_task.class.php
new file mode 100644
index 0000000..5213c28
--- /dev/null
+++ b/backup/moodle2/restore_discourse_activity_task.class.php
@@ -0,0 +1,118 @@
+.
+
+/**
+ * The task that provides a complete restore of mod_discourse is defined here.
+ *
+ * @package mod_discourse
+ * @copyright 2022 coactum GmbH
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once($CFG->dirroot.'/mod/discourse/backup/moodle2/restore_discourse_stepslib.php');
+
+/**
+ * Restore task for mod_discourse.
+ */
+class restore_discourse_activity_task extends restore_activity_task {
+
+ /**
+ * Defines particular settings that this activity can have.
+ */
+ protected function define_my_settings() {
+ return;
+ }
+
+ /**
+ * Defines particular steps that this activity can have.
+ *
+ * @return base_step.
+ */
+ protected function define_my_steps() {
+ $this->add_step(new restore_discourse_activity_structure_step('discourse_structure', 'discourse.xml'));
+ }
+
+ /**
+ * Defines the contents in the activity that must be processed by the link decoder.
+ *
+ * @return array.
+ */
+ public static function define_decode_contents() {
+ $contents = array();
+
+ // Define the contents (files in textareas).
+ $contents[] = new restore_decode_content('discourse', array('intro'), 'discourse');
+ $contents[] = new restore_decode_content('discourse_submissions', array('submission'), 'discourse_submission');
+
+ return $contents;
+ }
+
+ /**
+ * Defines the decoding rules for links belonging to the activity to be executed by the link decoder.
+ *
+ * @return array.
+ */
+ public static function define_decode_rules() {
+ $rules = array();
+
+ // Define the rules.
+
+ $rules[] = new restore_decode_rule('DISCOURSEINDEX', '/mod/discourse/index.php?id=$1', 'course');
+ $rules[] = new restore_decode_rule('DISCOURSEVIEWBYID', '/mod/discourse/view.php?id=$1', 'course_module');
+ $rules[] = new restore_decode_rule('DISCOURSEGROUPVIEW', '/mod/discourse/groupview.php?id=$1&group=$2&userid=$3',
+ array('course_module', 'groupid', 'userid'));
+
+ return $rules;
+ }
+
+ /**
+ * Defines the restore log rules that will be applied by the
+ * restore_logs_processor when restoring mod_discourse logs. It
+ * must return one array of restore_log_rule objects.
+ *
+ * @return array.
+ */
+ public static function define_restore_log_rules() {
+ $rules = array();
+
+ // Define the rules.
+ $rules[] = new restore_log_rule('discourse', 'add', 'view.php?id={course_module}', '{discourse}');
+ $rules[] = new restore_log_rule('discourse', 'update', 'view.php?id={course_module}', '{discourse}');
+ $rules[] = new restore_log_rule('discourse', 'view', 'view.php?id={course_module}', '{discourse}');
+
+ return $rules;
+ }
+
+ /**
+ * Define the restore log rules that will be applied
+ * by the restore_logs_processor when restoring
+ * course logs. It must return one array
+ * of restore_log_rule objects
+ *
+ * Note this rules are applied when restoring course logs
+ * by the restore final task, but are defined here at
+ * activity level. All them are rules not linked to any module instance (cmid = 0)
+ */
+ public static function define_restore_log_rules_for_course() {
+ $rules = array();
+
+ $rules[] = new restore_log_rule('discourse', 'view all', 'index.php?id={course}', null);
+
+ return $rules;
+ }
+}
diff --git a/backup/moodle2/restore_discourse_stepslib.php b/backup/moodle2/restore_discourse_stepslib.php
new file mode 100644
index 0000000..b412b70
--- /dev/null
+++ b/backup/moodle2/restore_discourse_stepslib.php
@@ -0,0 +1,198 @@
+.
+
+/**
+ * All the steps to restore mod_discourse are defined here.
+ *
+ * @package mod_discourse
+ * @copyright 2022 coactum GmbH
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Defines the structure step to restore one mod_discourse activity.
+ */
+class restore_discourse_activity_structure_step extends restore_activity_structure_step {
+
+ /** @var includeparticipantsandsubmissions Store whether submissions and participants should be included.
+ * Will not be included if groups/grouping information or user infos are not included in the backup.
+ */
+ protected $includeparticipantsandsubmissions = false;
+
+ /** @var newgroupingid Store the new grouping id. */
+ protected $newgroupingid = false;
+
+ /** @var newdiscourseid Store id of new discourse. */
+ protected $newdiscourseid = false;
+
+ /**
+ * Defines the structure to be restored.
+ *
+ * @return restore_path_element[].
+ */
+ protected function define_structure() {
+ $paths = array();
+
+ $userinfo = $this->get_setting_value('userinfo');
+ $groupinfo = $this->get_setting_value('groups');
+
+ $paths[] = new restore_path_element('discourse', '/activity/discourse');
+
+ if ($userinfo && $groupinfo) {
+ $paths[] = new restore_path_element('discourse_participant', '/activity/discourse/participants/participant');
+ $paths[] = new restore_path_element('discourse_submission', '/activity/discourse/submissions/submission');
+ }
+
+ return $this->prepare_activity_structure($paths);
+ }
+
+ /**
+ * Restore discourse.
+ *
+ * @param object $data data.
+ */
+ protected function process_discourse($data) {
+ global $DB;
+
+ $userinfo = $this->get_setting_value('userinfo');
+ $groupinfo = $this->get_setting_value('groups');
+
+ $data = (object)$data;
+ $oldid = $data->id;
+ $data->course = $this->get_courseid();
+
+ // Any changes to the list of dates that needs to be rolled should be same during course restore and course reset.
+ // See MDL-9367.
+ if (!isset($data->deadlinephaseone)) {
+ $data->deadlinephaseone = 0;
+ }
+ $data->deadlinephaseone = $this->apply_date_offset($data->deadlinephaseone);
+
+ if (!isset($data->deadlinephasetwo)) {
+ $data->deadlinephasetwo = 0;
+ }
+ $data->deadlinephasetwo = $this->apply_date_offset($data->deadlinephasetwo);
+
+ if (!isset($data->deadlinephasethree)) {
+ $data->deadlinephasethree = 0;
+ }
+ $data->deadlinephasethree = $this->apply_date_offset($data->deadlinephasethree);
+
+ if (!isset($data->deadlinephasefour)) {
+ $data->deadlinephasefour = 0;
+ }
+ $data->deadlinephasefour = $this->apply_date_offset($data->deadlinephasefour);
+
+ if ($userinfo && $groupinfo) {
+ $this->includeparticipantsandsubmissions = true;
+ }
+
+ if ($groupinfo) {
+ $this->newgroupingid = $this->get_mappingid('grouping', $data->groupingid);
+
+ if ($this->newgroupingid != $data->groupingid) {
+ $data->groupingid = $this->newgroupingid;
+ } else {
+ $this->newgroupingid = false;
+ $data->groupingid = 0;
+ }
+
+ if ($this->newgroupingid && $DB->record_exists('discourse', array('groupingid' => $this->newgroupingid))) {
+ $this->newgroupingid = false;
+ $data->groupingid = 0;
+ }
+ } else {
+ $this->newgroupingid = false;
+ $data->groupingid = 0;
+ }
+
+ $newitemid = $DB->insert_record('discourse', $data);
+ $this->apply_activity_instance($newitemid);
+ $this->newdiscourseid = $newitemid;
+
+ if ($groupinfo && $this->newgroupingid && $data->groupingid != 0) {
+ $groups = groups_get_all_groups($data->course, 0, $data->groupingid);
+ // Change discourse id in the new groups to the new discourse id.
+ foreach ($groups as $group) {
+ $group->idnumber = preg_replace('/discourse_[0-9]+_/', 'discourse_' . $this->newdiscourseid . '_', $group->idnumber);
+ $group->enablemessaging = 1;
+ groups_update_group($group);
+ }
+ }
+ }
+
+ /**
+ * Restore discourse participant.
+ *
+ * @param object $data data.
+ */
+ protected function process_discourse_participant($data) {
+
+ if (!$this->includeparticipantsandsubmissions || !$this->newgroupingid) {
+ return;
+ }
+
+ global $DB;
+
+ $data = (object)$data;
+ $oldid = $data->id;
+
+ $data->discourse = $this->get_new_parentid('discourse');
+ $data->userid = $this->get_mappingid('user', $data->userid);
+
+ // Update groupids for participants.
+ $newusergroups = groups_get_user_groups($this->get_courseid(), $data->userid);
+ if (isset($newusergroups[$this->newgroupingid])) {
+ $data->groupids = json_encode(array_keys($newusergroups[$this->newgroupingid]));
+ } else {
+ $data->groupids = json_encode(array());
+ }
+
+ $newitemid = $DB->insert_record('discourse_participants', $data);
+ $this->set_mapping('discourse_participant', $oldid, $newitemid);
+ }
+
+ /**
+ * Restore discourse submission.
+ *
+ * @param object $data data.
+ */
+ protected function process_discourse_submission($data) {
+
+ if (!$this->includeparticipantsandsubmissions || !$this->newgroupingid) {
+ return;
+ }
+
+ global $DB;
+
+ $data = (object)$data;
+ $oldid = $data->id;
+
+ $data->discourse = $this->get_new_parentid('discourse');
+ $data->groupid = $this->get_mappingid('group', $data->groupid);
+
+ $newitemid = $DB->insert_record('discourse_submissions', $data);
+ $this->set_mapping('discourse_submission', $oldid, $newitemid, true);
+ }
+
+ /**
+ * Defines post-execution actions.
+ */
+ protected function after_execute() {
+ // Add discourse related files, no need to match by itemname (just internally handled context).
+ $this->add_related_files('mod_discourse', 'intro', null);
+ }
+}
diff --git a/classes/event/course_module_instance_list_viewed.php b/classes/event/course_module_instance_list_viewed.php
index 1364858..f30b2d3 100644
--- a/classes/event/course_module_instance_list_viewed.php
+++ b/classes/event/course_module_instance_list_viewed.php
@@ -18,20 +18,18 @@
* The mod_discourse instance list viewed event.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_discourse\event;
-defined('MOODLE_INTERNAL') || die();
-
/**
* The mod_discourse instance list viewed event class.
*
* @package mod_discourse
* @since Moodle 3.9
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_module_instance_list_viewed extends \core\event\course_module_instance_list_viewed {
diff --git a/classes/event/course_module_viewed.php b/classes/event/course_module_viewed.php
index 985e67c..71cff3b 100644
--- a/classes/event/course_module_viewed.php
+++ b/classes/event/course_module_viewed.php
@@ -18,19 +18,18 @@
* The mod_discourse course module viewed event.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_discourse\event;
-defined('MOODLE_INTERNAL') || die();
/**
* The mod_discourse course module viewed event class.
*
* @package mod_discourse
* @since Moodle 3.9
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_module_viewed extends \core\event\course_module_viewed {
@@ -43,4 +42,11 @@ protected function init() {
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
$this->data['objecttable'] = 'discourse';
}
+
+ /**
+ * Get objectid mapping
+ */
+ public static function get_objectid_mapping() {
+ return array('db' => 'discourse', 'restore' => 'discourse');
+ }
}
diff --git a/classes/observer.php b/classes/observer.php
index 9194847..0dce10c 100644
--- a/classes/observer.php
+++ b/classes/observer.php
@@ -18,12 +18,10 @@
* Event observers used in discourse.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-defined('MOODLE_INTERNAL') || die();
-
/**
* Event observer for mod_discourse.
*/
diff --git a/classes/output/discourse_groupview.php b/classes/output/discourse_groupview.php
index cf144ca..f89c00c 100644
--- a/classes/output/discourse_groupview.php
+++ b/classes/output/discourse_groupview.php
@@ -18,11 +18,10 @@
* Class containing data for group view in discourse activity
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_discourse\output;
-defined('MOODLE_INTERNAL') || die();
use renderable;
use renderer_base;
@@ -33,7 +32,7 @@
* Class containing data for discourse_view
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class discourse_groupview implements renderable, templatable {
diff --git a/classes/output/discourse_view.php b/classes/output/discourse_view.php
index 61b9eb2..a7dec32 100644
--- a/classes/output/discourse_view.php
+++ b/classes/output/discourse_view.php
@@ -18,11 +18,10 @@
* Class containing data for discourse main page
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_discourse\output;
-defined('MOODLE_INTERNAL') || die();
use renderable;
use renderer_base;
@@ -33,7 +32,7 @@
* Class containing data for discourse_view
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class discourse_view implements renderable, templatable {
diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php
index 057e3d7..c1db627 100644
--- a/classes/privacy/provider.php
+++ b/classes/privacy/provider.php
@@ -18,7 +18,7 @@
* Privacy subsystem implementation for discourse.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -31,13 +31,12 @@
use \core_privacy\local\request\helper;
use \core_privacy\local\metadata\collection;
use \core_privacy\local\request\transform;
-
-defined('MOODLE_INTERNAL') || die();
+use core_privacy\local\request\contextlist;
/**
* Implementation of the privacy subsystem plugin provider for the discourse activity module.
*
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
@@ -65,7 +64,7 @@ public static function get_metadata(collection $items) : collection {
'groupids' => 'privacy:metadata:discourse_participants:groupids',
], 'privacy:metadata:discourse_participants');
- // The table 'discourse_submissions' stores all group subbissions.
+ // The table 'discourse_submissions' stores all group submissions.
$items->add_database_table('discourse_submissions', [
'discourse' => 'privacy:metadata:discourse_submissions:discourse',
'groupid' => 'privacy:metadata:discourse_submissions:groupid',
@@ -92,8 +91,8 @@ public static function get_metadata(collection $items) : collection {
* @param int $userid The user to search.
* @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
*/
- public static function get_contexts_for_userid(int $userid) : \core_privacy\local\request\contextlist {
- $contextlist = new \core_privacy\local\request\contextlist();
+ public static function get_contexts_for_userid(int $userid) : contextlist {
+ $contextlist = new contextlist();
$params = [
'modulename' => 'discourse',
@@ -244,7 +243,7 @@ public static function export_user_data(approved_contextlist $contextlist) {
$timemodified = null;
}
- $submissionsdata ['group ' . $submission->groupid] = [
+ $submissionsdata['group ' . $submission->groupid] = [
'discourse' => $submission->discourse,
'groupid' => $submission->groupid,
'submission' => format_text($submission->submission, $submission->format, array('para' => false)),
@@ -290,7 +289,7 @@ protected static function export_discourse_data_for_user(array $discoursedata, \
* @param context $context The specific context to delete data for.
*/
public static function delete_data_for_all_users_in_context(\context $context) {
- global $DB;
+ global $DB, $CFG;
// Check that this is a context_module.
if (!$context instanceof \context_module) {
@@ -302,6 +301,24 @@ public static function delete_data_for_all_users_in_context(\context $context) {
return;
}
+ require_once("$CFG->dirroot/group/lib.php");
+
+ if (!$DB->record_exists('discourse', array('id' => $cm->instance))) {
+ return;
+ } else {
+ $moduleinstance = $DB->get_record('discourse', array('id' => $cm->instance));
+ }
+
+ // Delete discourse groups.
+ $groups = groups_get_all_groups($moduleinstance->course, 0, $moduleinstance->groupingid);
+
+ foreach ($groups as $group) {
+ groups_delete_group($group);
+ }
+
+ // Delete discourse grouping.
+ groups_delete_grouping($moduleinstance->groupingid);
+
// Delete all records.
if ($DB->record_exists('discourse_participants', ['discourse' => $cm->instance])) {
$DB->delete_records('discourse_participants', ['discourse' => $cm->instance]);
diff --git a/classes/search/activity.php b/classes/search/activity.php
index 0ca923f..4266f87 100644
--- a/classes/search/activity.php
+++ b/classes/search/activity.php
@@ -18,19 +18,17 @@
* Search area for mod_discourse activities.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_discourse\search;
-defined('MOODLE_INTERNAL') || die();
-
/**
* Search area for mod_discourse activities.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class activity extends \core_search\base_activity {
diff --git a/classes/task/switchphases.php b/classes/task/switchphases.php
index bb6d398..9b11da0 100644
--- a/classes/task/switchphases.php
+++ b/classes/task/switchphases.php
@@ -18,19 +18,17 @@
* A cron_task class for switching phases in all discourses to be used by Tasks API.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_discourse\task;
-defined('MOODLE_INTERNAL') || die();
-
/**
* A cron_task class for switching phases in all discourses to be used by Tasks API.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class switchphases extends \core\task\scheduled_task {
diff --git a/db/access.php b/db/access.php
index 37cf9a8..36c6386 100644
--- a/db/access.php
+++ b/db/access.php
@@ -19,7 +19,7 @@
*
* @package mod_discourse
* @category access
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
diff --git a/db/events.php b/db/events.php
index 655d20c..3d31f2c 100644
--- a/db/events.php
+++ b/db/events.php
@@ -19,7 +19,7 @@
*
* @package mod_discourse
* @category event
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
diff --git a/db/install.php b/db/install.php
index fe599c5..eb031a3 100644
--- a/db/install.php
+++ b/db/install.php
@@ -19,12 +19,10 @@
*
* @package mod_discourse
* @category upgrade
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-defined('MOODLE_INTERNAL') || die();
-
/**
* Custom code to be run on installing the plugin.
*/
diff --git a/db/log.php b/db/log.php
index 83abd15..946fc7d 100644
--- a/db/log.php
+++ b/db/log.php
@@ -19,7 +19,7 @@
*
* @package mod_discourse
* @category log
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
diff --git a/db/messages.php b/db/messages.php
index f936e86..d04cea0 100644
--- a/db/messages.php
+++ b/db/messages.php
@@ -19,7 +19,7 @@
*
* @package mod_discourse
* @category message
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
diff --git a/db/tasks.php b/db/tasks.php
index de5c62d..93e039f 100644
--- a/db/tasks.php
+++ b/db/tasks.php
@@ -19,7 +19,7 @@
*
* @package mod_discourse
* @category task
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
diff --git a/db/uninstall.php b/db/uninstall.php
index df43baa..6bb9a62 100644
--- a/db/uninstall.php
+++ b/db/uninstall.php
@@ -19,26 +19,37 @@
*
* @package mod_discourse
* @category upgrade
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-defined('MOODLE_INTERNAL') || die();
-
/**
* Custom uninstallation procedure.
*/
function xmldb_discourse_uninstall() {
- // Deleting groups created by discourse activity with idnumber discourse_X_phase_x_group_X to prevent problems with already existing idsnumbers after reinstallation of plugin.
global $DB, $CFG;
require_once("$CFG->dirroot/group/lib.php");
+ // Delete all groupings associated with discourses.
+ $discourses = $DB->get_recordset('discourse');
+
+ if ($discourses->valid()) {
+ foreach ($discourses as $discourse) {
+ if (isset($discourse->groupingid) && $discourse->groupingid != 0) {
+ groups_delete_grouping($discourse->groupingid);
+ }
+ }
+
+ $discourses->close();
+ }
+
$select = "idnumber LIKE '%discourse%'";
$select .= "AND idnumber LIKE '%phase%'";
$select .= "AND idnumber LIKE '%group%'";
+ // Deleting groups created by discourse activity with idnumber discourse_X_phase_x_group_X to prevent problems with already existing idsnumbers after reinstallation of plugin.
$discoursegroups = $DB->get_recordset_select('groups', $select);
if ($discoursegroups->valid()) {
diff --git a/db/upgrade.php b/db/upgrade.php
index 2dcdccd..1721642 100644
--- a/db/upgrade.php
+++ b/db/upgrade.php
@@ -19,7 +19,7 @@
*
* @package mod_discourse
* @category upgrade
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
diff --git a/db/upgradelib.php b/db/upgradelib.php
index 388a5cd..f527949 100644
--- a/db/upgradelib.php
+++ b/db/upgradelib.php
@@ -19,12 +19,10 @@
*
* @package mod_discourse
* @category upgrade
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-defined('MOODLE_INTERNAL') || die();
-
/**
* Helper function used by the upgrade.php file.
*/
diff --git a/groupview.php b/groupview.php
index 894b0d9..279585e 100644
--- a/groupview.php
+++ b/groupview.php
@@ -18,7 +18,7 @@
* Prints the group view of mod_discourse.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
diff --git a/index.php b/index.php
index 823ce55..cc27088 100644
--- a/index.php
+++ b/index.php
@@ -18,7 +18,7 @@
* Display information about all the mod_discourse modules in the requested course.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
diff --git a/lang/de/discourse.php b/lang/de/discourse.php
index 6a0bd25..254561f 100644
--- a/lang/de/discourse.php
+++ b/lang/de/discourse.php
@@ -19,7 +19,7 @@
*
* @package mod_discourse
* @category string
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -27,7 +27,6 @@
$string['pluginname'] = 'DisKurs';
-// mod_form.php
$string['modulename'] = 'DisKurs';
$string['modulename_help'] = 'Die Aktivität DisKurs bietet die Möglichkeit, in einem mehrstufigen Verfahren Gruppendiskussionen durchzuführen.
@@ -69,15 +68,12 @@
$string['hintphasethree'] = 'Hinweis zur 2. Gruppenphase';
$string['hintphasefour'] = 'Hinweis zur Gemeinschaftsphase';
-// index.php
$string['modulenameplural'] = 'DisKurse';
$string['nonewmodules'] = 'Keine neuen DisKurse';
-// lib.php
-$string['deletealluserdata'] = 'Alle Benutzerdaten löschen';
-$string['resetting_data'] = 'TeilnehmerInnen und Einreichungen gelöscht';
+$string['deletealluserdata'] = 'Alle Benutzerdaten (Teilnehmer, Einreichungen, Gruppen und Groupings) löschen';
+$string['userdatadeleted'] = 'Benutzerdaten gelöscht';
-// locallib.php
$string['groupingdescription'] = 'Gruppierung für die DisKurs-Aktivität {$a}';
$string['phaseone'] = 'Einzelphase';
$string['phasetwo'] = '1. Gruppenphase';
@@ -86,7 +82,6 @@
$string['groupfor'] = 'Gruppe für {$a}';
$string['group'] = 'Gruppe';
-// discourse_view.mustache
$string['activephase'] = 'Aktive Phase';
$string['switchto'] = 'Wechseln zu';
$string['hint'] = 'Hinweis';
@@ -104,10 +99,8 @@
$string['shouldswitchphaseto'] = 'Der automatische Phasenwechsel ist deaktiviert. Die nächste Phase sollte aktiviert werden.';
$string['phaseswitched'] = 'Phase gewechselt.';
-// view.php
$string['view'] = 'Übersicht';
-// groupview.php
$string['groupview'] = 'Gruppenansicht';
$string['phasehint'] = 'Phasenhinweis';
$string['submissionstate'] = 'Status';
@@ -123,7 +116,6 @@
$string['errfilloutfield'] = 'Bitte Feld ausfüllen';
$string['backtooverview'] = 'Zurück zur Übersicht';
-// capabilities
$string['discourse:addinstance'] = 'Neuen DisKurs hinzufügen';
$string['discourse:potentialparticipant'] = 'DisKurs als Teilnehmer beitreten';
$string['discourse:editsubmission'] = 'Gruppentext einreichen oder bearbeiten';
@@ -132,17 +124,16 @@
$string['discourse:viewallgroups'] = 'Alle Gruppen sehen';
$string['discourse:viewgroupparticipants'] = 'Alle Gruppenteilnehmer einsehen';
-// errors
$string['groupinvalid'] = 'Gruppe nicht vorhanden';
$string['useridinvalid'] = 'Benutzer-ID ungültig';
$string['nogroupmember'] = 'Nicht möglich da kein Gruppenmitglied';
$string['submissionfaileddoubled'] = 'Einreichung fehlgeschlagen. Ein weiteres Gruppenmitglied hat bereits kürzlich eine Einreichung abgegeben.';
-$string['groupingmaybedeleted'] = 'Die zum Diskurs gehörende Gruppierung wurde gelöscht oder ist ungültig. Es werden sämtliche Kursgruppen (auch aus anderen Diskursen oder Aktivitäten) angezeigt.';
+$string['groupingmaybedeleted'] = 'Die zum Diskurs gehörende Gruppierung wurde gelöscht oder ist ungültig.';
+$string['alreadyparticipants'] = 'Bereits Teilnehmer vorhanden. Gruppen- und Teilnehmererstellung abgebrochen.';
+$string['alreadygrouping'] = 'Es ist bereits eine Gruppierung vorhanden. Gruppen- und Teilnehmererstellung abgebrochen.';
-// task
$string['task_switchphases'] = 'Automatischer Phasenwechsel';
-// privacy
$string['privacy:metadata:discourse_participants'] = 'Enthält die Gruppen aller DisKurs Teilnehmenden.';
$string['privacy:metadata:discourse_submissions'] = 'Enthält Informationen zu allen DisKurs Einreichungen.';
$string['privacy:metadata:discourse_participants:userid'] = 'Benutzer-ID der oder des Teilnehmenden';
diff --git a/lang/en/discourse.php b/lang/en/discourse.php
index afbcaea..22868ab 100644
--- a/lang/en/discourse.php
+++ b/lang/en/discourse.php
@@ -19,7 +19,7 @@
*
* @package mod_discourse
* @category string
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -71,8 +71,8 @@
$string['modulenameplural'] = 'DisCourses';
$string['nonewmodules'] = 'No new modules';
-$string['deletealluserdata'] = 'Delete all user data';
-$string['resetting_data'] = 'Participants and submissions deleted';
+$string['deletealluserdata'] = 'Delete all user data (participants, submissions, groups and groupings)';
+$string['userdatadeleted'] = 'User data deleted';
$string['groupingdescription'] = 'Grouping for DisCourse activity {$a}';
$string['phaseone'] = 'Solo phase';
@@ -128,7 +128,9 @@
$string['useridinvalid'] = 'User ID invalid';
$string['nogroupmember'] = 'Not possible because not a group member';
$string['submissionfaileddoubled'] = 'Submission failed. Another group member has already made a submission recently.';
-$string['groupingmaybedeleted'] = 'The grouping of the DisCourse was deleted or is invalid. All course groups (from other DisCourses or activities as well) will be displayed.';
+$string['groupingmaybedeleted'] = 'The grouping of the DisCourse was deleted or is invalid.';
+$string['alreadyparticipants'] = 'Participants already exist. Group and participant creation canceled.';
+$string['alreadygrouping'] = 'A grouping already exists. Group and participant creation canceled.';
$string['task_switchphases'] = 'Automatic phase switch';
diff --git a/lib.php b/lib.php
index 93e2e89..b105855 100644
--- a/lib.php
+++ b/lib.php
@@ -18,12 +18,10 @@
* Library of interface functions and constants.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-defined('MOODLE_INTERNAL') || die();
-
/**
* Indicates API features that the discourse supports.
*
@@ -41,6 +39,8 @@ function discourse_supports($feature) {
return true;
case FEATURE_SHOW_DESCRIPTION:
return true;
+ case FEATURE_BACKUP_MOODLE2:
+ return true;
case FEATURE_GROUPS:
return true;
case FEATURE_GROUPINGS:
@@ -80,6 +80,7 @@ function discourse_add_instance($discourse, mod_discourse_mod_form $mform = null
* @return void
*/
function discourse_instance_created($context, $discourse) {
+
$enrolledusers = get_enrolled_users($context, 'mod/discourse:potentialparticipant');
$discourse->create_groups_and_grouping($enrolledusers);
}
@@ -95,11 +96,44 @@ function discourse_instance_created($context, $discourse) {
* @return bool True if successful, false otherwise.
*/
function discourse_update_instance($discourse, mod_discourse_mod_form $mform = null) {
- global $DB;
+ global $DB, $CFG;
$discourse->timemodified = time();
$discourse->id = $discourse->instance;
+ $cmid = $discourse->cmid;
+ $oldname = $discourse->oldname;
+ unset($discourse->cmid);
+ unset($discourse->oldname);
+
+ // Rename groups.
+ if (isset($cmid)) {
+ if (isset($oldname) && ($discourse->name != $oldname) && $discourse->groupingid) {
+ require_once("$CFG->dirroot/group/lib.php");
+
+ list ($course, $cm) = get_course_and_cm_from_cmid($cmid, 'discourse');
+ $groups = groups_get_activity_allowed_groups($cm);
+
+ foreach ($groups as $group) {
+ $group->name = str_replace($oldname, $discourse->name, $group->name);
+
+ // Needed for groups_update_group.
+ if (strpos($group->idnumber, 'phase_1') == false) {
+ $group->enablemessaging = 1;
+ } else {
+ $group->enablemessaging = 0;
+ }
+
+ groups_update_group($group);
+ }
+
+ $grouping = groups_get_grouping($discourse->groupingid);
+ $grouping->name = $discourse->name;
+ groups_update_grouping($grouping);
+ }
+
+ }
+
return $DB->update_record('discourse', $discourse);
}
@@ -124,15 +158,22 @@ function discourse_delete_instance($id) {
$moduleinstance = $DB->get_record('discourse', array('id' => $id));
}
- // Delete discourse groups.
- $groups = groups_get_all_groups($moduleinstance->course, 0, $moduleinstance->groupingid);
+ if ($moduleinstance->groupingid != 0) {
+ // Delete discourse groups.
+ $groups = groups_get_all_groups($moduleinstance->course, 0, $moduleinstance->groupingid);
- foreach ($groups as $group) {
- groups_delete_group($group);
- }
+ foreach ($groups as $group) {
+ groups_delete_group($group);
+ }
- // Delete discourse grouping.
- groups_delete_grouping($moduleinstance->groupingid);
+ // Check if grouping is in same course as module instance
+ // (should not be neccessary but better be safe then sorry).
+ $grouping = groups_get_grouping($moduleinstance->groupingid);
+ if (!empty($grouping) && $grouping->courseid == $moduleinstance->course) {
+ // Delete discourse grouping.
+ groups_delete_grouping($moduleinstance->groupingid);
+ }
+ }
// Delete discourse participants.
if ($DB->record_exists('discourse_participants', array('discourse' => $id))) {
@@ -180,30 +221,48 @@ function discourse_reset_course_form_defaults($course) {
*/
function discourse_reset_userdata($data) {
- global $DB;
-
- $componentstr = get_string('modulenameplural', 'discourse');
$status = array();
- $params = array('course' => $data->courseid);
+ if (!empty($data->reset_discourse_all)) {
+ global $DB;
- $rs = $DB->get_recordset('discourse', $params);
+ $componentstr = get_string('modulenameplural', 'discourse');
- if ($rs->valid()) {
+ $params = array('course' => $data->courseid);
- foreach ($rs as $record) {
- if ($DB->record_exists('discourse_participants', array('discourse' => $record->id))) {
- $DB->delete_records('discourse_participants', array('discourse' => $record->id));
- }
+ $rs = $DB->get_recordset('discourse', $params);
- if ($DB->record_exists('discourse_submissions', array('discourse' => $record->id))) {
- $DB->delete_records('discourse_submissions', array('discourse' => $record->id));
+ if ($rs->valid()) {
+
+ foreach ($rs as $record) {
+ if ($DB->record_exists('discourse_participants', array('discourse' => $record->id))) {
+ $DB->delete_records('discourse_participants', array('discourse' => $record->id));
+ }
+
+ if ($DB->record_exists('discourse_submissions', array('discourse' => $record->id))) {
+ $DB->delete_records('discourse_submissions', array('discourse' => $record->id));
+ }
+
+ // Delete discourse groups.
+ $groups = groups_get_all_groups($record->course, 0, $record->groupingid);
+
+ foreach ($groups as $group) {
+ groups_delete_group($group);
+ }
+
+ // Check if grouping is in same course as module instance
+ // (should not be neccessary but better be safe then sorry).
+ $grouping = groups_get_grouping($record->groupingid);
+ if (!empty($grouping) && $grouping->courseid == $record->course) {
+ // Delete discourse grouping.
+ groups_delete_grouping($record->groupingid);
+ }
}
- }
- $rs->close();
+ $rs->close();
- $status[] = array('component' => $componentstr, 'item' => get_string('resetting_data', 'discourse'), 'error' => false);
+ $status[] = array('component' => $componentstr, 'item' => get_string('userdatadeleted', 'discourse'), 'error' => false);
+ }
}
// Updating dates - shift may be negative too.
diff --git a/locallib.php b/locallib.php
index be201a4..5ab0360 100644
--- a/locallib.php
+++ b/locallib.php
@@ -18,17 +18,15 @@
* Plugin internal classes, functions and constants are defined here.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-defined('MOODLE_INTERNAL') || die();
-
/**
* Base class for mod_discourse.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class discourse {
@@ -54,9 +52,6 @@ class discourse {
/** @var array cached list of user groups used in the discourse. */
private $groups;
- /** @var array Array of error messages encountered during the execution of discourse related operations. */
- private $errors = array();
-
/**
* Constructor for the base discourse class.
*
@@ -89,7 +84,12 @@ public function __construct($id, $d) {
$this->participants = $DB->get_records('discourse_participants', array('discourse' => $this->cm->instance), '', 'userid, discourse, groupids');
- $groups = groups_get_activity_allowed_groups($this->cm);
+ $grouping = groups_get_grouping($this->instance->groupingid);
+ if ($this->instance->groupingid && $grouping && $grouping->courseid == $this->instance->course) {
+ $groups = groups_get_activity_allowed_groups($this->cm);
+ } else {
+ $groups = array();
+ }
/**
* Helper callback function to compare group objects and sort them by name.
@@ -113,6 +113,15 @@ function compare($a, $b) {
foreach ($groups as $group) {
+ // Fix for caching bug in Moodle 4.0 where groups_get_activity_allowed_groups returns the groups of the original cm after duplicating an activity (despite the correct grouping is connected with the duplicated discourse) -> can be "fixed" by clearing the moodle cache or renaming an course activity
+ $control = $DB->get_record('groupings_groups', array('groupingid' => $this->instance->groupingid, 'groupid' => $group->id));
+ if (!$control) {
+ $groups = array();
+
+ \core\notification::add('Wrong groups found due to an internal moodle error. No groups are displayed. If this activity previously was duplicated you should just wait a few minutes and then reload your browser. If this issue remains the teacher should try renaming an activity in the course or ask the moodle administrator to clear the moodle cache to fix this error.', 'error');
+ break;
+ }
+
// Define phase of group.
if (stripos($group->idnumber, 'phase_1')) {
$group->phase = 1;
@@ -127,15 +136,23 @@ function compare($a, $b) {
}
// Get submission of group.
- $group->submission = $DB->get_record('discourse_submissions', array('groupid' => $group->id));
+ if ($DB->count_records('discourse_submissions', array('groupid' => $group->id)) <= 1) {
+ $group->submission = $DB->get_record('discourse_submissions', array('groupid' => $group->id));
+ } else {
+ $tempsubmissions = $DB->get_records('discourse_submissions', array('groupid' => $group->id));
+ $group->submission = $tempsubmissions[array_key_first($tempsubmissions)];
+ }
// Get profile link and shortened groupnames.
$groupurl = new moodle_url('/group/index.php', array('id' => $group->id[0], 'courseid' => $this->course->id));
$group->profilelink = ''.$group->name.'';
- if ($this->instance->name && strpos($group->name, $this->instance->name)) {
+ if ($this->instance->name && strpos($group->name, $this->instance->name)) { // If instance name is in group name.
$group->shortenedname = explode($this->instance->name, $group->name)[1];
$group->shortenednametwo = explode($this->instance->name, $group->name)[0] . '-' . explode($this->instance->name, $group->name)[1];
+ } else { // If instance name is not in group name (e.g. because group was manually renamed).
+ $group->shortenedname = $group->name;
+ $group->shortenednametwo = $group->name;
}
$group->participants = array();
@@ -161,8 +178,10 @@ function compare($a, $b) {
array_push($group->participants, $participant);
- if ($group->phase != 1 && $this->participants && !in_array(json_decode($this->participants[$participant->id]->groupids)[$group->phase - 2], $formergroupids)) {
- array_push($formergroupids, json_decode($this->participants[$participant->id]->groupids)[$group->phase - 2]);
+ if ($group->phase != 1 && $this->participants && $this->participants[$participant->id]
+ && !in_array(json_decode($this->participants[$participant->id]->groupids)[$group->phase - 2], $formergroupids)) {
+
+ array_push($formergroupids, json_decode($this->participants[$participant->id]->groupids)[$group->phase - 2]);
}
}
@@ -180,7 +199,11 @@ function compare($a, $b) {
$formersubmission->submission = false;
}
- $formersubmission->groupname = explode($this->instance->name, $formergroupname)[0] . '-' . explode($this->instance->name, $formergroupname)[1];
+ if (isset(explode($this->instance->name, $formergroupname)[0]) && isset(explode($this->instance->name, $formergroupname)[1])) {
+ $formersubmission->groupname = explode($this->instance->name, $formergroupname)[0] . '-' . explode($this->instance->name, $formergroupname)[1];
+ } else {
+ $formersubmission->groupname = $formergroupname;
+ }
$formersubmission->participants = implode(', ', array_column(groups_get_members($formergroupid), 'firstname', 'lastname'));
array_push($formersubmissions, $formersubmission);
@@ -329,6 +352,16 @@ public function create_groups_and_grouping($users) {
require_once("$CFG->dirroot/group/lib.php");
+ if ($DB->record_exists('discourse_participants', array('discourse' => $this->instance->id))) {
+ throw new moodle_exception('alreadyparticipants', 'mod_discourse');
+ return;
+ }
+
+ if (isset($this->instance->groupingid) && $this->instance->groupingid != 0) {
+ throw new moodle_exception('alreadygrouping', 'mod_discourse');
+ return;
+ }
+
// Create grouping for the discourse.
$grouping = new stdClass();
$grouping->courseid = $this->course->id;
@@ -353,6 +386,7 @@ public function create_groups_and_grouping($users) {
foreach ($users as $user) {
$groupdata->name = get_string('phaseone', 'mod_discourse') . ' ' . $this->instance->name . ' ' . get_string('group', 'mod_discourse') . ' ' . $i;
$groupdata->description = get_string('groupfor', 'mod_discourse', get_string('phaseone', 'mod_discourse'));
+ $groupdata->enablemessaging = 0;
$groupdata->idnumber = 'discourse_' . $this->instance->id . '_phase_' . 1 . '_group_' . $i;
$groupid = groups_create_group($groupdata);
@@ -370,7 +404,7 @@ public function create_groups_and_grouping($users) {
for ($i = 1; $i <= 4; $i ++) {
$groupdata->name = get_string('phasetwo', 'mod_discourse') . ' ' . $this->instance->name . ' ' . get_string('group', 'mod_discourse') . ' ' . $i;
$groupdata->description = get_string('groupfor', 'mod_discourse', get_string('phasetwo', 'mod_discourse'));
- $groupdata->enablemessaging = true;
+ $groupdata->enablemessaging = 1;
$groupdata->idnumber = 'discourse_' . $this->instance->id . '_phase_' . 2 . '_group_' . $i;
$groupid = groups_create_group($groupdata);
@@ -383,7 +417,7 @@ public function create_groups_and_grouping($users) {
for ($i = 5; $i <= 6; $i ++) {
$groupdata->name = get_string('phasethree', 'mod_discourse') . ' ' . $this->instance->name . ' ' . get_string('group', 'mod_discourse') . ' ' . ($i - 4);
$groupdata->description = get_string('groupfor', 'mod_discourse', get_string('phasethree', 'mod_discourse'));
- $groupdata->enablemessaging = true;
+ $groupdata->enablemessaging = 1;
$groupdata->idnumber = 'discourse_' . $this->instance->id . '_phase_' . 3 . '_group_' . ($i - 4);
$groupid = groups_create_group($groupdata);
@@ -420,7 +454,7 @@ public function create_groups_and_grouping($users) {
// Group for collaborative phase.
$groupdata->name = get_string('phasefour', 'mod_discourse') . ' ' . $this->instance->name . ' ' . get_string('group', 'mod_discourse') . ' ' . 1;
$groupdata->description = get_string('groupfor', 'mod_discourse', get_string('phasefour', 'mod_discourse'));
- $groupdata->enablemessaging = true;
+ $groupdata->enablemessaging = 1;
$groupdata->idnumber = 'discourse_' . $this->instance->id . '_phase_' . 4 . '_group_' . 1;
$groupid = groups_create_group($groupdata);
diff --git a/mod_form.php b/mod_form.php
index 468c37f..e3649f5 100644
--- a/mod_form.php
+++ b/mod_form.php
@@ -18,13 +18,11 @@
* The main mod_discourse configuration form.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-if (!defined('MOODLE_INTERNAL')) {
- die('Direct access to this script is forbidden.'); // It must be included from a Moodle page.
-}
+defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot.'/course/moodleform_mod.php');
require_once($CFG->dirroot . '/mod/discourse/locallib.php');
@@ -33,7 +31,7 @@
* Module instance settings form.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mod_discourse_mod_form extends moodleform_mod {
@@ -46,11 +44,22 @@ public function definition() {
$id = optional_param('update', null, PARAM_INT);
+ $mform = $this->_form;
+
if (isset($id) && $id !== 0) {
$discourse = discourse::get_discourse_instance($id);
- }
- $mform = $this->_form;
+ // For updating group names.
+ $mform->addElement('hidden', 'cmid', $id);
+ $mform->setType('cmid', PARAM_INT);
+
+ $mform->addElement('hidden', 'oldname', $discourse->get_module_instance()->name);
+ if (!empty($CFG->formatstringstriptags)) {
+ $mform->setType('oldname', PARAM_TEXT);
+ } else {
+ $mform->setType('oldname', PARAM_CLEANHTML);
+ }
+ }
// Adding the "general" fieldset, where all the common settings are showed.
$mform->addElement('header', 'general', get_string('general', 'form'));
diff --git a/renderer.php b/renderer.php
index ac7c763..99e1a2c 100644
--- a/renderer.php
+++ b/renderer.php
@@ -18,17 +18,15 @@
* Renderer class for discourse
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-defined('MOODLE_INTERNAL') || die();
-
/**
* Renderer class for discourse
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class renderer extends plugin_renderer_base {
diff --git a/submit_form.php b/submit_form.php
index 3318601..8e80d05 100644
--- a/submit_form.php
+++ b/submit_form.php
@@ -18,7 +18,7 @@
* File containing the class definition for the submit form for the discourse module.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -31,7 +31,7 @@
* Form for submissions.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL Juv3 or later
*/
class submit_form extends moodleform {
diff --git a/templates/discourse_groupview.mustache b/templates/discourse_groupview.mustache
index 812fdf6..3cb37c4 100644
--- a/templates/discourse_groupview.mustache
+++ b/templates/discourse_groupview.mustache
@@ -15,7 +15,7 @@
along with Moodle. If not, see .
}}
{{!
- @copyright 2021 coactum GmbH
+ @copyright 2022 coactum GmbH
@template discourse/discourse_groupview
Group view.
diff --git a/templates/discourse_view.mustache b/templates/discourse_view.mustache
index ba84b36..55831d8 100644
--- a/templates/discourse_view.mustache
+++ b/templates/discourse_view.mustache
@@ -15,7 +15,7 @@
along with Moodle. If not, see .
}}
{{!
- @copyright 2021 coactum GmbH
+ @copyright 2022 coactum GmbH
@template discourse/discourse_view
Overview.
diff --git a/version.php b/version.php
index f45b91a..a8c48ba 100644
--- a/version.php
+++ b/version.php
@@ -18,14 +18,14 @@
* Plugin version and other meta-data are defined here.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'mod_discourse';
-$plugin->release = '1.1.2';
-$plugin->version = 2022010700;
+$plugin->release = '1.2.0';
+$plugin->version = 2022081800;
$plugin->requires = 2020061500;
$plugin->maturity = MATURITY_STABLE;
diff --git a/view.php b/view.php
index 4f28ae4..9b68667 100644
--- a/view.php
+++ b/view.php
@@ -18,7 +18,7 @@
* Prints an instance of mod_discourse.
*
* @package mod_discourse
- * @copyright 2021 coactum GmbH
+ * @copyright 2022 coactum GmbH
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/