From 715e1320ea7bfda7c4a770767b2b1fc6b88a6807 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Tue, 13 Jun 2023 17:52:15 +0200
Subject: [PATCH 01/56] new class for interacting with posts
---
classes/post.php | 96 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 96 insertions(+)
create mode 100644 classes/post.php
diff --git a/classes/post.php b/classes/post.php
new file mode 100644
index 0000000000..e7ef784830
--- /dev/null
+++ b/classes/post.php
@@ -0,0 +1,96 @@
+.
+
+/**
+ * Class for working with posts
+ *
+ * @package mod_moodleoverflow
+ * @copyright 2023 Tamaro Walter
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+namespace mod_moodleoverflow;
+
+// Import namespace from the locallib, needs a check later which namespaces are really needed
+use mod_moodleoverflow\anonymous;
+use mod_moodleoverflow\capabilities;
+use mod_moodleoverflow\review;
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once(dirname(__FILE__) . '/lib.php');
+
+/**
+ * Class that represents a post.
+ *
+ * @package mod_moodleoverflow
+ * @copyright 2023 Tamaro Walter
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class post {
+ /**
+ * Wie funktioniert das erstellen, ändern und löschen eines posts?
+ * Was mach die post.php und die classes/post_form.php, wozu sind post.mustache und post_dummy.mustache da?
+ * Welche funktionen zu den posts hat die locallib.php?
+ *
+ * => Was sollte in diese Klasse (classes/post.php) integriert werden, was sollte sie können? Was lässt man in der post.php/locallib.php, braucht man später die postform noch?
+ *
+ * Funktionen aus der Locallib, die mit posts zu tun haben:
+ * - function moodleoverflow_get_post_full($postid) -> holt infos um einen post zu printen
+ * - function moodleoverflow_user_can_see_post($moodleoverflow, $discussion, $post, $cm)
+ * - function moodleoverflow_get_all_discussion_posts($discussionid, $tracking, $modcontext) -> holt sich die posts einer discussion
+ * - function moodleoverflow_print_post(...)
+ * - function moodleoverflow_print_posts_nested
+ * - function get_attachments($post, $cm) ->
+ * - function moodleoverflow_add_attachment($post, $forum, $cm) {
+ * - function moodleoverflow_add_new_post($post) {
+ * - function moodleoverflow_update_post($newpost) {
+ * - function moodleoverflow_count_replies($post, $onlyreviewed) -> zählt antworten auf eine frage
+ * - function moodleoverflow_delete_post($post, $deletechildren, $cm, $moodleoverflow) {
+ * - function moodleoverflow_add_discussion($discussion, $modulecontext, $userid = null) {
+ *
+ *
+ * Vorüberlegung zu classes/post.php:
+ * - Jeder Post im moodleoverflow ist ein Objekt identifizierbar über seine ID
+ * - Bei der erstellung einer neuen Diskussion (automatisch mit einem post) oder beim antworten/kommentieren soll ein neues objekt DIESER Klasse erstellt werden
+ * => realisierung der funktionen add_new_post, update_post, delete_post
+ *
+ * - Die funkionen:
+ * - get_post_full, print_post,
+ * - add_attachment und get_attachments
+ * sollten auch hier programmiert sein.
+ *
+ * - Diese Funktionen sollten in der Locallib bleiben:
+ * - user_can_see_post, da es von außen nur auf einen existierenden post zugreift
+ * - get_all_discussion_posts, da ein post nicht weitere posts in seiner umgebung kennt (außer seinen Elternpost)
+ * - print_post_nested, auch hier der gleiche grund, außerdem ruft print_post_nested auch nur print_posts_nested und geht zum nächsten Post
+ * - count_replies, da hier eine sammlung von posts abgeprüft wird.
+ * - vielleicht auch noch add_discussion()
+ *
+ *
+ *
+ * Wie funktionieren post.php und classes/post_form.php?
+ *
+ * post.php:
+ * Bei jeder art von Interaktion (erstellen, ändern, löschen) wird die post.php aufgerufen
+ * => Im 1. Schritt wird geprüft, welche Art von Interaktion vorliegt. -> vielliecht auch das in classes/post.php auslagern
+ * => Im 2. Schritt wird ein neues post_form Objekt gebaut (Was macht das objekt genau? Wahrscheinlich kann man das auch auslagern)
+ *
+ *
+ * classes/post_form.php:
+ */
+}
\ No newline at end of file
From 6eece3e4e40ceed8838ab25ada5e8e37deff5c5f Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Mon, 19 Jun 2023 17:19:36 +0200
Subject: [PATCH 02/56] WIP: class diagram for new structure
---
classes/post.drawio | 24 ++++++++++++++++++++++++
classes/post.php | 7 +++----
2 files changed, 27 insertions(+), 4 deletions(-)
create mode 100644 classes/post.drawio
diff --git a/classes/post.drawio b/classes/post.drawio
new file mode 100644
index 0000000000..b570918313
--- /dev/null
+++ b/classes/post.drawio
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/classes/post.php b/classes/post.php
index e7ef784830..adcf651294 100644
--- a/classes/post.php
+++ b/classes/post.php
@@ -79,10 +79,9 @@ class post {
* - get_all_discussion_posts, da ein post nicht weitere posts in seiner umgebung kennt (außer seinen Elternpost)
* - print_post_nested, auch hier der gleiche grund, außerdem ruft print_post_nested auch nur print_posts_nested und geht zum nächsten Post
* - count_replies, da hier eine sammlung von posts abgeprüft wird.
- * - vielleicht auch noch add_discussion()
- *
- *
- *
+ * - add_discussion() bleibt in der locallib, da hier nur die construct methode (add_new_post()) aufgerufen wird.
+ *
+ *
* Wie funktionieren post.php und classes/post_form.php?
*
* post.php:
From e6298dd120b967e1e52f2f2e5c4ad750f6efcbc9 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Tue, 20 Jun 2023 17:06:22 +0200
Subject: [PATCH 03/56] WIP: class diagram
---
classes/post.drawio | 61 +++++++++++++++++++++++++++++++++++++++------
classes/post.php | 6 ++++-
2 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/classes/post.drawio b/classes/post.drawio
index b570918313..4494d71c20 100644
--- a/classes/post.drawio
+++ b/classes/post.drawio
@@ -1,22 +1,69 @@
-
+
-
-
+
+
-
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/classes/post.php b/classes/post.php
index adcf651294..354eadfef3 100644
--- a/classes/post.php
+++ b/classes/post.php
@@ -73,6 +73,7 @@ class post {
* - get_post_full, print_post,
* - add_attachment und get_attachments
* sollten auch hier programmiert sein.
+ * Es soll auch möglich sein, den Elternpost, die Diskussion oder das Moodleoverflow als objekt zurückzugeben, damit alle Datenbankaufrufe hier passieren und nicht woanders.
*
* - Diese Funktionen sollten in der Locallib bleiben:
* - user_can_see_post, da es von außen nur auf einen existierenden post zugreift
@@ -82,14 +83,17 @@ class post {
* - add_discussion() bleibt in der locallib, da hier nur die construct methode (add_new_post()) aufgerufen wird.
*
*
+ *
+ *
* Wie funktionieren post.php und classes/post_form.php?
*
* post.php:
* Bei jeder art von Interaktion (erstellen, ändern, löschen) wird die post.php aufgerufen
* => Im 1. Schritt wird geprüft, welche Art von Interaktion vorliegt. -> vielliecht auch das in classes/post.php auslagern
- * => Im 2. Schritt wird ein neues post_form Objekt gebaut (Was macht das objekt genau? Wahrscheinlich kann man das auch auslagern)
+ * => Im 2. Schritt wird ein neues post_form Objekt gebaut und dem objekt neue funktionen übergeben
*
*
* classes/post_form.php:
+ * Bildet nur die form ab, wo man den titel, Inhalt und attachments seines posts eintragen kann
*/
}
\ No newline at end of file
From 82fd83ec25cddc32e0e56f271772b1a37f617954 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Tue, 20 Jun 2023 18:12:12 +0200
Subject: [PATCH 04/56] WIP: better class diagram
---
classes/post.drawio | 98 +++++++++++++++++++++++++++++++++++----------
1 file changed, 76 insertions(+), 22 deletions(-)
diff --git a/classes/post.drawio b/classes/post.drawio
index 4494d71c20..bfb1994bd1 100644
--- a/classes/post.drawio
+++ b/classes/post.drawio
@@ -1,11 +1,11 @@
-
+
-
+
@@ -15,55 +15,109 @@
-
+
-
+
-
+
-
+
-
+
-
-
+
+
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
From be057c9438b7f9266b4bb0d3d604d1d4e263e4b7 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Mon, 26 Jun 2023 14:33:16 +0200
Subject: [PATCH 05/56] WIP write post_control class
---
classes/post/post.control.php | 208 +++++++++++++++++++++++++++++++++
classes/{ => post}/post.drawio | 0
classes/{ => post}/post.php | 2 +-
lang/en/moodleoverflow.php | 3 +-
4 files changed, 211 insertions(+), 2 deletions(-)
create mode 100644 classes/post/post.control.php
rename classes/{ => post}/post.drawio (100%)
rename classes/{ => post}/post.php (99%)
diff --git a/classes/post/post.control.php b/classes/post/post.control.php
new file mode 100644
index 0000000000..03a9f4ff4e
--- /dev/null
+++ b/classes/post/post.control.php
@@ -0,0 +1,208 @@
+.
+
+/**
+ * Class that is important to interact with posts.
+ *
+ * @package mod_moodleoverflow
+ * @copyright 2023 Tamaro Walter
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+namespace mod_moodleoverflow\post;
+
+// Import namespace from the locallib, needs a check later which namespaces are really needed.
+use mod_moodleoverflow\anonymous;
+use mod_moodleoverflow\capabilities;
+use mod_moodleoverflow\review;
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once(dirname(__FILE__) . '/lib.php');
+
+/**
+ * Class that makes checks to interact with posts.
+ *
+ * @package mod_moodleoverflow
+ * @copyright 2023 Tamaro Walter
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class post_control {
+
+ /** @var string the Interaction type */
+ private $interaction;
+
+ /** @var object information about the post like it's moodleoverflow and other */
+ private $information;
+
+ /** @var object prepost for the classes/post/post_form.php */
+ private $prepost;
+
+ /**
+ * Constructor
+ *
+ * @param object $urlparameter Parameter that were sent when post.php where opened
+ */
+ public function __construct($urlparameter) {
+ $this->information = new \stdClass;
+ $this->detect_interaction($urlparameter); // Detects interaction and makes security checks.
+ }
+
+ public function get_interaction() {
+ return $this->interaction;
+ }
+
+ public function get_information() {
+ return $this->information;
+ }
+
+ private function security_checks_create($moodleoverflowid) {
+ global $DB, $SESSION;
+ // Check the moodleoverflow instance is valid.
+ if (!$this->information->moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflowid))) {
+ throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
+ }
+ // Get the related course.
+ if (!$this->information->course = $DB->get_record('course', array('id' => $this->information->moodleoverflow->course))) {
+ throw new moodle_exception('invalidcourseid');
+ }
+ // Get the related coursemodule.
+ if (!$this->information->cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflowid,
+ $this->information->course->id)) {
+ throw new moodle_exception('invalidcoursemodule');
+ }
+ // Retrieve the contexts.
+ $this->information->modulecontext = context_module::instance($this->information->cm->id);
+ $this->information->coursecontext = context_module::instance($this->information->course->id);
+
+ // Check if the user can start a new discussion.
+ if (!moodleoverflow_user_can_post_discussion($this->information->moodleoverflow,
+ $this->information->cm,
+ $this->information->modulecontext)) {
+
+ // Catch unenrolled user.
+ if (!isguestuser() && !is_enrolled($this->information->coursecontext)) {
+ if (enrol_selfenrol_available($this->information->course->id)) {
+ $SESSION->wantsurl = qualified_me();
+ $SESSION->enrolcancel = get_local_referer(false);
+ redirect(new moodle_url('/enrol/index.php', array(
+ 'id' => $course->id,
+ 'returnurl' => '/mod/moodleoverflow/view.php?m=' . $this->information->moodleoverflow->id
+ )), get_string('youneedtoenrol'));
+ }
+ }
+
+ // Notify the user, that he can not post a new discussion.
+ throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
+ }
+ // Where is the user coming from?
+ $SESSION->fromurl = get_local_referer(false);
+
+ // Load all the $post variables.
+ $this->prepost = new stdClass();
+ $this->prepost->course = $this->information->course->id;
+ $this->prepost->moodleoverflow = $this->information->moodleoverflow->id;
+ $this->prepost->discussion = 0;
+ $this->prepost->parent = 0;
+ $this->prepost->subject = '';
+ $this->prepost->userid = $USER->id;
+ $this->prepost->message = '';
+
+ // Unset where the user is coming from.
+ // Allows to calculate the correct return url later.
+ unset($SESSION->fromdiscussion);
+ }
+
+ private function security_checks_edit($postid) {
+ global $DB;
+
+ }
+
+ private function security_checks_reply($replypostid) {
+ global $DB;
+ // Check if the related post exists.
+ if (!$this->information->parent = moodleoverflow_get_post_full($replypostid)) {
+ throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
+ }
+
+ // Check if the post is part of a valid discussion.
+ if (!$this->information->discussion = $DB->get_record('moodleoverflow_discussions',
+ array('id' => $this->information->parent->discussion))) {
+ throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
+ }
+
+ // Check if the post is related to a valid moodleoverflow instance.
+ if (!$this->information->moodleoverflow = $DB->get_record('moodleoverflow',
+ array('id' => $this->information->discussion->moodleoverflow))) {
+ throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
+ }
+
+ // Check if the moodleoverflow instance is part of a course.
+ if (!$this->information->course = $DB->get_record('course', array('id' => $this->information->discussion->course))) {
+ throw new moodle_exception('invalidcourseid');
+ }
+
+ // Retrieve the related coursemodule.
+ if (!$this->information->cm = get_coursemodule_from_instance('moodleoverflow',
+ $this->information->moodleoverflow->id,
+ $this->information->course->id)) {
+ throw new moodle_exception('invalidcoursemodule');
+ }
+ }
+
+ private function security_checks_delete($deletepostid) {
+ global $DB;
+ }
+
+ /**
+ * Detects the interaction
+ * @param object parameter from the post.php
+ */
+ private function detect_interaction($urlparameter) {
+ $count = 0;
+ $count += $urlparameter->create ? 1 : 0;
+ $count += $urlparameter->reply ? 1 : 0;
+ $count += $urlparameter->edit ? 1 : 0;
+ $count += $urlparameter->delete ? 1 : 0;
+ if ($count !== 1) {
+ throw new coding_exception('Exactly one parameter should be specified!');
+ }
+
+ if ($urlparameter->create) {
+ $this->interaction = 'create';
+ $this->information->moodleoverflowid = $urlparameter->create;
+ $this->security_checks_create($this->information->moodleoverflowid);
+
+ } else if ($urlparameter->edit) {
+ $this->interaction = 'edit';
+ $this->information->editpostid = $urlparameter->edit;
+ $this->security_checks_edit($this->information->editpostid);
+
+ } else if ($urlparameter->reply) {
+ $this->interaction = 'reply';
+ $this->information->replypostid = $urlparameter->edit;
+ $this->security_checks_reply($this->information->replypostid);
+
+ } else if ($urlparameter->delete) {
+ $this->interaction = 'delete';
+ $this->information->deletepostid = $urlparameter->edit;
+ $this->security_checks_delete($this->information->deletepostid);
+ } else {
+ throw new moodle_exception('unknownparameter', 'moodleoverflow');
+ }
+ }
+}
diff --git a/classes/post.drawio b/classes/post/post.drawio
similarity index 100%
rename from classes/post.drawio
rename to classes/post/post.drawio
diff --git a/classes/post.php b/classes/post/post.php
similarity index 99%
rename from classes/post.php
rename to classes/post/post.php
index 354eadfef3..a43a527bc4 100644
--- a/classes/post.php
+++ b/classes/post/post.php
@@ -23,7 +23,7 @@
*/
-namespace mod_moodleoverflow;
+namespace mod_moodleoverflow\post;
// Import namespace from the locallib, needs a check later which namespaces are really needed
use mod_moodleoverflow\anonymous;
diff --git a/lang/en/moodleoverflow.php b/lang/en/moodleoverflow.php
index 23955a1580..a40da7ff5c 100644
--- a/lang/en/moodleoverflow.php
+++ b/lang/en/moodleoverflow.php
@@ -122,7 +122,7 @@
$string['maxmailingtime'] = 'Maximal mailing time';
$string['configmaxmailingtime'] = 'Posts older than this number of hours will not be mailed to the users. This will help to avoid problems where the cron has not been running for a long time.';
-// Strings for the post.php.
+// Strings for the post.php environment.
$string['invalidmoodleoverflowid'] = 'Forum ID was incorrect';
$string['invalidparentpostid'] = 'Parent post ID was incorrect';
$string['notpartofdiscussion'] = 'This post is not part of a discussion!';
@@ -147,6 +147,7 @@
$string['couldnotdeletereplies'] = 'Sorry, that cannot be deleted as people have already responded to it';
$string['errorwhiledelete'] = 'An error occurred while deleting record.';
$string['couldnotdeletereplies'] = 'Sorry, that cannot be deleted as people have already responded to it';
+$string['unknownparameter'] = 'unknown parameter specified';
// Strings for the classes/mod_form.php.
$string['subject'] = 'Subject';
From f9bac431ad05ed4a8c26a0c5d595b698d96921d2 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Tue, 27 Jun 2023 18:06:44 +0200
Subject: [PATCH 06/56] First stage of post_control ready
---
classes/post/post.control.php | 310 ++++++++++++++++++++++++++++------
classes/post/post.drawio | 59 ++++---
classes/post/post.php | 41 +++--
lang/en/moodleoverflow.php | 1 -
4 files changed, 316 insertions(+), 95 deletions(-)
diff --git a/classes/post/post.control.php b/classes/post/post.control.php
index 03a9f4ff4e..ca76b921c9 100644
--- a/classes/post/post.control.php
+++ b/classes/post/post.control.php
@@ -46,7 +46,7 @@ class post_control {
/** @var string the Interaction type */
private $interaction;
- /** @var object information about the post like it's moodleoverflow and other */
+ /** @var object information about the post like the related moodleoverflow, post etc. .*/
private $information;
/** @var object prepost for the classes/post/post_form.php */
@@ -55,23 +55,83 @@ class post_control {
/**
* Constructor
*
- * @param object $urlparameter Parameter that were sent when post.php where opened
+ * @param object $urlparameter Parameter that were sent when post.php where opened.
*/
public function __construct($urlparameter) {
$this->information = new \stdClass;
$this->detect_interaction($urlparameter); // Detects interaction and makes security checks.
}
+ /**
+ * Returns the interaction type.
+ */
public function get_interaction() {
return $this->interaction;
}
+ /**
+ * Returns the gathered important information in the build_prepost_() functions.
+ */
public function get_information() {
return $this->information;
}
- private function security_checks_create($moodleoverflowid) {
- global $DB, $SESSION;
+ /**
+ * Retuns the prepared post.
+ */
+ public function get_prepost() {
+ return $this->information;
+ }
+
+ /**
+ * Detects the interaction
+ * @param object $urlparamter parameter from the post.php .
+ */
+ private function detect_interaction($urlparameter) {
+ $count = 0;
+ $count += $urlparameter->create ? 1 : 0;
+ $count += $urlparameter->reply ? 1 : 0;
+ $count += $urlparameter->edit ? 1 : 0;
+ $count += $urlparameter->delete ? 1 : 0;
+ if ($count !== 1) {
+ throw new coding_exception('Exactly one parameter should be specified!');
+ }
+
+ if ($urlparameter->create) {
+ $this->interaction = 'create';
+ $this->information->moodleoverflowid = $urlparameter->create;
+ $this->build_prepost_create($this->information->moodleoverflowid);
+
+ } else if ($urlparameter->edit) {
+ $this->interaction = 'edit';
+ $this->information->editpostid = $urlparameter->edit;
+ $this->build_prepost_edit($this->information->editpostid);
+
+ } else if ($urlparameter->reply) {
+ $this->interaction = 'reply';
+ $this->information->replypostid = $urlparameter->edit;
+ $this->build_prepost_reply($this->information->replypostid);
+
+ } else if ($urlparameter->delete) {
+ $this->interaction = 'delete';
+ $this->information->deletepostid = $urlparameter->edit;
+ $this->build_prepost_delete($this->information->deletepostid);
+ } else {
+ throw new moodle_exception('unknownaction');
+ }
+ }
+
+ // Private functions.
+
+ // Build_prepost functions: makes important checks and saves all important information in $prepost object.
+
+ /**
+ * Function to prepare a new discussion in moodleoverflow.
+ *
+ * @param int $moodleoverflowid The ID of the moodleoverflow where the new discussion post is being created.
+ */
+ private function build_prepost_create($moodleoverflowid) {
+ global $DB, $SESSION, $USER;
// Check the moodleoverflow instance is valid.
if (!$this->information->moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflowid))) {
throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
@@ -99,25 +159,25 @@ private function security_checks_create($moodleoverflowid) {
if (enrol_selfenrol_available($this->information->course->id)) {
$SESSION->wantsurl = qualified_me();
$SESSION->enrolcancel = get_local_referer(false);
- redirect(new moodle_url('/enrol/index.php', array(
- 'id' => $course->id,
- 'returnurl' => '/mod/moodleoverflow/view.php?m=' . $this->information->moodleoverflow->id
- )), get_string('youneedtoenrol'));
+ redirect(new moodle_url('/enrol/index.php',
+ array('id' => $this->information->course->id,
+ 'returnurl' => '/mod/moodleoverflow/view.php?m=' .
+ $this->information->moodleoverflow->id)),
+ get_string('youneedtoenrol'));
}
}
-
// Notify the user, that he can not post a new discussion.
throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
}
// Where is the user coming from?
$SESSION->fromurl = get_local_referer(false);
- // Load all the $post variables.
+ // Prepare the post.
$this->prepost = new stdClass();
- $this->prepost->course = $this->information->course->id;
- $this->prepost->moodleoverflow = $this->information->moodleoverflow->id;
- $this->prepost->discussion = 0;
- $this->prepost->parent = 0;
+ $this->prepost->courseid = $this->information->course->id;
+ $this->prepost->moodleoverflowid = $this->information->moodleoverflow->id;
+ $this->prepost->discussionid = 0;
+ $this->prepost->parentid = 0;
$this->prepost->subject = '';
$this->prepost->userid = $USER->id;
$this->prepost->message = '';
@@ -127,13 +187,13 @@ private function security_checks_create($moodleoverflowid) {
unset($SESSION->fromdiscussion);
}
- private function security_checks_edit($postid) {
- global $DB;
-
- }
-
- private function security_checks_reply($replypostid) {
- global $DB;
+ /**
+ * Function to prepare a new post that replies to an existing post.
+ *
+ * @param int $replypostid The ID of the post that is being answered.
+ */
+ private function build_prepost_reply($replypostid) {
+ global $DB, $PAGE, $SESSION, $USER;
// Check if the related post exists.
if (!$this->information->parent = moodleoverflow_get_post_full($replypostid)) {
throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
@@ -162,47 +222,195 @@ private function security_checks_reply($replypostid) {
$this->information->course->id)) {
throw new moodle_exception('invalidcoursemodule');
}
+
+ // Ensure the coursemodule is set correctly.
+ $PAGE->set_cm($this->information->cm, $this->information->course, $this->information->moodleoverflow);
+
+ // Retrieve the contexts.
+ $this->information->modulecontext = context_module::instance($this->information->cm->id);
+ $this->information->coursecontext = context_module::instance($this->information->course->id);
+
+ // Check whether the user is allowed to post.
+ if (!moodleoverflow_user_can_post($this->information->modulecontext, $this->information->parent)) {
+
+ // Give the user the chance to enroll himself to the course.
+ if (!isguestuser() && !is_enrolled($this->information->coursecontext)) {
+ $SESSION->wantsurl = qualified_me();
+ $SESSION->enrolcancel = get_local_referer(false);
+ redirect(new moodle_url('/enrol/index.php',
+ array('id' => $this->information->course->id,
+ 'returnurl' => '/mod/moodleoverflow/view.php?m=' .
+ $this->information->moodleoverflow->id)),
+ get_string('youneedtoenrol'));
+ }
+ // Print the error message.
+ throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
+ }
+ // Make sure the user can post here.
+ if (!$this->information->cm->visible &&
+ !has_capability('moodle/course:viewhiddenactivities', $this->information->modulecontext)) {
+
+ throw new moodle_exception('activityiscurrentlyhidden');
+ }
+
+ // Prepare a post.
+ $this->prepost = new stdClass();
+ $this->prepost->courseid = $this->information->course->id;
+ $this->prepost->moodleoverflowid = $this->information->moodleoverflow->id;
+ $this->prepost->discussionid = $this->information->discussion->id;
+ $this->prepost->parentid = $this->information->parent->id;
+ $this->prepost->subject = $this->information->discussion->name;
+ $this->prepost->userid = $USER->id;
+ $this->prepost->message = '';
+
+ // Append 'RE: ' to the discussions subject.
+ $strre = get_string('re', 'moodleoverflow');
+ if (!(substr($this->prepost->subject, 0, strlen($strre)) == $strre)) {
+ $this->prepost->subject = $strre . ' ' . $this->prepost->subject;
+ }
+
+ // Unset where the user is coming from.
+ // Allows to calculate the correct return url later.
+ unset($SESSION->fromdiscussion);
}
- private function security_checks_delete($deletepostid) {
- global $DB;
+ /**
+ * Function to prepare the edit of an existing post.
+ *
+ * @param int $editpostid The ID of the post that is being edited.
+ */
+ private function build_prepost_edit($editpostid) {
+ global $DB, $PAGE, $SESSION, $USER;
+
+ // Third possibility: The user is editing his own post.
+
+ // Check if the submitted post exists.
+ if (!$this->information->relatedpost = moodleoverflow_get_post_full($editpostid)) {
+ throw new moodle_exception('invalidpostid', 'moodleoverflow');
+ }
+
+ // Get the parent post of this post if it is not the starting post of the discussion.
+ if ($this->information->relatedpost->parent) {
+ if (!$this->information->parent = moodleoverflow_get_post_full($this->information->relatedpost->parent)) {
+ throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
+ }
+ }
+
+ // Check if the post refers to a valid discussion.
+ if (!$this->information->discussion = $DB->get_record('moodleoverflow_discussions',
+ array('id' => $this->information->relatedpost->discussion))) {
+ throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
+ }
+
+ // Check if the post refers to a valid moodleoverflow instance.
+ if (!$this->information->moodleoverflow = $DB->get_record('moodleoverflow',
+ array('id' => $this->information->discussion->moodleoverflow))) {
+ throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
+ }
+
+ // Check if the post refers to a valid course.
+ if (!$this->information->course = $DB->get_record('course', array('id' => $this->information->discussion->course))) {
+ throw new moodle_exception('invalidcourseid');
+ }
+
+ // Retrieve the related coursemodule.
+ if (!$this->information->cm = get_coursemodule_from_instance('moodleoverflow',
+ $this->information->moodleoverflow->id,
+ $this->information->course->id)) {
+ throw new moodle_exception('invalidcoursemodule');
+ }
+
+ // Retrieve contexts.
+ $this->information->modulecontext = context_module::instance($this->information->cm->id);
+
+ // Set the pages context.
+ $PAGE->set_cm($this->information->cm, $this->information->course, $this->information->moodleoverflow);
+
+ // Check if the post can be edited.
+ $beyondtime = ((time() - $this->information->relatedpost->created) > get_config('moodleoverflow', 'maxeditingtime'));
+ $alreadyreviewed = review::should_post_be_reviewed($this->information->relatedpost, $this->information->moodleoverflow)
+ && $this->information->relatedpost->reviewed;
+ if (($beyondtime || $alreadyreviewed) && !has_capability('mod/moodleoverflow:editanypost',
+ $this->information->modulecontext)) {
+
+ throw new moodle_exception('maxtimehaspassed', 'moodleoverflow', '',
+ format_time(get_config('moodleoverflow', 'maxeditingtime')));
+ }
+
+ // If the current user is not the one who posted this post.
+ if ($this->information->relatedpost->userid <> $USER->id) {
+
+ // Check if the current user has not the capability to edit any post.
+ if (!has_capability('mod/moodleoverflow:editanypost', $this->information->modulecontext)) {
+
+ // Display the error. Capabilities are missing.
+ throw new moodle_exception('cannoteditposts', 'moodleoverflow');
+ }
+ }
+
+ // Load the $post variable.
+ $this->prepost = $this->information->relatedpost;
+ $this->prepost->editid = $editpostid;
+ $this->prepost->course = $this->information->course->id;
+ $this->prepost->moodleoverflow = $this->information->moodleoverflow->id;
+
+ // Unset where the user is coming from.
+ // Allows to calculate the correct return url later.
+ unset($SESSION->fromdiscussion);
}
/**
- * Detects the interaction
- * @param object parameter from the post.php
+ * Function to prepare the deletion of a post.
+ *
+ * @param int $deletepostid The ID of the post that is being deleted.
*/
- private function detect_interaction($urlparameter) {
- $count = 0;
- $count += $urlparameter->create ? 1 : 0;
- $count += $urlparameter->reply ? 1 : 0;
- $count += $urlparameter->edit ? 1 : 0;
- $count += $urlparameter->delete ? 1 : 0;
- if ($count !== 1) {
- throw new coding_exception('Exactly one parameter should be specified!');
+ private function build_prepost_delete($deletepostid) {
+ global $DB, $USER;
+
+ // Check if the post is existing.
+ if (!$this->information->relatedpost = moodleoverflow_get_post_full($deletepostid)) {
+ throw new moodle_exception('invalidpostid', 'moodleoverflow');
}
- if ($urlparameter->create) {
- $this->interaction = 'create';
- $this->information->moodleoverflowid = $urlparameter->create;
- $this->security_checks_create($this->information->moodleoverflowid);
+ // Get the related discussion.
+ if (!$this->information->discussion = $DB->get_record('moodleoverflow_discussions',
+ array('id' => $this->information->relatedpost->discussion))) {
+ throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
+ }
- } else if ($urlparameter->edit) {
- $this->interaction = 'edit';
- $this->information->editpostid = $urlparameter->edit;
- $this->security_checks_edit($this->information->editpostid);
+ // Get the related moodleoverflow instance.
+ if (!$this->information->moodleoverflow = $DB->get_record('moodleoverflow',
+ array('id' => $this->information->discussion->moodleoverflow))) {
+ throw new moodle_exception('invalidmoodleoverflowid', 'moodleoveflow');
+ }
- } else if ($urlparameter->reply) {
- $this->interaction = 'reply';
- $this->information->replypostid = $urlparameter->edit;
- $this->security_checks_reply($this->information->replypostid);
+ // Get the related coursemodule.
+ if (!$this->information->cm = get_coursemodule_from_instance('moodleoverflow',
+ $this->information->moodleoverflow->id,
+ $this->information->moodleoverflow->course)) {
+ throw new moodle_exception('invalidcoursemodule');
+ }
- } else if ($urlparameter->delete) {
- $this->interaction = 'delete';
- $this->information->deletepostid = $urlparameter->edit;
- $this->security_checks_delete($this->information->deletepostid);
- } else {
- throw new moodle_exception('unknownparameter', 'moodleoverflow');
+ // Get the related course.
+ if (!$this->information->course = $DB->get_record('course', array('id' => $this->information->moodleoverflow->course))) {
+ throw new moodle_exception('invalidcourseid');
+ }
+
+ // Require a login and retrieve the modulecontext.
+ require_login($this->information->course, false, $this->information->cm);
+ $this->information->modulecontext = context_module::instance($this->information->cm->id);
+
+ // Check some capabilities.
+ $this->information->deleteownpost = has_capability('mod/moodleoverflow:deleteownpost', $this->information->modulecontext);
+ $this->information->deleteanypost = has_capability('mod/moodleoverflow:deleteanypost', $this->information->modulecontext);
+ if (!(($this->information->relatedpost->userid == $USER->id && $this->information->deleteownpost)
+ || $this->information->deleteanypost)) {
+
+ throw new moodle_exception('cannotdeletepost', 'moodleoverflow');
}
+
+ // Count all replies of this post.
+ $this->information->replycount = moodleoverflow_count_replies($this->information->relatedpost, false);
}
+
}
diff --git a/classes/post/post.drawio b/classes/post/post.drawio
index bfb1994bd1..35da2c1a64 100644
--- a/classes/post/post.drawio
+++ b/classes/post/post.drawio
@@ -1,11 +1,11 @@
-
+
-
+
@@ -16,7 +16,7 @@
-
+
@@ -43,19 +43,19 @@
-
-
-
-
+
-
+
+
+
+
@@ -64,24 +64,24 @@
-
-
+
+
-
+
-
+
-
+
-
+
-
+
@@ -91,10 +91,10 @@
-
+
-
+
@@ -104,20 +104,35 @@
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/classes/post/post.php b/classes/post/post.php
index a43a527bc4..e46156d2b4 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -42,39 +42,39 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class post {
- /**
- * Wie funktioniert das erstellen, ändern und löschen eines posts?
- * Was mach die post.php und die classes/post_form.php, wozu sind post.mustache und post_dummy.mustache da?
+ /*
+ * Wie funktioniert das erstellen, ändern und löschen eines posts?
+ * Was mach die post.php und die classes/post_form.php, wozu sind post.mustache und post_dummy.mustache da?
* Welche funktionen zu den posts hat die locallib.php?
- *
+ *
* => Was sollte in diese Klasse (classes/post.php) integriert werden, was sollte sie können? Was lässt man in der post.php/locallib.php, braucht man später die postform noch?
- *
+ *
* Funktionen aus der Locallib, die mit posts zu tun haben:
* - function moodleoverflow_get_post_full($postid) -> holt infos um einen post zu printen
* - function moodleoverflow_user_can_see_post($moodleoverflow, $discussion, $post, $cm)
* - function moodleoverflow_get_all_discussion_posts($discussionid, $tracking, $modcontext) -> holt sich die posts einer discussion
* - function moodleoverflow_print_post(...)
* - function moodleoverflow_print_posts_nested
- * - function get_attachments($post, $cm) ->
+ * - function get_attachments($post, $cm)
* - function moodleoverflow_add_attachment($post, $forum, $cm) {
* - function moodleoverflow_add_new_post($post) {
* - function moodleoverflow_update_post($newpost) {
- * - function moodleoverflow_count_replies($post, $onlyreviewed) -> zählt antworten auf eine frage
+ * - function moodleoverflow_count_replies($post, $onlyreviewed) -> zählt antworten auf eine frage
* - function moodleoverflow_delete_post($post, $deletechildren, $cm, $moodleoverflow) {
* - function moodleoverflow_add_discussion($discussion, $modulecontext, $userid = null) {
- *
- *
- * Vorüberlegung zu classes/post.php:
+ *
+ *
+ * Vorüberlegung zu classes/post.php:
* - Jeder Post im moodleoverflow ist ein Objekt identifizierbar über seine ID
* - Bei der erstellung einer neuen Diskussion (automatisch mit einem post) oder beim antworten/kommentieren soll ein neues objekt DIESER Klasse erstellt werden
* => realisierung der funktionen add_new_post, update_post, delete_post
- *
- * - Die funkionen:
- * - get_post_full, print_post,
+ *
+ * - Die funktionen:
+ * - get_post_full, print_post,
* - add_attachment und get_attachments
* sollten auch hier programmiert sein.
* Es soll auch möglich sein, den Elternpost, die Diskussion oder das Moodleoverflow als objekt zurückzugeben, damit alle Datenbankaufrufe hier passieren und nicht woanders.
- *
+ *
* - Diese Funktionen sollten in der Locallib bleiben:
* - user_can_see_post, da es von außen nur auf einen existierenden post zugreift
* - get_all_discussion_posts, da ein post nicht weitere posts in seiner umgebung kennt (außer seinen Elternpost)
@@ -83,17 +83,16 @@ class post {
* - add_discussion() bleibt in der locallib, da hier nur die construct methode (add_new_post()) aufgerufen wird.
*
*
- *
- *
- * Wie funktionieren post.php und classes/post_form.php?
- *
+ *
+ * Wie funktionieren post.php und classes/post_form.php?
+ *
* post.php:
* Bei jeder art von Interaktion (erstellen, ändern, löschen) wird die post.php aufgerufen
* => Im 1. Schritt wird geprüft, welche Art von Interaktion vorliegt. -> vielliecht auch das in classes/post.php auslagern
* => Im 2. Schritt wird ein neues post_form Objekt gebaut und dem objekt neue funktionen übergeben
- *
- *
+ *
+ *
* classes/post_form.php:
* Bildet nur die form ab, wo man den titel, Inhalt und attachments seines posts eintragen kann
*/
-}
\ No newline at end of file
+}
diff --git a/lang/en/moodleoverflow.php b/lang/en/moodleoverflow.php
index a40da7ff5c..2d178eeeb4 100644
--- a/lang/en/moodleoverflow.php
+++ b/lang/en/moodleoverflow.php
@@ -147,7 +147,6 @@
$string['couldnotdeletereplies'] = 'Sorry, that cannot be deleted as people have already responded to it';
$string['errorwhiledelete'] = 'An error occurred while deleting record.';
$string['couldnotdeletereplies'] = 'Sorry, that cannot be deleted as people have already responded to it';
-$string['unknownparameter'] = 'unknown parameter specified';
// Strings for the classes/mod_form.php.
$string['subject'] = 'Subject';
From c100a2059693def2b0540b60bdeed519e025d7dd Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Mon, 3 Jul 2023 14:02:44 +0200
Subject: [PATCH 07/56] WIP: writing new post class for interacting with posts
---
classes/post/post.control.php | 2 +-
classes/post/post.drawio | 16 +-
classes/post/post.php | 326 +++++++++++++++++++++++++++++-----
3 files changed, 292 insertions(+), 52 deletions(-)
diff --git a/classes/post/post.control.php b/classes/post/post.control.php
index ca76b921c9..43d476127b 100644
--- a/classes/post/post.control.php
+++ b/classes/post/post.control.php
@@ -80,7 +80,7 @@ public function get_information() {
* Retuns the prepared post.
*/
public function get_prepost() {
- return $this->information;
+ return $this->prepost;
}
/**
diff --git a/classes/post/post.drawio b/classes/post/post.drawio
index 35da2c1a64..b6a01a8296 100644
--- a/classes/post/post.drawio
+++ b/classes/post/post.drawio
@@ -1,6 +1,6 @@
-
+
@@ -49,7 +49,7 @@
-
+
@@ -119,10 +119,10 @@
-
+
-
+
@@ -131,9 +131,15 @@
-
+
+
+
+
+
+
+
diff --git a/classes/post/post.php b/classes/post/post.php
index e46156d2b4..d79e1a7dd4 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -26,9 +26,10 @@
namespace mod_moodleoverflow\post;
// Import namespace from the locallib, needs a check later which namespaces are really needed
-use mod_moodleoverflow\anonymous;
-use mod_moodleoverflow\capabilities;
-use mod_moodleoverflow\review;
+// use mod_moodleoverflow\anonymous;
+// use mod_moodleoverflow\capabilities;
+// use mod_moodleoverflow\review;
+use mod_moodleoverflow\readtracking;
defined('MOODLE_INTERNAL') || die();
@@ -42,57 +43,290 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class post {
- /*
- * Wie funktioniert das erstellen, ändern und löschen eines posts?
- * Was mach die post.php und die classes/post_form.php, wozu sind post.mustache und post_dummy.mustache da?
- * Welche funktionen zu den posts hat die locallib.php?
- *
- * => Was sollte in diese Klasse (classes/post.php) integriert werden, was sollte sie können? Was lässt man in der post.php/locallib.php, braucht man später die postform noch?
- *
- * Funktionen aus der Locallib, die mit posts zu tun haben:
- * - function moodleoverflow_get_post_full($postid) -> holt infos um einen post zu printen
- * - function moodleoverflow_user_can_see_post($moodleoverflow, $discussion, $post, $cm)
- * - function moodleoverflow_get_all_discussion_posts($discussionid, $tracking, $modcontext) -> holt sich die posts einer discussion
- * - function moodleoverflow_print_post(...)
- * - function moodleoverflow_print_posts_nested
- * - function get_attachments($post, $cm)
- * - function moodleoverflow_add_attachment($post, $forum, $cm) {
- * - function moodleoverflow_add_new_post($post) {
- * - function moodleoverflow_update_post($newpost) {
- * - function moodleoverflow_count_replies($post, $onlyreviewed) -> zählt antworten auf eine frage
- * - function moodleoverflow_delete_post($post, $deletechildren, $cm, $moodleoverflow) {
- * - function moodleoverflow_add_discussion($discussion, $modulecontext, $userid = null) {
- *
+
+ /** @var int The post ID */
+ private $id;
+
+ /** @var int The corresponding discussion ID */
+ private $discussion;
+
+ /** @var int The parent post ID */
+ private $parent;
+
+ /** @var int The ID of the User who wrote the post */
+ private $userid;
+
+ /** @var int Creation timestamp */
+ private $created;
+
+ /** @var int Modification timestamp */
+ private $modified;
+
+ /** @var string The message (content) of the post */
+ private $message;
+
+ /** @var int The message format*/
+ private $messageformat;
+
+ /** @var char Attachment of the post */
+ private $attachment;
+
+ /** @var int Mailed status*/
+ private $mailed;
+
+ /** @var int Review status */
+ private $reviewed;
+
+ /** @var int The time where the post was reviewed*/
+ private $timereviewed;
+
+
+ /**
+ * Constructor to make a new post
+ */
+ public function __construct($id, $discussion, $parent, $userid, $created, $modified, $message, $messageformat, $attachment, $mailed, $reviewed, $timereviewed) {
+ $this->id = $id;
+ $this->discussion = $discussion;
+ $this->parent = $parent;
+ $this->userid = $userid;
+ $this->created = $created;
+ $this->modified = $modified;
+ $this->message = $message;
+ $this->messageformat = $messageformat;
+ $this->attachment = $attachment;
+ $this->mailed = $mailed;
+ $this->reviewed = $reviewed;
+ $this->timereviewed = $timereviewed;
+ }
+
+
+ /**
+ * Creates a Post from a DB record.
+ *
+ * @param object $record Data object.
+ * @return object post
+ */
+ public static function from_record($record) {
+ $id = null;
+ if (object_property_exists($record, 'id') && $record->id) {
+ $id = $record->id;
+ }
+
+ $discussion = null;
+ if (object_property_exists($record, 'discussion') && $record->discussion) {
+ $discussion = $record->discussion;
+ }
+
+ $parent = null;
+ if (object_property_exists($record, 'parent') && $record->parent) {
+ $parent = $record->parent;
+ }
+
+ $userid = null;
+ if (object_property_exists($record, 'userid') && $record->userid) {
+ $userid = $record->userid;
+ }
+
+ $created = null;
+ if (object_property_exists($record, 'created') && $record->created) {
+ $created = $record->created;
+ }
+
+ $modified = null;
+ if (object_property_exists($record, 'modified') && $record->modified) {
+ $modified = $record->modified;
+ }
+
+ $message = null;
+ if (object_property_exists($record, 'message') && $record->message) {
+ $message = $record->message;
+ }
+
+ $messageformat = null;
+ if (object_property_exists($record, 'messageformat') && $record->messageformat) {
+ $message = $record->messageformat;
+ }
+
+ $attachment = null;
+ if (object_property_exists($record, 'attachment') && $record->attachment) {
+ $attachment = $record->attachment;
+ }
+
+ $mailed = null;
+ if (object_property_exists($record, 'mailed') && $record->mailed) {
+ $mailed = $record->mailed;
+ }
+
+ $reviewed = null;
+ if (object_property_exists($record, 'reviewed') && $record->reviewed) {
+ $reviewed = $record->reviewed;
+ }
+
+ $timereviewed = null;
+ if (object_property_exists($record, 'timereviewed') && $record->timereviewed) {
+ $timereviewed = $record->timereviewed;
+ }
+
+ $instance = new self($id, $discussion, $parent, $userid, $created, $modified, $message, $messageformat, $attachment, $mailed, $reviewed, $timereviewed);
+
+ return $instance;
+ }
+
+ // Post Functions:
+
+ /**
+ * Adds a new post in an existing discussion.
+ * @return bool|int The Id of the post if operation was successful
+ * @throws coding_exception
+ * @throws dml_exception
+ */
+ public function moodleoverflow_add_new_post() {
+ global $USER, $DB;
+
+ $discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $this->discussion));
+ $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow));
+ $cm = $DB->get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id);
+
+
+ // Add post to the database.
+ $DB->insert_record('moodleoverflow_posts', $this);
+ // Soll hier die Message extra mit $DB->set_field('moodleoverflow_post...) nochmal gesetzt/eingefügt werden?.
+ $this->moodleoverflow_add_attachment($this, $moodleoverflow, $cm);
+
+ if ($this->reviewed) {
+ // Update the discussion.
+ $DB->set_field('moodleoverflow_discussions', 'timemodified', $this->modified, array('id' => $this->discussion));
+ $DB->set_field('moodleoverflow_discussions', 'usermodified', $this->userid, array('id' => $this->discussion));
+ }
+
+
+ // Mark the created post as read if the user is tracking the discussion.
+ $cantrack = readtracking::moodleoverflow_can_track_moodleoverflows($moodleoverflow);
+ $istracked = readtracking::moodleoverflow_is_tracked($moodleoverflow);
+ if ($cantrack && $istracked) {
+ readtracking::moodleoverflow_mark_post_read($this->userid, $this);
+ }
+
+ // Return the id of the created post.
+ return $this->id;
+ }
+
+ /**
+ * Deletes a single moodleoverflow post.
*
- * Vorüberlegung zu classes/post.php:
- * - Jeder Post im moodleoverflow ist ein Objekt identifizierbar über seine ID
- * - Bei der erstellung einer neuen Diskussion (automatisch mit einem post) oder beim antworten/kommentieren soll ein neues objekt DIESER Klasse erstellt werden
- * => realisierung der funktionen add_new_post, update_post, delete_post
+ * @param object $post The post
+ * @param bool $deletechildren The child posts
+ * @param object $cm The course module
+ * @param object $moodleoverflow The moodleoverflow
*
- * - Die funktionen:
- * - get_post_full, print_post,
- * - add_attachment und get_attachments
- * sollten auch hier programmiert sein.
- * Es soll auch möglich sein, den Elternpost, die Diskussion oder das Moodleoverflow als objekt zurückzugeben, damit alle Datenbankaufrufe hier passieren und nicht woanders.
+ * @return bool Whether the deletion was successful
+ */
+ public function moodleoverflow_delete_post($post, $deletechildren, $cm, $moodleoverflow) {
+
+ }
+
+ /**
+ * Gets a post with all info ready for moodleoverflow_print_post.
+ * Most of these joins are just to get the forum id.
*
- * - Diese Funktionen sollten in der Locallib bleiben:
- * - user_can_see_post, da es von außen nur auf einen existierenden post zugreift
- * - get_all_discussion_posts, da ein post nicht weitere posts in seiner umgebung kennt (außer seinen Elternpost)
- * - print_post_nested, auch hier der gleiche grund, außerdem ruft print_post_nested auch nur print_posts_nested und geht zum nächsten Post
- * - count_replies, da hier eine sammlung von posts abgeprüft wird.
- * - add_discussion() bleibt in der locallib, da hier nur die construct methode (add_new_post()) aufgerufen wird.
+ * @param int $postid
*
+ * @return mixed array of posts or false
+ */
+ public function moodleoverflow_get_post_full($postid) {
+
+ }
+
+
+ /**
+ * If successful, this function returns the name of the file
*
+ * @param object $post is a full post record, including course and forum
+ * @param object $forum
+ * @param object $cm
*
- * Wie funktionieren post.php und classes/post_form.php?
+ * @return bool
+ */
+ public function moodleoverflow_add_attachment($post, $forum, $cm) {
+
+ }
+
+ /**
+ * Returns attachments with information for the template
*
- * post.php:
- * Bei jeder art von Interaktion (erstellen, ändern, löschen) wird die post.php aufgerufen
- * => Im 1. Schritt wird geprüft, welche Art von Interaktion vorliegt. -> vielliecht auch das in classes/post.php auslagern
- * => Im 2. Schritt wird ein neues post_form Objekt gebaut und dem objekt neue funktionen übergeben
+ * @param object $post
+ * @param object $cm
*
+ * @return array
+ */
+ public function moodleoverflow_get_attachments($post, $cm) {
+
+ }
+
+ /**
+ * Prints a moodleoverflow post.
+ * @param object $post
+ * @param object $discussion
+ * @param object $moodleoverflow
+ * @param object $cm
+ * @param object $course
+ * @param object $ownpost
+ * @param bool $link
+ * @param string $footer
+ * @param string $highlight
+ * @param bool $postisread
+ * @param bool $dummyifcantsee
+ * @param bool $istracked
+ * @param bool $iscomment
+ * @param array $usermapping
+ * @param int $level
+ * @param bool $multiplemarks setting of multiplemarks
+ * @return void|null
+ * @throws coding_exception
+ * @throws dml_exception
+ * @throws moodle_exception
+ */
+ public function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $course,
+ $ownpost = false, $link = false,
+ $footer = '', $highlight = '', $postisread = null,
+ $dummyifcantsee = true, $istracked = false,
+ $iscomment = false, $usermapping = [], $level = 0, $multiplemarks = false) {
+
+ }
+
+ /**
+ * Prints all posts of the discussion in a nested form.
*
- * classes/post_form.php:
- * Bildet nur die form ab, wo man den titel, Inhalt und attachments seines posts eintragen kann
+ * @param object $course The course object
+ * @param object $cm
+ * @param object $moodleoverflow The moodleoverflow object
+ * @param object $discussion The discussion object
+ * @param object $parent The object of the parent post
+ * @param bool $istracked Whether the user tracks the discussion
+ * @param array $posts Array of posts within the discussion
+ * @param bool $iscomment Whether the current post is a comment
+ * @param array $usermapping
+ * @param bool $multiplemarks
+ * @return string
+ * @throws coding_exception
+ * @throws dml_exception
+ * @throws moodle_exception
*/
+ public function moodleoverflow_print_posts_nested($course, &$cm, $moodleoverflow, $discussion, $parent,
+ $istracked, $posts, $iscomment = null, $usermapping = [], $multiplemarks = false) {
+
+ }
+
+ public function moodleoverflow_get_parentpost($postid) {
+
+ }
+
+ public function moodleoverflow_get_moodleoverflow() {
+
+ }
+
+ public function moodleoverflow_get_discussion() {
+
+ }
+
}
From c4c3128a1d318d001f0140bbfafbc0face59058c Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Wed, 5 Jul 2023 10:38:33 +0200
Subject: [PATCH 08/56] run grunt
---
amd/build/activityhelp.min.js.map | 2 +-
amd/src/activityhelp.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/amd/build/activityhelp.min.js.map b/amd/build/activityhelp.min.js.map
index 7bae1c7cab..d7235c4241 100644
--- a/amd/build/activityhelp.min.js.map
+++ b/amd/build/activityhelp.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;IAyBMA,kBACO,CACLC,aAAc,8CAOF,WAChBC,SAASC,iBAAiB,SAAS,SAAAC,OAC3BA,MAAMC,OAAOC,QAAQN,kBAAkBC,eACvCG,MAAMG"}
\ No newline at end of file
+{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;IAyBMA,kBACO,CACLC,aAAc,8CAOF,WAChBC,SAASC,iBAAiB,SAAS,SAAAC,OAC3BA,MAAMC,OAAOC,QAAQN,kBAAkBC,eACvCG,MAAMG"}
\ No newline at end of file
diff --git a/amd/src/activityhelp.js b/amd/src/activityhelp.js
index 601b6ad243..dc4127b6f2 100644
--- a/amd/src/activityhelp.js
+++ b/amd/src/activityhelp.js
@@ -30,7 +30,7 @@ const Selectors = {
};
/**
- * Function that shows the help string.
+ * Function that shows the help icon string.
*/
export const init = () => {
document.addEventListener('click', event => {
From c8ace61e011c6e561a2ea0651d176fb61169d3b2 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Wed, 5 Jul 2023 14:10:14 +0200
Subject: [PATCH 09/56] WIP: building post class
---
classes/post/post.drawio | 9 ++-
classes/post/post.php | 150 +++++++++++++++++++++++++++++++------
lang/en/moodleoverflow.php | 1 +
3 files changed, 135 insertions(+), 25 deletions(-)
diff --git a/classes/post/post.drawio b/classes/post/post.drawio
index b6a01a8296..357dead8c0 100644
--- a/classes/post/post.drawio
+++ b/classes/post/post.drawio
@@ -1,6 +1,6 @@
-
+
@@ -134,12 +134,15 @@
-
+
-
+
+
+
+
diff --git a/classes/post/post.php b/classes/post/post.php
index d79e1a7dd4..fd349b8e18 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -25,7 +25,7 @@
namespace mod_moodleoverflow\post;
-// Import namespace from the locallib, needs a check later which namespaces are really needed
+// Import namespace from the locallib, needs a check later which namespaces are really needed.
// use mod_moodleoverflow\anonymous;
// use mod_moodleoverflow\capabilities;
// use mod_moodleoverflow\review;
@@ -34,6 +34,7 @@
defined('MOODLE_INTERNAL') || die();
require_once(dirname(__FILE__) . '/lib.php');
+require_once($CFG->dirroot . '/mod/moodleoverflow/locallib.php');
/**
* Class that represents a post.
@@ -80,12 +81,23 @@ class post {
/** @var int The time where the post was reviewed*/
private $timereviewed;
-
- /**
+ /**
* Constructor to make a new post
+ *
+ * @param int $discussion The discussion ID.
+ * @param int $parent The parent post ID.
+ * @param int $userid The user ID that created the post.
+ * @param int $created Creation timestamp
+ * @param int $modified Modification timestamp
+ * @param string $message The message (content) of the post
+ * @param int $messageformat The message format
+ * @param char $attachment Attachment of the post
+ * @param int $mailed Mailed status
+ * @param int $reviewed Review status
+ * @param int $timereviewed The time where the post was reviewed
*/
- public function __construct($id, $discussion, $parent, $userid, $created, $modified, $message, $messageformat, $attachment, $mailed, $reviewed, $timereviewed) {
- $this->id = $id;
+ public function __construct($discussion, $parent, $userid, $created, $modified, $message,
+ $messageformat, $attachment, $mailed, $reviewed, $timereviewed) {
$this->discussion = $discussion;
$this->parent = $parent;
$this->userid = $userid;
@@ -102,7 +114,7 @@ public function __construct($id, $discussion, $parent, $userid, $created, $modif
/**
* Creates a Post from a DB record.
- *
+ *
* @param object $record Data object.
* @return object post
*/
@@ -167,12 +179,13 @@ public static function from_record($record) {
$timereviewed = $record->timereviewed;
}
- $instance = new self($id, $discussion, $parent, $userid, $created, $modified, $message, $messageformat, $attachment, $mailed, $reviewed, $timereviewed);
+ $instance = new self($id, $discussion, $parent, $userid, $created, $modified, $message,
+ $messageformat, $attachment, $mailed, $reviewed, $timereviewed);
return $instance;
}
- // Post Functions:
+ // Post Functions.
/**
* Adds a new post in an existing discussion.
@@ -187,11 +200,9 @@ public function moodleoverflow_add_new_post() {
$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow));
$cm = $DB->get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id);
-
// Add post to the database.
- $DB->insert_record('moodleoverflow_posts', $this);
- // Soll hier die Message extra mit $DB->set_field('moodleoverflow_post...) nochmal gesetzt/eingefügt werden?.
- $this->moodleoverflow_add_attachment($this, $moodleoverflow, $cm);
+ $this->id = $DB->insert_record('moodleoverflow_posts', $this);
+ $this->moodleoverflow_add_attachment($this, $moodleoverflow, $cm); // RETHINK.
if ($this->reviewed) {
// Update the discussion.
@@ -199,7 +210,6 @@ public function moodleoverflow_add_new_post() {
$DB->set_field('moodleoverflow_discussions', 'usermodified', $this->userid, array('id' => $this->discussion));
}
-
// Mark the created post as read if the user is tracking the discussion.
$cantrack = readtracking::moodleoverflow_can_track_moodleoverflows($moodleoverflow);
$istracked = readtracking::moodleoverflow_is_tracked($moodleoverflow);
@@ -214,15 +224,87 @@ public function moodleoverflow_add_new_post() {
/**
* Deletes a single moodleoverflow post.
*
- * @param object $post The post
* @param bool $deletechildren The child posts
* @param object $cm The course module
* @param object $moodleoverflow The moodleoverflow
*
* @return bool Whether the deletion was successful
*/
- public function moodleoverflow_delete_post($post, $deletechildren, $cm, $moodleoverflow) {
+ public function moodleoverflow_delete_post($deletechildren, $cm, $moodleoverflow) {
+ global $DB, $USER;
+ if (empty($this->id)) {
+ throw new moodle_exception('noexistingpost', 'moodleoverflow');
+ }
+
+ // Iterate through all children and delete them.
+ // In case something does not work we throw the error as it should be known that something went ... terribly wrong.
+ // All DB transactions are rolled back.
+ try {
+ $transaction = $DB->start_delegated_transaction();
+
+ $childposts = $this->moodleoverflow_get_childposts();
+ if ($deletechildren && $childposts) {
+ foreach ($childposts as $childpost) {
+ $child = $this->from_record($childpost);
+ $child->moodleoverflow_delete_post();
+ }
+ }
+
+ // Delete the ratings.
+ $DB->delete_records('moodleoverflow_ratings', array('postid' => $this->id));
+
+ // Delete the post.
+ if ($DB->delete_records('moodleoverflow_posts', array('id' => $this->id))) {
+ // Delete the read records.
+ readtracking::moodleoverflow_delete_read_records(-1, $this->id);
+
+ // Delete the attachments.
+ $fs = get_file_storage();
+ $context = context_module::instance($cm->id);
+ $attachments = $fs->get_area_files($context->id, 'mod_moodleoverflow', 'attachment',
+ $this->id, "filename", true);
+ foreach ($attachments as $attachment) {
+ // Get file.
+ $file = $fs->get_file($context->id, 'mod_moodleoverflow', 'attachment', $this->id,
+ $attachment->get_filepath(), $attachment->get_filename());
+ // Delete it if it exists.
+ if ($file) {
+ $file->delete();
+ }
+ }
+
+ // Just in case, check for the new last post of the discussion.
+ moodleoverflow_discussion_update_last_post($this->discussion);
+
+ // Get the context module.
+ $modulecontext = context_module::instance($cm->id);
+
+ // Trigger the post deletion event.
+ $params = array(
+ 'context' => $modulecontext,
+ 'objectid' => $this->id,
+ 'other' => array(
+ 'discussionid' => $this->discussion,
+ 'moodleoverflowid' => $moodleoverflow->id
+ )
+ );
+ if ($this->userid !== $USER->id) {
+ $params['relateduserid'] = $this->userid;
+ }
+ $event = post_deleted::create($params);
+ $event->trigger();
+
+ // The post has been deleted.
+ $transaction->allow_commit();
+ return true;
+ }
+ } catch (Exception $e) {
+ $transaction->rollback($e);
+ }
+
+ // Deleting the post failed.
+ return false;
}
/**
@@ -242,13 +324,20 @@ public function moodleoverflow_get_post_full($postid) {
* If successful, this function returns the name of the file
*
* @param object $post is a full post record, including course and forum
- * @param object $forum
- * @param object $cm
+ * @param object $moodleoverflow The moodleoverflow object
+ * @param object $cm The course module
*
* @return bool
*/
- public function moodleoverflow_add_attachment($post, $forum, $cm) {
+ public function moodleoverflow_add_attachment($moodleoverflow, $cm) {
+ global $DB;
+
+ if (empty($this->attachment)) {
+ return true; // Nothing to do.
+ }
+ $context = context_module::instance($cm->id);
+ $info = file_get_draft_area_info($this->attachment);
}
/**
@@ -312,11 +401,11 @@ public function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $
* @throws dml_exception
* @throws moodle_exception
*/
- public function moodleoverflow_print_posts_nested($course, &$cm, $moodleoverflow, $discussion, $parent,
- $istracked, $posts, $iscomment = null, $usermapping = [], $multiplemarks = false) {
+ public function moodleoverflow_print_posts_nested($course, &$cm, $moodleoverflow, $discussion, $parent, $istracked,
+ $posts, $iscomment = null, $usermapping = [], $multiplemarks = false) {
}
-
+
public function moodleoverflow_get_parentpost($postid) {
}
@@ -326,7 +415,24 @@ public function moodleoverflow_get_moodleoverflow() {
}
public function moodleoverflow_get_discussion() {
-
+
+ }
+
+ /**
+ * Returns children posts (answers) as DB-records.
+ *
+ * @return object children/answer posts.
+ */
+ public function moodleoverflow_get_childposts() {
+ if (empty($this->id)) {
+ throw new moodle_exception('noexistingpost', 'moodleoverflow');
+ }
+
+ if ($childposts = $DB->get_records('moodleoverflow_posts', array('parent' => $this->id))) {
+ return $childposts;
+ }
+
+ return false;
}
}
diff --git a/lang/en/moodleoverflow.php b/lang/en/moodleoverflow.php
index 4965ba1e9d..966df37946 100644
--- a/lang/en/moodleoverflow.php
+++ b/lang/en/moodleoverflow.php
@@ -148,6 +148,7 @@
$string['couldnotdeletereplies'] = 'Sorry, that cannot be deleted as people have already responded to it';
$string['errorwhiledelete'] = 'An error occurred while deleting record.';
$string['couldnotdeletereplies'] = 'Sorry, that cannot be deleted as people have already responded to it';
+$string['noexistingpost'] = 'Post does not exists, needs to be created first';
// Strings for the classes/mod_form.php.
$string['subject'] = 'Subject';
From c120ca4a5574a65be3bb7fae76b14ae0b00fd592 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Mon, 10 Jul 2023 16:32:10 +0200
Subject: [PATCH 10/56] WIP: building the new post class
---
classes/post/post.php | 178 ++++++++++++++++++++++++++++++++-----
classes/post_form.php | 7 --
lang/en/moodleoverflow.php | 1 +
tests/review_test.php | 15 ++--
4 files changed, 165 insertions(+), 36 deletions(-)
diff --git a/classes/post/post.php b/classes/post/post.php
index fd349b8e18..5ec6764c97 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -81,23 +81,36 @@ class post {
/** @var int The time where the post was reviewed*/
private $timereviewed;
+ /** @var int This variable is optional, it contains important information for the add_attachment function */
+ private $formattachments;
+
+ /** @var object The discussion where the post is located */
+ private $discussionobject;
+
+ /** @var object The Moodleoverflow where the post is located*/
+ private $moodleoverflowobject;
+
+ /** @var object The parent post of an answerpost */
+ private $parentpost;
+
/**
* Constructor to make a new post
*
- * @param int $discussion The discussion ID.
- * @param int $parent The parent post ID.
- * @param int $userid The user ID that created the post.
- * @param int $created Creation timestamp
- * @param int $modified Modification timestamp
- * @param string $message The message (content) of the post
- * @param int $messageformat The message format
- * @param char $attachment Attachment of the post
- * @param int $mailed Mailed status
- * @param int $reviewed Review status
- * @param int $timereviewed The time where the post was reviewed
+ * @param int $discussion The discussion ID.
+ * @param int $parent The parent post ID.
+ * @param int $userid The user ID that created the post.
+ * @param int $created Creation timestamp
+ * @param int $modified Modification timestamp
+ * @param string $message The message (content) of the post
+ * @param int $messageformat The message format
+ * @param char $attachment Attachment of the post
+ * @param int $mailed Mailed status
+ * @param int $reviewed Review status
+ * @param int $timereviewed The time where the post was reviewed
+ * @param object $formattachments Information about attachments of the post_form
*/
public function __construct($discussion, $parent, $userid, $created, $modified, $message,
- $messageformat, $attachment, $mailed, $reviewed, $timereviewed) {
+ $messageformat, $attachment, $mailed, $reviewed, $timereviewed, $formattachments = false) {
$this->discussion = $discussion;
$this->parent = $parent;
$this->userid = $userid;
@@ -109,6 +122,7 @@ public function __construct($discussion, $parent, $userid, $created, $modified,
$this->mailed = $mailed;
$this->reviewed = $reviewed;
$this->timereviewed = $timereviewed;
+ $this->formattachments = $formattachments;
}
@@ -311,19 +325,36 @@ public function moodleoverflow_delete_post($deletechildren, $cm, $moodleoverflow
* Gets a post with all info ready for moodleoverflow_print_post.
* Most of these joins are just to get the forum id.
*
- * @param int $postid
*
* @return mixed array of posts or false
*/
- public function moodleoverflow_get_post_full($postid) {
+ public function moodleoverflow_get_post_full() {
+ global $DB, $CFG;
+ if (empty($this->id)) {
+ throw new moodle_exception('noexistingpost', 'moodleoverflow');
+ }
+ if ($CFG->branch >= 311) {
+ $allnames = \core_user\fields::for_name()->get_sql('u', false, '', '', false)->selects;
+ } else {
+ $allnames = implode(', ', fields::get_name_fields());
+ }
+ $sql = "SELECT p.*, d.moodleoverflow, $allnames, u.email, u.picture, u.imagealt
+ FROM {moodleoverflow_posts} p
+ JOIN {moodleoverflow_discussions} d ON p.discussion = d.id
+ LEFT JOIN {user} u ON p.userid = u.id
+ WHERE p.id = " . $this->id . " ;";
+
+ $post = $DB->get_records_sql($sql);
+ if ($post->userid === 0) {
+ $post->message = get_string('privacy:anonym_post_message', 'mod_moodleoverflow');
+ }
+ return $post;
}
-
/**
* If successful, this function returns the name of the file
*
- * @param object $post is a full post record, including course and forum
* @param object $moodleoverflow The moodleoverflow object
* @param object $cm The course module
*
@@ -332,24 +363,74 @@ public function moodleoverflow_get_post_full($postid) {
public function moodleoverflow_add_attachment($moodleoverflow, $cm) {
global $DB;
- if (empty($this->attachment)) {
+ if (empty($this->id)) {
+ throw new moodle_exception('noexistingpost', 'moodleoverflow');
+ }
+
+ if (!$this->formattachments) {
+ throw new moodle_exception('missingformattachments', 'moodleoverflow');
+ }
+
+ if (empty($this->formattachments)) {
return true; // Nothing to do.
}
$context = context_module::instance($cm->id);
- $info = file_get_draft_area_info($this->attachment);
+ $info = file_get_draft_area_info($this->formattachments);
+ $present = ($info['filecount'] > 0) ? '1' : '';
+ file_save_draft_area_file($this->formattachments, $context->id, 'mod_moodleoverflow', 'attachment', $this->id,
+ mod_moodleoverflow_post_form::attachment_options($moodleoverflow));
+ $DB->set_field('moodleoverflow_post', 'attachment', $present, array('id' => $this->id));
}
/**
* Returns attachments with information for the template
*
- * @param object $post
* @param object $cm
*
* @return array
*/
- public function moodleoverflow_get_attachments($post, $cm) {
+ public function moodleoverflow_get_attachments($cm) {
+ global $CFG, $OUTPUT;
+
+ if (empty($this->id)) {
+ throw new moodle_exception('noexistingpost', 'moodleoverflow');
+ }
+
+ if (empty($this->attachment) || (!$context = context_module::instance($cm->id))) {
+ return array();
+ }
+ $attachments = array();
+ $fs = get_file_storage();
+
+ // We retrieve all files according to the time that they were created. In the case that several files were uploaded
+ // at the sametime (e.g. in the case of drag/drop upload) we revert to using the filename.
+ $file = $fs->get_area_files($context->id, 'mod_moodleoverflow', 'attachment', $this->id, "filename", false);
+ if ($files) {
+ $i = 0;
+ foreach ($files as $file) {
+ $attachments[$i] = array();
+ $attachments[$i]['filename'] = $file->get_filename();
+ $mimetype = $file->get_mimetype();
+ $iconimage = $OUTPUT->pix_icon(file_file_icon($file),
+ get_mimetype_description($file), 'moodle',
+ array('class' => 'icon'));
+ $path = moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(), $file->get_filearea(),
+ $file->get_itemid(), $file->get_filepath(), $file->get_filename());
+ $attachments[$i]['icon'] = $iconimage;
+ $attachments[$i]['filepath'] = $path;
+
+ if (in_array($mimetype, array('image/gif', 'image/jpeg', 'image/png'))) {
+ // Image attachments don't get printed as links.
+ $attachments[$i]['image'] = true;
+ } else {
+ $attachments[$i]['image'] = false;
+ }
+ $i += 1;
+ }
+ }
+ return $attachments;
}
/**
@@ -406,16 +487,66 @@ public function moodleoverflow_print_posts_nested($course, &$cm, $moodleoverflow
}
- public function moodleoverflow_get_parentpost($postid) {
+ /**
+ * Returns the moodleoverflow where the post is located.
+ *
+ * @return object $moodleoverflow
+ */
+ public function moodleoverflow_get_moodleoverflow() {
+ global $DB;
- }
+ if (empty($this->id)) {
+ throw new moodle_exception('noexistingpost', 'moodleoverflow');
+ }
- public function moodleoverflow_get_moodleoverflow() {
+ if (!empty($this->moodleoverflowobject)) {
+ return $this->moodleoverflowobject;
+ }
+ $this->get_discussion();
+ $this->moodleoverflowobject = $DB->get_record('moodleoverflow', array('id' => $this->discussionobject->moodleoverflow));
+ return $this->moodleoverflowobject;
}
public function moodleoverflow_get_discussion() {
+ global $DB;
+
+ if (empty($this->id)) {
+ throw new moodle_exception('noexistingpost', 'moodleoverflow');
+ }
+
+ if (!empty($this->discussionobject)) {
+ return $this->discussionobject;
+ }
+
+ $this->discussionobject = $DB->get_record('moodleoverflow_discussions', array('id' => $this->discussion));
+ return $this->discussionobject;
+ }
+ /**
+ * Returns the parent post
+ *
+ * @return object $post
+ */
+ public function moodleoverflow_get_parentpost($postid) {
+ global $DB;
+ if (empty($this->id)) {
+ throw new moodle_exception('noexistingpost', 'moodleoverflow');
+ }
+
+ if ($this->parent == 0) {
+ // This post is the parent post.
+ $this->parentpost = false;
+ return;
+ }
+
+ if (!empty($this->parentpost)) {
+ return $this->parentpost;
+ }
+
+ $parentpostrecord = $DB->get_record('moodleoverflow_post', array('id' => $this->parent));
+ $this->parentpost = $this->from_record($parentpostrecord);
+ return $this->parentpost;
}
/**
@@ -424,6 +555,7 @@ public function moodleoverflow_get_discussion() {
* @return object children/answer posts.
*/
public function moodleoverflow_get_childposts() {
+ global $DB;
if (empty($this->id)) {
throw new moodle_exception('noexistingpost', 'moodleoverflow');
}
diff --git a/classes/post_form.php b/classes/post_form.php
index 206a2109a7..c181a1d85b 100644
--- a/classes/post_form.php
+++ b/classes/post_form.php
@@ -142,10 +142,3 @@ public static function attachment_options($moodleoverflow) {
);
}
}
-
-
-
-
-
-
-
diff --git a/lang/en/moodleoverflow.php b/lang/en/moodleoverflow.php
index 966df37946..3824b3791e 100644
--- a/lang/en/moodleoverflow.php
+++ b/lang/en/moodleoverflow.php
@@ -149,6 +149,7 @@
$string['errorwhiledelete'] = 'An error occurred while deleting record.';
$string['couldnotdeletereplies'] = 'Sorry, that cannot be deleted as people have already responded to it';
$string['noexistingpost'] = 'Post does not exists, needs to be created first';
+$string['missingformattachments'] = "This functions requires data that were not submitted. Please check the post_form";
// Strings for the classes/mod_form.php.
$string['subject'] = 'Subject';
diff --git a/tests/review_test.php b/tests/review_test.php
index 82a6823a16..52f176c8f7 100644
--- a/tests/review_test.php
+++ b/tests/review_test.php
@@ -292,16 +292,19 @@ private function create_post($options) {
private function check_mail_records($teacherpost, $studentpost, $review1, $review2, $mailed) {
global $DB;
- $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_PENDING, 'reviewed' => $review1, 'timereviewed' => null],
- $DB->get_record('moodleoverflow_posts', ['id' => $teacherpost->id]));
- $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_PENDING, 'reviewed' => $review2, 'timereviewed' => null],
- $DB->get_record('moodleoverflow_posts', ['id' => $studentpost->id]));
+ $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_PENDING, 'reviewed' => $review1,
+ 'timereviewed' => null],
+ $DB->get_record('moodleoverflow_posts', ['id' => $teacherpost->id]));
+ $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_PENDING, 'reviewed' => $review2,
+ 'timereviewed' => null],
+ $DB->get_record('moodleoverflow_posts', ['id' => $studentpost->id]));
$this->run_send_mails();
$this->run_send_mails(); // Execute twice to ensure no duplicate mails.
- $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_SUCCESS, 'reviewed' => $review1, 'timereviewed' => null],
- $DB->get_record('moodleoverflow_posts', ['id' => $teacherpost->id]));
+ $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_SUCCESS, 'reviewed' => $review1,
+ 'timereviewed' => null],
+ $DB->get_record('moodleoverflow_posts', ['id' => $teacherpost->id]));
$this->assert_matches_properties(['mailed' => $mailed, 'reviewed' => $review2, 'timereviewed' => null],
$DB->get_record('moodleoverflow_posts', ['id' => $studentpost->id]));
}
From fad532900d50872aa5c24be75bcfae348114743d Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Tue, 11 Jul 2023 15:52:11 +0200
Subject: [PATCH 11/56] WIP: new post class. Adjusting print function
---
classes/post/post.control.php | 2 +-
classes/post/post.drawio | 9 +-
classes/post/post.php | 538 +++++++++++++++++++++++++++++-----
3 files changed, 473 insertions(+), 76 deletions(-)
diff --git a/classes/post/post.control.php b/classes/post/post.control.php
index 43d476127b..ba6bea0324 100644
--- a/classes/post/post.control.php
+++ b/classes/post/post.control.php
@@ -85,7 +85,7 @@ public function get_prepost() {
/**
* Detects the interaction
- * @param object $urlparamter parameter from the post.php .
+ * @param object $urlparamter parameter from the post.php
*/
private function detect_interaction($urlparameter) {
$count = 0;
diff --git a/classes/post/post.drawio b/classes/post/post.drawio
index 357dead8c0..703caddef7 100644
--- a/classes/post/post.drawio
+++ b/classes/post/post.drawio
@@ -1,6 +1,6 @@
-
+
@@ -140,8 +140,11 @@
-
-
+
+
+
+
+
diff --git a/classes/post/post.php b/classes/post/post.php
index 5ec6764c97..a75e0ed0b5 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -84,6 +84,11 @@ class post {
/** @var int This variable is optional, it contains important information for the add_attachment function */
private $formattachments;
+ // Variable that are not from the constructor.
+
+ /** @var string The subject of the Discussion */
+ private $subject;
+
/** @var object The discussion where the post is located */
private $discussionobject;
@@ -210,8 +215,8 @@ public static function from_record($record) {
public function moodleoverflow_add_new_post() {
global $USER, $DB;
- $discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $this->discussion));
- $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow));
+ $discussion = $this->moodleoverflow_get_discussion();
+ $moodleoverflow = $this->moodleoverflow_get_moodleoverflow();
$cm = $DB->get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id);
// Add post to the database.
@@ -346,7 +351,7 @@ public function moodleoverflow_get_post_full() {
WHERE p.id = " . $this->id . " ;";
$post = $DB->get_records_sql($sql);
- if ($post->userid === 0) {
+ if ($post->userid == 0) {
$post->message = get_string('privacy:anonym_post_message', 'mod_moodleoverflow');
}
return $post;
@@ -433,60 +438,6 @@ public function moodleoverflow_get_attachments($cm) {
return $attachments;
}
- /**
- * Prints a moodleoverflow post.
- * @param object $post
- * @param object $discussion
- * @param object $moodleoverflow
- * @param object $cm
- * @param object $course
- * @param object $ownpost
- * @param bool $link
- * @param string $footer
- * @param string $highlight
- * @param bool $postisread
- * @param bool $dummyifcantsee
- * @param bool $istracked
- * @param bool $iscomment
- * @param array $usermapping
- * @param int $level
- * @param bool $multiplemarks setting of multiplemarks
- * @return void|null
- * @throws coding_exception
- * @throws dml_exception
- * @throws moodle_exception
- */
- public function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $course,
- $ownpost = false, $link = false,
- $footer = '', $highlight = '', $postisread = null,
- $dummyifcantsee = true, $istracked = false,
- $iscomment = false, $usermapping = [], $level = 0, $multiplemarks = false) {
-
- }
-
- /**
- * Prints all posts of the discussion in a nested form.
- *
- * @param object $course The course object
- * @param object $cm
- * @param object $moodleoverflow The moodleoverflow object
- * @param object $discussion The discussion object
- * @param object $parent The object of the parent post
- * @param bool $istracked Whether the user tracks the discussion
- * @param array $posts Array of posts within the discussion
- * @param bool $iscomment Whether the current post is a comment
- * @param array $usermapping
- * @param bool $multiplemarks
- * @return string
- * @throws coding_exception
- * @throws dml_exception
- * @throws moodle_exception
- */
- public function moodleoverflow_print_posts_nested($course, &$cm, $moodleoverflow, $discussion, $parent, $istracked,
- $posts, $iscomment = null, $usermapping = [], $multiplemarks = false) {
-
- }
-
/**
* Returns the moodleoverflow where the post is located.
*
@@ -499,15 +450,19 @@ public function moodleoverflow_get_moodleoverflow() {
throw new moodle_exception('noexistingpost', 'moodleoverflow');
}
- if (!empty($this->moodleoverflowobject)) {
- return $this->moodleoverflowobject;
+ if (empty($this->moodleoverflowobject)) {
+ $discussion = $this->get_discussion();
+ $this->moodleoverflowobject = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow));
}
- $this->get_discussion();
- $this->moodleoverflowobject = $DB->get_record('moodleoverflow', array('id' => $this->discussionobject->moodleoverflow));
return $this->moodleoverflowobject;
}
+ /**
+ * Returns the discussion where the post is located.
+ *
+ * @return object $discussionobject.
+ */
public function moodleoverflow_get_discussion() {
global $DB;
@@ -515,20 +470,18 @@ public function moodleoverflow_get_discussion() {
throw new moodle_exception('noexistingpost', 'moodleoverflow');
}
- if (!empty($this->discussionobject)) {
- return $this->discussionobject;
+ if (empty($this->discussionobject)) {
+ $this->discussionobject = $DB->get_record('moodleoverflow_discussions', array('id' => $this->discussion));
}
- $this->discussionobject = $DB->get_record('moodleoverflow_discussions', array('id' => $this->discussion));
return $this->discussionobject;
}
/**
* Returns the parent post
- *
* @return object $post
*/
- public function moodleoverflow_get_parentpost($postid) {
+ public function moodleoverflow_get_parentpost() {
global $DB;
if (empty($this->id)) {
throw new moodle_exception('noexistingpost', 'moodleoverflow');
@@ -537,15 +490,13 @@ public function moodleoverflow_get_parentpost($postid) {
if ($this->parent == 0) {
// This post is the parent post.
$this->parentpost = false;
- return;
+ return false;
}
- if (!empty($this->parentpost)) {
- return $this->parentpost;
+ if (empty($this->parentpost)) {
+ $parentpostrecord = $DB->get_record('moodleoverflow_post', array('id' => $this->parent));
+ $this->parentpost = $this->from_record($parentpostrecord);
}
-
- $parentpostrecord = $DB->get_record('moodleoverflow_post', array('id' => $this->parent));
- $this->parentpost = $this->from_record($parentpostrecord);
return $this->parentpost;
}
@@ -567,4 +518,447 @@ public function moodleoverflow_get_childposts() {
return false;
}
+ /**
+ * Calculate the ratings of a post.
+ *
+ * @return object $ratingsobject.
+ */
+ public function moodleoverflow_get_post_ratings() {
+ if (empty($this->id)) {
+ throw new moodle_exception('noexistingpost', 'moodleoverflow');
+ }
+
+ $discussionid = $this->moodleoverflow_get_discussion()->id;
+ $postratings = \mod_moodleoverflow\ratings::moodleoverflow_get_ratings_by_discussion($discussionid, $this->id);
+
+ $ratingsobject = new \stdClass();
+ $ratingsobject->upvotes = $postratings->upvotes;
+ $ratingsobject->downvotes = $postratings->downvotes;
+ $ratingsobject->votesdifference = $postratings->upvotes - $postratings->downvotes;
+ $ratingsobject->markedhelpful = $postratings->ishelpful;
+ $ratingsobject->markedsolution = $postratings->issolved;
+
+ return $ratingsobject;
+ }
+
+ // Big Functions.
+
+ // Print Functions.
+
+ /**
+ * Prints all posts of the discussion in a nested form.
+ *
+ * @param object $course The course object
+ * @param object $cm
+ * @param object $moodleoverflow The moodleoverflow object
+ * @param object $discussion The discussion object
+ * @param object $parent The object of the parent post
+ * @param bool $istracked Whether the user tracks the discussion
+ * @param array $posts Array of posts within the discussion
+ * @param bool $iscomment Whether the current post is a comment
+ * @param array $usermapping
+ * @param bool $multiplemarks
+ * @return string
+ * @throws coding_exception
+ * @throws dml_exception
+ * @throws moodle_exception
+ */
+ public function moodleoverflow_print_posts_nested($course, &$cm, $moodleoverflow, $discussion, $parent, $istracked,
+ $posts, $iscomment = null, $usermapping = [], $multiplemarks = false) {
+
+ }
+
+ /**
+ * Prints a moodleoverflow post.
+ * @param object $ownpost
+ * @param bool $link
+ * @param string $footer
+ * @param string $highlight
+ * @param bool $postisread
+ * @param bool $dummyifcantsee
+ * @param bool $istracked
+ * @param bool $iscomment
+ * @param array $usermapping
+ * @param int $level
+ * @param bool $multiplemarks setting of multiplemarks
+ * @return void|null
+ * @throws coding_exception
+ * @throws dml_exception
+ * @throws moodle_exception
+ */
+ public function moodleoverflow_print_post($ownpost = false, $link = false, $footer = '', $highlight = '', $postisread = null,
+ $dummyifcantsee = true, $istracked = false, $iscomment = false, $usermapping = [],
+ $level = 0, $multiplemarks = false) {
+ global $USER, $CFG, $OUTPUT, $PAGE;
+
+ // Get important variables.
+ $post = $this->moodleoverflow_get_post_full();
+ $discussion = $this->moodleoverflow_get_discussion();
+ $moodleoverflow = $this->moodleoverflow_get_moodleoverflow();
+ $cm = $DB->get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id);
+ $course = $DB->get_record('course', array('id' => $moodleoverflow->course));
+
+ // Add ratings to the post.
+ $postratings = $this->moodleoverflow_get_post_ratings();
+ $post->upvotes = $postratings->upvotes;
+ $post->downvotes = $postratings->downvotes;
+ $post->votesdifference = $postratings->votesdifference;
+ $post->markedhelpful = $postratings->markedhelpful;
+ $post->markedsolution = $postratings->markedsolution;
+
+ // Add other important stuff.
+ $post->subject = $this->subject;
+
+ // Requiere the filelib.
+ require_once($CFG->libdir . '/filelib.php');
+
+ // String cahe.
+ static $str;
+
+ // Print the 'unread' only on time.
+ static $firstunreadanchorprinted = false;
+
+ // Declare the modulecontext.
+ $modulecontext = context_module::instance($cm->id);
+
+ // Add some information to the post.
+ $post->courseid = $course->id;
+ $post->moodleoverflowid = $moodleoverflow->id;
+ $mcid = $modulecontext->id;
+ $post->message = file_rewrite_pluginfile_urls($post->message, 'pluginfile.php', $mcid,
+ 'mod_moodleoverflow', 'post', $post->id);
+
+ // Check if the user has the capability to see posts.
+ if (!moodleoverflow_user_can_see_post($moodleoverflow, $discussion, $post, $cm)) {
+ // No dummy message is requested.
+ if (!$dummyifcantsee) {
+ echo '';
+ return;
+ }
+
+ // Include the renderer to display the dummy content.
+ $renderer = $PAGE->get_renderer('mod_moodleoverflow');
+
+ // Collect the needed data being submitted to the template.
+ $mustachedata = new stdClass();
+
+ // Print the template.
+ return $renderer->render_post_dummy_cantsee($mustachedata);
+ }
+
+ // Check if the strings have been cached.
+ if (empty($str)) {
+ $str = new stdClass();
+ $str->edit = get_string('edit', 'moodleoverflow');
+ $str->delete = get_string('delete', 'moodleoverflow');
+ $str->reply = get_string('reply', 'moodleoverflow');
+ $str->replyfirst = get_string('replyfirst', 'moodleoverflow');
+ $str->parent = get_string('parent', 'moodleoverflow');
+ $str->markread = get_string('markread', 'moodleoverflow');
+ $str->markunread = get_string('markunread', 'moodleoverflow');
+ $str->marksolved = get_string('marksolved', 'moodleoverflow');
+ $str->alsomarksolved = get_string('alsomarksolved', 'moodleoverflow');
+ $str->marknotsolved = get_string('marknotsolved', 'moodleoverflow');
+ $str->markhelpful = get_string('markhelpful', 'moodleoverflow');
+ $str->alsomarkhelpful = get_string('alsomarkhelpful', 'moodleoverflow');
+ $str->marknothelpful = get_string('marknothelpful', 'moodleoverflow');
+ }
+
+ // Get the current link without unnecessary parameters.
+ $discussionlink = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $post->discussion));
+
+ // Build the object that represents the posting user.
+ $postinguser = new stdClass();
+ if ($CFG->branch >= 311) {
+ $postinguserfields = \core_user\fields::get_picture_fields();
+ } else {
+ $postinguserfields = explode(',', user_picture::fields());
+ }
+ $postinguser = username_load_fields_from_object($postinguser, $post, null, $postinguserfields);
+
+ // Post was anonymized.
+ if (anonymous::is_post_anonymous($discussion, $moodleoverflow, $post->userid)) {
+ $postinguser->id = null;
+ if ($post->userid == $USER->id) {
+ $postinguser->fullname = get_string('anonym_you', 'mod_moodleoverflow');
+ $postinguser->profilelink = new moodle_url('/user/view.php', array('id' => $post->userid, 'course' => $course->id));
+ } else {
+ $postinguser->fullname = $usermapping[(int) $post->userid];
+ $postinguser->profilelink = null;
+ }
+ } else {
+ $postinguser->fullname = fullname($postinguser, capabilities::has('moodle/site:viewfullnames', $modulecontext));
+ $postinguser->profilelink = new moodle_url('/user/view.php', array('id' => $post->userid, 'course' => $course->id));
+ $postinguser->id = $post->userid;
+ }
+
+ // Prepare an array of commands.
+ $commands = array();
+
+ // Create a permalink.
+ $permalink = new moodle_url($discussionlink);
+ $permalink->set_anchor('p' . $post->id);
+
+ // Check if multiplemarks are allowed. If so, check if there are already marked posts.
+ $helpfulposts = false;
+ $solvedposts = false;
+ if ($multiplemarks) {
+ $helpfulposts = \mod_moodleoverflow\ratings::moodleoverflow_discussion_is_solved($discussion->id, false);
+ $solvedposts = \mod_moodleoverflow\ratings::moodleoverflow_discussion_is_solved($discussion->id, true);
+ }
+
+ // If the user has started the discussion, he can mark the answer as helpful.
+ $canmarkhelpful = (($USER->id == $discussion->userid) && ($USER->id != $post->userid) &&
+ ($iscomment != $post->parent) && !empty($post->parent));
+ if ($canmarkhelpful) {
+ // When the post is already marked, remove the mark instead.
+ $link = '/mod/moodleoverflow/discussion.php';
+ if ($post->markedhelpful) {
+ $commands[] = html_writer::tag('a', $str->marknothelpful, array('class' => 'markhelpful onlyifreviewed',
+ 'role' => 'button',
+ 'data-moodleoverflow-action' => 'helpful'));
+ } else {
+ // If there are already marked posts, change the string of the button.
+ if ($helpfulposts) {
+ $commands[] = html_writer::tag('a', $str->alsomarkhelpful, array('class' => 'markhelpful onlyifreviewed',
+ 'role' => 'button',
+ 'data-moodleoverflow-action' => 'helpful'));
+ } else {
+ $commands[] = html_writer::tag('a', $str->markhelpful, array('class' => 'markhelpful onlyifreviewed',
+ 'role' => 'button',
+ 'data-moodleoverflow-action' => 'helpful'));
+ }
+ }
+ }
+
+ // A teacher can mark an answer as solved.
+ $canmarksolved = (($iscomment != $post->parent) && !empty($post->parent) &&
+ capabilities::has(capabilities::MARK_SOLVED, $modulecontext));
+ if ($canmarksolved) {
+ // When the post is already marked, remove the mark instead.
+ $link = '/mod/moodleoverflow/discussion.php';
+ if ($post->markedsolution) {
+ $commands[] = html_writer::tag('a', $str->marknotsolved, array('class' => 'marksolved onlyifreviewed',
+ 'role' => 'button',
+ 'data-moodleoverflow-action' => 'solved'));
+ } else {
+ // If there are already marked posts, change the string of the button.
+ if ($solvedposts) {
+ $commands[] = html_writer::tag('a', $str->alsomarksolved, array('class' => 'marksolved onlyifreviewed',
+ 'role' => 'button',
+ 'data-moodleoverflow-action' => 'solved'));
+ } else {
+ $commands[] = html_writer::tag('a', $str->marksolved, array('class' => 'marksolved onlyifreviewed',
+ 'role' => 'button',
+ 'data-moodleoverflow-action' => 'solved'));
+ }
+ }
+ }
+
+ // Calculate the age of the post.
+ $age = time() - $post->created;
+
+ // Make a link to edit your own post within the given time and not already reviewed.
+ if (($ownpost && ($age < get_config('moodleoverflow', 'maxeditingtime'))
+ && (!review::should_post_be_reviewed($post, $moodleoverflow) || !$post->reviewed))
+ || capabilities::has(capabilities::EDIT_ANY_POST, $modulecontext)) {
+
+ $editurl = new moodle_url('/mod/moodleoverflow/post.php', array('edit' => $post->id));
+ $commands[] = array('url' => $editurl, 'text' => $str->edit);
+ }
+
+ // Give the option to delete a post.
+ $notold = ($age < get_config('moodleoverflow', 'maxeditingtime'));
+ if (($ownpost && $notold && capabilities::has(capabilities::DELETE_OWN_POST, $modulecontext)) ||
+ capabilities::has(capabilities::DELETE_ANY_POST, $modulecontext)) {
+
+ $link = '/mod/moodleoverflow/post.php';
+ $commands[] = array('url' => new moodle_url($link, array('delete' => $post->id)), 'text' => $str->delete);
+ }
+
+ // Give the option to reply to a post.
+ if (moodleoverflow_user_can_post($modulecontext, $post, false)) {
+
+ $attributes = [
+ 'class' => 'onlyifreviewed'
+ ];
+
+ // Answer to the parent post.
+ if (empty($post->parent)) {
+ $replyurl = new moodle_url('/mod/moodleoverflow/post.php#mformmoodleoverflow', array('reply' => $post->id));
+ $commands[] = array('url' => $replyurl, 'text' => $str->replyfirst, 'attributes' => $attributes);
+
+ // If the post is a comment, answer to the parent post.
+ } else if (!$iscomment) {
+ $replyurl = new moodle_url('/mod/moodleoverflow/post.php#mformmoodleoverflow', array('reply' => $post->id));
+ $commands[] = array('url' => $replyurl, 'text' => $str->reply, 'attributes' => $attributes);
+
+ // Else simple respond to the answer.
+ } else {
+ $replyurl = new moodle_url('/mod/moodleoverflow/post.php#mformmoodleoverflow', array('reply' => $iscomment));
+ $commands[] = array('url' => $replyurl, 'text' => $str->reply, 'attributes' => $attributes);
+ }
+ }
+
+ // Begin of mustache data collecting.
+
+ // Initiate the output variables.
+ $mustachedata = new stdClass();
+ $mustachedata->istracked = $istracked;
+ $mustachedata->isread = false;
+ $mustachedata->isfirstunread = false;
+ $mustachedata->isfirstpost = false;
+ $mustachedata->iscomment = (!empty($post->parent) && ($iscomment == $post->parent));
+ $mustachedata->permalink = $permalink;
+
+ // Get the ratings.
+ $mustachedata->votes = $post->upvotes - $post->downvotes;
+
+ // Check if the post is marked.
+ $mustachedata->markedhelpful = $post->markedhelpful;
+ $mustachedata->markedsolution = $post->markedsolution;
+
+ // Did the user rated this post?
+ $rating = \mod_moodleoverflow\ratings::moodleoverflow_user_rated($post->id);
+
+ // Initiate the variables.
+ $mustachedata->userupvoted = false;
+ $mustachedata->userdownvoted = false;
+ $mustachedata->canchange = $USER->id != $post->userid;
+
+ // Check the actual rating.
+ if ($rating) {
+
+ // Convert the object.
+ $rating = $rating->rating;
+
+ // Did the user upvoted or downvoted this post?
+ // The user upvoted the post.
+ if ($rating == 1) {
+ $mustachedata->userdownvoted = true;
+ } else if ($rating == 2) {
+ $mustachedata->userupvoted = true;
+ }
+ }
+
+ // Check the reading status of the post.
+ $postclass = '';
+ if ($istracked) {
+ if ($postisread) {
+ $postclass .= ' read';
+ $mustachedata->isread = true;
+ } else {
+ $postclass .= ' unread';
+
+ // Anchor the first unread post of a discussion.
+ if (!$firstunreadanchorprinted) {
+ $mustachedata->isfirstunread = true;
+ $firstunreadanchorprinted = true;
+ }
+ }
+ }
+ if ($post->markedhelpful) {
+ $postclass .= ' markedhelpful';
+ }
+ if ($post->markedsolution) {
+ $postclass .= ' markedsolution';
+ }
+ $mustachedata->postclass = $postclass;
+
+ // Is this the firstpost?
+ if (empty($post->parent)) {
+ $mustachedata->isfirstpost = true;
+ }
+
+ // Create an element for the user which posted the post.
+ $postbyuser = new stdClass();
+ $postbyuser->post = $post->subject;
+
+ // Anonymization already handled in $postinguser->fullname.
+ $postbyuser->user = $postinguser->fullname;
+
+ $mustachedata->discussionby = get_string('postbyuser', 'moodleoverflow', $postbyuser);
+
+ // Set basic variables of the post.
+ $mustachedata->postid = $post->id;
+ $mustachedata->subject = format_string($post->subject);
+
+ // Post was anonymized.
+ if (!anonymous::is_post_anonymous($discussion, $moodleoverflow, $post->userid)) {
+ // User picture.
+ $mustachedata->picture = $OUTPUT->user_picture($postinguser, ['courseid' => $course->id]);
+ }
+
+ // The rating of the user.
+ if (anonymous::is_post_anonymous($discussion, $moodleoverflow, $post->userid)) {
+ $postuserrating = null;
+ } else {
+ $postuserrating = \mod_moodleoverflow\ratings::moodleoverflow_get_reputation($moodleoverflow->id, $postinguser->id);
+ }
+
+ // The name of the user and the date modified.
+ $mustachedata->bydate = userdate($post->modified);
+ $mustachedata->byshortdate = userdate($post->modified, get_string('strftimedatetimeshort', 'core_langconfig'));
+ $mustachedata->byname = $postinguser->profilelink ?
+ html_writer::link($postinguser->profilelink, $postinguser->fullname)
+ : $postinguser->fullname;
+ $mustachedata->byrating = $postuserrating;
+ $mustachedata->byuserid = $postinguser->id;
+ $mustachedata->showrating = $postuserrating !== null;
+ if (get_config('moodleoverflow', 'allowdisablerating') == 1) {
+ $mustachedata->showvotes = $moodleoverflow->allowrating;
+ $mustachedata->showreputation = $moodleoverflow->allowreputation;
+ } else {
+ $mustachedata->showvotes = MOODLEOVERFLOW_RATING_ALLOW;
+ $mustachedata->showreputation = MOODLEOVERFLOW_REPUTATION_ALLOW;
+ }
+ $mustachedata->questioner = $post->userid == $discussion->userid ? 'questioner' : '';
+
+ // Set options for the post.
+ $options = new stdClass();
+ $options->para = false;
+ $options->trusted = false;
+ $options->context = $modulecontext;
+
+ $reviewdelay = get_config('moodleoverflow', 'reviewpossibleaftertime');
+ $mustachedata->reviewdelay = format_time($reviewdelay);
+ $mustachedata->needsreview = !$post->reviewed;
+ $reviewable = time() - $post->created > $reviewdelay;
+ $mustachedata->canreview = capabilities::has(capabilities::REVIEW_POST, $modulecontext);
+ $mustachedata->withinreviewperiod = $reviewable;
+
+ // Prepare the post.
+ $mustachedata->postcontent = format_text($post->message, $post->messageformat, $options, $course->id);
+
+ // Load the attachments.
+ $mustachedata->attachments = get_attachments($post, $cm);
+
+ // Output the commands.
+ $commandhtml = array();
+ foreach ($commands as $command) {
+ if (is_array($command)) {
+ $commandhtml[] = html_writer::link($command['url'], $command['text'], $command['attributes'] ?? null);
+ } else {
+ $commandhtml[] = $command;
+ }
+ }
+ $mustachedata->commands = implode('', $commandhtml);
+
+ // Print a footer if requested.
+ $mustachedata->footer = $footer;
+
+ // Mark the forum post as read.
+ if ($istracked && !$postisread) {
+ readtracking::moodleoverflow_mark_post_read($USER->id, $post);
+ }
+
+ $mustachedata->iscomment = $level == 2;
+
+ // Include the renderer to display the dummy content.
+ $renderer = $PAGE->get_renderer('mod_moodleoverflow');
+
+ // Render the different elements.
+ return $renderer->render_post($mustachedata);
+ }
+
}
From c54fb2604c8a6cfea1378aa0cde102dfb0a46037 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 13 Jul 2023 17:05:34 +0200
Subject: [PATCH 12/56] new Discussion class as part of the redesign
---
classes/discussion/discussion.php | 209 ++++++++++++++++++++++++++++++
classes/post/post.drawio | 125 ++++++++++++------
classes/post/post.php | 111 +++++++++-------
classes/post/structure.drawio | 206 +++++++++++++++++++++++++++++
lang/en/moodleoverflow.php | 1 +
locallib.php | 4 +-
6 files changed, 570 insertions(+), 86 deletions(-)
create mode 100644 classes/discussion/discussion.php
create mode 100644 classes/post/structure.drawio
diff --git a/classes/discussion/discussion.php b/classes/discussion/discussion.php
new file mode 100644
index 0000000000..4d0395d8d1
--- /dev/null
+++ b/classes/discussion/discussion.php
@@ -0,0 +1,209 @@
+.
+
+/**
+ * Class for working with posts
+ *
+ * @package mod_moodleoverflow
+ * @copyright 2023 Tamaro Walter
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace mod_moodleoverflow\discussion;
+
+
+// Import namespace from the locallib, needs a check later which namespaces are really needed.
+use mod_moodleoverflow\anonymous;
+use mod_moodleoverflow\capabilities;
+use mod_moodleoverflow\review;
+use mod_moodleoverflow\readtracking;
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once(dirname(__FILE__) . '/lib.php');
+require_once($CFG->dirroot . '/mod/moodleoverflow/locallib.php');
+
+/**
+ * Class that represents a discussion.
+ * A discussion administrates the posts and has one parent post, that started the discussion.
+ *
+ * @package mod_moodleoverflow
+ * @copyright 2023 Tamaro Walter
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class discussion {
+
+ /** @var int The discussion ID */
+ private $id;
+
+ /** @var int The course ID where the discussion is located */
+ private $course;
+
+ /** @var int The moodleoverflow ID where the discussion is located*/
+ private $moodleoverflow;
+
+ /** @var char The title of the discussion, the titel of the parent post*/
+ private $name;
+
+ /** @var int The id of the parent/first post*/
+ private $firstpost;
+
+ /** @var int The user ID who started the discussion */
+ private $userid;
+
+ /** @var int Unix-timestamp of modification */
+ private $timemodified;
+
+ /** @var int Unix-timestamp of discussion creation */
+ private $timestart;
+
+ /** @var int the user ID who modified the discussion */
+ private $usermodified;
+
+ // Not Database-related attributes.
+
+ /** @var array an Array of posts that belong to this discussion */
+ private $posts;
+
+ // Constructors and other builders.
+
+ /**
+ * Constructor to build a new discussion.
+ * @param int $id The Discussion ID.
+ * @param int $course The course ID.
+ * @param int $moodleoverflow The moodleoverflow ID.
+ * @param char $name Discussion Title.
+ * @param int $firstpost .
+ * @param int $userid The course ID.
+ * @param int $timemodified The course ID.
+ * @param int $timestart The course ID.
+ * @param int $usermodified The course ID.
+ */
+ public function __construct($id, $course, $moodleoverflow, $name, $firstpost,
+ $userid, $timemodified, $timestart, $usermodified) {
+ $this->id = $id;
+ $this->course = $course;
+ $this->moodleoverflow = $moodleoverflow;
+ $this->name = $name;
+ $this->firstpost = $firstpost;
+ $this->userid = $userid;
+ $this->timemodified = $timemodified;
+ $this->timestart = $timestart;
+ $this->usermodified = $usermodified;
+ }
+
+ /**
+ * Builds a Discussion from a DB record.
+ *
+ * @param object $record Data object.
+ * @return object discussion instance
+ */
+ public static function from_record($record) {
+ $id = null;
+ if (object__property_exists($record, 'id') && $record->id) {
+ $id = $record->id;
+ }
+
+ $course = null;
+ if (object__property_exists($record, 'course') && $record->course) {
+ $course = $record->course;
+ }
+
+ $moodleoverflow = null;
+ if (object__property_exists($record, 'moodleoverflow') && $record->moodleoverflow) {
+ $moodleoverflow = $record->moodleoverflow;
+ }
+
+ $name = null;
+ if (object__property_exists($record, 'name') && $record->name) {
+ $name = $record->name;
+ }
+
+ $firstpost = null;
+ if (object__property_exists($record, 'firstpost') && $record->firstpost) {
+ $firstpost = $record->firstpost;
+ }
+
+ $userid = null;
+ if (object__property_exists($record, 'userid') && $record->userid) {
+ $userid = $record->userid;
+ }
+
+ $timemodified = null;
+ if (object__property_exists($record, 'timemodified') && $record->timemodified) {
+ $timemodified = $record->timemodified;
+ }
+
+ $timestart = null;
+ if (object__property_exists($record, 'timestart') && $record->timestart) {
+ $timestart = $record->timestart;
+ }
+
+ $usermodified = null;
+ if (object__property_exists($record, 'usermodified') && $record->usermodified) {
+ $usermodified = $record->usermodified;
+ }
+
+ $instance = new self($id, $course, $moodleoverflow, $name, $firstpost, $userid, $timemodified, $timestart, $usermodified);
+
+ return $instance;
+ }
+
+ /**
+ * Function to build a new discussion without specifying the Discussion ID.
+ * @param int $course The course ID.
+ * @param int $moodleoverflow The moodleoverflow ID.
+ * @param char $name Discussion Title.
+ * @param int $firstpost .
+ * @param int $userid The course ID.
+ * @param int $timemodified The course ID.
+ * @param int $timestart The course ID.
+ * @param int $usermodified The course ID.
+ */
+ public static function constructwithoutid($course, $moodleoverflow, $name, $firstpost,
+ $userid, $timemodified, $timestart, $usermodified) {
+ $id = null;
+ $instance = new self($id, $course, $moodleoverflow, $name, $firstpost, $userid, $timemodified, $timestart, $usermodified);
+ return $instance;
+ }
+
+ // Discussion Functions.
+
+ public function moodleoverflow_add_discussion() {}
+ public function moodleoverflow_delete_discussion() {}
+ public function moodleoverflow_add_post_to_discussion() {}
+ public function moodleoverflow_delete_post_from_discussion() {}
+ public function moodleoverflow_get_discussion_ratings() {}
+ public function moodleoverflow_get_discussion_posts() {}
+ public function moodleoverflow_discussion_update_last_post() {} // This function has something to do with updating the attribute "timemodified".
+
+ // Security.
+
+ /**
+ * Makes sure that the instance exists in the database. Every function in this class requires this check
+ * (except the function that adds the discussion to the database)
+ *
+ * @return true
+ * @throws moodle_exception
+ */
+ private function existence_check() {
+ if (empty($this->id) || $this->id == false || $this->id == null) {
+ throw new moodle_exception('noexistingdiscussion', 'moodleoverflow');
+ }
+ return true;
+ }
+
+}
diff --git a/classes/post/post.drawio b/classes/post/post.drawio
index 703caddef7..cdb9223a02 100644
--- a/classes/post/post.drawio
+++ b/classes/post/post.drawio
@@ -1,11 +1,11 @@
-
+
-
+
@@ -54,21 +54,21 @@
-
+
-
+
-
-
+
+
-
+
@@ -87,64 +87,115 @@
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
+
+
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
-
+
+
+
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/classes/post/post.php b/classes/post/post.php
index a75e0ed0b5..5ce9ebb42b 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -26,9 +26,9 @@
namespace mod_moodleoverflow\post;
// Import namespace from the locallib, needs a check later which namespaces are really needed.
-// use mod_moodleoverflow\anonymous;
-// use mod_moodleoverflow\capabilities;
-// use mod_moodleoverflow\review;
+use mod_moodleoverflow\anonymous;
+use mod_moodleoverflow\capabilities;
+use mod_moodleoverflow\review;
use mod_moodleoverflow\readtracking;
defined('MOODLE_INTERNAL') || die();
@@ -84,9 +84,9 @@ class post {
/** @var int This variable is optional, it contains important information for the add_attachment function */
private $formattachments;
- // Variable that are not from the constructor.
+ // Not database related functions.
- /** @var string The subject of the Discussion */
+ /** @var string The subject/title of the Discussion */
private $subject;
/** @var object The discussion where the post is located */
@@ -98,8 +98,10 @@ class post {
/** @var object The parent post of an answerpost */
private $parentpost;
+ // Constructors and other builders.
+
/**
- * Constructor to make a new post
+ * Constructor to make a new post.
*
* @param int $discussion The discussion ID.
* @param int $parent The parent post ID.
@@ -114,8 +116,9 @@ class post {
* @param int $timereviewed The time where the post was reviewed
* @param object $formattachments Information about attachments of the post_form
*/
- public function __construct($discussion, $parent, $userid, $created, $modified, $message,
+ public function __construct($id, $discussion, $parent, $userid, $created, $modified, $message,
$messageformat, $attachment, $mailed, $reviewed, $timereviewed, $formattachments = false) {
+ $this->id = $id;
$this->discussion = $discussion;
$this->parent = $parent;
$this->userid = $userid;
@@ -130,12 +133,11 @@ public function __construct($discussion, $parent, $userid, $created, $modified,
$this->formattachments = $formattachments;
}
-
/**
- * Creates a Post from a DB record.
+ * Builds a Post from a DB record.
*
- * @param object $record Data object.
- * @return object post
+ * @param object $record Data object.
+ * @return object post instance
*/
public static function from_record($record) {
$id = null;
@@ -204,6 +206,30 @@ public static function from_record($record) {
return $instance;
}
+ /**
+ * Function to make a new post without specifying the Post ID.
+ *
+ * @param int $discussion The discussion ID.
+ * @param int $parent The parent post ID.
+ * @param int $userid The user ID that created the post.
+ * @param int $created Creation timestamp
+ * @param int $modified Modification timestamp
+ * @param string $message The message (content) of the post
+ * @param int $messageformat The message format
+ * @param char $attachment Attachment of the post
+ * @param int $mailed Mailed status
+ * @param int $reviewed Review status
+ * @param int $timereviewed The time where the post was reviewed
+ * @param object $formattachments Information about attachments of the post_form
+ */
+ public static function constructwithoutid($discussion, $parent, $userid, $created, $modified, $message,
+ $messageformat, $attachment, $mailed, $reviewed, $timereviewed, $formattachments = false) {
+ $id = null;
+ $instance = new self($id, $discussion, $parent, $userid, $created, $modified, $message,
+ $messageformat, $attachment, $mailed, $reviewed, $timereviewed);
+ return $instance;
+ }
+
// Post Functions.
/**
@@ -251,10 +277,7 @@ public function moodleoverflow_add_new_post() {
*/
public function moodleoverflow_delete_post($deletechildren, $cm, $moodleoverflow) {
global $DB, $USER;
-
- if (empty($this->id)) {
- throw new moodle_exception('noexistingpost', 'moodleoverflow');
- }
+ $this->existence_check();
// Iterate through all children and delete them.
// In case something does not work we throw the error as it should be known that something went ... terribly wrong.
@@ -333,11 +356,9 @@ public function moodleoverflow_delete_post($deletechildren, $cm, $moodleoverflow
*
* @return mixed array of posts or false
*/
- public function moodleoverflow_get_post_full() {
+ public function moodleoverflow_get_complete_post() {
global $DB, $CFG;
- if (empty($this->id)) {
- throw new moodle_exception('noexistingpost', 'moodleoverflow');
- }
+ $this->existence_check();
if ($CFG->branch >= 311) {
$allnames = \core_user\fields::for_name()->get_sql('u', false, '', '', false)->selects;
@@ -367,10 +388,7 @@ public function moodleoverflow_get_post_full() {
*/
public function moodleoverflow_add_attachment($moodleoverflow, $cm) {
global $DB;
-
- if (empty($this->id)) {
- throw new moodle_exception('noexistingpost', 'moodleoverflow');
- }
+ $this->existence_check();
if (!$this->formattachments) {
throw new moodle_exception('missingformattachments', 'moodleoverflow');
@@ -397,10 +415,7 @@ public function moodleoverflow_add_attachment($moodleoverflow, $cm) {
*/
public function moodleoverflow_get_attachments($cm) {
global $CFG, $OUTPUT;
-
- if (empty($this->id)) {
- throw new moodle_exception('noexistingpost', 'moodleoverflow');
- }
+ $this->existence_check();
if (empty($this->attachment) || (!$context = context_module::instance($cm->id))) {
return array();
@@ -445,10 +460,7 @@ public function moodleoverflow_get_attachments($cm) {
*/
public function moodleoverflow_get_moodleoverflow() {
global $DB;
-
- if (empty($this->id)) {
- throw new moodle_exception('noexistingpost', 'moodleoverflow');
- }
+ $this->existence_check();
if (empty($this->moodleoverflowobject)) {
$discussion = $this->get_discussion();
@@ -460,15 +472,12 @@ public function moodleoverflow_get_moodleoverflow() {
/**
* Returns the discussion where the post is located.
- *
+ *
* @return object $discussionobject.
*/
public function moodleoverflow_get_discussion() {
global $DB;
-
- if (empty($this->id)) {
- throw new moodle_exception('noexistingpost', 'moodleoverflow');
- }
+ $this->existence_check();
if (empty($this->discussionobject)) {
$this->discussionobject = $DB->get_record('moodleoverflow_discussions', array('id' => $this->discussion));
@@ -483,9 +492,7 @@ public function moodleoverflow_get_discussion() {
*/
public function moodleoverflow_get_parentpost() {
global $DB;
- if (empty($this->id)) {
- throw new moodle_exception('noexistingpost', 'moodleoverflow');
- }
+ $this->existence_check();
if ($this->parent == 0) {
// This post is the parent post.
@@ -507,9 +514,7 @@ public function moodleoverflow_get_parentpost() {
*/
public function moodleoverflow_get_childposts() {
global $DB;
- if (empty($this->id)) {
- throw new moodle_exception('noexistingpost', 'moodleoverflow');
- }
+ $this->existence_check();
if ($childposts = $DB->get_records('moodleoverflow_posts', array('parent' => $this->id))) {
return $childposts;
@@ -524,9 +529,7 @@ public function moodleoverflow_get_childposts() {
* @return object $ratingsobject.
*/
public function moodleoverflow_get_post_ratings() {
- if (empty($this->id)) {
- throw new moodle_exception('noexistingpost', 'moodleoverflow');
- }
+ $this->existence_check();
$discussionid = $this->moodleoverflow_get_discussion()->id;
$postratings = \mod_moodleoverflow\ratings::moodleoverflow_get_ratings_by_discussion($discussionid, $this->id);
@@ -541,6 +544,20 @@ public function moodleoverflow_get_post_ratings() {
return $ratingsobject;
}
+ /**
+ * Makes sure that the instance exists in the database. Every function in this class requires this check
+ * (except the function that adds a post to the database)
+ *
+ * @return true
+ * @throws moodle_exception
+ */
+ private function existence_check() {
+ if (empty($this->id) || $this->id == false || $this->id == null) {
+ throw new moodle_exception('noexistingpost', 'moodleoverflow');
+ }
+ return true;
+ }
+
// Big Functions.
// Print Functions.
@@ -590,9 +607,9 @@ public function moodleoverflow_print_post($ownpost = false, $link = false, $foot
$dummyifcantsee = true, $istracked = false, $iscomment = false, $usermapping = [],
$level = 0, $multiplemarks = false) {
global $USER, $CFG, $OUTPUT, $PAGE;
-
+ $this->existence_check();
// Get important variables.
- $post = $this->moodleoverflow_get_post_full();
+ $post = $this->moodleoverflow_get_complete_post();
$discussion = $this->moodleoverflow_get_discussion();
$moodleoverflow = $this->moodleoverflow_get_moodleoverflow();
$cm = $DB->get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id);
diff --git a/classes/post/structure.drawio b/classes/post/structure.drawio
new file mode 100644
index 0000000000..f0f88c8c7f
--- /dev/null
+++ b/classes/post/structure.drawio
@@ -0,0 +1,206 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lang/en/moodleoverflow.php b/lang/en/moodleoverflow.php
index 3824b3791e..ec488cb78a 100644
--- a/lang/en/moodleoverflow.php
+++ b/lang/en/moodleoverflow.php
@@ -149,6 +149,7 @@
$string['errorwhiledelete'] = 'An error occurred while deleting record.';
$string['couldnotdeletereplies'] = 'Sorry, that cannot be deleted as people have already responded to it';
$string['noexistingpost'] = 'Post does not exists, needs to be created first';
+$string['noexistingdiscussion'] = 'Discussion does not exists, needs to be created first';
$string['missingformattachments'] = "This functions requires data that were not submitted. Please check the post_form";
// Strings for the classes/mod_form.php.
diff --git a/locallib.php b/locallib.php
index 64b993ff93..5443afdd21 100644
--- a/locallib.php
+++ b/locallib.php
@@ -1862,10 +1862,10 @@ function moodleoverflow_delete_post($post, $deletechildren, $cm, $moodleoverflow
$attachments = $fs->get_area_files($context->id, 'mod_moodleoverflow', 'attachment',
$post->id, "filename", true);
foreach ($attachments as $attachment) {
- // Get file
+ // Get file.
$file = $fs->get_file($context->id, 'mod_moodleoverflow', 'attachment', $post->id,
$attachment->get_filepath(), $attachment->get_filename());
- // Delete it if it exists
+ // Delete it if it exists.
if ($file) {
$file->delete();
}
From 66f77e5b4b71dae4efced7c534704bb179c6b684 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Mon, 17 Jul 2023 16:51:26 +0200
Subject: [PATCH 13/56] WIP: updating discussion functions in new
discussion.php
---
classes/discussion/discussion.php | 171 ++++++++++++++++++++++++++++--
classes/post/post.control.php | 10 +-
classes/post/post.php | 81 ++++++++------
3 files changed, 219 insertions(+), 43 deletions(-)
diff --git a/classes/discussion/discussion.php b/classes/discussion/discussion.php
index 4d0395d8d1..6e575ffbb5 100644
--- a/classes/discussion/discussion.php
+++ b/classes/discussion/discussion.php
@@ -27,9 +27,12 @@
// Import namespace from the locallib, needs a check later which namespaces are really needed.
use mod_moodleoverflow\anonymous;
-use mod_moodleoverflow\capabilities;
-use mod_moodleoverflow\review;
+
+// Important namespaces.
use mod_moodleoverflow\readtracking;
+use mod_moodleoverflow\review;
+use mod_moodleoverflow\post\post;
+use mod_moodleoverflow\capabilities;
defined('MOODLE_INTERNAL') || die();
@@ -78,6 +81,12 @@ class discussion {
/** @var array an Array of posts that belong to this discussion */
private $posts;
+ /** @var object The moodleoverflow object where the discussion is located */
+ private $moodleoverflowobject;
+
+ /** @var object The course module object */
+ private $cmobject;
+
// Constructors and other builders.
/**
@@ -103,6 +112,7 @@ public function __construct($id, $course, $moodleoverflow, $name, $firstpost,
$this->timemodified = $timemodified;
$this->timestart = $timestart;
$this->usermodified = $usermodified;
+ $this->posts = array();
}
/**
@@ -172,8 +182,10 @@ public static function from_record($record) {
* @param int $timemodified The course ID.
* @param int $timestart The course ID.
* @param int $usermodified The course ID.
+ *
+ * @return object discussion object without id.
*/
- public static function constructwithoutid($course, $moodleoverflow, $name, $firstpost,
+ public static function construct_without_id($course, $moodleoverflow, $name, $firstpost,
$userid, $timemodified, $timestart, $usermodified) {
$id = null;
$instance = new self($id, $course, $moodleoverflow, $name, $firstpost, $userid, $timemodified, $timestart, $usermodified);
@@ -182,13 +194,152 @@ public static function constructwithoutid($course, $moodleoverflow, $name, $firs
// Discussion Functions.
- public function moodleoverflow_add_discussion() {}
- public function moodleoverflow_delete_discussion() {}
- public function moodleoverflow_add_post_to_discussion() {}
- public function moodleoverflow_delete_post_from_discussion() {}
- public function moodleoverflow_get_discussion_ratings() {}
- public function moodleoverflow_get_discussion_posts() {}
- public function moodleoverflow_discussion_update_last_post() {} // This function has something to do with updating the attribute "timemodified".
+ /**
+ * Adds a new Discussion with a post.
+ *
+ * @param object $prepost The prepost object from the post_control. Has information about the post and other important stuff.
+ */
+ public function moodleoverflow_add_discussion($prepost) {
+ global $DB;
+
+ // Get the current time.
+ $timenow = time();
+
+ // Retrieve the module instance.
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $this->moodleoverflow))) {
+ return false;
+ }
+
+ // Add the discussion to the Database.
+ $this->id = $DB->insert_record('moodleoverflow_discussions', $this);
+
+ // Create the first/parent post for the new discussion and add it do the DB.
+ $post = post::construct_without_id($this->id, 0, $prepost->userid, $prepost->created, $prepost->modified,
+ $preposts->message, $prepost->messageformat, $prepost->attachment, $prepost->mailed,
+ $prepost->reviewed, $prepost->timereviewed, $prepost->formattachments);
+ // Add it to the DB and save the id of the first/parent post.
+ $this->firstpost = $post->moodleoverflow_add_new_post();
+
+ // Save the id of the first/parent post in the DB.
+ $DB->set_field('moodleoverflow_discussions', 'firstpost', $this->firstpost, array('id' => $this->id));
+
+ // Add the parent post to the $posts array.
+ $this->posts[$this->firstpost] = $post;
+
+ // Trigger event.
+ $params = array(
+ 'context' => $prepost->modulecontext,
+ 'objectid' => $post->discussion,
+ );
+ $event = \mod_moodleoverflow\event\discussion_viewed::create($params);
+ $event->trigger();
+
+ // Return the id of the discussion.
+ return $this->id;
+ }
+
+ /**
+ * Delete a discussion with all of it's posts
+ *
+ * @return bool Wether deletion was successful of not
+ */
+ public function moodleoverflow_delete_discussion() {
+ global $DB;
+ $this->existence_check();
+
+ // Delete a discussion with all of it's posts.
+ // In case something does not work we throw the error as it should be known that something went ... terribly wrong.
+ // All DB transactions are rolled back.
+ try {
+ $transaction = $DB->start_delegated_transaction();
+
+ // Delete every post of this discussion.
+ foreach ($posts as $post) {
+ $post->moodleoverflow_delete_post(false);
+ }
+
+ // Delete the read-records for the discussion.
+ readtracking::moodleoverflow_delete_read_records(-1, -1, $this->id);
+
+ // Remove the subscriptions for the discussion.
+ $DB->delete_records('moodleoverflow_discuss_subs', array('discussion' => $this->id));
+
+ // Delete the discussion from the database.
+ $DB->delete_records('moodleoverflow_discussions', array('id' => $this->id));
+
+ // Set the id of this instance to null, so that working with it is not possible anymore.
+ $this->id = null;
+
+ // The discussion has been deleted.
+ $transaction->allow_commit();
+ return true;
+
+ } catch (Exception $e) {
+ $transaction->rollback($e);
+ }
+
+ // Deleting the discussion has failed.
+ return false;
+ }
+
+ /**
+ * Adds a new post to this discussion and the DB.
+ *
+ * @param object $prepost The prepost object from the post_control. Has Information about the post and other important stuff.
+ */
+ public function moodleoverflow_add_post_to_discussion($prepost) {
+ global $DB;
+
+ }
+
+ public function moodleoverflow_delete_post_from_discussion() {
+
+ }
+ public function moodleoverflow_get_discussion_ratings() {
+
+ }
+ public function moodleoverflow_get_discussion_posts() {
+
+ }
+ public function moodleoverflow_discussion_update_last_post() {
+ // This function has something to do with updating the attribute "timemodified".
+ }
+
+
+ /**
+ * Returns the moodleoverflowobject
+ *
+ * @return object $moodleoverflowobject
+ */
+ public function get_moodleoverflow() {
+ global $DB;
+ $this->existence_check();
+
+ if (empty($this->moodleoverflowobject)) {
+ $this->moodleoverflowobject = $DB->get_records('moodleoverflow', array('id' => $this->moodleoverflow));
+ }
+
+ return $this->moodleoverflowobject;
+ }
+
+ /**
+ * Returns the coursemodule
+ *
+ * @return object $cmobject
+ */
+ public function get_coursemodule() {
+ $this->existence_check();
+
+ if (empty($this->cmobject)) {
+ if (!$this->cmobject = $DB->get_coursemodule_from_instance('moodleoverflow', $this->get_moodleoverflow()->id,
+ $this->get_moodleoverflow()->course)) {
+ throw new moodle_exception('invalidcoursemodule');
+ }
+
+ }
+
+ return $this->cmobject;
+ }
// Security.
diff --git a/classes/post/post.control.php b/classes/post/post.control.php
index ba6bea0324..9387a62763 100644
--- a/classes/post/post.control.php
+++ b/classes/post/post.control.php
@@ -23,7 +23,7 @@
*/
-namespace mod_moodleoverflow\post;
+namespace mod_moodleoverflow\post\post_control;
// Import namespace from the locallib, needs a check later which namespaces are really needed.
use mod_moodleoverflow\anonymous;
@@ -169,6 +169,13 @@ private function build_prepost_create($moodleoverflowid) {
// Notify the user, that he can not post a new discussion.
throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
}
+
+ // Set the post to not reviewed if questions should be reviewed and the user is not a reviewed themselve.
+ if (review::get_review_level($this->information->moodleoverflow) >= review::QUESTIONS &&
+ !capabilities::has(capabilities::REVIEW_POST, $this->information->modulecontext, $USER->id)) {
+ $reviewed = 0;
+ }
+
// Where is the user coming from?
$SESSION->fromurl = get_local_referer(false);
@@ -181,6 +188,7 @@ private function build_prepost_create($moodleoverflowid) {
$this->prepost->subject = '';
$this->prepost->userid = $USER->id;
$this->prepost->message = '';
+ $this->prepost->reviewed = $reviewed; // IST DAS OKAY?!
// Unset where the user is coming from.
// Allows to calculate the correct return url later.
diff --git a/classes/post/post.php b/classes/post/post.php
index 5ce9ebb42b..f6a2db7d2a 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -23,7 +23,7 @@
*/
-namespace mod_moodleoverflow\post;
+namespace mod_moodleoverflow\post\post;
// Import namespace from the locallib, needs a check later which namespaces are really needed.
use mod_moodleoverflow\anonymous;
@@ -95,6 +95,9 @@ class post {
/** @var object The Moodleoverflow where the post is located*/
private $moodleoverflowobject;
+ /** @var object The course module object */
+ private $cmobject;
+
/** @var object The parent post of an answerpost */
private $parentpost;
@@ -221,8 +224,10 @@ public static function from_record($record) {
* @param int $reviewed Review status
* @param int $timereviewed The time where the post was reviewed
* @param object $formattachments Information about attachments of the post_form
+ *
+ * @return object post object without id
*/
- public static function constructwithoutid($discussion, $parent, $userid, $created, $modified, $message,
+ public static function construct_without_id($discussion, $parent, $userid, $created, $modified, $message,
$messageformat, $attachment, $mailed, $reviewed, $timereviewed, $formattachments = false) {
$id = null;
$instance = new self($id, $discussion, $parent, $userid, $created, $modified, $message,
@@ -241,13 +246,9 @@ public static function constructwithoutid($discussion, $parent, $userid, $create
public function moodleoverflow_add_new_post() {
global $USER, $DB;
- $discussion = $this->moodleoverflow_get_discussion();
- $moodleoverflow = $this->moodleoverflow_get_moodleoverflow();
- $cm = $DB->get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id);
-
// Add post to the database.
$this->id = $DB->insert_record('moodleoverflow_posts', $this);
- $this->moodleoverflow_add_attachment($this, $moodleoverflow, $cm); // RETHINK.
+ $this->moodleoverflow_add_attachment($this, $this->get_moodleoverflow(), $this->get_coursemodule());
if ($this->reviewed) {
// Update the discussion.
@@ -256,8 +257,8 @@ public function moodleoverflow_add_new_post() {
}
// Mark the created post as read if the user is tracking the discussion.
- $cantrack = readtracking::moodleoverflow_can_track_moodleoverflows($moodleoverflow);
- $istracked = readtracking::moodleoverflow_is_tracked($moodleoverflow);
+ $cantrack = readtracking::moodleoverflow_can_track_moodleoverflows($this->get_moodleoverflow());
+ $istracked = readtracking::moodleoverflow_is_tracked($this->get_moodleoverflow());
if ($cantrack && $istracked) {
readtracking::moodleoverflow_mark_post_read($this->userid, $this);
}
@@ -269,13 +270,11 @@ public function moodleoverflow_add_new_post() {
/**
* Deletes a single moodleoverflow post.
*
- * @param bool $deletechildren The child posts
- * @param object $cm The course module
- * @param object $moodleoverflow The moodleoverflow
+ * @param bool $deletechildren The child posts
*
- * @return bool Whether the deletion was successful
+ * @return bool Whether the deletion was successful or not
*/
- public function moodleoverflow_delete_post($deletechildren, $cm, $moodleoverflow) {
+ public function moodleoverflow_delete_post($deletechildren) {
global $DB, $USER;
$this->existence_check();
@@ -303,7 +302,7 @@ public function moodleoverflow_delete_post($deletechildren, $cm, $moodleoverflow
// Delete the attachments.
$fs = get_file_storage();
- $context = context_module::instance($cm->id);
+ $context = context_module::instance($this->get_coursemodule()->id);
$attachments = $fs->get_area_files($context->id, 'mod_moodleoverflow', 'attachment',
$this->id, "filename", true);
foreach ($attachments as $attachment) {
@@ -320,7 +319,7 @@ public function moodleoverflow_delete_post($deletechildren, $cm, $moodleoverflow
moodleoverflow_discussion_update_last_post($this->discussion);
// Get the context module.
- $modulecontext = context_module::instance($cm->id);
+ $modulecontext = context_module::instance($this->get_coursemodule()->id);
// Trigger the post deletion event.
$params = array(
@@ -328,7 +327,7 @@ public function moodleoverflow_delete_post($deletechildren, $cm, $moodleoverflow
'objectid' => $this->id,
'other' => array(
'discussionid' => $this->discussion,
- 'moodleoverflowid' => $moodleoverflow->id
+ 'moodleoverflowid' => $this->get_moodleoverflow()->id
)
);
if ($this->userid !== $USER->id) {
@@ -337,6 +336,9 @@ public function moodleoverflow_delete_post($deletechildren, $cm, $moodleoverflow
$event = post_deleted::create($params);
$event->trigger();
+ // Set the id of this instance to null, so that working with it is not possible anymore.
+ $this->id = null;
+
// The post has been deleted.
$transaction->allow_commit();
return true;
@@ -381,12 +383,9 @@ public function moodleoverflow_get_complete_post() {
/**
* If successful, this function returns the name of the file
*
- * @param object $moodleoverflow The moodleoverflow object
- * @param object $cm The course module
- *
* @return bool
*/
- public function moodleoverflow_add_attachment($moodleoverflow, $cm) {
+ public function moodleoverflow_add_attachment() {
global $DB;
$this->existence_check();
@@ -398,26 +397,25 @@ public function moodleoverflow_add_attachment($moodleoverflow, $cm) {
return true; // Nothing to do.
}
- $context = context_module::instance($cm->id);
+ $context = context_module::instance($this->get_coursemodule()->id);
$info = file_get_draft_area_info($this->formattachments);
$present = ($info['filecount'] > 0) ? '1' : '';
file_save_draft_area_file($this->formattachments, $context->id, 'mod_moodleoverflow', 'attachment', $this->id,
- mod_moodleoverflow_post_form::attachment_options($moodleoverflow));
+ mod_moodleoverflow_post_form::attachment_options($this->get_moodleoverflow()));
$DB->set_field('moodleoverflow_post', 'attachment', $present, array('id' => $this->id));
}
/**
* Returns attachments with information for the template
*
- * @param object $cm
*
* @return array
*/
- public function moodleoverflow_get_attachments($cm) {
+ public function moodleoverflow_get_attachments() {
global $CFG, $OUTPUT;
$this->existence_check();
- if (empty($this->attachment) || (!$context = context_module::instance($cm->id))) {
+ if (empty($this->attachment) || (!$context = context_module::instance($this->get_coursemodule()->id))) {
return array();
}
@@ -453,12 +451,14 @@ public function moodleoverflow_get_attachments($cm) {
return $attachments;
}
+ // Helper Functions.
+
/**
* Returns the moodleoverflow where the post is located.
*
- * @return object $moodleoverflow
+ * @return object $moodleoverflowobject
*/
- public function moodleoverflow_get_moodleoverflow() {
+ public function get_moodleoverflow() {
global $DB;
$this->existence_check();
@@ -475,7 +475,7 @@ public function moodleoverflow_get_moodleoverflow() {
*
* @return object $discussionobject.
*/
- public function moodleoverflow_get_discussion() {
+ public function get_discussion() {
global $DB;
$this->existence_check();
@@ -486,6 +486,21 @@ public function moodleoverflow_get_discussion() {
return $this->discussionobject;
}
+ /**
+ * Returns the coursemodule
+ *
+ * @return object $cmobject
+ */
+ public function get_coursemodule() {
+ $this->existence_check();
+
+ if (empty($this->cmobject)) {
+ $this->cmobject = $DB->get_coursemodule_from_instance('moodleoverflow', $this->get_moodleoverflow()->id);
+ }
+
+ return $this->cmobject;
+ }
+
/**
* Returns the parent post
* @return object $post
@@ -531,7 +546,7 @@ public function moodleoverflow_get_childposts() {
public function moodleoverflow_get_post_ratings() {
$this->existence_check();
- $discussionid = $this->moodleoverflow_get_discussion()->id;
+ $discussionid = $this->get_discussion()->id;
$postratings = \mod_moodleoverflow\ratings::moodleoverflow_get_ratings_by_discussion($discussionid, $this->id);
$ratingsobject = new \stdClass();
@@ -544,6 +559,8 @@ public function moodleoverflow_get_post_ratings() {
return $ratingsobject;
}
+ // Security.
+
/**
* Makes sure that the instance exists in the database. Every function in this class requires this check
* (except the function that adds a post to the database)
@@ -610,8 +627,8 @@ public function moodleoverflow_print_post($ownpost = false, $link = false, $foot
$this->existence_check();
// Get important variables.
$post = $this->moodleoverflow_get_complete_post();
- $discussion = $this->moodleoverflow_get_discussion();
- $moodleoverflow = $this->moodleoverflow_get_moodleoverflow();
+ $discussion = $this->get_discussion();
+ $moodleoverflow = $this->get_moodleoverflow();
$cm = $DB->get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id);
$course = $DB->get_record('course', array('id' => $moodleoverflow->course));
From 437e6ea489d416268134e37226170a265d2b45a0 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Tue, 18 Jul 2023 15:59:02 +0200
Subject: [PATCH 14/56] WIP: new functions in discussion and post for editing
posts
---
classes/discussion/discussion.php | 153 ++++++++++++++++++++++++++++--
classes/post/post.php | 33 ++++++-
classes/post/structure.drawio | 21 +---
lang/en/moodleoverflow.php | 2 +
4 files changed, 182 insertions(+), 27 deletions(-)
diff --git a/classes/discussion/discussion.php b/classes/discussion/discussion.php
index 6e575ffbb5..2ded21a52b 100644
--- a/classes/discussion/discussion.php
+++ b/classes/discussion/discussion.php
@@ -43,6 +43,9 @@
* Class that represents a discussion.
* A discussion administrates the posts and has one parent post, that started the discussion.
*
+ * Please be careful with functions that delete posts or discussions.
+ * Security checks for these functions were done in the post_control class and these functions should only be accessed via this way.
+ * Accessing these functions directly without the checks from the post control could lead to serious errors.
* @package mod_moodleoverflow
* @copyright 2023 Tamaro Walter
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -81,6 +84,9 @@ class discussion {
/** @var array an Array of posts that belong to this discussion */
private $posts;
+ /** @var bool a variable for checking if this instance has all its posts */
+ private $postsbuild;
+
/** @var object The moodleoverflow object where the discussion is located */
private $moodleoverflowobject;
@@ -113,6 +119,7 @@ public function __construct($id, $course, $moodleoverflow, $name, $firstpost,
$this->timestart = $timestart;
$this->usermodified = $usermodified;
$this->posts = array();
+ $this->postsbuild = false;
}
/**
@@ -169,6 +176,9 @@ public static function from_record($record) {
$instance = new self($id, $course, $moodleoverflow, $name, $firstpost, $userid, $timemodified, $timestart, $usermodified);
+ // Get all the posts so that the instance can work with it.
+ $instance->moodleoverflow_get_discussion_posts();
+
return $instance;
}
@@ -205,16 +215,11 @@ public function moodleoverflow_add_discussion($prepost) {
// Get the current time.
$timenow = time();
- // Retrieve the module instance.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $this->moodleoverflow))) {
- return false;
- }
-
// Add the discussion to the Database.
$this->id = $DB->insert_record('moodleoverflow_discussions', $this);
// Create the first/parent post for the new discussion and add it do the DB.
- $post = post::construct_without_id($this->id, 0, $prepost->userid, $prepost->created, $prepost->modified,
+ $post = post::construct_without_id($this->id, 0, $prepost->userid, $timenow, $timenow,
$preposts->message, $prepost->messageformat, $prepost->attachment, $prepost->mailed,
$prepost->reviewed, $prepost->timereviewed, $prepost->formattachments);
// Add it to the DB and save the id of the first/parent post.
@@ -225,6 +230,7 @@ public function moodleoverflow_add_discussion($prepost) {
// Add the parent post to the $posts array.
$this->posts[$this->firstpost] = $post;
+ $this->postsbuild = true;
// Trigger event.
$params = array(
@@ -246,6 +252,7 @@ public function moodleoverflow_add_discussion($prepost) {
public function moodleoverflow_delete_discussion() {
global $DB;
$this->existence_check();
+ $this->posts_check();
// Delete a discussion with all of it's posts.
// In case something does not work we throw the error as it should be known that something went ... terribly wrong.
@@ -289,18 +296,123 @@ public function moodleoverflow_delete_discussion() {
*/
public function moodleoverflow_add_post_to_discussion($prepost) {
global $DB;
+ $this->existence_check();
+ $this->post_check();
+
+ // Get the current time.
+ $timenow = time();
+
+ // Create the post that will be added to the new discussion.
+ $post = post::construct_without_id($this->id, $prepost->parent, $timenow, $timenow, $prepost->message,
+ $prepost->messageformat, $prepost->attachment, $prepost->mailed,
+ $prepost->reviewed, $prepost->timereviewed, $prepost->formattachments);
+ // Add the post to the DB.
+ $postid = $post->moodleoverflow_add_new_post();
+
+ // Add the post to the $posts array.
+ $this->posts[$postid] = $post;
+
+ // Return the id of the added post.
+ return $postid;
+ }
+
+ /**
+ * Deletes a post that is in this discussion from the DB.
+ *
+ * @return bool Wether the deletion was possible
+ * @throws moodle_exception if post is not in this discussion or something failed.
+ */
+ public function moodleoverflow_delete_post_from_discussion($postid, $deletechildren) {
+ $this->existence_check();
+ $this->posts_check();
+
+ // Check if the posts exists in this discussion.
+ $this->post_exists_check($postid);
+
+ // Access the post and delete it.
+ $post = $this->posts[$postid];
+ if (!$post->moodleoverflow_delete_post($deletechildren)) {
+ // Deletion failed.
+ return false;
+ }
+ // Delete the post from the post array.
+ unset($this->posts[$postid]);
+ return true;
}
- public function moodleoverflow_delete_post_from_discussion() {
+ /**
+ * Edits the message of a post from this discussion.
+ */
+ public function moodleoverflow_edit_post_from_discussion($postid, $postmessage) {
+ global $DB;
+ $this->existence_check();
+ $this->posts_check();
+
+ // Check if the posts exists in this discussion.
+ $this->post_exists_check($postid);
+
+ // Get the current time.
+ $timenow = time();
+
+ // Access the post and edit its message.
+ $post = $this->post[$postid];
+ // If the post is the firstpost, then update the name of this discussion and the post. If not, only update the post.
+ if ($postid == array_key_first($posts));
}
+
+ /**
+ * Returns the ratings from this discussion.
+ *
+ * @return array of votings
+ */
public function moodleoverflow_get_discussion_ratings() {
+ $this->existence_check();
+ $this->posts_check();
+ $discussionratings = \mod_moodleoverflow\ratings::moodleoverflow_get_ratings_by_discussion($this->id);
+ return $discussionratings;
}
+
+ /**
+ * Get all posts from this Discussion.
+ * The first/parent post is on the first position in the array.
+ *
+ * @return array $posts Array ob posts objects
+ */
public function moodleoverflow_get_discussion_posts() {
+ global $DB;
+ $this->existence_check();
+
+ // Check if the posts array are build yet. If not, build it.
+ if (!$this->postsbuild) {
+ // Get the posts from the DB. Get the parent post first.
+ $firstpostsql = 'SELECT * FROM {moodleoverflow_posts} posts
+ WHERE posts.discussion = ' . $this->id . ' AND posts.parent = 0;';
+ $otherpostssql = 'SELECT * FROM {moodleoverflow_posts} posts
+ WHERE posts.discussion = ' . $this->id . ' AND posts.parent != 0;';
+ $firstpostrecord = $DB->get_record_sql($firstpostsql);
+ $otherpostsrecords = $DB->get_records_sql($otherpostssql);
+
+ // Add the first/parent post to the array, then add the other posts.
+ $firstpost = post::from_record($firstpostrecord);
+ $this->posts[$firstpost->get_id()] = $firstpost;
+
+ foreach ($otherpostrecords as $postrecord) {
+ $post = post::from_record($postrecord);
+ $this->posts[$post->get_id()] = $post;
+ }
+
+ // Now the posts are built.
+ $this->postsbuild = true;
+ }
+ // Return the posts array.
+ return $this->posts;
}
+
+
public function moodleoverflow_discussion_update_last_post() {
// This function has something to do with updating the attribute "timemodified".
}
@@ -357,4 +469,31 @@ private function existence_check() {
return true;
}
+ /**
+ * Makes sure that the instance knows all of its posts (That all posts of the db are in the local array).
+ * Not all functions need this check.
+ * @return true
+ * @throws moodle_exception
+ */
+ private function posts_check() {
+ if (!$this->postsbuild) {
+ throw new moodle_exception('notallpostsavailable', 'moodleoverflow');
+ }
+ return true;
+ }
+
+ /**
+ * Check, if certain posts really exists in this discussion.
+ *
+ * @param int $postid The ID of the post that is being checked.
+ * @return true
+ * @throws moodle_exception;
+ */
+ private function post_exists_check($postid) {
+ if (!$this->posts[$postid]) {
+ throw new moodle_exception('postnotpartofdiscussion', 'moodleoverflow');
+ }
+
+ return true;
+ }
}
diff --git a/classes/post/post.php b/classes/post/post.php
index f6a2db7d2a..ecdfd43ccf 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -316,7 +316,7 @@ public function moodleoverflow_delete_post($deletechildren) {
}
// Just in case, check for the new last post of the discussion.
- moodleoverflow_discussion_update_last_post($this->discussion);
+ moodleoverflow_discussion_update_last_post($this->discussion); // NEEDS TO CHANGE WITH NEW DISCUSSION CLASS.
// Get the context module.
$modulecontext = context_module::instance($this->get_coursemodule()->id);
@@ -351,6 +351,26 @@ public function moodleoverflow_delete_post($deletechildren) {
return false;
}
+ /**
+ * Edits the message from this instance.
+ *
+ * @param string $postmessage The new message
+ * @param object $postattachment
+ * @param timestamp $time The time the post was modified (given from the discussion class).
+ */
+ public function moodleoverflow_edit_post($postmessage, $postattachment, $time) {
+ global $DB;
+ $this->existence_check();
+
+ // Update the attributes.
+ $this->message = $postmessage;
+ $this->modified = $time;
+
+ $DB->update_record('moodleoverflow_posts', $this);
+
+
+ }
+
/**
* Gets a post with all info ready for moodleoverflow_print_post.
* Most of these joins are just to get the forum id.
@@ -453,6 +473,17 @@ public function moodleoverflow_get_attachments() {
// Helper Functions.
+ /**
+ * Returns the id of this instance.
+ *
+ * @return int $this->id
+ */
+ public function get_id() {
+ $this->existence_check();
+
+ return $this->id;
+ }
+
/**
* Returns the moodleoverflow where the post is located.
*
diff --git a/classes/post/structure.drawio b/classes/post/structure.drawio
index f0f88c8c7f..53cdbbc020 100644
--- a/classes/post/structure.drawio
+++ b/classes/post/structure.drawio
@@ -1,6 +1,6 @@
-
+
@@ -38,11 +38,6 @@
-
-
-
-
-
@@ -107,18 +102,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
@@ -179,7 +162,7 @@
-
+
diff --git a/lang/en/moodleoverflow.php b/lang/en/moodleoverflow.php
index ec488cb78a..96e589c1a3 100644
--- a/lang/en/moodleoverflow.php
+++ b/lang/en/moodleoverflow.php
@@ -150,6 +150,7 @@
$string['couldnotdeletereplies'] = 'Sorry, that cannot be deleted as people have already responded to it';
$string['noexistingpost'] = 'Post does not exists, needs to be created first';
$string['noexistingdiscussion'] = 'Discussion does not exists, needs to be created first';
+$string['notallpostsavailable'] = 'This Discussion does not have all of its posts, this could lead to errors! Please use moodleoverflow_get_discussion_posts()';
$string['missingformattachments'] = "This functions requires data that were not submitted. Please check the post_form";
// Strings for the classes/mod_form.php.
@@ -177,6 +178,7 @@
$string['notstartuser'] = 'Only the user who started the discussion can mark an answer as helpful.';
$string['notteacher'] = 'Only course owners can do this.';
$string['ratingtoold'] = 'Ratings can only be changed within 30 minutes after the first vote. ';
+$string['postnotpartofdiscussion'] = 'Post does not exist in this discussion, please check the parameter';
// Strings for the discussion.php.
$string['invaliddiscussionid'] = 'Discussion ID was incorrect';
From 0e3c97240f5a32af379c4825bd9c633ac3854599 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Fri, 21 Jul 2023 15:48:15 +0200
Subject: [PATCH 15/56] WIP: post and discussion class ready, post_control
refactoring
---
classes/discussion/discussion.php | 146 ++++++++++++++++++++++++------
classes/post/post.control.php | 44 ++++++++-
classes/post/post.php | 128 ++++++++++++++++++--------
classes/post/structure.drawio | 9 +-
lang/en/moodleoverflow.php | 2 +-
view.php | 1 -
6 files changed, 258 insertions(+), 72 deletions(-)
diff --git a/classes/discussion/discussion.php b/classes/discussion/discussion.php
index 2ded21a52b..58faf21974 100644
--- a/classes/discussion/discussion.php
+++ b/classes/discussion/discussion.php
@@ -43,8 +43,8 @@
* Class that represents a discussion.
* A discussion administrates the posts and has one parent post, that started the discussion.
*
- * Please be careful with functions that delete posts or discussions.
- * Security checks for these functions were done in the post_control class and these functions should only be accessed via this way.
+ * Please be careful with functions that delete, add or edit posts and discussions.
+ * Security checks for these functions were done in the post_control class and these functions should only be accessed that way.
* Accessing these functions directly without the checks from the post control could lead to serious errors.
* @package mod_moodleoverflow
* @copyright 2023 Tamaro Walter
@@ -62,7 +62,7 @@ class discussion {
private $moodleoverflow;
/** @var char The title of the discussion, the titel of the parent post*/
- private $name;
+ public $name;
/** @var int The id of the parent/first post*/
private $firstpost;
@@ -71,27 +71,27 @@ class discussion {
private $userid;
/** @var int Unix-timestamp of modification */
- private $timemodified;
+ public $timemodified;
/** @var int Unix-timestamp of discussion creation */
- private $timestart;
+ public $timestart;
/** @var int the user ID who modified the discussion */
- private $usermodified;
+ public $usermodified;
// Not Database-related attributes.
/** @var array an Array of posts that belong to this discussion */
- private $posts;
+ public $posts;
/** @var bool a variable for checking if this instance has all its posts */
- private $postsbuild;
+ public $postsbuild;
/** @var object The moodleoverflow object where the discussion is located */
- private $moodleoverflowobject;
+ public $moodleoverflowobject;
/** @var object The course module object */
- private $cmobject;
+ public $cmobject;
// Constructors and other builders.
@@ -303,14 +303,17 @@ public function moodleoverflow_add_post_to_discussion($prepost) {
$timenow = time();
// Create the post that will be added to the new discussion.
- $post = post::construct_without_id($this->id, $prepost->parent, $timenow, $timenow, $prepost->message,
+ $post = post::construct_without_id($this->id, $prepost->parent, $prepost->userid, $timenow, $timenow, $prepost->message,
$prepost->messageformat, $prepost->attachment, $prepost->mailed,
$prepost->reviewed, $prepost->timereviewed, $prepost->formattachments);
// Add the post to the DB.
$postid = $post->moodleoverflow_add_new_post();
- // Add the post to the $posts array.
+ // Add the post to the $posts array and update the timemodified in the DB.
$this->posts[$postid] = $post;
+ $this->timemodified = $timenow;
+ $this->usermodified = $prepost->userid;
+ $DB->update_record('moodleoverflow_discussions', $this);
// Return the id of the added post.
return $postid;
@@ -318,48 +321,137 @@ public function moodleoverflow_add_post_to_discussion($prepost) {
/**
* Deletes a post that is in this discussion from the DB.
- *
+ * @param object $prepost The prepost object from the post_control. Has Information about the post and other important stuff.
* @return bool Wether the deletion was possible
* @throws moodle_exception if post is not in this discussion or something failed.
*/
- public function moodleoverflow_delete_post_from_discussion($postid, $deletechildren) {
+ public function moodleoverflow_delete_post_from_discussion($prepost) {
$this->existence_check();
$this->posts_check();
// Check if the posts exists in this discussion.
- $this->post_exists_check($postid);
+ $this->post_exists_check($prepost->postid);
// Access the post and delete it.
- $post = $this->posts[$postid];
- if (!$post->moodleoverflow_delete_post($deletechildren)) {
+ $post = $this->posts[$prepost->postid];
+ if (!$post->moodleoverflow_delete_post($prepost->deletechildren)) {
// Deletion failed.
return false;
}
+
+ // Check for the new last post of the discussion.
+ $this->moodleoverflow_discussion_adapt_to_last_post();
+
// Delete the post from the post array.
- unset($this->posts[$postid]);
+ unset($this->posts[$prepost->postid]);
return true;
}
/**
* Edits the message of a post from this discussion.
+ * @param object $prepost The prepost object from the post_control. Has Information about the post and other important stuff.
*/
- public function moodleoverflow_edit_post_from_discussion($postid, $postmessage) {
+ public function moodleoverflow_edit_post_from_discussion($prepost) {
global $DB;
$this->existence_check();
$this->posts_check();
// Check if the posts exists in this discussion.
- $this->post_exists_check($postid);
+ $this->post_exists_check($prepost->id);
// Get the current time.
$timenow = time();
- // Access the post and edit its message.
- $post = $this->post[$postid];
+ // Access the post.
+ $post = $this->post[$prepost->id];
// If the post is the firstpost, then update the name of this discussion and the post. If not, only update the post.
- if ($postid == array_key_first($posts));
+ if ($prepost->id == array_key_first($posts)) {
+ $this->name = $prepost->subject;
+ $this->usermodified = $prepost->userid;
+ $this->timemodified = $timenow;
+ $DB->update_record('moodleoverflow_discussions', $this);
+ }
+ $post->moodleoverflow_edit_post($timenow, $prepost->message, $prepost->messageformat, $prepost->formattachment);
+
+ // The post has been edited successfully.
+ return true;
+ }
+
+ /**
+ * This Function checks, what the last added or edited post is. If it changed by a delete function,
+ * the timemodified and the usermodified need to be adapted to the last added or edited post.
+ *
+ * @return bool true if the DB needed to be adapted. false if it didn't change.
+ */
+ public function moodleoverflow_discussion_adapt_to_last_post() {
+ global $DB;
+ $this->existence_check();
+
+ // Find the last reviewed post of the discussion (even if the user has review capability, because it's written to DB).
+ $sql = 'SELECT id, userid, modified
+ FROM {moodleoverflow_posts}
+ WHERE discussion = ' . $this->id .
+ ' AND reviewed = 1
+ AND modified = (SELECT MAX(modified) as modified FROM {moodleoverflow_posts})';
+ $record = $DB->get_record_sql($sql);
+ $lastpost = post::from_record($record);
+
+ // Check if the last post changed. If it changed, then update the DB-record of this discussion.
+ if ($lastpost->modified != $this->timemodified || $lastpost->get_userid() != $this->usermodified) {
+ $this->timemodified = $lastpost->modified;
+ $this->usermodified = $lastpost->get_userid();
+ $DB->update_record('moodleoverflow_discussions', $this);
+
+ // Return that the discussion needed an update.
+ return true;
+ }
+
+ // Return that the discussion didn't need an update.
+ return false;
+ }
+
+ // Getter.
+
+ /**
+ * @return int $this->id The post ID.
+ */
+ public function get_id() {
+ $this->existence_check();
+ return $this->id;
+ }
+
+ /**
+ * @return int $this->course The ID of the course where the discussion is located.
+ */
+ public function get_courseid() {
+ $this->existence_check();
+ return $this->course;
+ }
+
+ /**
+ * @return int $this->moodleoverflow The ID of the moodleoverflow where the discussion is located.
+ */
+ public function get_moodleoverflowid() {
+ $this->existence_check();
+ return $this->moodleoverflow;
+ }
+
+ /**
+ * @return int $this->firstpost The ID of the first post.
+ */
+ public function get_firstpostid() {
+ $this->existence_check();
+ return $this->firstpost;
+ }
+
+ /**
+ * @return int $this->userid The ID of the user who wrote the post.
+ */
+ public function get_userid() {
+ $this->existence_check();
+ return $this->userid;
}
/**
@@ -413,11 +505,6 @@ public function moodleoverflow_get_discussion_posts() {
}
- public function moodleoverflow_discussion_update_last_post() {
- // This function has something to do with updating the attribute "timemodified".
- }
-
-
/**
* Returns the moodleoverflowobject
*
@@ -447,7 +534,6 @@ public function get_coursemodule() {
$this->get_moodleoverflow()->course)) {
throw new moodle_exception('invalidcoursemodule');
}
-
}
return $this->cmobject;
@@ -484,7 +570,7 @@ private function posts_check() {
/**
* Check, if certain posts really exists in this discussion.
- *
+ *
* @param int $postid The ID of the post that is being checked.
* @return true
* @throws moodle_exception;
diff --git a/classes/post/post.control.php b/classes/post/post.control.php
index 9387a62763..636d33dbd6 100644
--- a/classes/post/post.control.php
+++ b/classes/post/post.control.php
@@ -35,7 +35,17 @@
require_once(dirname(__FILE__) . '/lib.php');
/**
- * Class that makes checks to interact with posts.
+ * This Class controls the manipulation of posts and acts as controller of interactions with the post.php
+ *
+ * This Class has 2 main Tasks:
+ * 1. Before entering the post.php
+ * - Detect the wanted interaction (new discussion, new answer in a discussion, editing or deleting a post)
+ * - make capability and other security/integrity checks (are all given data correct?)
+ * - gather important information that need to be used later.
+ *
+ * 2. After working with the post.php
+ * - collect the information from the post_form (the post.php build a form where the user enters the message of a post...)
+ * - based on the interaction, call the right function
*
* @package mod_moodleoverflow
* @copyright 2023 Tamaro Walter
@@ -421,4 +431,36 @@ private function build_prepost_delete($deletepostid) {
$this->information->replycount = moodleoverflow_count_replies($this->information->relatedpost, false);
}
+ // Helper functions.
+
+ // Database checks.
+
+ /**
+ * Checks if the course exists and returns the $DB->record
+ *
+ * @param object $moodleoverflow
+ */
+ public function check_course_exists($moodleoverflow) {
+ global $DB;
+ if (!$course = $DB->get_record('course', array('id' => $moodleoverflow->course))) {
+ throw new moodle_exception('invalidcourseid');
+ }
+ return $course;
+ }
+
+ public function check_coursemodule_exists() {
+
+ }
+
+ public function check_moodleoverflow_exists() {
+
+ }
+ public function check_discussion_exists() {
+
+ }
+
+ public function check_post_exists() {
+
+ }
+
}
diff --git a/classes/post/post.php b/classes/post/post.php
index ecdfd43ccf..1cfc37a337 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -30,6 +30,7 @@
use mod_moodleoverflow\capabilities;
use mod_moodleoverflow\review;
use mod_moodleoverflow\readtracking;
+use mod_moodleoverflow\discussion;
defined('MOODLE_INTERNAL') || die();
@@ -39,12 +40,24 @@
/**
* Class that represents a post.
*
+ * Please be careful with functions that delete, add or edit posts.
+ * Security checks for these functions were done in the post_control class and these functions should only be accessed that way.
+ * Accessing these functions directly without the checks from the post_control could lead to serious errors.
+ *
+ * Most of the functions in this class are called by moodleoverflow/classes/discussion/discussion.php . The discussion class
+ * manages posts in a moodleoverflow and works like a toplevel class for the post class. If you want to manipulate
+ * (delete, add, edit) posts, please call the functions from the discussion class. To read and obtain information about posts
+ * you are free to choose.
+ *
* @package mod_moodleoverflow
* @copyright 2023 Tamaro Walter
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class post {
+ // Attributes. The most important attributes are private and can only be changed by internal functions.
+ // Other attributes can be accessed directly.
+
/** @var int The post ID */
private $id;
@@ -58,48 +71,48 @@ class post {
private $userid;
/** @var int Creation timestamp */
- private $created;
+ public $created;
/** @var int Modification timestamp */
- private $modified;
+ public $modified;
/** @var string The message (content) of the post */
- private $message;
+ public $message;
/** @var int The message format*/
- private $messageformat;
+ public $messageformat;
/** @var char Attachment of the post */
- private $attachment;
+ public $attachment;
/** @var int Mailed status*/
- private $mailed;
+ public $mailed;
/** @var int Review status */
- private $reviewed;
+ public $reviewed;
/** @var int The time where the post was reviewed*/
- private $timereviewed;
-
- /** @var int This variable is optional, it contains important information for the add_attachment function */
- private $formattachments;
+ public $timereviewed;
// Not database related functions.
+ /** @var int This variable is optional, it contains important information for the add_attachment function */
+ public $formattachments;
+
/** @var string The subject/title of the Discussion */
- private $subject;
+ public $subject;
/** @var object The discussion where the post is located */
- private $discussionobject;
+ public $discussionobject;
/** @var object The Moodleoverflow where the post is located*/
- private $moodleoverflowobject;
+ public $moodleoverflowobject;
/** @var object The course module object */
- private $cmobject;
+ public $cmobject;
/** @var object The parent post of an answerpost */
- private $parentpost;
+ public $parentpost;
// Constructors and other builders.
@@ -223,7 +236,7 @@ public static function from_record($record) {
* @param int $mailed Mailed status
* @param int $reviewed Review status
* @param int $timereviewed The time where the post was reviewed
- * @param object $formattachments Information about attachments of the post_form
+ * @param object $formattachments Information about attachments from the post_form
*
* @return object post object without id
*/
@@ -231,7 +244,7 @@ public static function construct_without_id($discussion, $parent, $userid, $crea
$messageformat, $attachment, $mailed, $reviewed, $timereviewed, $formattachments = false) {
$id = null;
$instance = new self($id, $discussion, $parent, $userid, $created, $modified, $message,
- $messageformat, $attachment, $mailed, $reviewed, $timereviewed);
+ $messageformat, $attachment, $mailed, $reviewed, $timereviewed, $formattachments);
return $instance;
}
@@ -315,9 +328,6 @@ public function moodleoverflow_delete_post($deletechildren) {
}
}
- // Just in case, check for the new last post of the discussion.
- moodleoverflow_discussion_update_last_post($this->discussion); // NEEDS TO CHANGE WITH NEW DISCUSSION CLASS.
-
// Get the context module.
$modulecontext = context_module::instance($this->get_coursemodule()->id);
@@ -353,29 +363,39 @@ public function moodleoverflow_delete_post($deletechildren) {
/**
* Edits the message from this instance.
- *
- * @param string $postmessage The new message
- * @param object $postattachment
- * @param timestamp $time The time the post was modified (given from the discussion class).
+ * @param timestamp $time The time the post was modified (given from the discussion class).
+ * @param string $postmessage The new message
+ * @param object $messageformat
+ * @param object $formattachments Information about attachments from the post_form
*/
- public function moodleoverflow_edit_post($postmessage, $postattachment, $time) {
+ public function moodleoverflow_edit_post($time, $postmessage, $messageformat, $formattachment) {
global $DB;
$this->existence_check();
// Update the attributes.
- $this->message = $postmessage;
$this->modified = $time;
+ $this->message = $postmessage;
+ $this->messageformat = $messageformat;
+ $this->formattachment = $formattachment; // PLEASE CHECK LATER IF THIS IS NEEDED AFTER WORKING WITH THE POST_FORM CLASS.
+ // Update the record in the database.
$DB->update_record('moodleoverflow_posts', $this);
+ // Update the attachments. This happens after the DB update call, as this function changes the DB record as well.
+ $this->moodleoverflow_add_attachment();
+
+ // Mark the edited post as read.
+ $this->mark_post_read();
+ // The post has been edited successfully.
+ return true;
}
/**
+ * // RETHINK THIS FUNCTION.
* Gets a post with all info ready for moodleoverflow_print_post.
* Most of these joins are just to get the forum id.
*
- *
* @return mixed array of posts or false
*/
public function moodleoverflow_get_complete_post() {
@@ -471,19 +491,40 @@ public function moodleoverflow_get_attachments() {
return $attachments;
}
- // Helper Functions.
+ // Getter.
/**
- * Returns the id of this instance.
- *
- * @return int $this->id
+ * @return int $this->id The post ID.
*/
public function get_id() {
$this->existence_check();
-
return $this->id;
}
+ /**
+ * @return int $this->discussion The ID of the discussion where the post is located.
+ */
+ public function get_discussionid() {
+ $this->existence_check();
+ return $this->discussion;
+ }
+
+ /**
+ * @return int $this->parent The ID of the parent post.
+ */
+ public function get_parentid() {
+ $this->existence_check();
+ return $this->parent;
+ }
+
+ /**
+ * @return int $this->userid The ID of the user who wrote the post.
+ */
+ public function get_userid() {
+ $this->existence_check();
+ return $this->userid;
+ }
+
/**
* Returns the moodleoverflow where the post is located.
*
@@ -495,7 +536,7 @@ public function get_moodleoverflow() {
if (empty($this->moodleoverflowobject)) {
$discussion = $this->get_discussion();
- $this->moodleoverflowobject = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow));
+ $this->moodleoverflowobject = $DB->get_record('moodleoverflow', array('id' => $discussion->get_moodleoverflowid()));
}
return $this->moodleoverflowobject;
@@ -511,9 +552,9 @@ public function get_discussion() {
$this->existence_check();
if (empty($this->discussionobject)) {
- $this->discussionobject = $DB->get_record('moodleoverflow_discussions', array('id' => $this->discussion));
+ $record = $DB->get_record('moodleoverflow_discussions', array('id' => $this->discussion));
+ $this->discussionobject = discussion::from_record($record);
}
-
return $this->discussionobject;
}
@@ -569,6 +610,8 @@ public function moodleoverflow_get_childposts() {
return false;
}
+ // Helper Functions.
+
/**
* Calculate the ratings of a post.
*
@@ -590,6 +633,19 @@ public function moodleoverflow_get_post_ratings() {
return $ratingsobject;
}
+ /**
+ * Marks the post as read if the user is tracking the discussion.
+ * Uses function from mod_moodleoverflow\readtracking.
+ */
+ public function mark_post_read() {
+ global $USER;
+ $cantrack = readtracking::moodleoverflow_can_track_moodleoverflows($this->get_moodleoverflow());
+ $istracked = readtracking::moodleoverflow_is_tracked($this->get_moodleoverflow());
+ if ($cantrack && $istracked) {
+ readtracking::moodleoverflow_mark_post_read($USER->id, $this);
+ }
+ }
+
// Security.
/**
diff --git a/classes/post/structure.drawio b/classes/post/structure.drawio
index 53cdbbc020..893bc6384a 100644
--- a/classes/post/structure.drawio
+++ b/classes/post/structure.drawio
@@ -1,6 +1,6 @@
-
+
@@ -103,7 +103,7 @@
-
+
@@ -148,7 +148,7 @@
-
+
@@ -183,6 +183,9 @@
+
+
+
diff --git a/lang/en/moodleoverflow.php b/lang/en/moodleoverflow.php
index 96e589c1a3..cd37006be0 100644
--- a/lang/en/moodleoverflow.php
+++ b/lang/en/moodleoverflow.php
@@ -143,7 +143,7 @@
$string['couldnotupdate'] = 'Could not update your post due to an unknown error';
$string['editedpostupdated'] = '{$a}\'s post was updated';
$string['postupdated'] = 'Your post was updated';
-$string['editedby'] = 'Edited by {$a->name} - original submission {$a->date}';
+$string['editedby'] = 'Edited by {$a->name} on {$a->date}';
$string['cannotdeletepost'] = 'You can\'t delete this post!';
$string['couldnotdeletereplies'] = 'Sorry, that cannot be deleted as people have already responded to it';
$string['errorwhiledelete'] = 'An error occurred while deleting record.';
diff --git a/view.php b/view.php
index 8867be8bd8..552292d209 100644
--- a/view.php
+++ b/view.php
@@ -65,7 +65,6 @@
// Save the allowmultiplemarks setting.
$marksetting = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow->id), 'allowmultiplemarks');
-
// Require a login.
require_login($course, true, $cm);
From 5ea922140353434aebadb54ea9a4446c3eb542bd Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Wed, 26 Jul 2023 17:22:35 +0200
Subject: [PATCH 16/56] WIP: new post.php file, post control is almost ready
---
classes/discussion/discussion.php | 13 +-
classes/post/post.control.php | 516 ++++++++++++++++++------------
classes/post/structure.drawio | 28 +-
classes/review.php | 2 +-
lang/en/moodleoverflow.php | 4 +
post_new.php | 114 +++++++
6 files changed, 455 insertions(+), 222 deletions(-)
create mode 100644 post_new.php
diff --git a/classes/discussion/discussion.php b/classes/discussion/discussion.php
index 58faf21974..b67dca505d 100644
--- a/classes/discussion/discussion.php
+++ b/classes/discussion/discussion.php
@@ -246,10 +246,10 @@ public function moodleoverflow_add_discussion($prepost) {
/**
* Delete a discussion with all of it's posts
- *
+ * @param object $prepost Information about the post from the post_control
* @return bool Wether deletion was successful of not
*/
- public function moodleoverflow_delete_discussion() {
+ public function moodleoverflow_delete_discussion($prepost) {
global $DB;
$this->existence_check();
$this->posts_check();
@@ -274,6 +274,15 @@ public function moodleoverflow_delete_discussion() {
// Delete the discussion from the database.
$DB->delete_records('moodleoverflow_discussions', array('id' => $this->id));
+ // Trigger the discussion deleted event.
+ $params = array(
+ 'objectid' => $this->id,
+ 'context' => $prepost->modulecontext,
+ );
+
+ $event = \mod_moodleoverflow\event\discussion_deleted::create($params);
+ $event->trigger();
+
// Set the id of this instance to null, so that working with it is not possible anymore.
$this->id = null;
diff --git a/classes/post/post.control.php b/classes/post/post.control.php
index 636d33dbd6..57c0cf2100 100644
--- a/classes/post/post.control.php
+++ b/classes/post/post.control.php
@@ -30,9 +30,13 @@
use mod_moodleoverflow\capabilities;
use mod_moodleoverflow\review;
+use mod_moodleoverflow\post\post;
+use mod_moodleoverflow\discussion;
+
defined('MOODLE_INTERNAL') || die();
require_once(dirname(__FILE__) . '/lib.php');
+require_once(dirname(__FILE__) . '/locallib.php');
/**
* This Class controls the manipulation of posts and acts as controller of interactions with the post.php
@@ -42,9 +46,12 @@
* - Detect the wanted interaction (new discussion, new answer in a discussion, editing or deleting a post)
* - make capability and other security/integrity checks (are all given data correct?)
* - gather important information that need to be used later.
+ * Note: if a post is being deleted, the post_control deletes it in the first step and the post.php does not call the post_form.php
+ *
+ * Now the post.php calls the post_form, so that the user can enter a message and attachments.
*
- * 2. After working with the post.php
- * - collect the information from the post_form (the post.php build a form where the user enters the message of a post...)
+ * 2. After calling the post_form:
+ * - collect the information from the post_form
* - based on the interaction, call the right function
*
* @package mod_moodleoverflow
@@ -53,13 +60,19 @@
*/
class post_control {
- /** @var string the Interaction type */
+ /** @var string the Interaction type, the interactions are:
+ * - create (creates a new discussion with a first post)
+ * - reply (replies to a existing post, can be an answer or a comment)
+ * - edit (change the contennt of an existing post)
+ * - delete (delete a post from a discussion)
+ */
private $interaction;
/** @var object information about the post like the related moodleoverflow, post etc. .*/
- private $information;
+ private $info;
- /** @var object prepost for the classes/post/post_form.php */
+ /** @var object prepost for the classes/post/post_form.php,
+ * this object is only used in this class and its not inserted in tehe database*/
private $prepost;
/**
@@ -67,37 +80,15 @@ class post_control {
*
* @param object $urlparameter Parameter that were sent when post.php where opened.
*/
- public function __construct($urlparameter) {
- $this->information = new \stdClass;
- $this->detect_interaction($urlparameter); // Detects interaction and makes security checks.
- }
-
- /**
- * Returns the interaction type.
- */
- public function get_interaction() {
- return $this->interaction;
- }
-
- /**
- * Returns the gathered important information in the build_prepost_() functions.
- */
- public function get_information() {
- return $this->information;
- }
-
- /**
- * Retuns the prepared post.
- */
- public function get_prepost() {
- return $this->prepost;
+ public function __construct() {
+ $this->info = new \stdClass;
}
/**
* Detects the interaction
* @param object $urlparamter parameter from the post.php
*/
- private function detect_interaction($urlparameter) {
+ public function detect_interaction($urlparameter) {
$count = 0;
$count += $urlparameter->create ? 1 : 0;
$count += $urlparameter->reply ? 1 : 0;
@@ -109,31 +100,56 @@ private function detect_interaction($urlparameter) {
if ($urlparameter->create) {
$this->interaction = 'create';
- $this->information->moodleoverflowid = $urlparameter->create;
- $this->build_prepost_create($this->information->moodleoverflowid);
+ $this->info->moodleoverflowid = $urlparameter->create;
+ $this->build_prepost_create($this->info->moodleoverflowid);
} else if ($urlparameter->edit) {
$this->interaction = 'edit';
- $this->information->editpostid = $urlparameter->edit;
- $this->build_prepost_edit($this->information->editpostid);
+ $this->info->editpostid = $urlparameter->edit;
+ $this->build_prepost_edit($this->info->editpostid);
} else if ($urlparameter->reply) {
$this->interaction = 'reply';
- $this->information->replypostid = $urlparameter->edit;
- $this->build_prepost_reply($this->information->replypostid);
+ $this->info->replypostid = $urlparameter->edit;
+ $this->build_prepost_reply($this->info->replypostid);
} else if ($urlparameter->delete) {
$this->interaction = 'delete';
- $this->information->deletepostid = $urlparameter->edit;
- $this->build_prepost_delete($this->information->deletepostid);
+ $this->info->deletepostid = $urlparameter->edit;
+ $this->build_prepost_delete($this->info->deletepostid);
} else {
throw new moodle_exception('unknownaction');
}
}
- // Private functions.
+ /**
+ * This function is used when a guest enters the post.php.
+ * Parameters will be checked so that the post.php can redirect the user to the right site.
+ *
+ * @return object $this->information // The gathered information.
+ */
+ public function catch_guest($postid = false, $moodleoverflowid = false) {
+ global $PAGE;
+ if ((!$postid && !$moodleoverflowid) || ($postid && $moodleoverflowid)) {
+ throw new moodle_exception('inaccurateparameter', 'moodleoverflow');
+ }
+ if ($postid) {
+ $this->collect_information($postid, false);
+ } else if ($moodleoverflowid) {
+ $this->collect_information(false, $moodleoverflowid);
+ }
+ $this->info->modulecontext = context_module::instance($this->info->cm->id);
+
+ // Set the parameters for the page.
+ $PAGE->set_cm($this->info->cm, $this->info->course, $this->info->moodleoverflow);
+ $PAGE->set_context($this->info->modulecontext);
+ $PAGE->set_title($this->info->course->shortname);
+ $PAGE->set_heading($this->info->course->fullname);
+ $PAGE->add_body_class('limitedwidth');
+ return $this->info;
+ }
- // Build_prepost functions: makes important checks and saves all important information in $prepost object.
+ // Build functions, that build the prepost object for further use.
/**
* Function to prepare a new discussion in moodleoverflow.
@@ -142,37 +158,26 @@ private function detect_interaction($urlparameter) {
*/
private function build_prepost_create($moodleoverflowid) {
global $DB, $SESSION, $USER;
- // Check the moodleoverflow instance is valid.
- if (!$this->information->moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflowid))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
- // Get the related course.
- if (!$this->information->course = $DB->get_record('course', array('id' => $this->information->moodleoverflow->course))) {
- throw new moodle_exception('invalidcourseid');
- }
- // Get the related coursemodule.
- if (!$this->information->cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflowid,
- $this->information->course->id)) {
- throw new moodle_exception('invalidcoursemodule');
- }
+
+ // Get the related moodleoverflow, course and coursemodule.
+ $this->collect_information(false, $moodleoverflowid);
+
// Retrieve the contexts.
- $this->information->modulecontext = context_module::instance($this->information->cm->id);
- $this->information->coursecontext = context_module::instance($this->information->course->id);
+ $this->info->modulecontext = context_module::instance($this->info->cm->id);
+ $this->info->coursecontext = context_module::instance($this->info->course->id);
// Check if the user can start a new discussion.
- if (!moodleoverflow_user_can_post_discussion($this->information->moodleoverflow,
- $this->information->cm,
- $this->information->modulecontext)) {
+ if (!moodleoverflow_user_can_post_discussion($this->info->moodleoverflow, $this->info->cm, $this->info->modulecontext)) {
// Catch unenrolled user.
- if (!isguestuser() && !is_enrolled($this->information->coursecontext)) {
- if (enrol_selfenrol_available($this->information->course->id)) {
+ if (!isguestuser() && !is_enrolled($this->info->coursecontext)) {
+ if (enrol_selfenrol_available($this->info->course->id)) {
$SESSION->wantsurl = qualified_me();
$SESSION->enrolcancel = get_local_referer(false);
redirect(new moodle_url('/enrol/index.php',
- array('id' => $this->information->course->id,
+ array('id' => $this->info->course->id,
'returnurl' => '/mod/moodleoverflow/view.php?m=' .
- $this->information->moodleoverflow->id)),
+ $this->info->moodleoverflow->id)),
get_string('youneedtoenrol'));
}
}
@@ -181,8 +186,8 @@ private function build_prepost_create($moodleoverflowid) {
}
// Set the post to not reviewed if questions should be reviewed and the user is not a reviewed themselve.
- if (review::get_review_level($this->information->moodleoverflow) >= review::QUESTIONS &&
- !capabilities::has(capabilities::REVIEW_POST, $this->information->modulecontext, $USER->id)) {
+ if (review::get_review_level($this->info->moodleoverflow) >= review::QUESTIONS &&
+ !capabilities::has(capabilities::REVIEW_POST, $this->info->modulecontext, $USER->id)) {
$reviewed = 0;
}
@@ -190,14 +195,16 @@ private function build_prepost_create($moodleoverflowid) {
$SESSION->fromurl = get_local_referer(false);
// Prepare the post.
- $this->prepost = new stdClass();
- $this->prepost->courseid = $this->information->course->id;
- $this->prepost->moodleoverflowid = $this->information->moodleoverflow->id;
+ $this->prepost = new \stdClass();
+ $this->prepost->postid = $this->info->relatedpost->get_id();
+ $this->prepost->courseid = $this->info->course->id;
+ $this->prepost->moodleoverflowid = $this->info->moodleoverflow->id;
$this->prepost->discussionid = 0;
$this->prepost->parentid = 0;
$this->prepost->subject = '';
$this->prepost->userid = $USER->id;
$this->prepost->message = '';
+ $this->prepost->modulecontext = $this->info->modulecontext;
$this->prepost->reviewed = $reviewed; // IST DAS OKAY?!
// Unset where the user is coming from.
@@ -212,74 +219,49 @@ private function build_prepost_create($moodleoverflowid) {
*/
private function build_prepost_reply($replypostid) {
global $DB, $PAGE, $SESSION, $USER;
- // Check if the related post exists.
- if (!$this->information->parent = moodleoverflow_get_post_full($replypostid)) {
- throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
- }
-
- // Check if the post is part of a valid discussion.
- if (!$this->information->discussion = $DB->get_record('moodleoverflow_discussions',
- array('id' => $this->information->parent->discussion))) {
- throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
- }
-
- // Check if the post is related to a valid moodleoverflow instance.
- if (!$this->information->moodleoverflow = $DB->get_record('moodleoverflow',
- array('id' => $this->information->discussion->moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
-
- // Check if the moodleoverflow instance is part of a course.
- if (!$this->information->course = $DB->get_record('course', array('id' => $this->information->discussion->course))) {
- throw new moodle_exception('invalidcourseid');
- }
- // Retrieve the related coursemodule.
- if (!$this->information->cm = get_coursemodule_from_instance('moodleoverflow',
- $this->information->moodleoverflow->id,
- $this->information->course->id)) {
- throw new moodle_exception('invalidcoursemodule');
- }
+ // Get the related poost, discussion, moodleoverflowm course and coursemodule.
+ $this->collect_information($replypostid, false);
// Ensure the coursemodule is set correctly.
- $PAGE->set_cm($this->information->cm, $this->information->course, $this->information->moodleoverflow);
+ $PAGE->set_cm($this->info->cm, $this->info->course, $this->info->moodleoverflow);
// Retrieve the contexts.
- $this->information->modulecontext = context_module::instance($this->information->cm->id);
- $this->information->coursecontext = context_module::instance($this->information->course->id);
+ $this->info->modulecontext = context_module::instance($this->info->cm->id);
+ $this->info->coursecontext = context_module::instance($this->info->course->id);
// Check whether the user is allowed to post.
- if (!moodleoverflow_user_can_post($this->information->modulecontext, $this->information->parent)) {
+ if (!moodleoverflow_user_can_post($this->info->modulecontext, $this->info->parent)) {
// Give the user the chance to enroll himself to the course.
- if (!isguestuser() && !is_enrolled($this->information->coursecontext)) {
+ if (!isguestuser() && !is_enrolled($this->info->coursecontext)) {
$SESSION->wantsurl = qualified_me();
$SESSION->enrolcancel = get_local_referer(false);
redirect(new moodle_url('/enrol/index.php',
- array('id' => $this->information->course->id,
+ array('id' => $this->info->course->id,
'returnurl' => '/mod/moodleoverflow/view.php?m=' .
- $this->information->moodleoverflow->id)),
+ $this->info->moodleoverflow->id)),
get_string('youneedtoenrol'));
}
// Print the error message.
throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
}
// Make sure the user can post here.
- if (!$this->information->cm->visible &&
- !has_capability('moodle/course:viewhiddenactivities', $this->information->modulecontext)) {
-
+ if (!$this->info->cm->visible && !has_capability('moodle/course:viewhiddenactivities', $this->info->modulecontext)) {
throw new moodle_exception('activityiscurrentlyhidden');
}
// Prepare a post.
- $this->prepost = new stdClass();
- $this->prepost->courseid = $this->information->course->id;
- $this->prepost->moodleoverflowid = $this->information->moodleoverflow->id;
- $this->prepost->discussionid = $this->information->discussion->id;
- $this->prepost->parentid = $this->information->parent->id;
- $this->prepost->subject = $this->information->discussion->name;
+ $this->prepost = new \stdClass();
+ $this->prepost->postid = $this->info->relatedpost->get_id();
+ $this->prepost->courseid = $this->info->course->id;
+ $this->prepost->moodleoverflowid = $this->info->moodleoverflow->id;
+ $this->prepost->discussionid = $this->info->discussion->get_id();
+ $this->prepost->parentid = $this->info->relatedpost->get_parentid();
+ $this->prepost->subject = $this->info->discussion->name;
$this->prepost->userid = $USER->id;
$this->prepost->message = '';
+ $this->prepost->modulecontext = $this->info->modulecontext;
// Append 'RE: ' to the discussions subject.
$strre = get_string('re', 'moodleoverflow');
@@ -293,73 +275,38 @@ private function build_prepost_reply($replypostid) {
}
/**
- * Function to prepare the edit of an existing post.
+ * Function to prepare the edit of an user own existing post.
*
* @param int $editpostid The ID of the post that is being edited.
*/
private function build_prepost_edit($editpostid) {
global $DB, $PAGE, $SESSION, $USER;
- // Third possibility: The user is editing his own post.
-
- // Check if the submitted post exists.
- if (!$this->information->relatedpost = moodleoverflow_get_post_full($editpostid)) {
- throw new moodle_exception('invalidpostid', 'moodleoverflow');
- }
-
- // Get the parent post of this post if it is not the starting post of the discussion.
- if ($this->information->relatedpost->parent) {
- if (!$this->information->parent = moodleoverflow_get_post_full($this->information->relatedpost->parent)) {
- throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
- }
- }
-
- // Check if the post refers to a valid discussion.
- if (!$this->information->discussion = $DB->get_record('moodleoverflow_discussions',
- array('id' => $this->information->relatedpost->discussion))) {
- throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
- }
-
- // Check if the post refers to a valid moodleoverflow instance.
- if (!$this->information->moodleoverflow = $DB->get_record('moodleoverflow',
- array('id' => $this->information->discussion->moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
-
- // Check if the post refers to a valid course.
- if (!$this->information->course = $DB->get_record('course', array('id' => $this->information->discussion->course))) {
- throw new moodle_exception('invalidcourseid');
- }
-
- // Retrieve the related coursemodule.
- if (!$this->information->cm = get_coursemodule_from_instance('moodleoverflow',
- $this->information->moodleoverflow->id,
- $this->information->course->id)) {
- throw new moodle_exception('invalidcoursemodule');
- }
+ // Get the related post, discussion, moodleoverflow, course and coursemodule.
+ $this->collect_information($editpostid, false);
// Retrieve contexts.
- $this->information->modulecontext = context_module::instance($this->information->cm->id);
+ $this->info->modulecontext = context_module::instance($this->info->cm->id);
// Set the pages context.
- $PAGE->set_cm($this->information->cm, $this->information->course, $this->information->moodleoverflow);
+ $PAGE->set_cm($this->info->cm, $this->info->course, $this->info->moodleoverflow);
// Check if the post can be edited.
- $beyondtime = ((time() - $this->information->relatedpost->created) > get_config('moodleoverflow', 'maxeditingtime'));
- $alreadyreviewed = review::should_post_be_reviewed($this->information->relatedpost, $this->information->moodleoverflow)
- && $this->information->relatedpost->reviewed;
+ $beyondtime = ((time() - $this->info->relatedpost->created) > get_config('moodleoverflow', 'maxeditingtime'));
+ $alreadyreviewed = review::should_post_be_reviewed($this->info->relatedpost, $this->info->moodleoverflow)
+ && $this->info->relatedpost->reviewed;
if (($beyondtime || $alreadyreviewed) && !has_capability('mod/moodleoverflow:editanypost',
- $this->information->modulecontext)) {
+ $this->info->modulecontext)) {
throw new moodle_exception('maxtimehaspassed', 'moodleoverflow', '',
format_time(get_config('moodleoverflow', 'maxeditingtime')));
}
// If the current user is not the one who posted this post.
- if ($this->information->relatedpost->userid <> $USER->id) {
+ if ($this->info->relatedpost->get_userid() != $USER->id) {
// Check if the current user has not the capability to edit any post.
- if (!has_capability('mod/moodleoverflow:editanypost', $this->information->modulecontext)) {
+ if (!has_capability('mod/moodleoverflow:editanypost', $this->info->modulecontext)) {
// Display the error. Capabilities are missing.
throw new moodle_exception('cannoteditposts', 'moodleoverflow');
@@ -367,10 +314,16 @@ private function build_prepost_edit($editpostid) {
}
// Load the $post variable.
- $this->prepost = $this->information->relatedpost;
- $this->prepost->editid = $editpostid;
- $this->prepost->course = $this->information->course->id;
- $this->prepost->moodleoverflow = $this->information->moodleoverflow->id;
+ $this->prepost = new \stdClass();
+ $this->prepost->postid = $this->info->relatedpost->get_id();
+ $this->prepost->courseid = $this->info->course->id;
+ $this->prepost->moodleoverflowid = $this->info->moodleoverflow->id;
+ $this->prepost->discussionid = $this->info->discussion->id;
+ $this->prepost->parentid = $this->info->relatedpost->get_parentid();
+ $this->prepost->subject = $this->info->discussion->name;
+ $this->prepost->message = $this->info->relatedpost->message;
+ $this->prepost->userid = $this->info->relatedpost->get_userid();
+ $this->prepost->modulecontext = $this->info->modulecontext;
// Unset where the user is coming from.
// Allows to calculate the correct return url later.
@@ -385,82 +338,235 @@ private function build_prepost_edit($editpostid) {
private function build_prepost_delete($deletepostid) {
global $DB, $USER;
- // Check if the post is existing.
- if (!$this->information->relatedpost = moodleoverflow_get_post_full($deletepostid)) {
- throw new moodle_exception('invalidpostid', 'moodleoverflow');
- }
+ // Get the realted post, discussion, moodleoverflow, course and coursemodule.
+ $this->collect_information($deletepostid, false);
- // Get the related discussion.
- if (!$this->information->discussion = $DB->get_record('moodleoverflow_discussions',
- array('id' => $this->information->relatedpost->discussion))) {
- throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
- }
+ // Require a login and retrieve the modulecontext.
+ require_login($this->info->course, false, $this->info->cm);
+ $this->info->modulecontext = context_module::instance($this->info->cm->id);
- // Get the related moodleoverflow instance.
- if (!$this->information->moodleoverflow = $DB->get_record('moodleoverflow',
- array('id' => $this->information->discussion->moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoveflow');
- }
+ // Check some capabilities.
+ $this->info->deleteownpost = has_capability('mod/moodleoverflow:deleteownpost', $this->info->modulecontext);
+ $this->info->deleteanypost = has_capability('mod/moodleoverflow:deleteanypost', $this->info->modulecontext);
+ if (!(($this->info->relatedpost->get_userid() == $USER->id && $this->info->deleteownpost)
+ || $this->info->deleteanypost)) {
- // Get the related coursemodule.
- if (!$this->information->cm = get_coursemodule_from_instance('moodleoverflow',
- $this->information->moodleoverflow->id,
- $this->information->moodleoverflow->course)) {
- throw new moodle_exception('invalidcoursemodule');
+ throw new moodle_exception('cannotdeletepost', 'moodleoverflow');
}
- // Get the related course.
- if (!$this->information->course = $DB->get_record('course', array('id' => $this->information->moodleoverflow->course))) {
- throw new moodle_exception('invalidcourseid');
+ // Count all replies of this post.
+ $this->info->replycount = moodleoverflow_count_replies($this->info->relatedpost, false);
+
+ // In the delete interaction the prepost is already the post object.
+ $this->prepost = new \stdClass();
+ $this->prepost->postid = $this->info->relatedpost->get_id();
+ $this->prepost->courseid = $this->info->course->id;
+ $this->prepost->moodleoverflowid = $this->info->moodleoverflow->id;
+ $this->prepost->discussionid = $this->info->discussion->id;
+ $this->prepost->parentid = $this->info->relatedpost->get_parentid();
+ $this->prepost->subject = $this->info->discussion->name;
+ $this->prepost->message = $this->info->relatedpost->message;
+ $this->prepost->userid = $this->info->relatedpost->get_userid();
+ $this->prepost->modulecontext = $this->info->modulecontext;
+ $this->prepost->deletechildren = true;
+ }
+
+
+ // Execute Functions, that execute an interaction.
+
+ public function execute_create() {
+ $this->check_interaction('create');
+ }
+
+ public function execute_reply() {
+ $this->check_interaction('reply');
+ }
+
+ public function execute_edit() {
+ $this->check_interaction('edit');
+ }
+
+ public function execute_delete() {
+ $this->check_interaction('delete');
+
+ // Check if the user has the capability to delete the post.
+ $timepassed = time() - $this->info->relatedpost->created;
+ $url = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->info->discussion->get_id()));
+ if (($timepassed > get_config('moodleoverflow', 'maxeditingtime')) && !$this->info->deleteanypost) {
+ throw new moodle_exception('cannotdeletepost', 'moodleoverflow', moodleoverflow_go_back_to($url));
}
- // Require a login and retrieve the modulecontext.
- require_login($this->information->course, false, $this->information->cm);
- $this->information->modulecontext = context_module::instance($this->information->cm->id);
+ // A normal user cannot delete his post if there are direct replies.
+ if ($this->infro->replycount && !$this->info->deleteanypost) {
+ throw new moodle_exception('cannotdeletereplies', 'moodleoverflow', moodleoverflow_go_back_to($url));
+ }
- // Check some capabilities.
- $this->information->deleteownpost = has_capability('mod/moodleoverflow:deleteownpost', $this->information->modulecontext);
- $this->information->deleteanypost = has_capability('mod/moodleoverflow:deleteanypost', $this->information->modulecontext);
- if (!(($this->information->relatedpost->userid == $USER->id && $this->information->deleteownpost)
- || $this->information->deleteanypost)) {
+ // Check if the post is a parent post or not.
+ if ($this->prepost->get_parentid() == 0) {
+ $this->info->discussion->moodleoverflow_delete_discussion($this->prepost);
- throw new moodle_exception('cannotdeletepost', 'moodleoverflow');
+ // Redirect the user back to the start page of the moodleoverflow instance.
+ redirect('view.php?m=' . $this->info->discussion->get_moodleoverflowid());
+ } else {
+ $this->info->discussion->moodleoverflow_delete_post_from_discussion($this->prepost);
+ $discussionurl = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->info->discussion->get_id()));
+ redirect(moodleoverflow_go_back_to($discussionurl));
}
+ }
- // Count all replies of this post.
- $this->information->replycount = moodleoverflow_count_replies($this->information->relatedpost, false);
+ // Confirm Function for the delete interaction.
+
+ /**
+ * Builds a part of confirmation page. The confirmation request box is being build by the post.php.
+ */
+ public function confirm_delete() {
+ $this->check_interaction('delete');
+ global $PAGE;
+ moodleoverflow_set_return();
+ $PAGE->navbar->add(get_string('delete', 'moodleoverflow'));
+ $PAGE->set_title($this->info->course->shortname);
+ $PAGE->set_heading($this->info->course->fullname);
+ $PAGE->add_body_class('limitedwidth');
}
// Helper functions.
+ // Getter.
+
+ /**
+ * Returns the interaction type.
+ * @return string $interaction
+ */
+ public function get_interaction() {
+ return $this->interaction;
+ }
+
+ /**
+ * Returns the gathered important information in the build_prepost_() functions.
+ * @return object $info
+ */
+ public function get_information() {
+ return $this->info;
+ }
+
+ /**
+ * Retuns the prepared post.
+ * @return object $prepost
+ */
+ public function get_prepost() {
+ return $this->prepost;
+ }
+
+ // Information function.
+
+ /**
+ * Builds the information object that is being used in the build prepost functions.
+ * The variables are optional, but one is necessary to build the information object.
+ * @param int $postid
+ * @param int $moodleoverflowid
+ * @return bool, if object could be build or not.
+ */
+ private function collect_information($postid = false, $moodleoverflowid = false) {
+ if ((!$postid && !$moodleoverflowid) || ($postid && $moodleoverflowid)) {
+ throw new moodle_exception('inaccurateparameter', 'moodleoverflow');
+ return false;
+ }
+ if ($postid) {
+ $this->info->relatedpost = $this->check_post_exists($postid);
+ $this->info->discussion = $this->check_discussion_exists($this->info->relatedpost->get_discussionid());
+ $localmoodleoverflowid = $this->info->discussion->get_moodleoverflowid();
+ } else if ($moodleoverflowid) {
+ $localmoodleoverflowid = $moodleoverflowid;
+ }
+ $this->info->moodleoverflow = $this->check_moodleoverflow_exists($localmoodleoverflowid);
+ $this->info->course = $this->check_course_exists($this->info->moodleoverflow->course);
+ $this->info->cm = $this->check_coursemodule_exists($this->info->moodleoverflow->id, $this->info->course->id);
+ return true;
+ }
+
+ // Interaction check.
+
+ /**
+ * Checks if the interaction is correct
+ * @param string $interaction
+ * @return true if the interaction is correct
+ */
+ private function check_interaction($interaction) {
+ if ($this->interaction != $interaction) {
+ throw new moodle_exception('wronginteraction' , 'moodleoverflow');
+ }
+ return true;
+ }
+
// Database checks.
/**
- * Checks if the course exists and returns the $DB->record
- *
- * @param object $moodleoverflow
+ * Checks if the course exists. Returns the $DB->record of the course.
+ * @param int $courseid
+ * @return object $course
*/
- public function check_course_exists($moodleoverflow) {
+ private function check_course_exists($courseid) {
global $DB;
- if (!$course = $DB->get_record('course', array('id' => $moodleoverflow->course))) {
+ if (!$course = $DB->get_record('course', array('id' => $courseid))) {
throw new moodle_exception('invalidcourseid');
}
return $course;
}
- public function check_coursemodule_exists() {
-
+ /**
+ * Checks if the coursemodule exists.
+ * @param int $moodleoverflowid
+ * @param int $courseid
+ * @return object $cm
+ */
+ private function check_coursemodule_exists($moodleoverflowid, $courseid) {
+ if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflowid,
+ $courseid)) {
+ throw new moodle_exception('invalidcoursemodule');
+ }
+ return $cm;
}
- public function check_moodleoverflow_exists() {
-
+ /**
+ * Checks if the related moodleoverflow exists.
+ * @param int $moodleoverflowid
+ * @return object $moodleoverflow
+ */
+ private function check_moodleoverflow_exists($moodleoverflowid) {
+ // Get the related moodleoverflow instance.
+ global $DB;
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflowid))) {
+ throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
+ }
+ return $moodleoverflow;
}
- public function check_discussion_exists() {
+ /**
+ * Checks if the related discussion exists.
+ * @param int $discussionid
+ * @return object $discussion
+ */
+ private function check_discussion_exists($discussionid) {
+ global $DB;
+ if (!$discussionrecord = $DB->get_record('moodleoverflow_discussions', array('id' => $discussionid))) {
+ throw new moodle_exception('invaliddiscussionid', 'moodleoverflow');
+ }
+ $discussion = discussion::from_record($discussionrecord);
+ return $discussion;
}
- public function check_post_exists() {
-
+ /**
+ * Checks if a post exists.
+ * @param int $postid
+ * @return object $post
+ */
+ private function check_post_exists($postid) {
+ global $DB;
+ if (!$postrecord = $DB->get_record('moodleoverflow_posts', array('id' => $postid))) {
+ throw new moodle_exception('invalidpostid', 'moodleoverflow');
+ }
+ $post = post::from_record($postrecord);
+ return $post;
}
}
diff --git a/classes/post/structure.drawio b/classes/post/structure.drawio
index 893bc6384a..691bd360a6 100644
--- a/classes/post/structure.drawio
+++ b/classes/post/structure.drawio
@@ -1,6 +1,6 @@
-
+
@@ -63,20 +63,20 @@
-
+
-
+
-
+
-
-
+
+
-
+
@@ -89,7 +89,7 @@
-
+
@@ -99,8 +99,8 @@
-
-
+
+
@@ -153,9 +153,9 @@
-
+
-
+
@@ -183,8 +183,8 @@
-
-
+
+
diff --git a/classes/review.php b/classes/review.php
index 7d6b417dff..77ddd2e67b 100644
--- a/classes/review.php
+++ b/classes/review.php
@@ -132,7 +132,7 @@ public static function get_first_review_post($moodleoverflowid, $afterpostid = n
*/
public static function should_post_be_reviewed($post, $moodleoverflow): bool {
$reviewlevel = self::get_review_level($moodleoverflow);
- if ($post->parent) {
+ if ($post->get_parentid() != 0) {
return $reviewlevel == self::EVERYTHING;
} else {
return $reviewlevel >= self::QUESTIONS;
diff --git a/lang/en/moodleoverflow.php b/lang/en/moodleoverflow.php
index cd37006be0..2fb184cf39 100644
--- a/lang/en/moodleoverflow.php
+++ b/lang/en/moodleoverflow.php
@@ -153,6 +153,10 @@
$string['notallpostsavailable'] = 'This Discussion does not have all of its posts, this could lead to errors! Please use moodleoverflow_get_discussion_posts()';
$string['missingformattachments'] = "This functions requires data that were not submitted. Please check the post_form";
+// String for the classes/post/post_control.php.
+$string['inaccurateparameter'] = 'Please check your parameter and give exactly 1 parameter to the function';
+$string['wronginteraction'] = 'Wrong interaction detected, please choose the right function';
+
// Strings for the classes/mod_form.php.
$string['subject'] = 'Subject';
$string['reply'] = 'Comment';
diff --git a/post_new.php b/post_new.php
new file mode 100644
index 0000000000..d292ac902e
--- /dev/null
+++ b/post_new.php
@@ -0,0 +1,114 @@
+.
+
+/**
+ * The file that is opened in Moodle when the user interacts with posts
+ *
+ * @package mod_moodleoverflow
+ * @copyright 2023 Tamaro Walter
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+use mod_moodleoverflow\review;
+use mod_moodleoverflow\post\post_control;
+require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
+require_once(dirname(__FILE__) . '/locallib.php');
+require_once($CFG->libdir . '/completionlib.php');
+
+global $CFG, $USER, $DB, $PAGE, $SESSION, $OUTPUT;
+
+// Declare optional url parameters.
+$moodleoverflow = optional_param('moodleoverflow', 0, PARAM_INT);
+$reply = optional_param('reply', 0, PARAM_INT);
+$edit = optional_param('edit', 0, PARAM_INT);
+$delete = optional_param('delete', 0, PARAM_INT);
+$confirm = optional_param('confirm', 0, PARAM_INT);
+
+// Set the URL that should be used to return to this page.
+$PAGE->set_url('/mod/moodleoverflow/post.php', array(
+ 'moodleoverflow' => $moodleoverflow,
+ 'reply' => $reply,
+ 'edit' => $edit,
+ 'delete' => $delete,
+ 'confirm' => $confirm,
+));
+
+// These params will be passed as hidden variables later in the form.
+$pageparams = array('moodleoverflow' => $moodleoverflow, 'reply' => $reply, 'edit' => $edit);
+
+// Get the system context instance.
+$systemcontext = context_system::instance();
+
+// Create a post_control object to control the process.
+$postcontrol = new post_control();
+
+// Put all interaction parameters in one object for the post_control.
+$urlparameter = new \stdClass();
+$urlparameter->create = $moodleoverflow;
+$urlparameter->reply = $reply;
+$urlparameter->edit = $edit;
+$urlparameter->delete = $delete;
+
+// Catch guests.
+if (!isloggedin() || isguestuser()) {
+ // Gather information and set the page right so that user can be redirected to the right site.
+ $information = $postcontrol->catch_guest();
+
+ // The guest needs to login.
+ $strlogin = get_string('noguestpost', 'forum') . '
' . get_string('liketologin');
+ echo $OUTPUT->header();
+ echo $OUTPUT->confirm($strlogin, get_login_url(),
+ $CFG->wwwroot . '/mod/moodleoverflow/view.php?m= ' . $information->moodleoverflow->id);
+ echo $OUTPUT->footer();
+ exit;
+}
+
+// Require a general login to post something.
+require_login(0, false);
+
+// Now the post_control checks which interaction is wanted and builds a prepost.
+$postcontrol->detect_interaction($urlparameter);
+
+// If a post is being deleted, delete it immediately.
+if ($postcontrol->get_interaction() == 'delete') {
+ // Has the user confirmed the deletion?
+ if (!empty($confirm) && confirm_sesskey()) {
+ $postcontrol->execute_delete();
+ exit;
+ } else {
+ // Deletion needs to be confirmed.
+ $postcontrol->confirm_delete();
+
+ // Display a confirmation request depending on the number of posts that are being deleted.
+ $information = $postcontrol->get_information();
+ echo $OUTPUT->header();
+ if ($information->deletetype == 'plural') {
+ echo $OUTPUT->confirm(get_string('deletesureplural', 'moodleoverflow', $information->replycount + 1),
+ 'post.php?delete='.$delete.'&confirm='.$delete,
+ $CFG->wwwroot . '/mod/moodleoverflow/discussion.php?d=' . $information->discussion->get_id() .
+ '#p' . $information->relatedpost->get_id());
+ } else {
+ echo $OUTPUT->confirm(get_string('deletesure', 'moodleoverflow', $information->replycount),
+ "post.php?delete=$delete&confirm=$delete",
+ $CFG->wwwroot . '/mod/moodleoverflow/discussion.php?d=' . $information->discussion->get_id() .
+ '#p' . $information->relatedpost->get_id());
+ }
+ echo $OUTPUT->footer();
+ exit;
+ }
+}
+
+// Now the post_form will be prepared.
From 70ac6d62ac9a1a46a7fd6f8c9c72bceede69b32c Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 27 Jul 2023 16:03:40 +0200
Subject: [PATCH 17/56] new post.php complete
---
classes/discussion/discussion.php | 18 ++-
classes/post/post.control.php | 208 ++++++++++++++++++++----------
classes/post/post.php | 9 +-
classes/post_form.php | 5 +-
classes/review.php | 2 +-
post_new.php | 46 ++++++-
6 files changed, 209 insertions(+), 79 deletions(-)
diff --git a/classes/discussion/discussion.php b/classes/discussion/discussion.php
index b67dca505d..67c9a3aec2 100644
--- a/classes/discussion/discussion.php
+++ b/classes/discussion/discussion.php
@@ -40,15 +40,15 @@
require_once($CFG->dirroot . '/mod/moodleoverflow/locallib.php');
/**
- * Class that represents a discussion.
- * A discussion administrates the posts and has one parent post, that started the discussion.
+ * Class that represents a discussion. A discussion administrates the posts and has one parent post, that started the discussion.
*
- * Please be careful with functions that delete, add or edit posts and discussions.
- * Security checks for these functions were done in the post_control class and these functions should only be accessed that way.
- * Accessing these functions directly without the checks from the post control could lead to serious errors.
* @package mod_moodleoverflow
* @copyright 2023 Tamaro Walter
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ *
+ * Please be careful with functions that delete, add or edit posts and discussions.
+ * Security checks for these functions were done in the post_control class and these functions should only be accessed that way.
+ * Accessing these functions directly without the checks from the post control could lead to serious errors.
*/
class discussion {
@@ -424,6 +424,7 @@ public function moodleoverflow_discussion_adapt_to_last_post() {
// Getter.
/**
+ * Getter for the post ID
* @return int $this->id The post ID.
*/
public function get_id() {
@@ -432,6 +433,7 @@ public function get_id() {
}
/**
+ * Getter for the courseid
* @return int $this->course The ID of the course where the discussion is located.
*/
public function get_courseid() {
@@ -440,6 +442,7 @@ public function get_courseid() {
}
/**
+ * Getter for the moodleoverflowid
* @return int $this->moodleoverflow The ID of the moodleoverflow where the discussion is located.
*/
public function get_moodleoverflowid() {
@@ -448,6 +451,7 @@ public function get_moodleoverflowid() {
}
/**
+ * Getter for the firstpostid
* @return int $this->firstpost The ID of the first post.
*/
public function get_firstpostid() {
@@ -456,7 +460,8 @@ public function get_firstpostid() {
}
/**
- * @return int $this->userid The ID of the user who wrote the post.
+ * Getter for the userid
+ * @return int $this->userid The ID of the user who wrote the first post.
*/
public function get_userid() {
$this->existence_check();
@@ -465,7 +470,6 @@ public function get_userid() {
/**
* Returns the ratings from this discussion.
- *
* @return array of votings
*/
public function moodleoverflow_get_discussion_ratings() {
diff --git a/classes/post/post.control.php b/classes/post/post.control.php
index 57c0cf2100..b4b4f4f07b 100644
--- a/classes/post/post.control.php
+++ b/classes/post/post.control.php
@@ -37,6 +37,8 @@
require_once(dirname(__FILE__) . '/lib.php');
require_once(dirname(__FILE__) . '/locallib.php');
+require_once($CFG->libdir . '/completionlib.php');
+require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
/**
* This Class controls the manipulation of posts and acts as controller of interactions with the post.php
@@ -68,25 +70,28 @@ class post_control {
*/
private $interaction;
- /** @var object information about the post like the related moodleoverflow, post etc. .*/
+ /** @var object information about the post like the related moodleoverflow, post etc.
+ * Difference between info and prepost: Info has objects, prepost mostly ID's and string like the message of the post.
+ */
private $info;
/** @var object prepost for the classes/post/post_form.php,
- * this object is only used in this class and its not inserted in tehe database*/
+ * this object is more like a prototype of a post and it's not in the database*
+ * Difference between info and prepost. Info has objects, prepost mostly ID's and strings like the message of the post.
+ */
private $prepost;
/**
* Constructor
- *
- * @param object $urlparameter Parameter that were sent when post.php where opened.
*/
public function __construct() {
$this->info = new \stdClass;
}
/**
- * Detects the interaction
+ * Detects the interaction and builds the prepost.
* @param object $urlparamter parameter from the post.php
+ * @throws moodle_exception if the interaction is not correct.
*/
public function detect_interaction($urlparameter) {
$count = 0;
@@ -122,10 +127,32 @@ public function detect_interaction($urlparameter) {
}
}
+ /**
+ * Controls the execution of an interaction.
+ * @param object $form The results from the post_form.
+ * @return bool if the execution succeded
+ */
+ public function execute_interaction($form) {
+ // Redirect url in case of occuring errors.
+ if (empty($SESSION->fromurl)) {
+ $errordestination = '$CFG->wwwroot/mod/moodleoverflow/view.php?m=' . $this->prepost->moodleoverflowid;
+ } else {
+ $errordestination = $SESSION->fromurl;
+ }
+
+ // Format the submitted data.
+ $this->prepost->messageformat = $fromform->message['format'];
+ $this->prepost->message = $fromform->message['text'];
+ $this->prepost->messagetrust = trusttext_trusted($this->prepost->modulecontext);
+
+ // FEHLT.
+ }
+
/**
* This function is used when a guest enters the post.php.
* Parameters will be checked so that the post.php can redirect the user to the right site.
- *
+ * @param int $postid
+ * @param int $moodleoverflowid
* @return object $this->information // The gathered information.
*/
public function catch_guest($postid = false, $moodleoverflowid = false) {
@@ -159,13 +186,9 @@ public function catch_guest($postid = false, $moodleoverflowid = false) {
private function build_prepost_create($moodleoverflowid) {
global $DB, $SESSION, $USER;
- // Get the related moodleoverflow, course and coursemodule.
+ // Get the related moodleoverflow, course coursemodule and the contexts.
$this->collect_information(false, $moodleoverflowid);
- // Retrieve the contexts.
- $this->info->modulecontext = context_module::instance($this->info->cm->id);
- $this->info->coursecontext = context_module::instance($this->info->course->id);
-
// Check if the user can start a new discussion.
if (!moodleoverflow_user_can_post_discussion($this->info->moodleoverflow, $this->info->cm, $this->info->modulecontext)) {
@@ -195,16 +218,13 @@ private function build_prepost_create($moodleoverflowid) {
$SESSION->fromurl = get_local_referer(false);
// Prepare the post.
- $this->prepost = new \stdClass();
- $this->prepost->postid = $this->info->relatedpost->get_id();
- $this->prepost->courseid = $this->info->course->id;
- $this->prepost->moodleoverflowid = $this->info->moodleoverflow->id;
- $this->prepost->discussionid = 0;
+ $this->assemble_prepost();
+ $this->prepost->postid = null;
+ $this->prepost->discussionid = null;
$this->prepost->parentid = 0;
$this->prepost->subject = '';
$this->prepost->userid = $USER->id;
$this->prepost->message = '';
- $this->prepost->modulecontext = $this->info->modulecontext;
$this->prepost->reviewed = $reviewed; // IST DAS OKAY?!
// Unset where the user is coming from.
@@ -220,16 +240,12 @@ private function build_prepost_create($moodleoverflowid) {
private function build_prepost_reply($replypostid) {
global $DB, $PAGE, $SESSION, $USER;
- // Get the related poost, discussion, moodleoverflowm course and coursemodule.
+ // Get the related poost, discussion, moodleoverflow, course, coursemodule and contexts.
$this->collect_information($replypostid, false);
// Ensure the coursemodule is set correctly.
$PAGE->set_cm($this->info->cm, $this->info->course, $this->info->moodleoverflow);
- // Retrieve the contexts.
- $this->info->modulecontext = context_module::instance($this->info->cm->id);
- $this->info->coursecontext = context_module::instance($this->info->course->id);
-
// Check whether the user is allowed to post.
if (!moodleoverflow_user_can_post($this->info->modulecontext, $this->info->parent)) {
@@ -252,16 +268,9 @@ private function build_prepost_reply($replypostid) {
}
// Prepare a post.
- $this->prepost = new \stdClass();
- $this->prepost->postid = $this->info->relatedpost->get_id();
- $this->prepost->courseid = $this->info->course->id;
- $this->prepost->moodleoverflowid = $this->info->moodleoverflow->id;
- $this->prepost->discussionid = $this->info->discussion->get_id();
- $this->prepost->parentid = $this->info->relatedpost->get_parentid();
- $this->prepost->subject = $this->info->discussion->name;
+ $this->assemble_prepost();
$this->prepost->userid = $USER->id;
$this->prepost->message = '';
- $this->prepost->modulecontext = $this->info->modulecontext;
// Append 'RE: ' to the discussions subject.
$strre = get_string('re', 'moodleoverflow');
@@ -282,12 +291,9 @@ private function build_prepost_reply($replypostid) {
private function build_prepost_edit($editpostid) {
global $DB, $PAGE, $SESSION, $USER;
- // Get the related post, discussion, moodleoverflow, course and coursemodule.
+ // Get the related post, discussion, moodleoverflow, course, coursemodule and contexts.
$this->collect_information($editpostid, false);
- // Retrieve contexts.
- $this->info->modulecontext = context_module::instance($this->info->cm->id);
-
// Set the pages context.
$PAGE->set_cm($this->info->cm, $this->info->course, $this->info->moodleoverflow);
@@ -314,16 +320,7 @@ private function build_prepost_edit($editpostid) {
}
// Load the $post variable.
- $this->prepost = new \stdClass();
- $this->prepost->postid = $this->info->relatedpost->get_id();
- $this->prepost->courseid = $this->info->course->id;
- $this->prepost->moodleoverflowid = $this->info->moodleoverflow->id;
- $this->prepost->discussionid = $this->info->discussion->id;
- $this->prepost->parentid = $this->info->relatedpost->get_parentid();
- $this->prepost->subject = $this->info->discussion->name;
- $this->prepost->message = $this->info->relatedpost->message;
- $this->prepost->userid = $this->info->relatedpost->get_userid();
- $this->prepost->modulecontext = $this->info->modulecontext;
+ $this->assemble->prepost();
// Unset where the user is coming from.
// Allows to calculate the correct return url later.
@@ -338,12 +335,11 @@ private function build_prepost_edit($editpostid) {
private function build_prepost_delete($deletepostid) {
global $DB, $USER;
- // Get the realted post, discussion, moodleoverflow, course and coursemodule.
+ // Get the realted post, discussion, moodleoverflow, course, coursemodule and contexts.
$this->collect_information($deletepostid, false);
// Require a login and retrieve the modulecontext.
require_login($this->info->course, false, $this->info->cm);
- $this->info->modulecontext = context_module::instance($this->info->cm->id);
// Check some capabilities.
$this->info->deleteownpost = has_capability('mod/moodleoverflow:deleteownpost', $this->info->modulecontext);
@@ -357,32 +353,22 @@ private function build_prepost_delete($deletepostid) {
// Count all replies of this post.
$this->info->replycount = moodleoverflow_count_replies($this->info->relatedpost, false);
- // In the delete interaction the prepost is already the post object.
- $this->prepost = new \stdClass();
- $this->prepost->postid = $this->info->relatedpost->get_id();
- $this->prepost->courseid = $this->info->course->id;
- $this->prepost->moodleoverflowid = $this->info->moodleoverflow->id;
- $this->prepost->discussionid = $this->info->discussion->id;
- $this->prepost->parentid = $this->info->relatedpost->get_parentid();
- $this->prepost->subject = $this->info->discussion->name;
- $this->prepost->message = $this->info->relatedpost->message;
- $this->prepost->userid = $this->info->relatedpost->get_userid();
- $this->prepost->modulecontext = $this->info->modulecontext;
+ // Build the prepost.
+ $this->assemble->prepost();
$this->prepost->deletechildren = true;
}
-
// Execute Functions, that execute an interaction.
- public function execute_create() {
+ private function execute_create() {
$this->check_interaction('create');
}
- public function execute_reply() {
+ private function execute_reply() {
$this->check_interaction('reply');
}
- public function execute_edit() {
+ private function execute_edit() {
$this->check_interaction('edit');
}
@@ -414,7 +400,7 @@ public function execute_delete() {
}
}
- // Confirm Function for the delete interaction.
+ // Functions that uses the post.php to build the page.
/**
* Builds a part of confirmation page. The confirmation request box is being build by the post.php.
@@ -429,6 +415,72 @@ public function confirm_delete() {
$PAGE->add_body_class('limitedwidth');
}
+ /**
+ * Builds and returns a post_form object where the users enters/edits the message and attachments of the post.
+ * @param array $pageparams An object that the post.php created.
+ * @return object a mod_moodleoverflow_post_form object.
+ */
+ public function build_postform($pageparams) {
+ // Require that the user is logged in properly and enrolled to the course.
+ require_login($this->info->course, false, $this->info->cm);
+
+ // Prepare the attachments.
+ $draftitemid = file_get_submitted_draft_itemid('attachments');
+ file_prepare_draft_area($draftitemid, $this->info->modulecontext->id, 'mod_moodleoverflow', 'attachment',
+ empty($this->prepost->postid) ? null : $this->prepost->postid,
+ mod_moodleoverflow_post_form::attachment_options($this->info->moodleoverflow));
+
+ // Prepare the form.
+ $edit = $this->interaction == 'edit' ? true : false;
+ $formarray = array( 'course' => $this->info->course, 'cm' => $this->info->cm, 'coursecontext' => $this->info->coursecontext,
+ 'modulecontext' => $this->info->modulecontext, 'moodleoverflow' => $this->info->moodleoverflow,
+ 'post' => $this->info->post, 'edit' => $edit);
+
+ // Declare the post_form.
+ $mformpost = new mod_moodleoverflow_post_form('post.php', $formarray, 'post', '', array('id' => 'mformmoodleoverflow'));
+
+ // If the user is not the original author append an extra message to the message. (Happens when interaction = 'edit').
+ if ($USER->id != $this->prepost->userid) {
+ // Create a temporary object.
+ $data = new \stdClass();
+ $data->date = userdate(time());
+ $this->prepost->messageformat = editors_get_preferred_format();
+ if ($this->prepost->messageformat == FORMAT_HTML) {
+ $data->name = '' . fullname($USER) . '';
+ $this->prepost->message .= '(' . get_string('editedby', 'moodleoverflow', $data) .
+ ')
';
+ } else {
+ $data->name = fullname($USER);
+ $this->prepost->message .= "\n\n(" . get_string('editedby', 'moodleoverflow', $data) . ')';
+ }
+ // Delete the temporary object.
+ unset($data);
+ }
+
+ // Define the heading for the form.
+ $formheading = '';
+ if ($this->info->relatedpost->moodleoverflow_get_parentpost()) {
+ $heading = get_string('yourreply', 'moodleoverflow');
+ $formheading = get_string('reply', 'moodleoverflow');
+ } else {
+ $heading = get_string('yournewtopic', 'moodleoverflow');
+ }
+
+ // Set data for the form.
+ $mformpost->set_data(array(
+ 'attachments' => $draftitemid, 'general' => $heading, 'subject' => $this->prepost->subject,
+ 'message' => array('text' => $this->prepost->message,
+ 'format' => editors_get_preferred_format(),
+ 'itemid' => $this->prepost->postid),
+ 'userid' => $this->prepost->userid, 'parent' => $this->prepost->parentid, 'discussion' => $this->prepost->discussionid,
+ 'course' => $this->prepost->courseid)
+ + $pageparams
+ );
+
+ return $mformpost;
+ }
+
// Helper functions.
// Getter.
@@ -457,7 +509,7 @@ public function get_prepost() {
return $this->prepost;
}
- // Information function.
+ // Functions that build the info and prepost object.
/**
* Builds the information object that is being used in the build prepost functions.
@@ -467,7 +519,7 @@ public function get_prepost() {
* @return bool, if object could be build or not.
*/
private function collect_information($postid = false, $moodleoverflowid = false) {
- if ((!$postid && !$moodleoverflowid) || ($postid && $moodleoverflowid)) {
+ if (!($postid xor $moodleoverflowid)) {
throw new moodle_exception('inaccurateparameter', 'moodleoverflow');
return false;
}
@@ -475,15 +527,41 @@ private function collect_information($postid = false, $moodleoverflowid = false)
$this->info->relatedpost = $this->check_post_exists($postid);
$this->info->discussion = $this->check_discussion_exists($this->info->relatedpost->get_discussionid());
$localmoodleoverflowid = $this->info->discussion->get_moodleoverflowid();
- } else if ($moodleoverflowid) {
+ } else {
$localmoodleoverflowid = $moodleoverflowid;
}
$this->info->moodleoverflow = $this->check_moodleoverflow_exists($localmoodleoverflowid);
$this->info->course = $this->check_course_exists($this->info->moodleoverflow->course);
$this->info->cm = $this->check_coursemodule_exists($this->info->moodleoverflow->id, $this->info->course->id);
+ $this->info->modulecontext = context_module::instance($this->info->cm->id);
+ $this->info->coursecontext = context_module::instance($this->info->course->id);
return true;
}
+ /**
+ * Assembles the prepost object. Helps to reduce code in the build_prepost functions.
+ * Some prepost parameters will be assigned individually by the build_prepost functions.
+ */
+ private function assemble_prepost() {
+ $this->prepost = new \stdClass();
+ $this->prepost->courseid = $this->info->course->id;
+ $this->prepost->moodleoverflowid = $this->info->moodleoverflow->id;
+ $this->prepost->modulecontext = $this->info->modulecontext;
+
+ if ($this->interaction != 'create') {
+ $this->prepost->postid = $this->info->relatedpost->get_id();
+ $this->prepost->discussionid = $this->info->discussion->get_id();
+ $this->prepost->parentid = $this->info->relatedpost->get_parentid();
+ $this->prepost->subject = $this->info->discussion->name;
+
+ if ($this->interaction != 'edit') {
+ $this->prepost->userid = $this->info->relatedpost->get_userid();
+ $this->prepost->message = $this->info->relatedpost->message();
+ }
+ }
+ }
+
+
// Interaction check.
/**
diff --git a/classes/post/post.php b/classes/post/post.php
index 1cfc37a337..89c35ff9a2 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -118,7 +118,7 @@ class post {
/**
* Constructor to make a new post.
- *
+ * @param int $id The post ID.
* @param int $discussion The discussion ID.
* @param int $parent The parent post ID.
* @param int $userid The user ID that created the post.
@@ -367,6 +367,8 @@ public function moodleoverflow_delete_post($deletechildren) {
* @param string $postmessage The new message
* @param object $messageformat
* @param object $formattachments Information about attachments from the post_form
+ *
+ * @return true if the post has been edited successfully
*/
public function moodleoverflow_edit_post($time, $postmessage, $messageformat, $formattachment) {
global $DB;
@@ -494,6 +496,7 @@ public function moodleoverflow_get_attachments() {
// Getter.
/**
+ * Getter for the postid
* @return int $this->id The post ID.
*/
public function get_id() {
@@ -502,6 +505,7 @@ public function get_id() {
}
/**
+ * Getter for the discussionid
* @return int $this->discussion The ID of the discussion where the post is located.
*/
public function get_discussionid() {
@@ -510,6 +514,7 @@ public function get_discussionid() {
}
/**
+ * Getter for the parentid
* @return int $this->parent The ID of the parent post.
*/
public function get_parentid() {
@@ -518,6 +523,7 @@ public function get_parentid() {
}
/**
+ * Getter for the userid
* @return int $this->userid The ID of the user who wrote the post.
*/
public function get_userid() {
@@ -527,7 +533,6 @@ public function get_userid() {
/**
* Returns the moodleoverflow where the post is located.
- *
* @return object $moodleoverflowobject
*/
public function get_moodleoverflow() {
diff --git a/classes/post_form.php b/classes/post_form.php
index c181a1d85b..6631f326e6 100644
--- a/classes/post_form.php
+++ b/classes/post_form.php
@@ -43,8 +43,9 @@ class mod_moodleoverflow_post_form extends moodleform {
*/
public function definition() {
- $modform =& $this->_form;
+ $modform =& $this->_form;
$post = $this->_customdata['post'];
+ $edit = $this->_customdata['edit'];
$modcontext = $this->_customdata['modulecontext'];
$moodleoverflow = $this->_customdata['moodleoverflow'];
@@ -70,7 +71,7 @@ public function definition() {
}
// Submit buttons.
- if (isset($post->edit)) {
+ if ($edit) {
$strsubmit = get_string('savechanges');
} else {
$strsubmit = get_string('posttomoodleoverflow', 'moodleoverflow');
diff --git a/classes/review.php b/classes/review.php
index 77ddd2e67b..7ee4d82ec1 100644
--- a/classes/review.php
+++ b/classes/review.php
@@ -132,7 +132,7 @@ public static function get_first_review_post($moodleoverflowid, $afterpostid = n
*/
public static function should_post_be_reviewed($post, $moodleoverflow): bool {
$reviewlevel = self::get_review_level($moodleoverflow);
- if ($post->get_parentid() != 0) {
+ if ($post->parent != 0 /*$post->get_parentid() != 0*/) {
return $reviewlevel == self::EVERYTHING;
} else {
return $reviewlevel >= self::QUESTIONS;
diff --git a/post_new.php b/post_new.php
index d292ac902e..9a3a2db972 100644
--- a/post_new.php
+++ b/post_new.php
@@ -52,7 +52,7 @@
// Get the system context instance.
$systemcontext = context_system::instance();
-// Create a post_control object to control the process.
+// Create a post_control object to control and lead the process.
$postcontrol = new post_control();
// Put all interaction parameters in one object for the post_control.
@@ -111,4 +111,46 @@
}
}
-// Now the post_form will be prepared.
+// A post will be created or edited. For that the post_control builds a post_form.
+$mformpost = $postcontrol->build_postform();
+
+// The User now entered information in the form. The post.php now needs to process the information and call the right function.
+
+// Get attributes from the postcontrol.
+$information = $postcontrol->get_information();
+$prepost = $postcontrol->get_prepost();
+
+// If the interaction was cancelled, the user needs to be redirected.
+if ($mformpost->is_cancelled()) {
+ if (!issett($prepost->discussionid)) {
+ redirect(new moodle_url('/mod/moodleoverflow/view.php', array('m' => $prepost->moodleoverflowid)));
+ } else {
+ redirect(new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $prepost->discussionid)));
+ }
+ exit;
+}
+
+// If the post_form is submitted, the post_control executes the right function.
+if ($fromform = $mformpost->get_data()) {
+ $postcontrol->execute_interaction($fromform);
+ exit;
+}
+
+// If the script gets to this point, nothing has been submitted.
+// The post_form will be displayed.
+
+// Define the message to be displayed above the form.
+$toppost = new \stdClass();
+$toppost->subject = get_string('addanewdiscussion', 'moodleoverflow');
+
+// Initiate the page.
+$PAGE->set_title($information->course->shortname . ': ' .
+ $information->moodleoverflow->name . ' ' .
+ format_string($toppost->subject));
+$PAGE->set_heading($information->course->fullname);
+$PAGE->add_body_class('limitedwidth');
+
+// Display all.
+echo $OUTPUT->header();
+$mformpost->display();
+echo $OUTPUT->footer();
From d99ec28e10c3821c8a70242d92c21e318335694d Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Fri, 28 Jul 2023 15:04:15 +0200
Subject: [PATCH 18/56] new post structure ready
---
classes/discussion/discussion.php | 26 +-
classes/post/post.control.php | 202 +++++++-
lang/en/moodleoverflow.php | 5 +-
locallib.php | 2 +-
post.php | 766 +++--------------------------
post_new.php | 156 ------
post_old.php | 792 ++++++++++++++++++++++++++++++
7 files changed, 1049 insertions(+), 900 deletions(-)
delete mode 100644 post_new.php
create mode 100644 post_old.php
diff --git a/classes/discussion/discussion.php b/classes/discussion/discussion.php
index 67c9a3aec2..b188f3c262 100644
--- a/classes/discussion/discussion.php
+++ b/classes/discussion/discussion.php
@@ -212,16 +212,12 @@ public static function construct_without_id($course, $moodleoverflow, $name, $fi
public function moodleoverflow_add_discussion($prepost) {
global $DB;
- // Get the current time.
- $timenow = time();
-
// Add the discussion to the Database.
$this->id = $DB->insert_record('moodleoverflow_discussions', $this);
// Create the first/parent post for the new discussion and add it do the DB.
- $post = post::construct_without_id($this->id, 0, $prepost->userid, $timenow, $timenow,
- $preposts->message, $prepost->messageformat, $prepost->attachment, $prepost->mailed,
- $prepost->reviewed, $prepost->timereviewed, $prepost->formattachments);
+ $post = post::construct_without_id($this->id, 0, $prepost->userid, $prepost->timenow, $prepost->timenow, $preposts->message,
+ $prepost->messageformat, "", 0, $prepost->review, null, $prepost->formattachments);
// Add it to the DB and save the id of the first/parent post.
$this->firstpost = $post->moodleoverflow_add_new_post();
@@ -308,13 +304,10 @@ public function moodleoverflow_add_post_to_discussion($prepost) {
$this->existence_check();
$this->post_check();
- // Get the current time.
- $timenow = time();
-
// Create the post that will be added to the new discussion.
- $post = post::construct_without_id($this->id, $prepost->parent, $prepost->userid, $timenow, $timenow, $prepost->message,
- $prepost->messageformat, $prepost->attachment, $prepost->mailed,
- $prepost->reviewed, $prepost->timereviewed, $prepost->formattachments);
+ $post = post::construct_without_id($this->id, $prepost->parentid, $prepost->userid, $prepost->timenow, $prepost->timenow,
+ $prepost->message, $prepost->messageformat, "", 0, $prepost->reviewed, null,
+ $prepost->formattachments);
// Add the post to the DB.
$postid = $post->moodleoverflow_add_new_post();
@@ -367,19 +360,16 @@ public function moodleoverflow_edit_post_from_discussion($prepost) {
$this->posts_check();
// Check if the posts exists in this discussion.
- $this->post_exists_check($prepost->id);
-
- // Get the current time.
- $timenow = time();
+ $this->post_exists_check($prepost->postid);
// Access the post.
- $post = $this->post[$prepost->id];
+ $post = $this->post[$prepost->postid];
// If the post is the firstpost, then update the name of this discussion and the post. If not, only update the post.
if ($prepost->id == array_key_first($posts)) {
$this->name = $prepost->subject;
$this->usermodified = $prepost->userid;
- $this->timemodified = $timenow;
+ $this->timemodified = $prepost->timenow;
$DB->update_record('moodleoverflow_discussions', $this);
}
$post->moodleoverflow_edit_post($timenow, $prepost->message, $prepost->messageformat, $prepost->formattachment);
diff --git a/classes/post/post.control.php b/classes/post/post.control.php
index b4b4f4f07b..bb99a6e46e 100644
--- a/classes/post/post.control.php
+++ b/classes/post/post.control.php
@@ -141,11 +141,24 @@ public function execute_interaction($form) {
}
// Format the submitted data.
- $this->prepost->messageformat = $fromform->message['format'];
- $this->prepost->message = $fromform->message['text'];
+ $this->prepost->messageformat = $form->message['format'];
+ $this->prepost->formattachments = $form->attachments;
+ $this->prepost->message = $form->message['text'];
$this->prepost->messagetrust = trusttext_trusted($this->prepost->modulecontext);
- // FEHLT.
+ // Get the current time.
+ $this->prepost->timenow = time();
+
+ // Execute the right function.
+ if ($this->interaction == 'create' && $form->moodleoverflow === $this->prepost->moodleoverflowid) {
+ $this->execute_create($form, $errordestination);
+ } else if ($this->interaction == 'reply' && $form->reply === $this->prepost->parentid) {
+ $this->execute_reply($form, $errordestination);
+ } else if ($this->interaction == 'edit' && $form->edit === $this->prepost->postid) {
+ $this->execute_edit($form, $errordestination);
+ } else {
+ throw new moodle_exception('unexpectedinteractionerror', 'moodleoverflow', $errordestination);
+ }
}
/**
@@ -208,12 +221,6 @@ private function build_prepost_create($moodleoverflowid) {
throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
}
- // Set the post to not reviewed if questions should be reviewed and the user is not a reviewed themselve.
- if (review::get_review_level($this->info->moodleoverflow) >= review::QUESTIONS &&
- !capabilities::has(capabilities::REVIEW_POST, $this->info->modulecontext, $USER->id)) {
- $reviewed = 0;
- }
-
// Where is the user coming from?
$SESSION->fromurl = get_local_referer(false);
@@ -225,7 +232,6 @@ private function build_prepost_create($moodleoverflowid) {
$this->prepost->subject = '';
$this->prepost->userid = $USER->id;
$this->prepost->message = '';
- $this->prepost->reviewed = $reviewed; // IST DAS OKAY?!
// Unset where the user is coming from.
// Allows to calculate the correct return url later.
@@ -269,6 +275,8 @@ private function build_prepost_reply($replypostid) {
// Prepare a post.
$this->assemble_prepost();
+ $this->prepost->postid = null;
+ $this->prepost->parentid = $this->info->relatedpost->get_id();
$this->prepost->userid = $USER->id;
$this->prepost->message = '';
@@ -322,8 +330,7 @@ private function build_prepost_edit($editpostid) {
// Load the $post variable.
$this->assemble->prepost();
- // Unset where the user is coming from.
- // Allows to calculate the correct return url later.
+ // Unset where the user is coming from. This allows to calculate the correct return url later.
unset($SESSION->fromdiscussion);
}
@@ -360,16 +367,121 @@ private function build_prepost_delete($deletepostid) {
// Execute Functions, that execute an interaction.
- private function execute_create() {
- $this->check_interaction('create');
+ private function execute_create($form, $errordestination) {
+ // Check if the user is allowed to post.
+ $this->check_user_can_create_discussion();
+
+ // Set the post to not reviewed if questions should be reviewed and the user is not a reviewed themselves.
+ if (review::get_review_level($this->info->moodleoverflow) >= review::QUESTIONS &&
+ !capabilities::has(capabilities::REVIEW_POST, $this->info->modulecontext, $USER->id)) {
+ $this->prepost->reviewed = 0;
+ } else {
+ $this->prepost->reviewed = 1;
+ }
+
+ // Create the discussion object.
+ $discussion = discussion::construct_without_id($this->prepost->courseid, $this->prepost->moodleoverflowid,
+ $this->prepost->subject, null, $this->prepost->userid,
+ $this->prepost->timenow, $this->prepost->timenow, $this->prepost->userid);
+ if (!$discussion->moodleoverflow_add_discussion($this->prepost)) {
+ throw new moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
+ }
+
+ // The creation was successful.
+ $redirectmessage = '' . get_string("postaddedsuccess", "moodleoverflow") . '
';
+
+ // Trigger the discussion created event.
+ $params = array( 'context' => $modulecontext, 'objectid' => $discussion->id,);
+ $event = \mod_moodleoverflow\event\discussion_created::create($params);
+ $event->trigger();
+
+ // Subscribe to this thread.
+ //\mod_moodleoverflow\subscriptions::moodleoverflow_post_subscription($form, $this->info->moodleoverflow,
+ //$discussion, $this->info->modulecontext);
+
+ // Define the location to redirect the user after successfully posting.
+ $redirectto = new moodle_url('/mod/moodleoverflow/view.php', array('m' => $form->moodleoverflow));
+ redirect(moodleoverflow_go_back_to($redirectto->out()), $redirectmessage, null, \core\output\notification::NOTIFY_SUCCESS);
}
- private function execute_reply() {
- $this->check_interaction('reply');
+ private function execute_reply($form, $errordestination) {
+ // Check if the user has the capability to write a reply.
+ $this->check_user_can_create_reply();
+
+ // Set to not reviewed, if posts should be reviewed, and user is not a reviewer themselves.
+ if (review::get_review_level($this->info->moodleoverflow) == review::EVERYTHING &&
+ !has_capability('mod/moodleoverflow:reviewpost', context_module::instance($this->info->cm->id))) {
+ $this->prepost->reviewed = 0;
+ } else {
+ $this->prepost->reviewed = 1;
+ }
+
+ // Create the new post.
+ if (!$newpostid = $this->info->discussion->moodleoverflow_add_post_to_discussion($this->prepost)) {
+ throw new moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
+ }
+
+ // The creation was successful.
+ $redirectmessage = '' . get_string("postaddedsuccess", "moodleoverflow") . '
';
+ $redirectmessage .= '' . get_string("postaddedtimeleft", "moodleoverflow",
+ format_time(get_config('moodleoverflow', 'maxeditingtime'))) . '
';
+
+ // Trigger the post created event.
+ $params = array('context' => $this->info->modulecontext, 'objectid' => $form->id,
+ 'other' => array('discussionid' => $this->prepost->discussionid,
+ 'moodleoverflowid' => $this->prepost->moodleoverflowid)
+ );
+ $event = \mod_moodleoverflow\event\post_created::create($params);
+ $event->trigger();
+
+ // Subscribe to this thread;
+ // \mod_moodleoverflow\subscriptions::moodleoverflow_post_subscription(form, $this->info->moodleoverflow,
+ //$this->info->discussion, $this->info->modulecontext);
+
+ // Define the location to redirect the user after successfully posting.
+ $redirectto = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->prepost->discussionid, $newpost->id));
+ redirect(oodleoverflow_go_back_to($redirectto->out()), $redirectmessage, null, \core\output\notification::NOTIFY_SUCCESS);
+
+
}
- private function execute_edit() {
- $this->check_interaction('edit');
+ private function execute_edit($form, $errordestination) {
+ global $USER;
+ // Check if the user has the capability to edit his post.
+ $this->check_user_can_edit_post();
+
+ // Update the post.
+ if (!$this->info->discussion->moodleoverflow_edit_post_from_discussion($this->prepost)) {
+ throw new moodle_exception('couldnotupdate', 'moodleoverflow', $errordestination);
+ }
+
+ // The edit was successful.
+ $redirectmessage = get_string('postupdated', 'moodleoverflow');
+ /*if ($this->prepost->userid == $USER->id) {
+ $redirectmessage = get_string('postupdated', 'moodleoverflow');
+ } else {
+ if (\mod_moodleoverflow\anonymous::is_post_anonymous($this->info->discussion, $this->info->moodleoverflow,
+ $this->prepost->userid)) {
+ $name = get_string('anonymous', 'moodleoverflow');
+ } else {
+ $realuser = $DB->get_record('user', array('id' => $this->prepost->userid));
+ $name = fullname($realuser);
+ }
+ $redirectmessage = get_string('editedpostupdated', 'moodleoverflow', $name);
+ }*/
+
+ // Trigger the post updated event.
+ $params = array('context' => $this->info->modulecontext, 'objectid' => $form->edit,
+ 'other' => array('discussionid' => $this->prepost->discussionid,
+ 'moodleoverflowid' => $this->prepost->moodleoverflowid),
+ 'relateduserid' => $this->prepost->userid == $USER->id ? $this->prepost->userid : null
+ );
+ $event = \mod_moodleoverflow\event\post_updated::create($params);
+ $event->trigger();
+
+ // Define the location to redirect the user after successfully editing.
+ $redirectto = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->prepost->discussionid, $form->edit));
+ redirect(moodleoverflow_go_back_to($redirectto->out()), $redirectmessage, null, \core\output\notification::NOTIFY_SUCCESS);
}
public function execute_delete() {
@@ -388,7 +500,7 @@ public function execute_delete() {
}
// Check if the post is a parent post or not.
- if ($this->prepost->get_parentid() == 0) {
+ if ($this->prepost->parentid == 0) {
$this->info->discussion->moodleoverflow_delete_discussion($this->prepost);
// Redirect the user back to the start page of the moodleoverflow instance.
@@ -524,6 +636,7 @@ private function collect_information($postid = false, $moodleoverflowid = false)
return false;
}
if ($postid) {
+ // The related post is the post that is being answered, edited, or deleted.
$this->info->relatedpost = $this->check_post_exists($postid);
$this->info->discussion = $this->check_discussion_exists($this->info->relatedpost->get_discussionid());
$localmoodleoverflowid = $this->info->discussion->get_moodleoverflowid();
@@ -549,12 +662,12 @@ private function assemble_prepost() {
$this->prepost->modulecontext = $this->info->modulecontext;
if ($this->interaction != 'create') {
- $this->prepost->postid = $this->info->relatedpost->get_id();
$this->prepost->discussionid = $this->info->discussion->get_id();
- $this->prepost->parentid = $this->info->relatedpost->get_parentid();
$this->prepost->subject = $this->info->discussion->name;
- if ($this->interaction != 'edit') {
+ if ($this->interaction != 'reply') {
+ $this->prepost->parentid = $this->info->relatedpost->get_parentid();
+ $this->prepost->postid = $this->info->relatedpost->get_id();
$this->prepost->userid = $this->info->relatedpost->get_userid();
$this->prepost->message = $this->info->relatedpost->message();
}
@@ -647,4 +760,49 @@ private function check_post_exists($postid) {
return $post;
}
+
+ // Capability checks.
+
+ /**
+ * Checks if a user can create a discussion.
+ * @return true
+ * @throws moodle_exception
+ */
+ private function check_user_can_create_discussion() {
+ if (!has_capability('mod/moodleoverflow:startdiscussion', $this->info->modulecontext)) {
+ throw new moodle_exception('cannotcreatediscussion', 'moodleoverflow');
+ }
+ return true;
+ }
+
+ /**
+ * Checks if a user can reply in a discussion.
+ * @return true
+ * @throws moodle_exception
+ */
+ private function check_user_can_create_reply() {
+ if (!has_capability('mod/moodleoverflow:replypost', $this->info->modulecontext, $this->prepost->userid)) {
+ throw new moodle_exception('cannotreply', 'moodleoverflow');
+ }
+ return true;
+ }
+
+ /**
+ * Checks if a user can edit a post.
+ * A user can edit if he can edit any post of if he edits his own post and has the ability to:
+ * start a new discussion or to reply to a post.
+ *
+ * @return true
+ * @throws moodle_exception
+ */
+ private function check_user_can_edit_post() {
+ $editanypost = has_capability('mod/moodleoverflow:editanypost', $this->info->modulecontext);
+ $replypost = has_capability('mod/moodleoverflow:replypost', $this->info->modulecontext);
+ $startdiscussion = has_capability('mod/moodleoverflow:startdiscussion', $this->info->modulecontext);
+ $ownpost = ($this->prepost->userid == $USER->id);
+ if (!(($ownpost && ($replypost || $startdiscussion)) || $editanypost)) {
+ throw new moodle_exception('cannotupdatepost', 'moodleoverflow');
+ }
+ return true;
+ }
}
diff --git a/lang/en/moodleoverflow.php b/lang/en/moodleoverflow.php
index 2fb184cf39..5ee1d3c3b2 100644
--- a/lang/en/moodleoverflow.php
+++ b/lang/en/moodleoverflow.php
@@ -150,8 +150,9 @@
$string['couldnotdeletereplies'] = 'Sorry, that cannot be deleted as people have already responded to it';
$string['noexistingpost'] = 'Post does not exists, needs to be created first';
$string['noexistingdiscussion'] = 'Discussion does not exists, needs to be created first';
-$string['notallpostsavailable'] = 'This Discussion does not have all of its posts, this could lead to errors! Please use moodleoverflow_get_discussion_posts()';
-$string['missingformattachments'] = "This functions requires data that were not submitted. Please check the post_form";
+$string['notallpostsavailable'] = 'This Discussion does not have all of its posts, this could lead to errors!';
+$string['missingformattachments'] = 'This functions requires data that was not submitted.';
+$string['unexpectedinteractionerror'] = 'An unexpected error occured, please try again';
// String for the classes/post/post_control.php.
$string['inaccurateparameter'] = 'Please check your parameter and give exactly 1 parameter to the function';
diff --git a/locallib.php b/locallib.php
index 5443afdd21..73fec551c6 100644
--- a/locallib.php
+++ b/locallib.php
@@ -534,7 +534,7 @@ function moodleoverflow_count_discussion_replies($cm) {
*/
function moodleoverflow_user_can_post_discussion($moodleoverflow, $cm = null, $context = null) {
- // Guests an not-logged-in users can not psot.
+ // Guests an not-logged-in users can not post.
if (isguestuser() || !isloggedin()) {
return false;
}
diff --git a/post.php b/post.php
index 5baa519ba5..9a3a2db972 100644
--- a/post.php
+++ b/post.php
@@ -15,40 +15,28 @@
// along with Moodle. If not, see .
/**
- * The file to manage posts.
+ * The file that is opened in Moodle when the user interacts with posts
*
* @package mod_moodleoverflow
- * @copyright 2017 Kennet Winter
+ * @copyright 2023 Tamaro Walter
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-// TODO refactor this. For more readability, and to avoid security issues.
-
-// Include config and locallib.
use mod_moodleoverflow\review;
-
+use mod_moodleoverflow\post\post_control;
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
-global $CFG, $USER, $DB, $PAGE, $SESSION, $OUTPUT;
require_once(dirname(__FILE__) . '/locallib.php');
require_once($CFG->libdir . '/completionlib.php');
-// Declare optional parameters.
+global $CFG, $USER, $DB, $PAGE, $SESSION, $OUTPUT;
+
+// Declare optional url parameters.
$moodleoverflow = optional_param('moodleoverflow', 0, PARAM_INT);
$reply = optional_param('reply', 0, PARAM_INT);
$edit = optional_param('edit', 0, PARAM_INT);
$delete = optional_param('delete', 0, PARAM_INT);
$confirm = optional_param('confirm', 0, PARAM_INT);
-$count = 0;
-$count += $moodleoverflow ? 1 : 0;
-$count += $reply ? 1 : 0;
-$count += $edit ? 1 : 0;
-$count += $delete ? 1 : 0;
-
-if ($count !== 1) {
- throw new coding_exception('Exactly one parameter should be specified!');
-}
-
// Set the URL that should be used to return to this page.
$PAGE->set_url('/mod/moodleoverflow/post.php', array(
'moodleoverflow' => $moodleoverflow,
@@ -64,729 +52,105 @@
// Get the system context instance.
$systemcontext = context_system::instance();
-// Catch guests.
-if (!isloggedin() || isguestuser()) {
+// Create a post_control object to control and lead the process.
+$postcontrol = new post_control();
- // The user is starting a new discussion in a moodleoverflow instance.
- if (!empty($moodleoverflow)) {
+// Put all interaction parameters in one object for the post_control.
+$urlparameter = new \stdClass();
+$urlparameter->create = $moodleoverflow;
+$urlparameter->reply = $reply;
+$urlparameter->edit = $edit;
+$urlparameter->delete = $delete;
- // Check the moodleoverflow instance is valid.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
-
- // The user is replying to an existing moodleoverflow discussion.
- } else if (!empty($reply)) {
-
- // Check if the related post exists.
- if (!$parent = moodleoverflow_get_post_full($reply)) {
- throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
- }
-
- // Check if the post is part of a valid discussion.
- if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $parent->discussion))) {
- throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
- }
-
- // Check if the post is related to a valid moodleoverflow instance.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
- }
-
- // Get the related course.
- if (!$course = $DB->get_record('course', array('id' => $moodleoverflow->course))) {
- throw new moodle_exception('invalidcourseid');
- }
-
- // Get the related coursemodule and its context.
- if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $course->id)) {
- throw new moodle_exception('invalidcoursemodule');
- }
-
- // Get the context of the module.
- $modulecontext = context_module::instance($cm->id);
-
- // Set parameters for the page.
- $PAGE->set_cm($cm, $course, $moodleoverflow);
- $PAGE->set_context($modulecontext);
- $PAGE->set_title($course->shortname);
- $PAGE->set_heading($course->fullname);
-
- // The page should not be large, only pages containing broad tables are usually.
- $PAGE->add_body_class('limitedwidth');
+// Catch guests.
+if (!isloggedin() || isguestuser()) {
+ // Gather information and set the page right so that user can be redirected to the right site.
+ $information = $postcontrol->catch_guest();
// The guest needs to login.
- echo $OUTPUT->header();
$strlogin = get_string('noguestpost', 'forum') . '
' . get_string('liketologin');
- echo $OUTPUT->confirm($strlogin, get_login_url(), $CFG->wwwroot . '/mod/moodleoverflow/view.php?m=' . $moodleoverflow->id);
+ echo $OUTPUT->header();
+ echo $OUTPUT->confirm($strlogin, get_login_url(),
+ $CFG->wwwroot . '/mod/moodleoverflow/view.php?m= ' . $information->moodleoverflow->id);
echo $OUTPUT->footer();
exit;
}
-// First step: A general login is needed to post something.
+// Require a general login to post something.
require_login(0, false);
-// First possibility: User is starting a new discussion in a moodleoverflow instance.
-if (!empty($moodleoverflow)) {
-
- // Check the moodleoverflow instance is valid.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
-
- // Get the related course.
- if (!$course = $DB->get_record('course', array('id' => $moodleoverflow->course))) {
- throw new moodle_exception('invalidcourseid');
- }
-
- // Get the related coursemodule.
- if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $course->id)) {
- throw new moodle_exception('invalidcoursemodule');
- }
-
- // Retrieve the contexts.
- $modulecontext = context_module::instance($cm->id);
- $coursecontext = context_course::instance($course->id);
-
- // Check if the user can start a new discussion.
- if (!moodleoverflow_user_can_post_discussion($moodleoverflow, $cm, $modulecontext)) {
-
- // Catch unenrolled user.
- if (!isguestuser() && !is_enrolled($coursecontext)) {
- if (enrol_selfenrol_available($course->id)) {
- $SESSION->wantsurl = qualified_me();
- $SESSION->enrolcancel = get_local_referer(false);
- redirect(new moodle_url('/enrol/index.php', array(
- 'id' => $course->id,
- 'returnurl' => '/mod/moodleoverflow/view.php?m=' . $moodleoverflow->id
- )), get_string('youneedtoenrol'));
- }
- }
-
- // Notify the user, that he can not post a new discussion.
- throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
- }
-
- // Where is the user coming from?
- $SESSION->fromurl = get_local_referer(false);
-
- // Load all the $post variables.
- $post = new stdClass();
- $post->course = $course->id;
- $post->moodleoverflow = $moodleoverflow->id;
- $post->discussion = 0;
- $post->parent = 0;
- $post->subject = '';
- $post->userid = $USER->id;
- $post->message = '';
-
- // Unset where the user is coming from.
- // Allows to calculate the correct return url later.
- unset($SESSION->fromdiscussion);
-
-} else if (!empty($reply)) {
- // Second possibility: The user is writing a new reply.
-
- // Check if the post exists.
- if (!$parent = moodleoverflow_get_post_full($reply)) {
- throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
- }
-
- // Check if the post is part of a discussion.
- if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $parent->discussion))) {
- throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
- }
-
- // Check if the discussion is part of a moodleoverflow instance.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
-
- // Check if the moodleoverflow instance is part of a course.
- if (!$course = $DB->get_record('course', array('id' => $discussion->course))) {
- throw new moodle_exception('invalidcourseid');
- }
-
- // Retrieve the related coursemodule.
- if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $course->id)) {
- throw new moodle_exception('invalidcoursemodule');
- }
-
- // Ensure the coursemodule is set correctly.
- $PAGE->set_cm($cm, $course, $moodleoverflow);
-
- // Retrieve the other contexts.
- $modulecontext = context_module::instance($cm->id);
- $coursecontext = context_course::instance($course->id);
-
- // Check whether the user is allowed to post.
- if (!moodleoverflow_user_can_post($modulecontext, $parent)) {
-
- // Give the user the chance to enroll himself to the course.
- if (!isguestuser() && !is_enrolled($coursecontext)) {
- $SESSION->wantsurl = qualified_me();
- $SESSION->enrolcancel = get_local_referer(false);
- redirect(new moodle_url('/enrol/index.php',
- array('id' => $course->id, 'returnurl' => '/mod/moodleoverflow/view.php?m=' . $moodleoverflow->id)),
- get_string('youneedtoenrol'));
- }
-
- // Print the error message.
- throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
- }
-
- // Make sure the user can post here.
- if (!$cm->visible && !has_capability('moodle/course:viewhiddenactivities', $modulecontext)) {
- throw new moodle_exception('activityiscurrentlyhidden');
- }
-
- // Load the $post variable.
- $post = new stdClass();
- $post->course = $course->id;
- $post->moodleoverflow = $moodleoverflow->id;
- $post->discussion = $parent->discussion;
- $post->parent = $parent->id;
- $post->subject = $discussion->name;
- $post->userid = $USER->id;
- $post->message = '';
-
- // Append 'RE: ' to the discussions subject.
- $strre = get_string('re', 'moodleoverflow');
- if (!(substr($post->subject, 0, strlen($strre)) == $strre)) {
- $post->subject = $strre . ' ' . $post->subject;
- }
-
- // Unset where the user is coming from.
- // Allows to calculate the correct return url later.
- unset($SESSION->fromdiscussion);
-
-
-} else if (!empty($edit)) {
- // Third possibility: The user is editing his own post.
-
- // Check if the submitted post exists.
- if (!$post = moodleoverflow_get_post_full($edit)) {
- throw new moodle_exception('invalidpostid', 'moodleoverflow');
- }
-
- // Get the parent post of this post if it is not the starting post of the discussion.
- if ($post->parent) {
- if (!$parent = moodleoverflow_get_post_full($post->parent)) {
- throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
- }
- }
-
- // Check if the post refers to a valid discussion.
- if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $post->discussion))) {
- throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
- }
-
- // Check if the post refers to a valid moodleoverflow instance.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
-
- // Check if the post refers to a valid course.
- if (!$course = $DB->get_record('course', array('id' => $discussion->course))) {
- throw new moodle_exception('invalidcourseid');
- }
-
- // Retrieve the related coursemodule.
- if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $course->id)) {
- throw new moodle_exception('invalidcoursemodule');
- } else {
- $modulecontext = context_module::instance($cm->id);
- }
-
- // Set the pages context.
- $PAGE->set_cm($cm, $course, $moodleoverflow);
-
- // Check if the post can be edited.
- $beyondtime = ((time() - $post->created) > get_config('moodleoverflow', 'maxeditingtime'));
- $alreadyreviewed = review::should_post_be_reviewed($post, $moodleoverflow) && $post->reviewed;
- if (($beyondtime || $alreadyreviewed) && !has_capability('mod/moodleoverflow:editanypost', $modulecontext)) {
- throw new moodle_exception('maxtimehaspassed', 'moodleoverflow', '',
- format_time(get_config('moodleoverflow', 'maxeditingtime')));
- }
-
-
-
- // If the current user is not the one who posted this post.
- if ($post->userid <> $USER->id) {
-
- // Check if the current user has not the capability to edit any post.
- if (!has_capability('mod/moodleoverflow:editanypost', $modulecontext)) {
-
- // Display the error. Capabilities are missing.
- throw new moodle_exception('cannoteditposts', 'moodleoverflow');
- }
- }
-
- // Load the $post variable.
- $post->edit = $edit;
- $post->course = $course->id;
- $post->moodleoverflow = $moodleoverflow->id;
-
- // Unset where the user is coming from.
- // Allows to calculate the correct return url later.
- unset($SESSION->fromdiscussion);
-
-} else if (!empty($delete)) {
- // Fourth possibility: The user is deleting a post.
- // Check if the post is existing.
- if (!$post = moodleoverflow_get_post_full($delete)) {
- throw new moodle_exception('invalidpostid', 'moodleoverflow');
- }
-
- // Get the related discussion.
- if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $post->discussion))) {
- throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
- }
-
- // Get the related moodleoverflow instance.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoveflow');
- }
-
- // Get the related coursemodule.
- if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $moodleoverflow->course)) {
- throw new moodle_exception('invalidcoursemodule');
- }
-
- // Get the related course.
- if (!$course = $DB->get_record('course', array('id' => $moodleoverflow->course))) {
- throw new moodle_exception('invalidcourseid');
- }
-
- // Require a login and retrieve the modulecontext.
- require_login($course, false, $cm);
- $modulecontext = context_module::instance($cm->id);
-
- // Check some capabilities.
- $deleteownpost = has_capability('mod/moodleoverflow:deleteownpost', $modulecontext);
- $deleteanypost = has_capability('mod/moodleoverflow:deleteanypost', $modulecontext);
- if (!(($post->userid == $USER->id && $deleteownpost) || $deleteanypost)) {
- throw new moodle_exception('cannotdeletepost', 'moodleoverflow');
- }
-
- // Count all replies of this post.
- $replycount = moodleoverflow_count_replies($post, false);
+// Now the post_control checks which interaction is wanted and builds a prepost.
+$postcontrol->detect_interaction($urlparameter);
+// If a post is being deleted, delete it immediately.
+if ($postcontrol->get_interaction() == 'delete') {
// Has the user confirmed the deletion?
if (!empty($confirm) && confirm_sesskey()) {
-
- // Check if the user has the capability to delete the post.
- $timepassed = time() - $post->created;
- if (($timepassed > get_config('moodleoverflow', 'maxeditingtime')) && !$deleteanypost) {
- $url = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $post->discussion));
- throw new moodle_exception('cannotdeletepost', 'moodleoverflow', moodleoverflow_go_back_to($url));
- }
-
- // A normal user cannot delete his post if there are direct replies.
- if ($replycount && !$deleteanypost) {
- $url = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $post->discussion));
- throw new moodle_exception('couldnotdeletereplies', 'moodleoverflow', moodleoverflow_go_back_to($url));
- } else {
- // Delete the post.
-
- // The post is the starting post of a discussion. Delete the topic as well.
- if (!$post->parent) {
- moodleoverflow_delete_discussion($discussion, $course, $cm, $moodleoverflow);
-
- // Trigger the discussion deleted event.
- $params = array(
- 'objectid' => $discussion->id,
- 'context' => $modulecontext,
- );
-
- $event = \mod_moodleoverflow\event\discussion_deleted::create($params);
- $event->trigger();
-
- // Redirect the user back to start page of the moodleoverflow instance.
- redirect("view.php?m=$discussion->moodleoverflow");
- exit;
-
- } else if (moodleoverflow_delete_post($post, $deleteanypost, $cm, $moodleoverflow)) {
- // Delete a single post.
- // Redirect back to the discussion.
- $discussionurl = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $discussion->id));
- redirect(moodleoverflow_go_back_to($discussionurl));
- exit;
-
- } else {
- // Something went wrong.
- throw new moodle_exception('errorwhiledelete', 'moodleoverflow');
- }
- }
+ $postcontrol->execute_delete();
+ exit;
} else {
// Deletion needs to be confirmed.
-
- moodleoverflow_set_return();
- $PAGE->navbar->add(get_string('delete', 'moodleoverflow'));
- $PAGE->set_title($course->shortname);
- $PAGE->set_heading($course->fullname);
-
- // The page should not be large, only pages containing broad tables are usually.
- $PAGE->add_body_class('limitedwidth');
-
- // Check if there are replies for the post.
- if ($replycount) {
-
- // Check if the user has capabilities to delete more than one post.
- if (!$deleteanypost) {
- throw new moodle_exception('couldnotdeletereplies', 'moodleoverflow',
- moodleoverflow_go_back_to(new moodle_url('/mod/moodleoverflow/discussion.php',
- array('d' => $post->discussion, 'p' . $post->id))));
- }
-
- // Request a confirmation to delete the post.
- echo $OUTPUT->header();
- echo $OUTPUT->confirm(get_string("deletesureplural", "moodleoverflow", $replycount + 1),
- "post.php?delete=$delete&confirm=$delete", $CFG->wwwroot . '/mod/moodleoverflow/discussion.php?d=' .
- $post->discussion . '#p' . $post->id);
-
+ $postcontrol->confirm_delete();
+
+ // Display a confirmation request depending on the number of posts that are being deleted.
+ $information = $postcontrol->get_information();
+ echo $OUTPUT->header();
+ if ($information->deletetype == 'plural') {
+ echo $OUTPUT->confirm(get_string('deletesureplural', 'moodleoverflow', $information->replycount + 1),
+ 'post.php?delete='.$delete.'&confirm='.$delete,
+ $CFG->wwwroot . '/mod/moodleoverflow/discussion.php?d=' . $information->discussion->get_id() .
+ '#p' . $information->relatedpost->get_id());
} else {
- // Delete a single post.
-
- // Print a confirmation message.
- echo $OUTPUT->header();
- echo $OUTPUT->confirm(get_string("deletesure", "moodleoverflow", $replycount),
+ echo $OUTPUT->confirm(get_string('deletesure', 'moodleoverflow', $information->replycount),
"post.php?delete=$delete&confirm=$delete",
- $CFG->wwwroot . '/mod/moodleoverflow/discussion.php?d=' . $post->discussion . '#p' . $post->id);
+ $CFG->wwwroot . '/mod/moodleoverflow/discussion.php?d=' . $information->discussion->get_id() .
+ '#p' . $information->relatedpost->get_id());
}
+ echo $OUTPUT->footer();
+ exit;
}
- echo $OUTPUT->footer();
- exit;
-
-} else {
- // Last posibility: the action is not known.
-
- throw new moodle_exception('unknownaction');
-}
-
-// Second step: The user must be logged on properly. Must be enrolled to the course as well.
-require_login($course, false, $cm);
-
-// Get the contexts.
-$modulecontext = context_module::instance($cm->id);
-$coursecontext = context_course::instance($course->id);
-
-// Get the subject.
-if ($edit) {
- $subject = $discussion->name;
-} else if ($reply) {
- $subject = $post->subject;
-} else if ($moodleoverflow) {
- $subject = $post->subject;
-}
-
-// Get attachments.
-$draftitemid = file_get_submitted_draft_itemid('attachments');
-file_prepare_draft_area($draftitemid,
- $modulecontext->id,
- 'mod_moodleoverflow',
- 'attachment',
- empty($post->id) ? null : $post->id,
- mod_moodleoverflow_post_form::attachment_options($moodleoverflow));
-
-// Prepare the form.
-$formarray = array(
- 'course' => $course,
- 'cm' => $cm,
- 'coursecontext' => $coursecontext,
- 'modulecontext' => $modulecontext,
- 'moodleoverflow' => $moodleoverflow,
- 'post' => $post,
- 'edit' => $edit,
-);
-$mformpost = new mod_moodleoverflow_post_form('post.php', $formarray, 'post', '', array('id' => 'mformmoodleoverflow'));
-
-// The current user is not the original author.
-// Append the message to the end of the message.
-if ($USER->id != $post->userid) {
-
- // Create a temporary object.
- $data = new stdClass();
- $data->date = userdate($post->modified);
- $post->messageformat = editors_get_preferred_format();
-
- // Append the message depending on the messages format.
- if ($post->messageformat == FORMAT_HTML) {
- $data->name = '' . fullname($USER) . '';
- $post->message .= '(' . get_string('editedby', 'moodleoverflow', $data) . ')
';
- } else {
- $data->name = fullname($USER);
- $post->message .= "\n\n(" . get_string('editedby', 'moodleoverflow', $data) . ')';
- }
-
- // Delete the temporary object.
- unset($data);
}
-// Define the heading for the form.
-$formheading = '';
-if (!empty($parent)) {
- $heading = get_string('yourreply', 'moodleoverflow');
- $formheading = get_string('reply', 'moodleoverflow');
-} else {
- $heading = get_string('yournewtopic', 'moodleoverflow');
-}
+// A post will be created or edited. For that the post_control builds a post_form.
+$mformpost = $postcontrol->build_postform();
-// Get the original post.
-$postid = empty($post->id) ? null : $post->id;
-$postmessage = empty($post->message) ? null : $post->message;
+// The User now entered information in the form. The post.php now needs to process the information and call the right function.
-// Set data for the form.
-// TODO Refactor.
-$param1 = (isset($discussion->id) ? array($discussion->id) : array());
-$param2 = (isset($post->format) ? array('format' => $post->format) : array());
-$param3 = (isset($discussion->timestart) ? array('timestart' => $discussion->timestart) : array());
-$param4 = (isset($discussion->timeend) ? array('timeend' => $discussion->timeend) : array());
-$param5 = (isset($discussion->id) ? array('discussion' => $discussion->id) : array());
-$mformpost->set_data(array(
- 'attachments' => $draftitemid,
- 'general' => $heading,
- 'subject' => $subject,
- 'message' => array(
- 'text' => $postmessage,
- 'format' => editors_get_preferred_format(),
- 'itemid' => $postid,
- ),
- 'userid' => $post->userid,
- 'parent' => $post->parent,
- 'discussion' => $post->discussion,
- 'course' => $course->id
- ) + $pageparams + $param1 + $param2 + $param3 + $param4 + $param5);
+// Get attributes from the postcontrol.
+$information = $postcontrol->get_information();
+$prepost = $postcontrol->get_prepost();
-// Is it canceled?
+// If the interaction was cancelled, the user needs to be redirected.
if ($mformpost->is_cancelled()) {
-
- // Redirect the user back.
- if (!isset($discussion->id)) {
- redirect(new moodle_url('/mod/moodleoverflow/view.php', array('m' => $moodleoverflow->id)));
+ if (!issett($prepost->discussionid)) {
+ redirect(new moodle_url('/mod/moodleoverflow/view.php', array('m' => $prepost->moodleoverflowid)));
} else {
- redirect(new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $discussion->id)));
+ redirect(new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $prepost->discussionid)));
}
-
- // Cancel.
- exit();
+ exit;
}
-// Is it submitted?
+// If the post_form is submitted, the post_control executes the right function.
if ($fromform = $mformpost->get_data()) {
-
- // Redirect url in case of occuring errors.
- if (empty($SESSION->fromurl)) {
- $errordestination = "$CFG->wwwroot/mod/moodleoverflow/view.php?m=$moodleoverflow->id";
- } else {
- $errordestination = $SESSION->fromurl;
- }
-
- // Format the submitted data.
- $fromform->messageformat = $fromform->message['format'];
- $fromform->message = $fromform->message['text'];
- $fromform->messagetrust = trusttext_trusted($modulecontext);
-
- // If we are updating a post.
- if ($fromform->edit) {
-
- // Initiate some variables.
- unset($fromform->groupid);
- $fromform->id = $fromform->edit;
- $message = '';
-
- // The FORUM-Plugin had an bug: https://tracker.moodle.org/browse/MDL-4314
- // This is a fix for it.
- if (!$realpost = $DB->get_record('moodleoverflow_posts', array('id' => $fromform->id))) {
- $realpost = new stdClass();
- $realpost->userid = -1;
- }
-
- // Check the capabilities of the user.
- // He may proceed if he can edit any post or if he has the startnewdiscussion
- // capability or the capability to reply and is editing his own post.
- $editanypost = has_capability('mod/moodleoverflow:editanypost', $modulecontext);
- $replypost = has_capability('mod/moodleoverflow:replypost', $modulecontext);
- $startdiscussion = has_capability('mod/moodleoverflow:startdiscussion', $modulecontext);
- $ownpost = ($realpost->userid == $USER->id);
- if (!(($ownpost && ($replypost || $startdiscussion)) || $editanypost)) {
- throw new moodle_exception('cannotupdatepost', 'moodleoverflow');
- }
-
- // Update the post or print an error message.
- $updatepost = $fromform;
- $updatepost->moodleoverflow = $moodleoverflow->id;
- if (!moodleoverflow_update_post($updatepost, $mformpost)) {
- throw new moodle_exception('couldnotupdate', 'moodleoverflow', $errordestination);
- }
-
- // Create a success-message.
- if ($realpost->userid == $USER->id) {
- $message .= get_string('postupdated', 'moodleoverflow');
- } else {
- if (\mod_moodleoverflow\anonymous::is_post_anonymous($discussion, $moodleoverflow, $realpost->userid)) {
- $name = get_string('anonymous', 'moodleoverflow');
- } else {
- $realuser = $DB->get_record('user', array('id' => $realpost->userid));
- $name = fullname($realuser);
- }
- $message .= get_string('editedpostupdated', 'moodleoverflow', $name);
- }
-
- // Create a link to go back to the discussion.
- $discussionurl = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $discussion->id), 'p' . $fromform->id);
-
- // Set some parameters.
- $params = array(
- 'context' => $modulecontext,
- 'objectid' => $fromform->id,
- 'other' => array(
- 'discussionid' => $discussion->id,
- 'moodleoverflowid' => $moodleoverflow->id,
- ));
-
- // If the editing user is not the original author, add the original author to the params.
- if ($realpost->userid != $USER->id) {
- $params['relateduserid'] = $realpost->userid;
- }
-
- // Trigger post updated event.
- $event = \mod_moodleoverflow\event\post_updated::create($params);
- $event->trigger();
-
- // Redirect back to the discussion.
- redirect(moodleoverflow_go_back_to($discussionurl), $message, null, \core\output\notification::NOTIFY_SUCCESS);
-
- // Cancel.
- exit;
-
- } else if ($fromform->discussion) {
- // Add a new post to an existing discussion.
-
- // Set some basic variables.
- unset($fromform->groupid);
- $message = '';
- $addpost = $fromform;
- $addpost->moodleoverflow = $moodleoverflow->id;
-
- // Create the new post.
- if ($fromform->id = moodleoverflow_add_new_post($addpost)) {
-
- // Subscribe to this thread.
- $discussion = new \stdClass();
- $discussion->id = $fromform->discussion;
- $discussion->moodleoverflow = $moodleoverflow->id;
- \mod_moodleoverflow\subscriptions::moodleoverflow_post_subscription($fromform,
- $moodleoverflow, $discussion, $modulecontext);
-
- // Print a success-message.
- $message .= '' . get_string("postaddedsuccess", "moodleoverflow") . '
';
- $message .= '' . get_string("postaddedtimeleft", "moodleoverflow",
- format_time(get_config('moodleoverflow', 'maxeditingtime'))) . '
';
-
- // Set the URL that links back to the discussion.
- $link = '/mod/moodleoverflow/discussion.php';
- $discussionurl = new moodle_url($link, array('d' => $discussion->id), 'p' . $fromform->id);
-
- // Trigger post created event.
- $params = array(
- 'context' => $modulecontext,
- 'objectid' => $fromform->id,
- 'other' => array(
- 'discussionid' => $discussion->id,
- 'moodleoverflowid' => $moodleoverflow->id,
- ));
- $event = \mod_moodleoverflow\event\post_created::create($params);
- $event->trigger();
- redirect(
- moodleoverflow_go_back_to($discussionurl),
- $message,
- \core\output\notification::NOTIFY_SUCCESS
- );
-
- // Print an error if the answer could not be added.
- } else {
- throw new moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
- }
-
- // The post has been added.
- exit;
-
- } else {
- // Add a new discussion.
-
- // The location to redirect the user after successfully posting.
- $redirectto = new moodle_url('view.php', array('m' => $fromform->moodleoverflow));
-
- $discussion = $fromform;
- $discussion->name = $fromform->subject;
-
- // Check if the user is allowed to post here.
- if (!moodleoverflow_user_can_post_discussion($moodleoverflow)) {
- throw new moodle_exception('cannotcreatediscussion', 'moodleoverflow');
- }
-
- // Check if the creation of the new discussion failed.
- if (!$discussion->id = moodleoverflow_add_discussion($discussion, $modulecontext)) {
-
- throw new moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
-
- } else { // The creation of the new discussion was successful.
-
- $params = array(
- 'context' => $modulecontext,
- 'objectid' => $discussion->id,
- 'other' => array(
- 'moodleoverflowid' => $moodleoverflow->id,
- )
- );
-
- $message = '' . get_string("postaddedsuccess", "moodleoverflow") . '
';
-
- // Trigger the discussion created event.
- $params = array(
- 'context' => $modulecontext,
- 'objectid' => $discussion->id,
- );
- $event = \mod_moodleoverflow\event\discussion_created::create($params);
- $event->trigger();
- // Subscribe to this thread.
- $discussion->moodleoverflow = $moodleoverflow->id;
- \mod_moodleoverflow\subscriptions::moodleoverflow_post_subscription($fromform,
- $moodleoverflow, $discussion, $modulecontext);
- }
-
- // Redirect back to te discussion.
- redirect(moodleoverflow_go_back_to($redirectto->out()), $message, null, \core\output\notification::NOTIFY_SUCCESS);
-
- // Do not continue.
- exit;
- }
+ $postcontrol->execute_interaction($fromform);
+ exit;
}
// If the script gets to this point, nothing has been submitted.
-// We have to display the form.
-// $course and $moodleoverflow are defined.
-// $discussion is only used for replying and editing.
+// The post_form will be displayed.
// Define the message to be displayed above the form.
-$toppost = new stdClass();
-$toppost->subject = get_string("addanewdiscussion", "moodleoverflow");
+$toppost = new \stdClass();
+$toppost->subject = get_string('addanewdiscussion', 'moodleoverflow');
// Initiate the page.
-$PAGE->set_title("$course->shortname: $moodleoverflow->name " . format_string($toppost->subject));
-$PAGE->set_heading($course->fullname);
-
-// The page should not be large, only pages containing broad tables are usually.
+$PAGE->set_title($information->course->shortname . ': ' .
+ $information->moodleoverflow->name . ' ' .
+ format_string($toppost->subject));
+$PAGE->set_heading($information->course->fullname);
$PAGE->add_body_class('limitedwidth');
-// Display the header.
+// Display all.
echo $OUTPUT->header();
-
-// Display the form.
$mformpost->display();
-
-// Display the footer.
echo $OUTPUT->footer();
diff --git a/post_new.php b/post_new.php
deleted file mode 100644
index 9a3a2db972..0000000000
--- a/post_new.php
+++ /dev/null
@@ -1,156 +0,0 @@
-.
-
-/**
- * The file that is opened in Moodle when the user interacts with posts
- *
- * @package mod_moodleoverflow
- * @copyright 2023 Tamaro Walter
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-use mod_moodleoverflow\review;
-use mod_moodleoverflow\post\post_control;
-require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
-require_once(dirname(__FILE__) . '/locallib.php');
-require_once($CFG->libdir . '/completionlib.php');
-
-global $CFG, $USER, $DB, $PAGE, $SESSION, $OUTPUT;
-
-// Declare optional url parameters.
-$moodleoverflow = optional_param('moodleoverflow', 0, PARAM_INT);
-$reply = optional_param('reply', 0, PARAM_INT);
-$edit = optional_param('edit', 0, PARAM_INT);
-$delete = optional_param('delete', 0, PARAM_INT);
-$confirm = optional_param('confirm', 0, PARAM_INT);
-
-// Set the URL that should be used to return to this page.
-$PAGE->set_url('/mod/moodleoverflow/post.php', array(
- 'moodleoverflow' => $moodleoverflow,
- 'reply' => $reply,
- 'edit' => $edit,
- 'delete' => $delete,
- 'confirm' => $confirm,
-));
-
-// These params will be passed as hidden variables later in the form.
-$pageparams = array('moodleoverflow' => $moodleoverflow, 'reply' => $reply, 'edit' => $edit);
-
-// Get the system context instance.
-$systemcontext = context_system::instance();
-
-// Create a post_control object to control and lead the process.
-$postcontrol = new post_control();
-
-// Put all interaction parameters in one object for the post_control.
-$urlparameter = new \stdClass();
-$urlparameter->create = $moodleoverflow;
-$urlparameter->reply = $reply;
-$urlparameter->edit = $edit;
-$urlparameter->delete = $delete;
-
-// Catch guests.
-if (!isloggedin() || isguestuser()) {
- // Gather information and set the page right so that user can be redirected to the right site.
- $information = $postcontrol->catch_guest();
-
- // The guest needs to login.
- $strlogin = get_string('noguestpost', 'forum') . '
' . get_string('liketologin');
- echo $OUTPUT->header();
- echo $OUTPUT->confirm($strlogin, get_login_url(),
- $CFG->wwwroot . '/mod/moodleoverflow/view.php?m= ' . $information->moodleoverflow->id);
- echo $OUTPUT->footer();
- exit;
-}
-
-// Require a general login to post something.
-require_login(0, false);
-
-// Now the post_control checks which interaction is wanted and builds a prepost.
-$postcontrol->detect_interaction($urlparameter);
-
-// If a post is being deleted, delete it immediately.
-if ($postcontrol->get_interaction() == 'delete') {
- // Has the user confirmed the deletion?
- if (!empty($confirm) && confirm_sesskey()) {
- $postcontrol->execute_delete();
- exit;
- } else {
- // Deletion needs to be confirmed.
- $postcontrol->confirm_delete();
-
- // Display a confirmation request depending on the number of posts that are being deleted.
- $information = $postcontrol->get_information();
- echo $OUTPUT->header();
- if ($information->deletetype == 'plural') {
- echo $OUTPUT->confirm(get_string('deletesureplural', 'moodleoverflow', $information->replycount + 1),
- 'post.php?delete='.$delete.'&confirm='.$delete,
- $CFG->wwwroot . '/mod/moodleoverflow/discussion.php?d=' . $information->discussion->get_id() .
- '#p' . $information->relatedpost->get_id());
- } else {
- echo $OUTPUT->confirm(get_string('deletesure', 'moodleoverflow', $information->replycount),
- "post.php?delete=$delete&confirm=$delete",
- $CFG->wwwroot . '/mod/moodleoverflow/discussion.php?d=' . $information->discussion->get_id() .
- '#p' . $information->relatedpost->get_id());
- }
- echo $OUTPUT->footer();
- exit;
- }
-}
-
-// A post will be created or edited. For that the post_control builds a post_form.
-$mformpost = $postcontrol->build_postform();
-
-// The User now entered information in the form. The post.php now needs to process the information and call the right function.
-
-// Get attributes from the postcontrol.
-$information = $postcontrol->get_information();
-$prepost = $postcontrol->get_prepost();
-
-// If the interaction was cancelled, the user needs to be redirected.
-if ($mformpost->is_cancelled()) {
- if (!issett($prepost->discussionid)) {
- redirect(new moodle_url('/mod/moodleoverflow/view.php', array('m' => $prepost->moodleoverflowid)));
- } else {
- redirect(new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $prepost->discussionid)));
- }
- exit;
-}
-
-// If the post_form is submitted, the post_control executes the right function.
-if ($fromform = $mformpost->get_data()) {
- $postcontrol->execute_interaction($fromform);
- exit;
-}
-
-// If the script gets to this point, nothing has been submitted.
-// The post_form will be displayed.
-
-// Define the message to be displayed above the form.
-$toppost = new \stdClass();
-$toppost->subject = get_string('addanewdiscussion', 'moodleoverflow');
-
-// Initiate the page.
-$PAGE->set_title($information->course->shortname . ': ' .
- $information->moodleoverflow->name . ' ' .
- format_string($toppost->subject));
-$PAGE->set_heading($information->course->fullname);
-$PAGE->add_body_class('limitedwidth');
-
-// Display all.
-echo $OUTPUT->header();
-$mformpost->display();
-echo $OUTPUT->footer();
diff --git a/post_old.php b/post_old.php
new file mode 100644
index 0000000000..5baa519ba5
--- /dev/null
+++ b/post_old.php
@@ -0,0 +1,792 @@
+.
+
+/**
+ * The file to manage posts.
+ *
+ * @package mod_moodleoverflow
+ * @copyright 2017 Kennet Winter
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+// TODO refactor this. For more readability, and to avoid security issues.
+
+// Include config and locallib.
+use mod_moodleoverflow\review;
+
+require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
+global $CFG, $USER, $DB, $PAGE, $SESSION, $OUTPUT;
+require_once(dirname(__FILE__) . '/locallib.php');
+require_once($CFG->libdir . '/completionlib.php');
+
+// Declare optional parameters.
+$moodleoverflow = optional_param('moodleoverflow', 0, PARAM_INT);
+$reply = optional_param('reply', 0, PARAM_INT);
+$edit = optional_param('edit', 0, PARAM_INT);
+$delete = optional_param('delete', 0, PARAM_INT);
+$confirm = optional_param('confirm', 0, PARAM_INT);
+
+$count = 0;
+$count += $moodleoverflow ? 1 : 0;
+$count += $reply ? 1 : 0;
+$count += $edit ? 1 : 0;
+$count += $delete ? 1 : 0;
+
+if ($count !== 1) {
+ throw new coding_exception('Exactly one parameter should be specified!');
+}
+
+// Set the URL that should be used to return to this page.
+$PAGE->set_url('/mod/moodleoverflow/post.php', array(
+ 'moodleoverflow' => $moodleoverflow,
+ 'reply' => $reply,
+ 'edit' => $edit,
+ 'delete' => $delete,
+ 'confirm' => $confirm,
+));
+
+// These params will be passed as hidden variables later in the form.
+$pageparams = array('moodleoverflow' => $moodleoverflow, 'reply' => $reply, 'edit' => $edit);
+
+// Get the system context instance.
+$systemcontext = context_system::instance();
+
+// Catch guests.
+if (!isloggedin() || isguestuser()) {
+
+ // The user is starting a new discussion in a moodleoverflow instance.
+ if (!empty($moodleoverflow)) {
+
+ // Check the moodleoverflow instance is valid.
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow))) {
+ throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
+ }
+
+ // The user is replying to an existing moodleoverflow discussion.
+ } else if (!empty($reply)) {
+
+ // Check if the related post exists.
+ if (!$parent = moodleoverflow_get_post_full($reply)) {
+ throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
+ }
+
+ // Check if the post is part of a valid discussion.
+ if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $parent->discussion))) {
+ throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
+ }
+
+ // Check if the post is related to a valid moodleoverflow instance.
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
+ throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
+ }
+ }
+
+ // Get the related course.
+ if (!$course = $DB->get_record('course', array('id' => $moodleoverflow->course))) {
+ throw new moodle_exception('invalidcourseid');
+ }
+
+ // Get the related coursemodule and its context.
+ if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $course->id)) {
+ throw new moodle_exception('invalidcoursemodule');
+ }
+
+ // Get the context of the module.
+ $modulecontext = context_module::instance($cm->id);
+
+ // Set parameters for the page.
+ $PAGE->set_cm($cm, $course, $moodleoverflow);
+ $PAGE->set_context($modulecontext);
+ $PAGE->set_title($course->shortname);
+ $PAGE->set_heading($course->fullname);
+
+ // The page should not be large, only pages containing broad tables are usually.
+ $PAGE->add_body_class('limitedwidth');
+
+ // The guest needs to login.
+ echo $OUTPUT->header();
+ $strlogin = get_string('noguestpost', 'forum') . '
' . get_string('liketologin');
+ echo $OUTPUT->confirm($strlogin, get_login_url(), $CFG->wwwroot . '/mod/moodleoverflow/view.php?m=' . $moodleoverflow->id);
+ echo $OUTPUT->footer();
+ exit;
+}
+
+// First step: A general login is needed to post something.
+require_login(0, false);
+
+// First possibility: User is starting a new discussion in a moodleoverflow instance.
+if (!empty($moodleoverflow)) {
+
+ // Check the moodleoverflow instance is valid.
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow))) {
+ throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
+ }
+
+ // Get the related course.
+ if (!$course = $DB->get_record('course', array('id' => $moodleoverflow->course))) {
+ throw new moodle_exception('invalidcourseid');
+ }
+
+ // Get the related coursemodule.
+ if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $course->id)) {
+ throw new moodle_exception('invalidcoursemodule');
+ }
+
+ // Retrieve the contexts.
+ $modulecontext = context_module::instance($cm->id);
+ $coursecontext = context_course::instance($course->id);
+
+ // Check if the user can start a new discussion.
+ if (!moodleoverflow_user_can_post_discussion($moodleoverflow, $cm, $modulecontext)) {
+
+ // Catch unenrolled user.
+ if (!isguestuser() && !is_enrolled($coursecontext)) {
+ if (enrol_selfenrol_available($course->id)) {
+ $SESSION->wantsurl = qualified_me();
+ $SESSION->enrolcancel = get_local_referer(false);
+ redirect(new moodle_url('/enrol/index.php', array(
+ 'id' => $course->id,
+ 'returnurl' => '/mod/moodleoverflow/view.php?m=' . $moodleoverflow->id
+ )), get_string('youneedtoenrol'));
+ }
+ }
+
+ // Notify the user, that he can not post a new discussion.
+ throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
+ }
+
+ // Where is the user coming from?
+ $SESSION->fromurl = get_local_referer(false);
+
+ // Load all the $post variables.
+ $post = new stdClass();
+ $post->course = $course->id;
+ $post->moodleoverflow = $moodleoverflow->id;
+ $post->discussion = 0;
+ $post->parent = 0;
+ $post->subject = '';
+ $post->userid = $USER->id;
+ $post->message = '';
+
+ // Unset where the user is coming from.
+ // Allows to calculate the correct return url later.
+ unset($SESSION->fromdiscussion);
+
+} else if (!empty($reply)) {
+ // Second possibility: The user is writing a new reply.
+
+ // Check if the post exists.
+ if (!$parent = moodleoverflow_get_post_full($reply)) {
+ throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
+ }
+
+ // Check if the post is part of a discussion.
+ if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $parent->discussion))) {
+ throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
+ }
+
+ // Check if the discussion is part of a moodleoverflow instance.
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
+ throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
+ }
+
+ // Check if the moodleoverflow instance is part of a course.
+ if (!$course = $DB->get_record('course', array('id' => $discussion->course))) {
+ throw new moodle_exception('invalidcourseid');
+ }
+
+ // Retrieve the related coursemodule.
+ if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $course->id)) {
+ throw new moodle_exception('invalidcoursemodule');
+ }
+
+ // Ensure the coursemodule is set correctly.
+ $PAGE->set_cm($cm, $course, $moodleoverflow);
+
+ // Retrieve the other contexts.
+ $modulecontext = context_module::instance($cm->id);
+ $coursecontext = context_course::instance($course->id);
+
+ // Check whether the user is allowed to post.
+ if (!moodleoverflow_user_can_post($modulecontext, $parent)) {
+
+ // Give the user the chance to enroll himself to the course.
+ if (!isguestuser() && !is_enrolled($coursecontext)) {
+ $SESSION->wantsurl = qualified_me();
+ $SESSION->enrolcancel = get_local_referer(false);
+ redirect(new moodle_url('/enrol/index.php',
+ array('id' => $course->id, 'returnurl' => '/mod/moodleoverflow/view.php?m=' . $moodleoverflow->id)),
+ get_string('youneedtoenrol'));
+ }
+
+ // Print the error message.
+ throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
+ }
+
+ // Make sure the user can post here.
+ if (!$cm->visible && !has_capability('moodle/course:viewhiddenactivities', $modulecontext)) {
+ throw new moodle_exception('activityiscurrentlyhidden');
+ }
+
+ // Load the $post variable.
+ $post = new stdClass();
+ $post->course = $course->id;
+ $post->moodleoverflow = $moodleoverflow->id;
+ $post->discussion = $parent->discussion;
+ $post->parent = $parent->id;
+ $post->subject = $discussion->name;
+ $post->userid = $USER->id;
+ $post->message = '';
+
+ // Append 'RE: ' to the discussions subject.
+ $strre = get_string('re', 'moodleoverflow');
+ if (!(substr($post->subject, 0, strlen($strre)) == $strre)) {
+ $post->subject = $strre . ' ' . $post->subject;
+ }
+
+ // Unset where the user is coming from.
+ // Allows to calculate the correct return url later.
+ unset($SESSION->fromdiscussion);
+
+
+} else if (!empty($edit)) {
+ // Third possibility: The user is editing his own post.
+
+ // Check if the submitted post exists.
+ if (!$post = moodleoverflow_get_post_full($edit)) {
+ throw new moodle_exception('invalidpostid', 'moodleoverflow');
+ }
+
+ // Get the parent post of this post if it is not the starting post of the discussion.
+ if ($post->parent) {
+ if (!$parent = moodleoverflow_get_post_full($post->parent)) {
+ throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
+ }
+ }
+
+ // Check if the post refers to a valid discussion.
+ if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $post->discussion))) {
+ throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
+ }
+
+ // Check if the post refers to a valid moodleoverflow instance.
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
+ throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
+ }
+
+ // Check if the post refers to a valid course.
+ if (!$course = $DB->get_record('course', array('id' => $discussion->course))) {
+ throw new moodle_exception('invalidcourseid');
+ }
+
+ // Retrieve the related coursemodule.
+ if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $course->id)) {
+ throw new moodle_exception('invalidcoursemodule');
+ } else {
+ $modulecontext = context_module::instance($cm->id);
+ }
+
+ // Set the pages context.
+ $PAGE->set_cm($cm, $course, $moodleoverflow);
+
+ // Check if the post can be edited.
+ $beyondtime = ((time() - $post->created) > get_config('moodleoverflow', 'maxeditingtime'));
+ $alreadyreviewed = review::should_post_be_reviewed($post, $moodleoverflow) && $post->reviewed;
+ if (($beyondtime || $alreadyreviewed) && !has_capability('mod/moodleoverflow:editanypost', $modulecontext)) {
+ throw new moodle_exception('maxtimehaspassed', 'moodleoverflow', '',
+ format_time(get_config('moodleoverflow', 'maxeditingtime')));
+ }
+
+
+
+ // If the current user is not the one who posted this post.
+ if ($post->userid <> $USER->id) {
+
+ // Check if the current user has not the capability to edit any post.
+ if (!has_capability('mod/moodleoverflow:editanypost', $modulecontext)) {
+
+ // Display the error. Capabilities are missing.
+ throw new moodle_exception('cannoteditposts', 'moodleoverflow');
+ }
+ }
+
+ // Load the $post variable.
+ $post->edit = $edit;
+ $post->course = $course->id;
+ $post->moodleoverflow = $moodleoverflow->id;
+
+ // Unset where the user is coming from.
+ // Allows to calculate the correct return url later.
+ unset($SESSION->fromdiscussion);
+
+} else if (!empty($delete)) {
+ // Fourth possibility: The user is deleting a post.
+ // Check if the post is existing.
+ if (!$post = moodleoverflow_get_post_full($delete)) {
+ throw new moodle_exception('invalidpostid', 'moodleoverflow');
+ }
+
+ // Get the related discussion.
+ if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $post->discussion))) {
+ throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
+ }
+
+ // Get the related moodleoverflow instance.
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
+ throw new moodle_exception('invalidmoodleoverflowid', 'moodleoveflow');
+ }
+
+ // Get the related coursemodule.
+ if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $moodleoverflow->course)) {
+ throw new moodle_exception('invalidcoursemodule');
+ }
+
+ // Get the related course.
+ if (!$course = $DB->get_record('course', array('id' => $moodleoverflow->course))) {
+ throw new moodle_exception('invalidcourseid');
+ }
+
+ // Require a login and retrieve the modulecontext.
+ require_login($course, false, $cm);
+ $modulecontext = context_module::instance($cm->id);
+
+ // Check some capabilities.
+ $deleteownpost = has_capability('mod/moodleoverflow:deleteownpost', $modulecontext);
+ $deleteanypost = has_capability('mod/moodleoverflow:deleteanypost', $modulecontext);
+ if (!(($post->userid == $USER->id && $deleteownpost) || $deleteanypost)) {
+ throw new moodle_exception('cannotdeletepost', 'moodleoverflow');
+ }
+
+ // Count all replies of this post.
+ $replycount = moodleoverflow_count_replies($post, false);
+
+ // Has the user confirmed the deletion?
+ if (!empty($confirm) && confirm_sesskey()) {
+
+ // Check if the user has the capability to delete the post.
+ $timepassed = time() - $post->created;
+ if (($timepassed > get_config('moodleoverflow', 'maxeditingtime')) && !$deleteanypost) {
+ $url = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $post->discussion));
+ throw new moodle_exception('cannotdeletepost', 'moodleoverflow', moodleoverflow_go_back_to($url));
+ }
+
+ // A normal user cannot delete his post if there are direct replies.
+ if ($replycount && !$deleteanypost) {
+ $url = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $post->discussion));
+ throw new moodle_exception('couldnotdeletereplies', 'moodleoverflow', moodleoverflow_go_back_to($url));
+ } else {
+ // Delete the post.
+
+ // The post is the starting post of a discussion. Delete the topic as well.
+ if (!$post->parent) {
+ moodleoverflow_delete_discussion($discussion, $course, $cm, $moodleoverflow);
+
+ // Trigger the discussion deleted event.
+ $params = array(
+ 'objectid' => $discussion->id,
+ 'context' => $modulecontext,
+ );
+
+ $event = \mod_moodleoverflow\event\discussion_deleted::create($params);
+ $event->trigger();
+
+ // Redirect the user back to start page of the moodleoverflow instance.
+ redirect("view.php?m=$discussion->moodleoverflow");
+ exit;
+
+ } else if (moodleoverflow_delete_post($post, $deleteanypost, $cm, $moodleoverflow)) {
+ // Delete a single post.
+ // Redirect back to the discussion.
+ $discussionurl = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $discussion->id));
+ redirect(moodleoverflow_go_back_to($discussionurl));
+ exit;
+
+ } else {
+ // Something went wrong.
+ throw new moodle_exception('errorwhiledelete', 'moodleoverflow');
+ }
+ }
+ } else {
+ // Deletion needs to be confirmed.
+
+ moodleoverflow_set_return();
+ $PAGE->navbar->add(get_string('delete', 'moodleoverflow'));
+ $PAGE->set_title($course->shortname);
+ $PAGE->set_heading($course->fullname);
+
+ // The page should not be large, only pages containing broad tables are usually.
+ $PAGE->add_body_class('limitedwidth');
+
+ // Check if there are replies for the post.
+ if ($replycount) {
+
+ // Check if the user has capabilities to delete more than one post.
+ if (!$deleteanypost) {
+ throw new moodle_exception('couldnotdeletereplies', 'moodleoverflow',
+ moodleoverflow_go_back_to(new moodle_url('/mod/moodleoverflow/discussion.php',
+ array('d' => $post->discussion, 'p' . $post->id))));
+ }
+
+ // Request a confirmation to delete the post.
+ echo $OUTPUT->header();
+ echo $OUTPUT->confirm(get_string("deletesureplural", "moodleoverflow", $replycount + 1),
+ "post.php?delete=$delete&confirm=$delete", $CFG->wwwroot . '/mod/moodleoverflow/discussion.php?d=' .
+ $post->discussion . '#p' . $post->id);
+
+ } else {
+ // Delete a single post.
+
+ // Print a confirmation message.
+ echo $OUTPUT->header();
+ echo $OUTPUT->confirm(get_string("deletesure", "moodleoverflow", $replycount),
+ "post.php?delete=$delete&confirm=$delete",
+ $CFG->wwwroot . '/mod/moodleoverflow/discussion.php?d=' . $post->discussion . '#p' . $post->id);
+ }
+ }
+ echo $OUTPUT->footer();
+ exit;
+
+} else {
+ // Last posibility: the action is not known.
+
+ throw new moodle_exception('unknownaction');
+}
+
+// Second step: The user must be logged on properly. Must be enrolled to the course as well.
+require_login($course, false, $cm);
+
+// Get the contexts.
+$modulecontext = context_module::instance($cm->id);
+$coursecontext = context_course::instance($course->id);
+
+// Get the subject.
+if ($edit) {
+ $subject = $discussion->name;
+} else if ($reply) {
+ $subject = $post->subject;
+} else if ($moodleoverflow) {
+ $subject = $post->subject;
+}
+
+// Get attachments.
+$draftitemid = file_get_submitted_draft_itemid('attachments');
+file_prepare_draft_area($draftitemid,
+ $modulecontext->id,
+ 'mod_moodleoverflow',
+ 'attachment',
+ empty($post->id) ? null : $post->id,
+ mod_moodleoverflow_post_form::attachment_options($moodleoverflow));
+
+// Prepare the form.
+$formarray = array(
+ 'course' => $course,
+ 'cm' => $cm,
+ 'coursecontext' => $coursecontext,
+ 'modulecontext' => $modulecontext,
+ 'moodleoverflow' => $moodleoverflow,
+ 'post' => $post,
+ 'edit' => $edit,
+);
+$mformpost = new mod_moodleoverflow_post_form('post.php', $formarray, 'post', '', array('id' => 'mformmoodleoverflow'));
+
+// The current user is not the original author.
+// Append the message to the end of the message.
+if ($USER->id != $post->userid) {
+
+ // Create a temporary object.
+ $data = new stdClass();
+ $data->date = userdate($post->modified);
+ $post->messageformat = editors_get_preferred_format();
+
+ // Append the message depending on the messages format.
+ if ($post->messageformat == FORMAT_HTML) {
+ $data->name = '' . fullname($USER) . '';
+ $post->message .= '(' . get_string('editedby', 'moodleoverflow', $data) . ')
';
+ } else {
+ $data->name = fullname($USER);
+ $post->message .= "\n\n(" . get_string('editedby', 'moodleoverflow', $data) . ')';
+ }
+
+ // Delete the temporary object.
+ unset($data);
+}
+
+// Define the heading for the form.
+$formheading = '';
+if (!empty($parent)) {
+ $heading = get_string('yourreply', 'moodleoverflow');
+ $formheading = get_string('reply', 'moodleoverflow');
+} else {
+ $heading = get_string('yournewtopic', 'moodleoverflow');
+}
+
+// Get the original post.
+$postid = empty($post->id) ? null : $post->id;
+$postmessage = empty($post->message) ? null : $post->message;
+
+// Set data for the form.
+// TODO Refactor.
+$param1 = (isset($discussion->id) ? array($discussion->id) : array());
+$param2 = (isset($post->format) ? array('format' => $post->format) : array());
+$param3 = (isset($discussion->timestart) ? array('timestart' => $discussion->timestart) : array());
+$param4 = (isset($discussion->timeend) ? array('timeend' => $discussion->timeend) : array());
+$param5 = (isset($discussion->id) ? array('discussion' => $discussion->id) : array());
+$mformpost->set_data(array(
+ 'attachments' => $draftitemid,
+ 'general' => $heading,
+ 'subject' => $subject,
+ 'message' => array(
+ 'text' => $postmessage,
+ 'format' => editors_get_preferred_format(),
+ 'itemid' => $postid,
+ ),
+ 'userid' => $post->userid,
+ 'parent' => $post->parent,
+ 'discussion' => $post->discussion,
+ 'course' => $course->id
+ ) + $pageparams + $param1 + $param2 + $param3 + $param4 + $param5);
+
+// Is it canceled?
+if ($mformpost->is_cancelled()) {
+
+ // Redirect the user back.
+ if (!isset($discussion->id)) {
+ redirect(new moodle_url('/mod/moodleoverflow/view.php', array('m' => $moodleoverflow->id)));
+ } else {
+ redirect(new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $discussion->id)));
+ }
+
+ // Cancel.
+ exit();
+}
+
+// Is it submitted?
+if ($fromform = $mformpost->get_data()) {
+
+ // Redirect url in case of occuring errors.
+ if (empty($SESSION->fromurl)) {
+ $errordestination = "$CFG->wwwroot/mod/moodleoverflow/view.php?m=$moodleoverflow->id";
+ } else {
+ $errordestination = $SESSION->fromurl;
+ }
+
+ // Format the submitted data.
+ $fromform->messageformat = $fromform->message['format'];
+ $fromform->message = $fromform->message['text'];
+ $fromform->messagetrust = trusttext_trusted($modulecontext);
+
+ // If we are updating a post.
+ if ($fromform->edit) {
+
+ // Initiate some variables.
+ unset($fromform->groupid);
+ $fromform->id = $fromform->edit;
+ $message = '';
+
+ // The FORUM-Plugin had an bug: https://tracker.moodle.org/browse/MDL-4314
+ // This is a fix for it.
+ if (!$realpost = $DB->get_record('moodleoverflow_posts', array('id' => $fromform->id))) {
+ $realpost = new stdClass();
+ $realpost->userid = -1;
+ }
+
+ // Check the capabilities of the user.
+ // He may proceed if he can edit any post or if he has the startnewdiscussion
+ // capability or the capability to reply and is editing his own post.
+ $editanypost = has_capability('mod/moodleoverflow:editanypost', $modulecontext);
+ $replypost = has_capability('mod/moodleoverflow:replypost', $modulecontext);
+ $startdiscussion = has_capability('mod/moodleoverflow:startdiscussion', $modulecontext);
+ $ownpost = ($realpost->userid == $USER->id);
+ if (!(($ownpost && ($replypost || $startdiscussion)) || $editanypost)) {
+ throw new moodle_exception('cannotupdatepost', 'moodleoverflow');
+ }
+
+ // Update the post or print an error message.
+ $updatepost = $fromform;
+ $updatepost->moodleoverflow = $moodleoverflow->id;
+ if (!moodleoverflow_update_post($updatepost, $mformpost)) {
+ throw new moodle_exception('couldnotupdate', 'moodleoverflow', $errordestination);
+ }
+
+ // Create a success-message.
+ if ($realpost->userid == $USER->id) {
+ $message .= get_string('postupdated', 'moodleoverflow');
+ } else {
+ if (\mod_moodleoverflow\anonymous::is_post_anonymous($discussion, $moodleoverflow, $realpost->userid)) {
+ $name = get_string('anonymous', 'moodleoverflow');
+ } else {
+ $realuser = $DB->get_record('user', array('id' => $realpost->userid));
+ $name = fullname($realuser);
+ }
+ $message .= get_string('editedpostupdated', 'moodleoverflow', $name);
+ }
+
+ // Create a link to go back to the discussion.
+ $discussionurl = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $discussion->id), 'p' . $fromform->id);
+
+ // Set some parameters.
+ $params = array(
+ 'context' => $modulecontext,
+ 'objectid' => $fromform->id,
+ 'other' => array(
+ 'discussionid' => $discussion->id,
+ 'moodleoverflowid' => $moodleoverflow->id,
+ ));
+
+ // If the editing user is not the original author, add the original author to the params.
+ if ($realpost->userid != $USER->id) {
+ $params['relateduserid'] = $realpost->userid;
+ }
+
+ // Trigger post updated event.
+ $event = \mod_moodleoverflow\event\post_updated::create($params);
+ $event->trigger();
+
+ // Redirect back to the discussion.
+ redirect(moodleoverflow_go_back_to($discussionurl), $message, null, \core\output\notification::NOTIFY_SUCCESS);
+
+ // Cancel.
+ exit;
+
+ } else if ($fromform->discussion) {
+ // Add a new post to an existing discussion.
+
+ // Set some basic variables.
+ unset($fromform->groupid);
+ $message = '';
+ $addpost = $fromform;
+ $addpost->moodleoverflow = $moodleoverflow->id;
+
+ // Create the new post.
+ if ($fromform->id = moodleoverflow_add_new_post($addpost)) {
+
+ // Subscribe to this thread.
+ $discussion = new \stdClass();
+ $discussion->id = $fromform->discussion;
+ $discussion->moodleoverflow = $moodleoverflow->id;
+ \mod_moodleoverflow\subscriptions::moodleoverflow_post_subscription($fromform,
+ $moodleoverflow, $discussion, $modulecontext);
+
+ // Print a success-message.
+ $message .= '' . get_string("postaddedsuccess", "moodleoverflow") . '
';
+ $message .= '' . get_string("postaddedtimeleft", "moodleoverflow",
+ format_time(get_config('moodleoverflow', 'maxeditingtime'))) . '
';
+
+ // Set the URL that links back to the discussion.
+ $link = '/mod/moodleoverflow/discussion.php';
+ $discussionurl = new moodle_url($link, array('d' => $discussion->id), 'p' . $fromform->id);
+
+ // Trigger post created event.
+ $params = array(
+ 'context' => $modulecontext,
+ 'objectid' => $fromform->id,
+ 'other' => array(
+ 'discussionid' => $discussion->id,
+ 'moodleoverflowid' => $moodleoverflow->id,
+ ));
+ $event = \mod_moodleoverflow\event\post_created::create($params);
+ $event->trigger();
+ redirect(
+ moodleoverflow_go_back_to($discussionurl),
+ $message,
+ \core\output\notification::NOTIFY_SUCCESS
+ );
+
+ // Print an error if the answer could not be added.
+ } else {
+ throw new moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
+ }
+
+ // The post has been added.
+ exit;
+
+ } else {
+ // Add a new discussion.
+
+ // The location to redirect the user after successfully posting.
+ $redirectto = new moodle_url('view.php', array('m' => $fromform->moodleoverflow));
+
+ $discussion = $fromform;
+ $discussion->name = $fromform->subject;
+
+ // Check if the user is allowed to post here.
+ if (!moodleoverflow_user_can_post_discussion($moodleoverflow)) {
+ throw new moodle_exception('cannotcreatediscussion', 'moodleoverflow');
+ }
+
+ // Check if the creation of the new discussion failed.
+ if (!$discussion->id = moodleoverflow_add_discussion($discussion, $modulecontext)) {
+
+ throw new moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
+
+ } else { // The creation of the new discussion was successful.
+
+ $params = array(
+ 'context' => $modulecontext,
+ 'objectid' => $discussion->id,
+ 'other' => array(
+ 'moodleoverflowid' => $moodleoverflow->id,
+ )
+ );
+
+ $message = '' . get_string("postaddedsuccess", "moodleoverflow") . '
';
+
+ // Trigger the discussion created event.
+ $params = array(
+ 'context' => $modulecontext,
+ 'objectid' => $discussion->id,
+ );
+ $event = \mod_moodleoverflow\event\discussion_created::create($params);
+ $event->trigger();
+ // Subscribe to this thread.
+ $discussion->moodleoverflow = $moodleoverflow->id;
+ \mod_moodleoverflow\subscriptions::moodleoverflow_post_subscription($fromform,
+ $moodleoverflow, $discussion, $modulecontext);
+ }
+
+ // Redirect back to te discussion.
+ redirect(moodleoverflow_go_back_to($redirectto->out()), $message, null, \core\output\notification::NOTIFY_SUCCESS);
+
+ // Do not continue.
+ exit;
+ }
+}
+
+// If the script gets to this point, nothing has been submitted.
+// We have to display the form.
+// $course and $moodleoverflow are defined.
+// $discussion is only used for replying and editing.
+
+// Define the message to be displayed above the form.
+$toppost = new stdClass();
+$toppost->subject = get_string("addanewdiscussion", "moodleoverflow");
+
+// Initiate the page.
+$PAGE->set_title("$course->shortname: $moodleoverflow->name " . format_string($toppost->subject));
+$PAGE->set_heading($course->fullname);
+
+// The page should not be large, only pages containing broad tables are usually.
+$PAGE->add_body_class('limitedwidth');
+
+// Display the header.
+echo $OUTPUT->header();
+
+// Display the form.
+$mformpost->display();
+
+// Display the footer.
+echo $OUTPUT->footer();
From b71565edcd71e2466e91656d37326a42113abd16 Mon Sep 17 00:00:00 2001
From: NinaHerrmann
Date: Fri, 28 Jul 2023 15:19:06 +0200
Subject: [PATCH 19/56] change includes
---
classes/post/post.php | 2 +-
classes/post/{post.control.php => post_control.php} | 2 +-
post.php | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
rename classes/post/{post.control.php => post_control.php} (99%)
diff --git a/classes/post/post.php b/classes/post/post.php
index 89c35ff9a2..0f58487225 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -23,7 +23,7 @@
*/
-namespace mod_moodleoverflow\post\post;
+namespace mod_moodleoverflow\post;
// Import namespace from the locallib, needs a check later which namespaces are really needed.
use mod_moodleoverflow\anonymous;
diff --git a/classes/post/post.control.php b/classes/post/post_control.php
similarity index 99%
rename from classes/post/post.control.php
rename to classes/post/post_control.php
index bb99a6e46e..1ec280eef5 100644
--- a/classes/post/post.control.php
+++ b/classes/post/post_control.php
@@ -23,7 +23,7 @@
*/
-namespace mod_moodleoverflow\post\post_control;
+namespace mod_moodleoverflow\post;
// Import namespace from the locallib, needs a check later which namespaces are really needed.
use mod_moodleoverflow\anonymous;
diff --git a/post.php b/post.php
index 9a3a2db972..c9d802a02a 100644
--- a/post.php
+++ b/post.php
@@ -23,7 +23,6 @@
*/
use mod_moodleoverflow\review;
-use mod_moodleoverflow\post\post_control;
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
require_once(dirname(__FILE__) . '/locallib.php');
require_once($CFG->libdir . '/completionlib.php');
@@ -53,6 +52,7 @@
$systemcontext = context_system::instance();
// Create a post_control object to control and lead the process.
+$postcontrol = new \mod_moodleoverflow\post\post_control();
$postcontrol = new post_control();
// Put all interaction parameters in one object for the post_control.
From 0eed5624da5f90fe961543c70d77839ddebef379 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Fri, 28 Jul 2023 16:46:43 +0200
Subject: [PATCH 20/56] WIP: fixing errors
---
classes/discussion/discussion.php | 1 -
classes/post/post.drawio | 203 ------------------------------
classes/post/post.php | 1 -
classes/post/post_control.php | 79 ++++++------
lang/en/moodleoverflow.php | 1 -
post.php | 7 +-
6 files changed, 44 insertions(+), 248 deletions(-)
delete mode 100644 classes/post/post.drawio
diff --git a/classes/discussion/discussion.php b/classes/discussion/discussion.php
index b188f3c262..2cf6262d41 100644
--- a/classes/discussion/discussion.php
+++ b/classes/discussion/discussion.php
@@ -36,7 +36,6 @@
defined('MOODLE_INTERNAL') || die();
-require_once(dirname(__FILE__) . '/lib.php');
require_once($CFG->dirroot . '/mod/moodleoverflow/locallib.php');
/**
diff --git a/classes/post/post.drawio b/classes/post/post.drawio
deleted file mode 100644
index cdb9223a02..0000000000
--- a/classes/post/post.drawio
+++ /dev/null
@@ -1,203 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/classes/post/post.php b/classes/post/post.php
index 0f58487225..ca80a6002c 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -34,7 +34,6 @@
defined('MOODLE_INTERNAL') || die();
-require_once(dirname(__FILE__) . '/lib.php');
require_once($CFG->dirroot . '/mod/moodleoverflow/locallib.php');
/**
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index 1ec280eef5..ecd4a1eed9 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -30,15 +30,14 @@
use mod_moodleoverflow\capabilities;
use mod_moodleoverflow\review;
-use mod_moodleoverflow\post\post;
+use mod_moodleoverflow\post;
use mod_moodleoverflow\discussion;
defined('MOODLE_INTERNAL') || die();
+global $CFG;
-require_once(dirname(__FILE__) . '/lib.php');
-require_once(dirname(__FILE__) . '/locallib.php');
+require_once($CFG->dirroot . '/mod/moodleoverflow/locallib.php');
require_once($CFG->libdir . '/completionlib.php');
-require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
/**
* This Class controls the manipulation of posts and acts as controller of interactions with the post.php
@@ -85,13 +84,14 @@ class post_control {
* Constructor
*/
public function __construct() {
- $this->info = new \stdClass;
+ $this->info = new \stdClass();
}
/**
* Detects the interaction and builds the prepost.
* @param object $urlparamter parameter from the post.php
* @throws moodle_exception if the interaction is not correct.
+ * @throws \moodle_exception
*/
public function detect_interaction($urlparameter) {
$count = 0;
@@ -100,7 +100,7 @@ public function detect_interaction($urlparameter) {
$count += $urlparameter->edit ? 1 : 0;
$count += $urlparameter->delete ? 1 : 0;
if ($count !== 1) {
- throw new coding_exception('Exactly one parameter should be specified!');
+ throw new \coding_exception('Exactly one parameter should be specified!');
}
if ($urlparameter->create) {
@@ -115,7 +115,7 @@ public function detect_interaction($urlparameter) {
} else if ($urlparameter->reply) {
$this->interaction = 'reply';
- $this->info->replypostid = $urlparameter->edit;
+ $this->info->replypostid = $urlparameter->reply;
$this->build_prepost_reply($this->info->replypostid);
} else if ($urlparameter->delete) {
@@ -123,19 +123,20 @@ public function detect_interaction($urlparameter) {
$this->info->deletepostid = $urlparameter->edit;
$this->build_prepost_delete($this->info->deletepostid);
} else {
- throw new moodle_exception('unknownaction');
+ throw new \moodle_exception('unknownaction');
}
}
/**
* Controls the execution of an interaction.
* @param object $form The results from the post_form.
- * @return bool if the execution succeded
+ * @return bool if the execution succeeded
*/
public function execute_interaction($form) {
- // Redirect url in case of occuring errors.
+ global $CFG;
+ // Redirect url in case of occurring errors.
if (empty($SESSION->fromurl)) {
- $errordestination = '$CFG->wwwroot/mod/moodleoverflow/view.php?m=' . $this->prepost->moodleoverflowid;
+ $errordestination = $CFG->wwwroot . '/mod/moodleoverflow/view.php?m=' . $this->prepost->moodleoverflowid;
} else {
$errordestination = $SESSION->fromurl;
}
@@ -157,7 +158,7 @@ public function execute_interaction($form) {
} else if ($this->interaction == 'edit' && $form->edit === $this->prepost->postid) {
$this->execute_edit($form, $errordestination);
} else {
- throw new moodle_exception('unexpectedinteractionerror', 'moodleoverflow', $errordestination);
+ throw new \moodle_exception('unexpectedinteractionerror', 'moodleoverflow', $errordestination);
}
}
@@ -171,14 +172,14 @@ public function execute_interaction($form) {
public function catch_guest($postid = false, $moodleoverflowid = false) {
global $PAGE;
if ((!$postid && !$moodleoverflowid) || ($postid && $moodleoverflowid)) {
- throw new moodle_exception('inaccurateparameter', 'moodleoverflow');
+ throw new \moodle_exception('inaccurateparameter', 'moodleoverflow');
}
if ($postid) {
$this->collect_information($postid, false);
} else if ($moodleoverflowid) {
$this->collect_information(false, $moodleoverflowid);
}
- $this->info->modulecontext = context_module::instance($this->info->cm->id);
+ $this->info->modulecontext = \context_module::instance($this->info->cm->id);
// Set the parameters for the page.
$PAGE->set_cm($this->info->cm, $this->info->course, $this->info->moodleoverflow);
@@ -218,7 +219,7 @@ private function build_prepost_create($moodleoverflowid) {
}
}
// Notify the user, that he can not post a new discussion.
- throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
+ throw new \moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
}
// Where is the user coming from?
@@ -266,11 +267,11 @@ private function build_prepost_reply($replypostid) {
get_string('youneedtoenrol'));
}
// Print the error message.
- throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
+ throw new \moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
}
// Make sure the user can post here.
if (!$this->info->cm->visible && !has_capability('moodle/course:viewhiddenactivities', $this->info->modulecontext)) {
- throw new moodle_exception('activityiscurrentlyhidden');
+ throw new \moodle_exception('activityiscurrentlyhidden');
}
// Prepare a post.
@@ -312,7 +313,7 @@ private function build_prepost_edit($editpostid) {
if (($beyondtime || $alreadyreviewed) && !has_capability('mod/moodleoverflow:editanypost',
$this->info->modulecontext)) {
- throw new moodle_exception('maxtimehaspassed', 'moodleoverflow', '',
+ throw new \moodle_exception('maxtimehaspassed', 'moodleoverflow', '',
format_time(get_config('moodleoverflow', 'maxeditingtime')));
}
@@ -323,7 +324,7 @@ private function build_prepost_edit($editpostid) {
if (!has_capability('mod/moodleoverflow:editanypost', $this->info->modulecontext)) {
// Display the error. Capabilities are missing.
- throw new moodle_exception('cannoteditposts', 'moodleoverflow');
+ throw new \moodle_exception('cannoteditposts', 'moodleoverflow');
}
}
@@ -354,7 +355,7 @@ private function build_prepost_delete($deletepostid) {
if (!(($this->info->relatedpost->get_userid() == $USER->id && $this->info->deleteownpost)
|| $this->info->deleteanypost)) {
- throw new moodle_exception('cannotdeletepost', 'moodleoverflow');
+ throw new \moodle_exception('cannotdeletepost', 'moodleoverflow');
}
// Count all replies of this post.
@@ -384,7 +385,7 @@ private function execute_create($form, $errordestination) {
$this->prepost->subject, null, $this->prepost->userid,
$this->prepost->timenow, $this->prepost->timenow, $this->prepost->userid);
if (!$discussion->moodleoverflow_add_discussion($this->prepost)) {
- throw new moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
+ throw new \moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
}
// The creation was successful.
@@ -418,7 +419,7 @@ private function execute_reply($form, $errordestination) {
// Create the new post.
if (!$newpostid = $this->info->discussion->moodleoverflow_add_post_to_discussion($this->prepost)) {
- throw new moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
+ throw new \moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
}
// The creation was successful.
@@ -452,7 +453,7 @@ private function execute_edit($form, $errordestination) {
// Update the post.
if (!$this->info->discussion->moodleoverflow_edit_post_from_discussion($this->prepost)) {
- throw new moodle_exception('couldnotupdate', 'moodleoverflow', $errordestination);
+ throw new \moodle_exception('couldnotupdate', 'moodleoverflow', $errordestination);
}
// The edit was successful.
@@ -491,12 +492,12 @@ public function execute_delete() {
$timepassed = time() - $this->info->relatedpost->created;
$url = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->info->discussion->get_id()));
if (($timepassed > get_config('moodleoverflow', 'maxeditingtime')) && !$this->info->deleteanypost) {
- throw new moodle_exception('cannotdeletepost', 'moodleoverflow', moodleoverflow_go_back_to($url));
+ throw new \moodle_exception('cannotdeletepost', 'moodleoverflow', moodleoverflow_go_back_to($url));
}
// A normal user cannot delete his post if there are direct replies.
if ($this->infro->replycount && !$this->info->deleteanypost) {
- throw new moodle_exception('cannotdeletereplies', 'moodleoverflow', moodleoverflow_go_back_to($url));
+ throw new \moodle_exception('cannotdeletereplies', 'moodleoverflow', moodleoverflow_go_back_to($url));
}
// Check if the post is a parent post or not.
@@ -631,10 +632,6 @@ public function get_prepost() {
* @return bool, if object could be build or not.
*/
private function collect_information($postid = false, $moodleoverflowid = false) {
- if (!($postid xor $moodleoverflowid)) {
- throw new moodle_exception('inaccurateparameter', 'moodleoverflow');
- return false;
- }
if ($postid) {
// The related post is the post that is being answered, edited, or deleted.
$this->info->relatedpost = $this->check_post_exists($postid);
@@ -643,6 +640,11 @@ private function collect_information($postid = false, $moodleoverflowid = false)
} else {
$localmoodleoverflowid = $moodleoverflowid;
}
+ var_dump($moodleoverflowid);
+ var_dump($postid);
+ var_dump($this->info->relatedpost);
+ var_dump($this->info->discussion);
+ var_dump($localmoodleoverflowid);
$this->info->moodleoverflow = $this->check_moodleoverflow_exists($localmoodleoverflowid);
$this->info->course = $this->check_course_exists($this->info->moodleoverflow->course);
$this->info->cm = $this->check_coursemodule_exists($this->info->moodleoverflow->id, $this->info->course->id);
@@ -684,7 +686,7 @@ private function assemble_prepost() {
*/
private function check_interaction($interaction) {
if ($this->interaction != $interaction) {
- throw new moodle_exception('wronginteraction' , 'moodleoverflow');
+ throw new \moodle_exception('wronginteraction' , 'moodleoverflow');
}
return true;
}
@@ -699,7 +701,7 @@ private function check_interaction($interaction) {
private function check_course_exists($courseid) {
global $DB;
if (!$course = $DB->get_record('course', array('id' => $courseid))) {
- throw new moodle_exception('invalidcourseid');
+ throw new \moodle_exception('invalidcourseid');
}
return $course;
}
@@ -713,7 +715,7 @@ private function check_course_exists($courseid) {
private function check_coursemodule_exists($moodleoverflowid, $courseid) {
if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflowid,
$courseid)) {
- throw new moodle_exception('invalidcoursemodule');
+ throw new \moodle_exception('invalidcoursemodule');
}
return $cm;
}
@@ -727,7 +729,7 @@ private function check_moodleoverflow_exists($moodleoverflowid) {
// Get the related moodleoverflow instance.
global $DB;
if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflowid))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
+ throw new \moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
}
return $moodleoverflow;
}
@@ -740,7 +742,7 @@ private function check_moodleoverflow_exists($moodleoverflowid) {
private function check_discussion_exists($discussionid) {
global $DB;
if (!$discussionrecord = $DB->get_record('moodleoverflow_discussions', array('id' => $discussionid))) {
- throw new moodle_exception('invaliddiscussionid', 'moodleoverflow');
+ throw new \moodle_exception('invaliddiscussionid', 'moodleoverflow');
}
$discussion = discussion::from_record($discussionrecord);
return $discussion;
@@ -754,13 +756,12 @@ private function check_discussion_exists($discussionid) {
private function check_post_exists($postid) {
global $DB;
if (!$postrecord = $DB->get_record('moodleoverflow_posts', array('id' => $postid))) {
- throw new moodle_exception('invalidpostid', 'moodleoverflow');
+ throw new \moodle_exception('invalidpostid', 'moodleoverflow');
}
$post = post::from_record($postrecord);
return $post;
}
-
// Capability checks.
/**
@@ -770,7 +771,7 @@ private function check_post_exists($postid) {
*/
private function check_user_can_create_discussion() {
if (!has_capability('mod/moodleoverflow:startdiscussion', $this->info->modulecontext)) {
- throw new moodle_exception('cannotcreatediscussion', 'moodleoverflow');
+ throw new \moodle_exception('cannotcreatediscussion', 'moodleoverflow');
}
return true;
}
@@ -782,7 +783,7 @@ private function check_user_can_create_discussion() {
*/
private function check_user_can_create_reply() {
if (!has_capability('mod/moodleoverflow:replypost', $this->info->modulecontext, $this->prepost->userid)) {
- throw new moodle_exception('cannotreply', 'moodleoverflow');
+ throw new \moodle_exception('cannotreply', 'moodleoverflow');
}
return true;
}
@@ -801,7 +802,7 @@ private function check_user_can_edit_post() {
$startdiscussion = has_capability('mod/moodleoverflow:startdiscussion', $this->info->modulecontext);
$ownpost = ($this->prepost->userid == $USER->id);
if (!(($ownpost && ($replypost || $startdiscussion)) || $editanypost)) {
- throw new moodle_exception('cannotupdatepost', 'moodleoverflow');
+ throw new \moodle_exception('cannotupdatepost', 'moodleoverflow');
}
return true;
}
diff --git a/lang/en/moodleoverflow.php b/lang/en/moodleoverflow.php
index 5ee1d3c3b2..cad4ecab22 100644
--- a/lang/en/moodleoverflow.php
+++ b/lang/en/moodleoverflow.php
@@ -155,7 +155,6 @@
$string['unexpectedinteractionerror'] = 'An unexpected error occured, please try again';
// String for the classes/post/post_control.php.
-$string['inaccurateparameter'] = 'Please check your parameter and give exactly 1 parameter to the function';
$string['wronginteraction'] = 'Wrong interaction detected, please choose the right function';
// Strings for the classes/mod_form.php.
diff --git a/post.php b/post.php
index c9d802a02a..d292e520f7 100644
--- a/post.php
+++ b/post.php
@@ -22,13 +22,14 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
+use mod_moodleoverflow\post\post_control;
use mod_moodleoverflow\review;
+
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
require_once(dirname(__FILE__) . '/locallib.php');
-require_once($CFG->libdir . '/completionlib.php');
global $CFG, $USER, $DB, $PAGE, $SESSION, $OUTPUT;
-
+require_once($CFG->libdir . '/completionlib.php');
// Declare optional url parameters.
$moodleoverflow = optional_param('moodleoverflow', 0, PARAM_INT);
$reply = optional_param('reply', 0, PARAM_INT);
@@ -52,8 +53,8 @@
$systemcontext = context_system::instance();
// Create a post_control object to control and lead the process.
-$postcontrol = new \mod_moodleoverflow\post\post_control();
$postcontrol = new post_control();
+//$postcontrol = new post_control();
// Put all interaction parameters in one object for the post_control.
$urlparameter = new \stdClass();
From ebc4be9fc085dde656e0b74dfd2b7f9b1f37b1b9 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 3 Aug 2023 14:29:39 +0200
Subject: [PATCH 21/56] Testing new structure: replies works
---
classes/discussion/discussion.php | 74 +++--
classes/post/post.php | 474 +++---------------------------
classes/post/post_control.php | 107 +++----
classes/readtracking.php | 2 +-
classes/review.php | 2 +-
locallib.php | 24 +-
post.php | 8 +-
7 files changed, 168 insertions(+), 523 deletions(-)
diff --git a/classes/discussion/discussion.php b/classes/discussion/discussion.php
index 2cf6262d41..479c1721f6 100644
--- a/classes/discussion/discussion.php
+++ b/classes/discussion/discussion.php
@@ -60,7 +60,7 @@ class discussion {
/** @var int The moodleoverflow ID where the discussion is located*/
private $moodleoverflow;
- /** @var char The title of the discussion, the titel of the parent post*/
+ /** @var string The title of the discussion, the titel of the parent post*/
public $name;
/** @var int The id of the parent/first post*/
@@ -129,47 +129,47 @@ public function __construct($id, $course, $moodleoverflow, $name, $firstpost,
*/
public static function from_record($record) {
$id = null;
- if (object__property_exists($record, 'id') && $record->id) {
+ if (object_property_exists($record, 'id') && $record->id) {
$id = $record->id;
}
$course = null;
- if (object__property_exists($record, 'course') && $record->course) {
+ if (object_property_exists($record, 'course') && $record->course) {
$course = $record->course;
}
$moodleoverflow = null;
- if (object__property_exists($record, 'moodleoverflow') && $record->moodleoverflow) {
+ if (object_property_exists($record, 'moodleoverflow') && $record->moodleoverflow) {
$moodleoverflow = $record->moodleoverflow;
}
$name = null;
- if (object__property_exists($record, 'name') && $record->name) {
+ if (object_property_exists($record, 'name') && $record->name) {
$name = $record->name;
}
$firstpost = null;
- if (object__property_exists($record, 'firstpost') && $record->firstpost) {
+ if (object_property_exists($record, 'firstpost') && $record->firstpost) {
$firstpost = $record->firstpost;
}
$userid = null;
- if (object__property_exists($record, 'userid') && $record->userid) {
+ if (object_property_exists($record, 'userid') && $record->userid) {
$userid = $record->userid;
}
$timemodified = null;
- if (object__property_exists($record, 'timemodified') && $record->timemodified) {
+ if (object_property_exists($record, 'timemodified') && $record->timemodified) {
$timemodified = $record->timemodified;
}
$timestart = null;
- if (object__property_exists($record, 'timestart') && $record->timestart) {
+ if (object_property_exists($record, 'timestart') && $record->timestart) {
$timestart = $record->timestart;
}
$usermodified = null;
- if (object__property_exists($record, 'usermodified') && $record->usermodified) {
+ if (object_property_exists($record, 'usermodified') && $record->usermodified) {
$usermodified = $record->usermodified;
}
@@ -212,7 +212,7 @@ public function moodleoverflow_add_discussion($prepost) {
global $DB;
// Add the discussion to the Database.
- $this->id = $DB->insert_record('moodleoverflow_discussions', $this);
+ $this->id = $DB->insert_record('moodleoverflow_discussions', $this->build_db_object());
// Create the first/parent post for the new discussion and add it do the DB.
$post = post::construct_without_id($this->id, 0, $prepost->userid, $prepost->timenow, $prepost->timenow, $preposts->message,
@@ -301,7 +301,7 @@ public function moodleoverflow_delete_discussion($prepost) {
public function moodleoverflow_add_post_to_discussion($prepost) {
global $DB;
$this->existence_check();
- $this->post_check();
+ $this->posts_check();
// Create the post that will be added to the new discussion.
$post = post::construct_without_id($this->id, $prepost->parentid, $prepost->userid, $prepost->timenow, $prepost->timenow,
@@ -312,9 +312,9 @@ public function moodleoverflow_add_post_to_discussion($prepost) {
// Add the post to the $posts array and update the timemodified in the DB.
$this->posts[$postid] = $post;
- $this->timemodified = $timenow;
+ $this->timemodified = $prepost->timenow;
$this->usermodified = $prepost->userid;
- $DB->update_record('moodleoverflow_discussions', $this);
+ $DB->update_record('moodleoverflow_discussions', $this->build_db_object());
// Return the id of the added post.
return $postid;
@@ -362,16 +362,16 @@ public function moodleoverflow_edit_post_from_discussion($prepost) {
$this->post_exists_check($prepost->postid);
// Access the post.
- $post = $this->post[$prepost->postid];
+ $post = $this->posts[$prepost->postid];
// If the post is the firstpost, then update the name of this discussion and the post. If not, only update the post.
- if ($prepost->id == array_key_first($posts)) {
+ if ($prepost->postid == array_key_first($this->posts)) {
$this->name = $prepost->subject;
$this->usermodified = $prepost->userid;
$this->timemodified = $prepost->timenow;
- $DB->update_record('moodleoverflow_discussions', $this);
+ $DB->update_record('moodleoverflow_discussions', $this->build_db_object());
}
- $post->moodleoverflow_edit_post($timenow, $prepost->message, $prepost->messageformat, $prepost->formattachment);
+ $post->moodleoverflow_edit_post($prepost->timenow, $prepost->message, $prepost->messageformat, $prepost->formattachment);
// The post has been edited successfully.
return true;
@@ -400,7 +400,7 @@ public function moodleoverflow_discussion_adapt_to_last_post() {
if ($lastpost->modified != $this->timemodified || $lastpost->get_userid() != $this->usermodified) {
$this->timemodified = $lastpost->modified;
$this->usermodified = $lastpost->get_userid();
- $DB->update_record('moodleoverflow_discussions', $this);
+ $DB->update_record('moodleoverflow_discussions', $this->build_db_object());
// Return that the discussion needed an update.
return true;
@@ -487,13 +487,13 @@ public function moodleoverflow_get_discussion_posts() {
$otherpostssql = 'SELECT * FROM {moodleoverflow_posts} posts
WHERE posts.discussion = ' . $this->id . ' AND posts.parent != 0;';
$firstpostrecord = $DB->get_record_sql($firstpostsql);
- $otherpostsrecords = $DB->get_records_sql($otherpostssql);
+ $otherpostsrecord = $DB->get_records_sql($otherpostssql);
// Add the first/parent post to the array, then add the other posts.
$firstpost = post::from_record($firstpostrecord);
$this->posts[$firstpost->get_id()] = $firstpost;
- foreach ($otherpostrecords as $postrecord) {
+ foreach ($otherpostsrecord as $postrecord) {
$post = post::from_record($postrecord);
$this->posts[$post->get_id()] = $post;
}
@@ -534,13 +534,37 @@ public function get_coursemodule() {
if (empty($this->cmobject)) {
if (!$this->cmobject = $DB->get_coursemodule_from_instance('moodleoverflow', $this->get_moodleoverflow()->id,
$this->get_moodleoverflow()->course)) {
- throw new moodle_exception('invalidcoursemodule');
+ throw new \moodle_exception('invalidcoursemodule');
}
}
return $this->cmobject;
}
+ // Helper functions.
+
+ /**
+ * Builds an object from this instance that has only DB-relevant attributes.
+ * @return object $dbobject
+ */
+ private function build_db_object() {
+ $this->existence_check();
+ $this->posts_check();
+
+ $dbobject = new \stdClass();
+ $dbobject->id = $this->id;
+ $dbobject->course = $this->course;
+ $dbobject->moodleoverflow = $this->moodleoverflow;
+ $dbobject->name = $this->name;
+ $dbobject->firstpost = $this->firstpost;
+ $dbobject->userid = $this->userid;
+ $dbobject->timemodified = $this->timemodified;
+ $dbobject->timestart = $this->timestart;
+ $dbobject->usermodified = $this->usermodified;
+
+ return $dbobject;
+ }
+
// Security.
/**
@@ -552,7 +576,7 @@ public function get_coursemodule() {
*/
private function existence_check() {
if (empty($this->id) || $this->id == false || $this->id == null) {
- throw new moodle_exception('noexistingdiscussion', 'moodleoverflow');
+ throw new \moodle_exception('noexistingdiscussion', 'moodleoverflow');
}
return true;
}
@@ -565,7 +589,7 @@ private function existence_check() {
*/
private function posts_check() {
if (!$this->postsbuild) {
- throw new moodle_exception('notallpostsavailable', 'moodleoverflow');
+ throw new \moodle_exception('notallpostsavailable', 'moodleoverflow');
}
return true;
}
@@ -579,7 +603,7 @@ private function posts_check() {
*/
private function post_exists_check($postid) {
if (!$this->posts[$postid]) {
- throw new moodle_exception('postnotpartofdiscussion', 'moodleoverflow');
+ throw new \moodle_exception('postnotpartofdiscussion', 'moodleoverflow');
}
return true;
diff --git a/classes/post/post.php b/classes/post/post.php
index ca80a6002c..0e1d29d864 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -30,10 +30,11 @@
use mod_moodleoverflow\capabilities;
use mod_moodleoverflow\review;
use mod_moodleoverflow\readtracking;
-use mod_moodleoverflow\discussion;
+use mod_moodleoverflow\discussion\discussion;
defined('MOODLE_INTERNAL') || die();
+global $CFG;
require_once($CFG->dirroot . '/mod/moodleoverflow/locallib.php');
/**
@@ -81,7 +82,7 @@ class post {
/** @var int The message format*/
public $messageformat;
- /** @var char Attachment of the post */
+ /** @var string Attachment of the post */
public $attachment;
/** @var int Mailed status*/
@@ -259,7 +260,7 @@ public function moodleoverflow_add_new_post() {
global $USER, $DB;
// Add post to the database.
- $this->id = $DB->insert_record('moodleoverflow_posts', $this);
+ $this->id = $DB->insert_record('moodleoverflow_posts', $this->build_db_object());
$this->moodleoverflow_add_attachment($this, $this->get_moodleoverflow(), $this->get_coursemodule());
if ($this->reviewed) {
@@ -314,7 +315,7 @@ public function moodleoverflow_delete_post($deletechildren) {
// Delete the attachments.
$fs = get_file_storage();
- $context = context_module::instance($this->get_coursemodule()->id);
+ $context = \context_module::instance($this->get_coursemodule()->id);
$attachments = $fs->get_area_files($context->id, 'mod_moodleoverflow', 'attachment',
$this->id, "filename", true);
foreach ($attachments as $attachment) {
@@ -328,7 +329,7 @@ public function moodleoverflow_delete_post($deletechildren) {
}
// Get the context module.
- $modulecontext = context_module::instance($this->get_coursemodule()->id);
+ $modulecontext = \context_module::instance($this->get_coursemodule()->id);
// Trigger the post deletion event.
$params = array(
@@ -380,7 +381,7 @@ public function moodleoverflow_edit_post($time, $postmessage, $messageformat, $f
$this->formattachment = $formattachment; // PLEASE CHECK LATER IF THIS IS NEEDED AFTER WORKING WITH THE POST_FORM CLASS.
// Update the record in the database.
- $DB->update_record('moodleoverflow_posts', $this);
+ $DB->update_record('moodleoverflow_posts', $this->build_db_object());
// Update the attachments. This happens after the DB update call, as this function changes the DB record as well.
$this->moodleoverflow_add_attachment();
@@ -431,19 +432,19 @@ public function moodleoverflow_add_attachment() {
$this->existence_check();
if (!$this->formattachments) {
- throw new moodle_exception('missingformattachments', 'moodleoverflow');
+ throw new \moodle_exception('missingformattachments', 'moodleoverflow');
}
if (empty($this->formattachments)) {
return true; // Nothing to do.
}
- $context = context_module::instance($this->get_coursemodule()->id);
+ $context = \context_module::instance($this->get_coursemodule()->id);
$info = file_get_draft_area_info($this->formattachments);
$present = ($info['filecount'] > 0) ? '1' : '';
- file_save_draft_area_file($this->formattachments, $context->id, 'mod_moodleoverflow', 'attachment', $this->id,
- mod_moodleoverflow_post_form::attachment_options($this->get_moodleoverflow()));
- $DB->set_field('moodleoverflow_post', 'attachment', $present, array('id' => $this->id));
+ file_save_draft_area_files($this->formattachments, $context->id, 'mod_moodleoverflow', 'attachment', $this->id,
+ \mod_moodleoverflow_post_form::attachment_options($this->get_moodleoverflow()));
+ $DB->set_field('moodleoverflow_posts', 'attachment', $present, array('id' => $this->id));
}
/**
@@ -456,7 +457,7 @@ public function moodleoverflow_get_attachments() {
global $CFG, $OUTPUT;
$this->existence_check();
- if (empty($this->attachment) || (!$context = context_module::instance($this->get_coursemodule()->id))) {
+ if (empty($this->attachment) || (!$context = \context_module::instance($this->get_coursemodule()->id))) {
return array();
}
@@ -465,7 +466,7 @@ public function moodleoverflow_get_attachments() {
// We retrieve all files according to the time that they were created. In the case that several files were uploaded
// at the sametime (e.g. in the case of drag/drop upload) we revert to using the filename.
- $file = $fs->get_area_files($context->id, 'mod_moodleoverflow', 'attachment', $this->id, "filename", false);
+ $files = $fs->get_area_files($context->id, 'mod_moodleoverflow', 'attachment', $this->id, "filename", false);
if ($files) {
$i = 0;
foreach ($files as $file) {
@@ -571,7 +572,7 @@ public function get_coursemodule() {
$this->existence_check();
if (empty($this->cmobject)) {
- $this->cmobject = $DB->get_coursemodule_from_instance('moodleoverflow', $this->get_moodleoverflow()->id);
+ $this->cmobject = \get_coursemodule_from_instance('moodleoverflow', $this->get_moodleoverflow()->id);
}
return $this->cmobject;
@@ -650,6 +651,28 @@ public function mark_post_read() {
}
}
+ /**
+ * Builds an object from this instance that has only DB-relevant attributes.
+ * @return object $dbobject
+ */
+ private function build_db_object() {
+ $dbobject = new \stdClass();
+ $dbobject->id = $this->id;
+ $dbobject->discussion = $this->discussion;
+ $dbobject->parent = $this->parent;
+ $dbobject->userid = $this->userid;
+ $dbobject->created = $this->created;
+ $dbobject->modified = $this->modified;
+ $dbobject->message = $this->message;
+ $dbobject->messageformat = $this->messageformat;
+ $dbobject->attachment = $this->attachment;
+ $dbobject->mailed = $this->mailed;
+ $dbobject->reviewed = $this->reviewed;
+ $dbobject->timereviewed = $this->timereviewed;
+
+ return $dbobject;
+ }
+
// Security.
/**
@@ -661,429 +684,8 @@ public function mark_post_read() {
*/
private function existence_check() {
if (empty($this->id) || $this->id == false || $this->id == null) {
- throw new moodle_exception('noexistingpost', 'moodleoverflow');
+ throw new \moodle_exception('noexistingpost', 'moodleoverflow');
}
return true;
}
-
- // Big Functions.
-
- // Print Functions.
-
- /**
- * Prints all posts of the discussion in a nested form.
- *
- * @param object $course The course object
- * @param object $cm
- * @param object $moodleoverflow The moodleoverflow object
- * @param object $discussion The discussion object
- * @param object $parent The object of the parent post
- * @param bool $istracked Whether the user tracks the discussion
- * @param array $posts Array of posts within the discussion
- * @param bool $iscomment Whether the current post is a comment
- * @param array $usermapping
- * @param bool $multiplemarks
- * @return string
- * @throws coding_exception
- * @throws dml_exception
- * @throws moodle_exception
- */
- public function moodleoverflow_print_posts_nested($course, &$cm, $moodleoverflow, $discussion, $parent, $istracked,
- $posts, $iscomment = null, $usermapping = [], $multiplemarks = false) {
-
- }
-
- /**
- * Prints a moodleoverflow post.
- * @param object $ownpost
- * @param bool $link
- * @param string $footer
- * @param string $highlight
- * @param bool $postisread
- * @param bool $dummyifcantsee
- * @param bool $istracked
- * @param bool $iscomment
- * @param array $usermapping
- * @param int $level
- * @param bool $multiplemarks setting of multiplemarks
- * @return void|null
- * @throws coding_exception
- * @throws dml_exception
- * @throws moodle_exception
- */
- public function moodleoverflow_print_post($ownpost = false, $link = false, $footer = '', $highlight = '', $postisread = null,
- $dummyifcantsee = true, $istracked = false, $iscomment = false, $usermapping = [],
- $level = 0, $multiplemarks = false) {
- global $USER, $CFG, $OUTPUT, $PAGE;
- $this->existence_check();
- // Get important variables.
- $post = $this->moodleoverflow_get_complete_post();
- $discussion = $this->get_discussion();
- $moodleoverflow = $this->get_moodleoverflow();
- $cm = $DB->get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id);
- $course = $DB->get_record('course', array('id' => $moodleoverflow->course));
-
- // Add ratings to the post.
- $postratings = $this->moodleoverflow_get_post_ratings();
- $post->upvotes = $postratings->upvotes;
- $post->downvotes = $postratings->downvotes;
- $post->votesdifference = $postratings->votesdifference;
- $post->markedhelpful = $postratings->markedhelpful;
- $post->markedsolution = $postratings->markedsolution;
-
- // Add other important stuff.
- $post->subject = $this->subject;
-
- // Requiere the filelib.
- require_once($CFG->libdir . '/filelib.php');
-
- // String cahe.
- static $str;
-
- // Print the 'unread' only on time.
- static $firstunreadanchorprinted = false;
-
- // Declare the modulecontext.
- $modulecontext = context_module::instance($cm->id);
-
- // Add some information to the post.
- $post->courseid = $course->id;
- $post->moodleoverflowid = $moodleoverflow->id;
- $mcid = $modulecontext->id;
- $post->message = file_rewrite_pluginfile_urls($post->message, 'pluginfile.php', $mcid,
- 'mod_moodleoverflow', 'post', $post->id);
-
- // Check if the user has the capability to see posts.
- if (!moodleoverflow_user_can_see_post($moodleoverflow, $discussion, $post, $cm)) {
- // No dummy message is requested.
- if (!$dummyifcantsee) {
- echo '';
- return;
- }
-
- // Include the renderer to display the dummy content.
- $renderer = $PAGE->get_renderer('mod_moodleoverflow');
-
- // Collect the needed data being submitted to the template.
- $mustachedata = new stdClass();
-
- // Print the template.
- return $renderer->render_post_dummy_cantsee($mustachedata);
- }
-
- // Check if the strings have been cached.
- if (empty($str)) {
- $str = new stdClass();
- $str->edit = get_string('edit', 'moodleoverflow');
- $str->delete = get_string('delete', 'moodleoverflow');
- $str->reply = get_string('reply', 'moodleoverflow');
- $str->replyfirst = get_string('replyfirst', 'moodleoverflow');
- $str->parent = get_string('parent', 'moodleoverflow');
- $str->markread = get_string('markread', 'moodleoverflow');
- $str->markunread = get_string('markunread', 'moodleoverflow');
- $str->marksolved = get_string('marksolved', 'moodleoverflow');
- $str->alsomarksolved = get_string('alsomarksolved', 'moodleoverflow');
- $str->marknotsolved = get_string('marknotsolved', 'moodleoverflow');
- $str->markhelpful = get_string('markhelpful', 'moodleoverflow');
- $str->alsomarkhelpful = get_string('alsomarkhelpful', 'moodleoverflow');
- $str->marknothelpful = get_string('marknothelpful', 'moodleoverflow');
- }
-
- // Get the current link without unnecessary parameters.
- $discussionlink = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $post->discussion));
-
- // Build the object that represents the posting user.
- $postinguser = new stdClass();
- if ($CFG->branch >= 311) {
- $postinguserfields = \core_user\fields::get_picture_fields();
- } else {
- $postinguserfields = explode(',', user_picture::fields());
- }
- $postinguser = username_load_fields_from_object($postinguser, $post, null, $postinguserfields);
-
- // Post was anonymized.
- if (anonymous::is_post_anonymous($discussion, $moodleoverflow, $post->userid)) {
- $postinguser->id = null;
- if ($post->userid == $USER->id) {
- $postinguser->fullname = get_string('anonym_you', 'mod_moodleoverflow');
- $postinguser->profilelink = new moodle_url('/user/view.php', array('id' => $post->userid, 'course' => $course->id));
- } else {
- $postinguser->fullname = $usermapping[(int) $post->userid];
- $postinguser->profilelink = null;
- }
- } else {
- $postinguser->fullname = fullname($postinguser, capabilities::has('moodle/site:viewfullnames', $modulecontext));
- $postinguser->profilelink = new moodle_url('/user/view.php', array('id' => $post->userid, 'course' => $course->id));
- $postinguser->id = $post->userid;
- }
-
- // Prepare an array of commands.
- $commands = array();
-
- // Create a permalink.
- $permalink = new moodle_url($discussionlink);
- $permalink->set_anchor('p' . $post->id);
-
- // Check if multiplemarks are allowed. If so, check if there are already marked posts.
- $helpfulposts = false;
- $solvedposts = false;
- if ($multiplemarks) {
- $helpfulposts = \mod_moodleoverflow\ratings::moodleoverflow_discussion_is_solved($discussion->id, false);
- $solvedposts = \mod_moodleoverflow\ratings::moodleoverflow_discussion_is_solved($discussion->id, true);
- }
-
- // If the user has started the discussion, he can mark the answer as helpful.
- $canmarkhelpful = (($USER->id == $discussion->userid) && ($USER->id != $post->userid) &&
- ($iscomment != $post->parent) && !empty($post->parent));
- if ($canmarkhelpful) {
- // When the post is already marked, remove the mark instead.
- $link = '/mod/moodleoverflow/discussion.php';
- if ($post->markedhelpful) {
- $commands[] = html_writer::tag('a', $str->marknothelpful, array('class' => 'markhelpful onlyifreviewed',
- 'role' => 'button',
- 'data-moodleoverflow-action' => 'helpful'));
- } else {
- // If there are already marked posts, change the string of the button.
- if ($helpfulposts) {
- $commands[] = html_writer::tag('a', $str->alsomarkhelpful, array('class' => 'markhelpful onlyifreviewed',
- 'role' => 'button',
- 'data-moodleoverflow-action' => 'helpful'));
- } else {
- $commands[] = html_writer::tag('a', $str->markhelpful, array('class' => 'markhelpful onlyifreviewed',
- 'role' => 'button',
- 'data-moodleoverflow-action' => 'helpful'));
- }
- }
- }
-
- // A teacher can mark an answer as solved.
- $canmarksolved = (($iscomment != $post->parent) && !empty($post->parent) &&
- capabilities::has(capabilities::MARK_SOLVED, $modulecontext));
- if ($canmarksolved) {
- // When the post is already marked, remove the mark instead.
- $link = '/mod/moodleoverflow/discussion.php';
- if ($post->markedsolution) {
- $commands[] = html_writer::tag('a', $str->marknotsolved, array('class' => 'marksolved onlyifreviewed',
- 'role' => 'button',
- 'data-moodleoverflow-action' => 'solved'));
- } else {
- // If there are already marked posts, change the string of the button.
- if ($solvedposts) {
- $commands[] = html_writer::tag('a', $str->alsomarksolved, array('class' => 'marksolved onlyifreviewed',
- 'role' => 'button',
- 'data-moodleoverflow-action' => 'solved'));
- } else {
- $commands[] = html_writer::tag('a', $str->marksolved, array('class' => 'marksolved onlyifreviewed',
- 'role' => 'button',
- 'data-moodleoverflow-action' => 'solved'));
- }
- }
- }
-
- // Calculate the age of the post.
- $age = time() - $post->created;
-
- // Make a link to edit your own post within the given time and not already reviewed.
- if (($ownpost && ($age < get_config('moodleoverflow', 'maxeditingtime'))
- && (!review::should_post_be_reviewed($post, $moodleoverflow) || !$post->reviewed))
- || capabilities::has(capabilities::EDIT_ANY_POST, $modulecontext)) {
-
- $editurl = new moodle_url('/mod/moodleoverflow/post.php', array('edit' => $post->id));
- $commands[] = array('url' => $editurl, 'text' => $str->edit);
- }
-
- // Give the option to delete a post.
- $notold = ($age < get_config('moodleoverflow', 'maxeditingtime'));
- if (($ownpost && $notold && capabilities::has(capabilities::DELETE_OWN_POST, $modulecontext)) ||
- capabilities::has(capabilities::DELETE_ANY_POST, $modulecontext)) {
-
- $link = '/mod/moodleoverflow/post.php';
- $commands[] = array('url' => new moodle_url($link, array('delete' => $post->id)), 'text' => $str->delete);
- }
-
- // Give the option to reply to a post.
- if (moodleoverflow_user_can_post($modulecontext, $post, false)) {
-
- $attributes = [
- 'class' => 'onlyifreviewed'
- ];
-
- // Answer to the parent post.
- if (empty($post->parent)) {
- $replyurl = new moodle_url('/mod/moodleoverflow/post.php#mformmoodleoverflow', array('reply' => $post->id));
- $commands[] = array('url' => $replyurl, 'text' => $str->replyfirst, 'attributes' => $attributes);
-
- // If the post is a comment, answer to the parent post.
- } else if (!$iscomment) {
- $replyurl = new moodle_url('/mod/moodleoverflow/post.php#mformmoodleoverflow', array('reply' => $post->id));
- $commands[] = array('url' => $replyurl, 'text' => $str->reply, 'attributes' => $attributes);
-
- // Else simple respond to the answer.
- } else {
- $replyurl = new moodle_url('/mod/moodleoverflow/post.php#mformmoodleoverflow', array('reply' => $iscomment));
- $commands[] = array('url' => $replyurl, 'text' => $str->reply, 'attributes' => $attributes);
- }
- }
-
- // Begin of mustache data collecting.
-
- // Initiate the output variables.
- $mustachedata = new stdClass();
- $mustachedata->istracked = $istracked;
- $mustachedata->isread = false;
- $mustachedata->isfirstunread = false;
- $mustachedata->isfirstpost = false;
- $mustachedata->iscomment = (!empty($post->parent) && ($iscomment == $post->parent));
- $mustachedata->permalink = $permalink;
-
- // Get the ratings.
- $mustachedata->votes = $post->upvotes - $post->downvotes;
-
- // Check if the post is marked.
- $mustachedata->markedhelpful = $post->markedhelpful;
- $mustachedata->markedsolution = $post->markedsolution;
-
- // Did the user rated this post?
- $rating = \mod_moodleoverflow\ratings::moodleoverflow_user_rated($post->id);
-
- // Initiate the variables.
- $mustachedata->userupvoted = false;
- $mustachedata->userdownvoted = false;
- $mustachedata->canchange = $USER->id != $post->userid;
-
- // Check the actual rating.
- if ($rating) {
-
- // Convert the object.
- $rating = $rating->rating;
-
- // Did the user upvoted or downvoted this post?
- // The user upvoted the post.
- if ($rating == 1) {
- $mustachedata->userdownvoted = true;
- } else if ($rating == 2) {
- $mustachedata->userupvoted = true;
- }
- }
-
- // Check the reading status of the post.
- $postclass = '';
- if ($istracked) {
- if ($postisread) {
- $postclass .= ' read';
- $mustachedata->isread = true;
- } else {
- $postclass .= ' unread';
-
- // Anchor the first unread post of a discussion.
- if (!$firstunreadanchorprinted) {
- $mustachedata->isfirstunread = true;
- $firstunreadanchorprinted = true;
- }
- }
- }
- if ($post->markedhelpful) {
- $postclass .= ' markedhelpful';
- }
- if ($post->markedsolution) {
- $postclass .= ' markedsolution';
- }
- $mustachedata->postclass = $postclass;
-
- // Is this the firstpost?
- if (empty($post->parent)) {
- $mustachedata->isfirstpost = true;
- }
-
- // Create an element for the user which posted the post.
- $postbyuser = new stdClass();
- $postbyuser->post = $post->subject;
-
- // Anonymization already handled in $postinguser->fullname.
- $postbyuser->user = $postinguser->fullname;
-
- $mustachedata->discussionby = get_string('postbyuser', 'moodleoverflow', $postbyuser);
-
- // Set basic variables of the post.
- $mustachedata->postid = $post->id;
- $mustachedata->subject = format_string($post->subject);
-
- // Post was anonymized.
- if (!anonymous::is_post_anonymous($discussion, $moodleoverflow, $post->userid)) {
- // User picture.
- $mustachedata->picture = $OUTPUT->user_picture($postinguser, ['courseid' => $course->id]);
- }
-
- // The rating of the user.
- if (anonymous::is_post_anonymous($discussion, $moodleoverflow, $post->userid)) {
- $postuserrating = null;
- } else {
- $postuserrating = \mod_moodleoverflow\ratings::moodleoverflow_get_reputation($moodleoverflow->id, $postinguser->id);
- }
-
- // The name of the user and the date modified.
- $mustachedata->bydate = userdate($post->modified);
- $mustachedata->byshortdate = userdate($post->modified, get_string('strftimedatetimeshort', 'core_langconfig'));
- $mustachedata->byname = $postinguser->profilelink ?
- html_writer::link($postinguser->profilelink, $postinguser->fullname)
- : $postinguser->fullname;
- $mustachedata->byrating = $postuserrating;
- $mustachedata->byuserid = $postinguser->id;
- $mustachedata->showrating = $postuserrating !== null;
- if (get_config('moodleoverflow', 'allowdisablerating') == 1) {
- $mustachedata->showvotes = $moodleoverflow->allowrating;
- $mustachedata->showreputation = $moodleoverflow->allowreputation;
- } else {
- $mustachedata->showvotes = MOODLEOVERFLOW_RATING_ALLOW;
- $mustachedata->showreputation = MOODLEOVERFLOW_REPUTATION_ALLOW;
- }
- $mustachedata->questioner = $post->userid == $discussion->userid ? 'questioner' : '';
-
- // Set options for the post.
- $options = new stdClass();
- $options->para = false;
- $options->trusted = false;
- $options->context = $modulecontext;
-
- $reviewdelay = get_config('moodleoverflow', 'reviewpossibleaftertime');
- $mustachedata->reviewdelay = format_time($reviewdelay);
- $mustachedata->needsreview = !$post->reviewed;
- $reviewable = time() - $post->created > $reviewdelay;
- $mustachedata->canreview = capabilities::has(capabilities::REVIEW_POST, $modulecontext);
- $mustachedata->withinreviewperiod = $reviewable;
-
- // Prepare the post.
- $mustachedata->postcontent = format_text($post->message, $post->messageformat, $options, $course->id);
-
- // Load the attachments.
- $mustachedata->attachments = get_attachments($post, $cm);
-
- // Output the commands.
- $commandhtml = array();
- foreach ($commands as $command) {
- if (is_array($command)) {
- $commandhtml[] = html_writer::link($command['url'], $command['text'], $command['attributes'] ?? null);
- } else {
- $commandhtml[] = $command;
- }
- }
- $mustachedata->commands = implode('', $commandhtml);
-
- // Print a footer if requested.
- $mustachedata->footer = $footer;
-
- // Mark the forum post as read.
- if ($istracked && !$postisread) {
- readtracking::moodleoverflow_mark_post_read($USER->id, $post);
- }
-
- $mustachedata->iscomment = $level == 2;
-
- // Include the renderer to display the dummy content.
- $renderer = $PAGE->get_renderer('mod_moodleoverflow');
-
- // Render the different elements.
- return $renderer->render_post($mustachedata);
- }
-
}
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index ecd4a1eed9..e330f7f80b 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -26,19 +26,18 @@
namespace mod_moodleoverflow\post;
// Import namespace from the locallib, needs a check later which namespaces are really needed.
-use mod_moodleoverflow\anonymous;
use mod_moodleoverflow\capabilities;
use mod_moodleoverflow\review;
-use mod_moodleoverflow\post;
-use mod_moodleoverflow\discussion;
+use mod_moodleoverflow\post\post;
+use mod_moodleoverflow\discussion\discussion;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/mod/moodleoverflow/locallib.php');
require_once($CFG->libdir . '/completionlib.php');
-
+//require once($CFG->dirroot . 'mod/moodleoverflow/classes/post/post.php');
/**
* This Class controls the manipulation of posts and acts as controller of interactions with the post.php
*
@@ -64,7 +63,7 @@ class post_control {
/** @var string the Interaction type, the interactions are:
* - create (creates a new discussion with a first post)
* - reply (replies to a existing post, can be an answer or a comment)
- * - edit (change the contennt of an existing post)
+ * - edit (change the content of an existing post)
* - delete (delete a post from a discussion)
*/
private $interaction;
@@ -91,7 +90,6 @@ public function __construct() {
* Detects the interaction and builds the prepost.
* @param object $urlparamter parameter from the post.php
* @throws moodle_exception if the interaction is not correct.
- * @throws \moodle_exception
*/
public function detect_interaction($urlparameter) {
$count = 0;
@@ -130,7 +128,6 @@ public function detect_interaction($urlparameter) {
/**
* Controls the execution of an interaction.
* @param object $form The results from the post_form.
- * @return bool if the execution succeeded
*/
public function execute_interaction($form) {
global $CFG;
@@ -149,13 +146,20 @@ public function execute_interaction($form) {
// Get the current time.
$this->prepost->timenow = time();
-
+ /*
+ var_dump($this->interaction);
+ var_dump('
');
+ var_dump($this->prepost);
+ var_dump('');
+ var_dump($form->reply);
+ var_dump($this->prepost->parentid);*/
+ var_dump($form);
// Execute the right function.
- if ($this->interaction == 'create' && $form->moodleoverflow === $this->prepost->moodleoverflowid) {
+ if ($this->interaction == 'create' && $form->moodleoverflow == $this->prepost->moodleoverflowid) {
$this->execute_create($form, $errordestination);
- } else if ($this->interaction == 'reply' && $form->reply === $this->prepost->parentid) {
+ } else if ($this->interaction == 'reply' && $form->reply == $this->prepost->parentid) {
$this->execute_reply($form, $errordestination);
- } else if ($this->interaction == 'edit' && $form->edit === $this->prepost->postid) {
+ } else if ($this->interaction == 'edit' && $form->edit == $this->prepost->postid) {
$this->execute_edit($form, $errordestination);
} else {
throw new \moodle_exception('unexpectedinteractionerror', 'moodleoverflow', $errordestination);
@@ -211,7 +215,7 @@ private function build_prepost_create($moodleoverflowid) {
if (enrol_selfenrol_available($this->info->course->id)) {
$SESSION->wantsurl = qualified_me();
$SESSION->enrolcancel = get_local_referer(false);
- redirect(new moodle_url('/enrol/index.php',
+ redirect(new \moodle_url('/enrol/index.php',
array('id' => $this->info->course->id,
'returnurl' => '/mod/moodleoverflow/view.php?m=' .
$this->info->moodleoverflow->id)),
@@ -253,18 +257,25 @@ private function build_prepost_reply($replypostid) {
// Ensure the coursemodule is set correctly.
$PAGE->set_cm($this->info->cm, $this->info->course, $this->info->moodleoverflow);
+ // Prepare a post.
+ $this->assemble_prepost();
+ $this->prepost->postid = null;
+ $this->prepost->parentid = $this->info->relatedpost->get_id();
+ $this->prepost->userid = $USER->id;
+ $this->prepost->message = '';
+
// Check whether the user is allowed to post.
- if (!moodleoverflow_user_can_post($this->info->modulecontext, $this->info->parent)) {
+ if (!$this->check_user_can_create_reply()) {
// Give the user the chance to enroll himself to the course.
if (!isguestuser() && !is_enrolled($this->info->coursecontext)) {
$SESSION->wantsurl = qualified_me();
$SESSION->enrolcancel = get_local_referer(false);
- redirect(new moodle_url('/enrol/index.php',
- array('id' => $this->info->course->id,
- 'returnurl' => '/mod/moodleoverflow/view.php?m=' .
- $this->info->moodleoverflow->id)),
- get_string('youneedtoenrol'));
+ redirect(new \moodle_url('/enrol/index.php',
+ array('id' => $this->info->course->id,
+ 'returnurl' => '/mod/moodleoverflow/view.php?m=' .
+ $this->info->moodleoverflow->id)),
+ get_string('youneedtoenrol'));
}
// Print the error message.
throw new \moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
@@ -274,16 +285,9 @@ private function build_prepost_reply($replypostid) {
throw new \moodle_exception('activityiscurrentlyhidden');
}
- // Prepare a post.
- $this->assemble_prepost();
- $this->prepost->postid = null;
- $this->prepost->parentid = $this->info->relatedpost->get_id();
- $this->prepost->userid = $USER->id;
- $this->prepost->message = '';
-
// Append 'RE: ' to the discussions subject.
$strre = get_string('re', 'moodleoverflow');
- if (!(substr($this->prepost->subject, 0, strlen($strre)) == $strre)) {
+ if (!(str_starts_with($this->prepost->subject, $strre))) {
$this->prepost->subject = $strre . ' ' . $this->prepost->subject;
}
@@ -329,7 +333,7 @@ private function build_prepost_edit($editpostid) {
}
// Load the $post variable.
- $this->assemble->prepost();
+ $this->assemble_prepost();
// Unset where the user is coming from. This allows to calculate the correct return url later.
unset($SESSION->fromdiscussion);
@@ -362,13 +366,14 @@ private function build_prepost_delete($deletepostid) {
$this->info->replycount = moodleoverflow_count_replies($this->info->relatedpost, false);
// Build the prepost.
- $this->assemble->prepost();
+ $this->assemble_prepost();
$this->prepost->deletechildren = true;
}
// Execute Functions, that execute an interaction.
private function execute_create($form, $errordestination) {
+ global $USER;
// Check if the user is allowed to post.
$this->check_user_can_create_discussion();
@@ -392,7 +397,7 @@ private function execute_create($form, $errordestination) {
$redirectmessage = '' . get_string("postaddedsuccess", "moodleoverflow") . '
';
// Trigger the discussion created event.
- $params = array( 'context' => $modulecontext, 'objectid' => $discussion->id,);
+ $params = array( 'context' => $this->info->modulecontext, 'objectid' => $discussion->id,);
$event = \mod_moodleoverflow\event\discussion_created::create($params);
$event->trigger();
@@ -401,7 +406,7 @@ private function execute_create($form, $errordestination) {
//$discussion, $this->info->modulecontext);
// Define the location to redirect the user after successfully posting.
- $redirectto = new moodle_url('/mod/moodleoverflow/view.php', array('m' => $form->moodleoverflow));
+ $redirectto = new \moodle_url('/mod/moodleoverflow/view.php', array('m' => $form->moodleoverflow));
redirect(moodleoverflow_go_back_to($redirectto->out()), $redirectmessage, null, \core\output\notification::NOTIFY_SUCCESS);
}
@@ -411,7 +416,7 @@ private function execute_reply($form, $errordestination) {
// Set to not reviewed, if posts should be reviewed, and user is not a reviewer themselves.
if (review::get_review_level($this->info->moodleoverflow) == review::EVERYTHING &&
- !has_capability('mod/moodleoverflow:reviewpost', context_module::instance($this->info->cm->id))) {
+ !has_capability('mod/moodleoverflow:reviewpost', \context_module::instance($this->info->cm->id))) {
$this->prepost->reviewed = 0;
} else {
$this->prepost->reviewed = 1;
@@ -428,7 +433,7 @@ private function execute_reply($form, $errordestination) {
format_time(get_config('moodleoverflow', 'maxeditingtime'))) . '
';
// Trigger the post created event.
- $params = array('context' => $this->info->modulecontext, 'objectid' => $form->id,
+ $params = array('context' => $this->info->modulecontext, 'objectid' => $newpostid,
'other' => array('discussionid' => $this->prepost->discussionid,
'moodleoverflowid' => $this->prepost->moodleoverflowid)
);
@@ -440,8 +445,8 @@ private function execute_reply($form, $errordestination) {
//$this->info->discussion, $this->info->modulecontext);
// Define the location to redirect the user after successfully posting.
- $redirectto = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->prepost->discussionid, $newpost->id));
- redirect(oodleoverflow_go_back_to($redirectto->out()), $redirectmessage, null, \core\output\notification::NOTIFY_SUCCESS);
+ $redirectto = new \moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->prepost->discussionid, 'p' => $newpostid));
+ redirect(\moodleoverflow_go_back_to($redirectto->out()), $redirectmessage, null, \core\output\notification::NOTIFY_SUCCESS);
}
@@ -481,7 +486,7 @@ private function execute_edit($form, $errordestination) {
$event->trigger();
// Define the location to redirect the user after successfully editing.
- $redirectto = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->prepost->discussionid, $form->edit));
+ $redirectto = new \moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->prepost->discussionid, 'p' => $form->edit));
redirect(moodleoverflow_go_back_to($redirectto->out()), $redirectmessage, null, \core\output\notification::NOTIFY_SUCCESS);
}
@@ -490,7 +495,7 @@ public function execute_delete() {
// Check if the user has the capability to delete the post.
$timepassed = time() - $this->info->relatedpost->created;
- $url = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->info->discussion->get_id()));
+ $url = new \moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->info->discussion->get_id()));
if (($timepassed > get_config('moodleoverflow', 'maxeditingtime')) && !$this->info->deleteanypost) {
throw new \moodle_exception('cannotdeletepost', 'moodleoverflow', moodleoverflow_go_back_to($url));
}
@@ -508,7 +513,7 @@ public function execute_delete() {
redirect('view.php?m=' . $this->info->discussion->get_moodleoverflowid());
} else {
$this->info->discussion->moodleoverflow_delete_post_from_discussion($this->prepost);
- $discussionurl = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->info->discussion->get_id()));
+ $discussionurl = new \moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->info->discussion->get_id()));
redirect(moodleoverflow_go_back_to($discussionurl));
}
}
@@ -534,6 +539,7 @@ public function confirm_delete() {
* @return object a mod_moodleoverflow_post_form object.
*/
public function build_postform($pageparams) {
+ global $USER, $CFG;
// Require that the user is logged in properly and enrolled to the course.
require_login($this->info->course, false, $this->info->cm);
@@ -541,16 +547,16 @@ public function build_postform($pageparams) {
$draftitemid = file_get_submitted_draft_itemid('attachments');
file_prepare_draft_area($draftitemid, $this->info->modulecontext->id, 'mod_moodleoverflow', 'attachment',
empty($this->prepost->postid) ? null : $this->prepost->postid,
- mod_moodleoverflow_post_form::attachment_options($this->info->moodleoverflow));
+ \mod_moodleoverflow_post_form::attachment_options($this->info->moodleoverflow));
// Prepare the form.
- $edit = $this->interaction == 'edit' ? true : false;
+ $edit = $this->interaction == 'edit';
$formarray = array( 'course' => $this->info->course, 'cm' => $this->info->cm, 'coursecontext' => $this->info->coursecontext,
'modulecontext' => $this->info->modulecontext, 'moodleoverflow' => $this->info->moodleoverflow,
- 'post' => $this->info->post, 'edit' => $edit);
+ 'post' => $this->prepost, 'edit' => $edit);
// Declare the post_form.
- $mformpost = new mod_moodleoverflow_post_form('post.php', $formarray, 'post', '', array('id' => 'mformmoodleoverflow'));
+ $mformpost = new \mod_moodleoverflow_post_form('post.php', $formarray, 'post', '', array('id' => 'mformmoodleoverflow'));
// If the user is not the original author append an extra message to the message. (Happens when interaction = 'edit').
if ($USER->id != $this->prepost->userid) {
@@ -573,7 +579,7 @@ public function build_postform($pageparams) {
// Define the heading for the form.
$formheading = '';
- if ($this->info->relatedpost->moodleoverflow_get_parentpost()) {
+ if ($this->interaction == 'reply') {
$heading = get_string('yourreply', 'moodleoverflow');
$formheading = get_string('reply', 'moodleoverflow');
} else {
@@ -629,7 +635,6 @@ public function get_prepost() {
* The variables are optional, but one is necessary to build the information object.
* @param int $postid
* @param int $moodleoverflowid
- * @return bool, if object could be build or not.
*/
private function collect_information($postid = false, $moodleoverflowid = false) {
if ($postid) {
@@ -640,17 +645,18 @@ private function collect_information($postid = false, $moodleoverflowid = false)
} else {
$localmoodleoverflowid = $moodleoverflowid;
}
+ /*
var_dump($moodleoverflowid);
var_dump($postid);
var_dump($this->info->relatedpost);
var_dump($this->info->discussion);
var_dump($localmoodleoverflowid);
+ */
$this->info->moodleoverflow = $this->check_moodleoverflow_exists($localmoodleoverflowid);
$this->info->course = $this->check_course_exists($this->info->moodleoverflow->course);
$this->info->cm = $this->check_coursemodule_exists($this->info->moodleoverflow->id, $this->info->course->id);
- $this->info->modulecontext = context_module::instance($this->info->cm->id);
- $this->info->coursecontext = context_module::instance($this->info->course->id);
- return true;
+ $this->info->modulecontext = \context_module::instance($this->info->cm->id);
+ $this->info->coursecontext = \context_course::instance($this->info->course->id);
}
/**
@@ -671,7 +677,7 @@ private function assemble_prepost() {
$this->prepost->parentid = $this->info->relatedpost->get_parentid();
$this->prepost->postid = $this->info->relatedpost->get_id();
$this->prepost->userid = $this->info->relatedpost->get_userid();
- $this->prepost->message = $this->info->relatedpost->message();
+ $this->prepost->message = $this->info->relatedpost->message;
}
}
}
@@ -744,8 +750,7 @@ private function check_discussion_exists($discussionid) {
if (!$discussionrecord = $DB->get_record('moodleoverflow_discussions', array('id' => $discussionid))) {
throw new \moodle_exception('invaliddiscussionid', 'moodleoverflow');
}
- $discussion = discussion::from_record($discussionrecord);
- return $discussion;
+ return discussion::from_record($discussionrecord);
}
/**
@@ -758,8 +763,7 @@ private function check_post_exists($postid) {
if (!$postrecord = $DB->get_record('moodleoverflow_posts', array('id' => $postid))) {
throw new \moodle_exception('invalidpostid', 'moodleoverflow');
}
- $post = post::from_record($postrecord);
- return $post;
+ return post::from_record($postrecord);
}
// Capability checks.
@@ -797,6 +801,7 @@ private function check_user_can_create_reply() {
* @throws moodle_exception
*/
private function check_user_can_edit_post() {
+ global $USER;
$editanypost = has_capability('mod/moodleoverflow:editanypost', $this->info->modulecontext);
$replypost = has_capability('mod/moodleoverflow:replypost', $this->info->modulecontext);
$startdiscussion = has_capability('mod/moodleoverflow:startdiscussion', $this->info->modulecontext);
diff --git a/classes/readtracking.php b/classes/readtracking.php
index 54a5e57e65..519fcd397f 100644
--- a/classes/readtracking.php
+++ b/classes/readtracking.php
@@ -201,7 +201,7 @@ public static function moodleoverflow_mark_post_read($userid, $post) {
}
// Create a new read record.
- return self::moodleoverflow_add_read_record($userid, $post->id);
+ return self::moodleoverflow_add_read_record($userid, $post->get_id());
}
/**
diff --git a/classes/review.php b/classes/review.php
index 7ee4d82ec1..b975bfbf0b 100644
--- a/classes/review.php
+++ b/classes/review.php
@@ -132,7 +132,7 @@ public static function get_first_review_post($moodleoverflowid, $afterpostid = n
*/
public static function should_post_be_reviewed($post, $moodleoverflow): bool {
$reviewlevel = self::get_review_level($moodleoverflow);
- if ($post->parent != 0 /*$post->get_parentid() != 0*/) {
+ if (/*$post->parent != 0 */$post->get_parentid() != 0) {
return $reviewlevel == self::EVERYTHING;
} else {
return $reviewlevel >= self::QUESTIONS;
diff --git a/locallib.php b/locallib.php
index 73fec551c6..1187827aa2 100644
--- a/locallib.php
+++ b/locallib.php
@@ -926,7 +926,14 @@ function moodleoverflow_user_can_post($modulecontext, $posttoreplyto, $considerr
* @param bool $multiplemarks The setting of multiplemarks (default: multiplemarks are not allowed)
*/
function moodleoverflow_print_discussion($course, $cm, $moodleoverflow, $discussion, $post, $multiplemarks = false) {
- global $USER;
+ global $USER, $DB;
+
+ // TODO: REFACTOR WITH NEW POST AND DISCUSSION STRUCTURE.
+
+ // THE NEXT STEP IS NECESSARY UNTIL THE REFACTORING IS COMPLETE.
+ $discussionrecord = $DB->get_record('moodleoverflow_discussions', array('id' => $discussion->id));
+ $discussionobject = \mod_moodleoverflow\discussion\discussion::from_record($discussionrecord);
+
// Check if the current is the starter of the discussion.
$ownpost = (isloggedin() && ($USER->id == $post->userid));
@@ -937,9 +944,10 @@ function moodleoverflow_print_discussion($course, $cm, $moodleoverflow, $discuss
$istracked = readtracking::moodleoverflow_is_tracked($moodleoverflow);
// Retrieve all posts of the discussion.
- $posts = moodleoverflow_get_all_discussion_posts($discussion->id, $istracked, $modulecontext);
+ $posts = moodleoverflow_get_all_discussion_posts($discussionobject->get_id(), $istracked, $modulecontext);
+ //$posts = $discussionobjects->posts;
- $usermapping = anonymous::get_userid_mapping($moodleoverflow, $discussion->id);
+ $usermapping = anonymous::get_userid_mapping($moodleoverflow, $discussionobject->get_id());
// Start with the parent post.
$post = $posts[$post->id];
@@ -1105,6 +1113,8 @@ function moodleoverflow_get_all_discussion_posts($discussionid, $tracking, $modc
/**
+ *
+ * TODO: REFACTOR THIS FUNCTION FOR THE NEW POST STRUCTURE.
* Prints a moodleoverflow post.
* @param object $post
* @param object $discussion
@@ -1132,7 +1142,7 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co
$footer = '', $highlight = '', $postisread = null,
$dummyifcantsee = true, $istracked = false,
$iscomment = false, $usermapping = [], $level = 0, $multiplemarks = false) {
- global $USER, $CFG, $OUTPUT, $PAGE;
+ global $USER, $CFG, $OUTPUT, $PAGE, $DB;
// Require the filelib.
require_once($CFG->libdir . '/filelib.php');
@@ -1284,9 +1294,13 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co
// Calculate the age of the post.
$age = time() - $post->created;
+ // TODO: REFACTOR FOR NEW POST STRUCTURE: FOR A TIME, THIS IS THE FIX.
+ $postrecord = $DB->get_record('moodleoverflow_posts', array('id' => $post->id));
+ $postobject = \mod_moodleoverflow\post\post::from_record($postrecord);
+
// Make a link to edit your own post within the given time and not already reviewed.
if (($ownpost && ($age < get_config('moodleoverflow', 'maxeditingtime')) &&
- (!review::should_post_be_reviewed($post, $moodleoverflow) || !$post->reviewed))
+ (!review::should_post_be_reviewed($postobject, $moodleoverflow) || !$post->reviewed))
|| capabilities::has(capabilities::EDIT_ANY_POST, $modulecontext)
) {
$editurl = new moodle_url('/mod/moodleoverflow/post.php', array('edit' => $post->id));
diff --git a/post.php b/post.php
index d292e520f7..3a59050729 100644
--- a/post.php
+++ b/post.php
@@ -30,6 +30,7 @@
global $CFG, $USER, $DB, $PAGE, $SESSION, $OUTPUT;
require_once($CFG->libdir . '/completionlib.php');
+
// Declare optional url parameters.
$moodleoverflow = optional_param('moodleoverflow', 0, PARAM_INT);
$reply = optional_param('reply', 0, PARAM_INT);
@@ -88,7 +89,6 @@
// Has the user confirmed the deletion?
if (!empty($confirm) && confirm_sesskey()) {
$postcontrol->execute_delete();
- exit;
} else {
// Deletion needs to be confirmed.
$postcontrol->confirm_delete();
@@ -108,12 +108,12 @@
'#p' . $information->relatedpost->get_id());
}
echo $OUTPUT->footer();
- exit;
}
+ exit;
}
// A post will be created or edited. For that the post_control builds a post_form.
-$mformpost = $postcontrol->build_postform();
+$mformpost = $postcontrol->build_postform($pageparams);
// The User now entered information in the form. The post.php now needs to process the information and call the right function.
@@ -123,7 +123,7 @@
// If the interaction was cancelled, the user needs to be redirected.
if ($mformpost->is_cancelled()) {
- if (!issett($prepost->discussionid)) {
+ if (!isset($prepost->discussionid)) {
redirect(new moodle_url('/mod/moodleoverflow/view.php', array('m' => $prepost->moodleoverflowid)));
} else {
redirect(new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $prepost->discussionid)));
From 8961316c8a086e4fa0c0297e0027263cc0adef60 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Wed, 9 Aug 2023 15:47:57 +0200
Subject: [PATCH 22/56] first testing completed and successful. Test classes
still needed
---
classes/discussion/discussion.php | 51 ++++++++------
classes/post/post.php | 66 +++++++++---------
classes/post/post_control.php | 110 +++++++++++++++++-------------
classes/subscriptions.php | 2 +
locallib.php | 5 +-
post.php | 1 -
6 files changed, 131 insertions(+), 104 deletions(-)
diff --git a/classes/discussion/discussion.php b/classes/discussion/discussion.php
index 479c1721f6..c7957a705d 100644
--- a/classes/discussion/discussion.php
+++ b/classes/discussion/discussion.php
@@ -36,6 +36,7 @@
defined('MOODLE_INTERNAL') || die();
+global $CFG;
require_once($CFG->dirroot . '/mod/moodleoverflow/locallib.php');
/**
@@ -133,42 +134,42 @@ public static function from_record($record) {
$id = $record->id;
}
- $course = null;
+ $course = 0;
if (object_property_exists($record, 'course') && $record->course) {
$course = $record->course;
}
- $moodleoverflow = null;
+ $moodleoverflow = 0;
if (object_property_exists($record, 'moodleoverflow') && $record->moodleoverflow) {
$moodleoverflow = $record->moodleoverflow;
}
- $name = null;
+ $name = '';
if (object_property_exists($record, 'name') && $record->name) {
$name = $record->name;
}
- $firstpost = null;
+ $firstpost = 0;
if (object_property_exists($record, 'firstpost') && $record->firstpost) {
$firstpost = $record->firstpost;
}
- $userid = null;
+ $userid = 0;
if (object_property_exists($record, 'userid') && $record->userid) {
$userid = $record->userid;
}
- $timemodified = null;
+ $timemodified = 0;
if (object_property_exists($record, 'timemodified') && $record->timemodified) {
$timemodified = $record->timemodified;
}
- $timestart = null;
+ $timestart = 0;
if (object_property_exists($record, 'timestart') && $record->timestart) {
$timestart = $record->timestart;
}
- $usermodified = null;
+ $usermodified = 0;
if (object_property_exists($record, 'usermodified') && $record->usermodified) {
$usermodified = $record->usermodified;
}
@@ -215,8 +216,8 @@ public function moodleoverflow_add_discussion($prepost) {
$this->id = $DB->insert_record('moodleoverflow_discussions', $this->build_db_object());
// Create the first/parent post for the new discussion and add it do the DB.
- $post = post::construct_without_id($this->id, 0, $prepost->userid, $prepost->timenow, $prepost->timenow, $preposts->message,
- $prepost->messageformat, "", 0, $prepost->review, null, $prepost->formattachments);
+ $post = post::construct_without_id($this->id, 0, $prepost->userid, $prepost->timenow, $prepost->timenow, $prepost->message,
+ $prepost->messageformat, "", 0, $prepost->reviewed, null, $prepost->formattachments);
// Add it to the DB and save the id of the first/parent post.
$this->firstpost = $post->moodleoverflow_add_new_post();
@@ -230,7 +231,7 @@ public function moodleoverflow_add_discussion($prepost) {
// Trigger event.
$params = array(
'context' => $prepost->modulecontext,
- 'objectid' => $post->discussion,
+ 'objectid' => $this->id,
);
$event = \mod_moodleoverflow\event\discussion_viewed::create($params);
$event->trigger();
@@ -256,7 +257,7 @@ public function moodleoverflow_delete_discussion($prepost) {
$transaction = $DB->start_delegated_transaction();
// Delete every post of this discussion.
- foreach ($posts as $post) {
+ foreach ($this->posts as $post) {
$post->moodleoverflow_delete_post(false);
}
@@ -371,7 +372,7 @@ public function moodleoverflow_edit_post_from_discussion($prepost) {
$this->timemodified = $prepost->timenow;
$DB->update_record('moodleoverflow_discussions', $this->build_db_object());
}
- $post->moodleoverflow_edit_post($prepost->timenow, $prepost->message, $prepost->messageformat, $prepost->formattachment);
+ $post->moodleoverflow_edit_post($prepost->timenow, $prepost->message, $prepost->messageformat, $prepost->formattachments);
// The post has been edited successfully.
return true;
@@ -388,11 +389,13 @@ public function moodleoverflow_discussion_adapt_to_last_post() {
$this->existence_check();
// Find the last reviewed post of the discussion (even if the user has review capability, because it's written to DB).
- $sql = 'SELECT id, userid, modified
+ $sql = 'SELECT *
FROM {moodleoverflow_posts}
WHERE discussion = ' . $this->id .
' AND reviewed = 1
- AND modified = (SELECT MAX(modified) as modified FROM {moodleoverflow_posts})';
+ AND modified = (SELECT MAX(modified) as modified
+ FROM {moodleoverflow_posts}
+ WHERE discussion = ' . $this->id . ');';
$record = $DB->get_record_sql($sql);
$lastpost = post::from_record($record);
@@ -483,9 +486,9 @@ public function moodleoverflow_get_discussion_posts() {
if (!$this->postsbuild) {
// Get the posts from the DB. Get the parent post first.
$firstpostsql = 'SELECT * FROM {moodleoverflow_posts} posts
- WHERE posts.discussion = ' . $this->id . ' AND posts.parent = 0;';
+ WHERE discussion = ' . $this->id . ' AND parent = 0;';
$otherpostssql = 'SELECT * FROM {moodleoverflow_posts} posts
- WHERE posts.discussion = ' . $this->id . ' AND posts.parent != 0;';
+ WHERE discussion = ' . $this->id . ' AND parent != 0;';
$firstpostrecord = $DB->get_record_sql($firstpostsql);
$otherpostsrecord = $DB->get_records_sql($otherpostssql);
@@ -541,16 +544,24 @@ public function get_coursemodule() {
return $this->cmobject;
}
+ /**
+ * This getter works as an help function in case another file/function needs the db-object of this instance (as the function
+ * is not adapted/refactored to the new way of working with discussion).
+ * @return object
+ */
+ public function get_db_object() {
+ $this->existence_check();
+ return $this->build_db_object();
+ }
+
// Helper functions.
/**
* Builds an object from this instance that has only DB-relevant attributes.
+ * As this is an private function, it doesn't need an existence check.
* @return object $dbobject
*/
private function build_db_object() {
- $this->existence_check();
- $this->posts_check();
-
$dbobject = new \stdClass();
$dbobject->id = $this->id;
$dbobject->course = $this->course;
diff --git a/classes/post/post.php b/classes/post/post.php
index 0e1d29d864..16e0ff6591 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -151,7 +151,7 @@ public function __construct($id, $discussion, $parent, $userid, $created, $modif
/**
* Builds a Post from a DB record.
- *
+ * Look up database structure for standard values.
* @param object $record Data object.
* @return object post instance
*/
@@ -161,52 +161,52 @@ public static function from_record($record) {
$id = $record->id;
}
- $discussion = null;
+ $discussion = 0;
if (object_property_exists($record, 'discussion') && $record->discussion) {
$discussion = $record->discussion;
}
- $parent = null;
+ $parent = 0;
if (object_property_exists($record, 'parent') && $record->parent) {
$parent = $record->parent;
}
- $userid = null;
+ $userid = 0;
if (object_property_exists($record, 'userid') && $record->userid) {
$userid = $record->userid;
}
- $created = null;
+ $created = 0;
if (object_property_exists($record, 'created') && $record->created) {
$created = $record->created;
}
- $modified = null;
+ $modified = 0;
if (object_property_exists($record, 'modified') && $record->modified) {
$modified = $record->modified;
}
- $message = null;
+ $message = '';
if (object_property_exists($record, 'message') && $record->message) {
$message = $record->message;
}
- $messageformat = null;
+ $messageformat = 0;
if (object_property_exists($record, 'messageformat') && $record->messageformat) {
- $message = $record->messageformat;
+ $messageformat = $record->messageformat;
}
- $attachment = null;
+ $attachment = '';
if (object_property_exists($record, 'attachment') && $record->attachment) {
$attachment = $record->attachment;
}
- $mailed = null;
+ $mailed = 0;
if (object_property_exists($record, 'mailed') && $record->mailed) {
$mailed = $record->mailed;
}
- $reviewed = null;
+ $reviewed = 1;
if (object_property_exists($record, 'reviewed') && $record->reviewed) {
$reviewed = $record->reviewed;
}
@@ -216,10 +216,8 @@ public static function from_record($record) {
$timereviewed = $record->timereviewed;
}
- $instance = new self($id, $discussion, $parent, $userid, $created, $modified, $message,
- $messageformat, $attachment, $mailed, $reviewed, $timereviewed);
-
- return $instance;
+ return new self($id, $discussion, $parent, $userid, $created, $modified, $message, $messageformat, $attachment, $mailed,
+ $reviewed, $timereviewed);
}
/**
@@ -243,9 +241,8 @@ public static function from_record($record) {
public static function construct_without_id($discussion, $parent, $userid, $created, $modified, $message,
$messageformat, $attachment, $mailed, $reviewed, $timereviewed, $formattachments = false) {
$id = null;
- $instance = new self($id, $discussion, $parent, $userid, $created, $modified, $message,
- $messageformat, $attachment, $mailed, $reviewed, $timereviewed, $formattachments);
- return $instance;
+ return new self($id, $discussion, $parent, $userid, $created, $modified, $message, $messageformat, $attachment, $mailed,
+ $reviewed, $timereviewed, $formattachments);
}
// Post Functions.
@@ -297,11 +294,13 @@ public function moodleoverflow_delete_post($deletechildren) {
try {
$transaction = $DB->start_delegated_transaction();
+ // Get the coursemoduleid for later use.
+ $coursemoduleid = $this->get_coursemodule()->id;
$childposts = $this->moodleoverflow_get_childposts();
if ($deletechildren && $childposts) {
foreach ($childposts as $childpost) {
$child = $this->from_record($childpost);
- $child->moodleoverflow_delete_post();
+ $child->moodleoverflow_delete_post($deletechildren);
}
}
@@ -315,7 +314,7 @@ public function moodleoverflow_delete_post($deletechildren) {
// Delete the attachments.
$fs = get_file_storage();
- $context = \context_module::instance($this->get_coursemodule()->id);
+ $context = \context_module::instance($coursemoduleid);
$attachments = $fs->get_area_files($context->id, 'mod_moodleoverflow', 'attachment',
$this->id, "filename", true);
foreach ($attachments as $attachment) {
@@ -328,12 +327,9 @@ public function moodleoverflow_delete_post($deletechildren) {
}
}
- // Get the context module.
- $modulecontext = \context_module::instance($this->get_coursemodule()->id);
-
// Trigger the post deletion event.
$params = array(
- 'context' => $modulecontext,
+ 'context' => $context,
'objectid' => $this->id,
'other' => array(
'discussionid' => $this->discussion,
@@ -343,7 +339,7 @@ public function moodleoverflow_delete_post($deletechildren) {
if ($this->userid !== $USER->id) {
$params['relateduserid'] = $this->userid;
}
- $event = post_deleted::create($params);
+ $event = \mod_moodleoverflow\event\post_deleted::create($params);
$event->trigger();
// Set the id of this instance to null, so that working with it is not possible anymore.
@@ -370,7 +366,7 @@ public function moodleoverflow_delete_post($deletechildren) {
*
* @return true if the post has been edited successfully
*/
- public function moodleoverflow_edit_post($time, $postmessage, $messageformat, $formattachment) {
+ public function moodleoverflow_edit_post($time, $postmessage, $messageformat, $formattachments) {
global $DB;
$this->existence_check();
@@ -378,7 +374,7 @@ public function moodleoverflow_edit_post($time, $postmessage, $messageformat, $f
$this->modified = $time;
$this->message = $postmessage;
$this->messageformat = $messageformat;
- $this->formattachment = $formattachment; // PLEASE CHECK LATER IF THIS IS NEEDED AFTER WORKING WITH THE POST_FORM CLASS.
+ $this->formattachments = $formattachments;
// Update the record in the database.
$DB->update_record('moodleoverflow_posts', $this->build_db_object());
@@ -431,10 +427,6 @@ public function moodleoverflow_add_attachment() {
global $DB;
$this->existence_check();
- if (!$this->formattachments) {
- throw new \moodle_exception('missingformattachments', 'moodleoverflow');
- }
-
if (empty($this->formattachments)) {
return true; // Nothing to do.
}
@@ -615,6 +607,16 @@ public function moodleoverflow_get_childposts() {
return false;
}
+ /**
+ * This getter works as an help function in case another file/function needs the db-object of this instance (as the function
+ * is not adapted/refactored to the new way of working with discussion).
+ * @return object
+ */
+ public function get_db_object() {
+ $this->existence_check();
+ return $this->build_db_object;
+ }
+
// Helper Functions.
/**
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index e330f7f80b..33a7be9ab5 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -37,7 +37,7 @@
require_once($CFG->dirroot . '/mod/moodleoverflow/locallib.php');
require_once($CFG->libdir . '/completionlib.php');
-//require once($CFG->dirroot . 'mod/moodleoverflow/classes/post/post.php');
+
/**
* This Class controls the manipulation of posts and acts as controller of interactions with the post.php
*
@@ -118,7 +118,7 @@ public function detect_interaction($urlparameter) {
} else if ($urlparameter->delete) {
$this->interaction = 'delete';
- $this->info->deletepostid = $urlparameter->edit;
+ $this->info->deletepostid = $urlparameter->delete;
$this->build_prepost_delete($this->info->deletepostid);
} else {
throw new \moodle_exception('unknownaction');
@@ -146,14 +146,7 @@ public function execute_interaction($form) {
// Get the current time.
$this->prepost->timenow = time();
- /*
- var_dump($this->interaction);
- var_dump('
');
- var_dump($this->prepost);
- var_dump('');
- var_dump($form->reply);
- var_dump($this->prepost->parentid);*/
- var_dump($form);
+
// Execute the right function.
if ($this->interaction == 'create' && $form->moodleoverflow == $this->prepost->moodleoverflowid) {
$this->execute_create($form, $errordestination);
@@ -347,30 +340,28 @@ private function build_prepost_edit($editpostid) {
private function build_prepost_delete($deletepostid) {
global $DB, $USER;
- // Get the realted post, discussion, moodleoverflow, course, coursemodule and contexts.
+ // Get the related post, discussion, moodleoverflow, course, coursemodule and contexts.
$this->collect_information($deletepostid, false);
// Require a login and retrieve the modulecontext.
require_login($this->info->course, false, $this->info->cm);
// Check some capabilities.
- $this->info->deleteownpost = has_capability('mod/moodleoverflow:deleteownpost', $this->info->modulecontext);
- $this->info->deleteanypost = has_capability('mod/moodleoverflow:deleteanypost', $this->info->modulecontext);
- if (!(($this->info->relatedpost->get_userid() == $USER->id && $this->info->deleteownpost)
- || $this->info->deleteanypost)) {
-
- throw new \moodle_exception('cannotdeletepost', 'moodleoverflow');
- }
+ $this->check_user_can_delete_post();
// Count all replies of this post.
$this->info->replycount = moodleoverflow_count_replies($this->info->relatedpost, false);
-
+ if ($this->info->replycount >= 1) {
+ $this->info->deletetype = 'plural';
+ } else {
+ $this->info->deletetype = 'singular';
+ }
// Build the prepost.
$this->assemble_prepost();
$this->prepost->deletechildren = true;
}
- // Execute Functions, that execute an interaction.
+ // Execute Functions.
private function execute_create($form, $errordestination) {
global $USER;
@@ -385,9 +376,12 @@ private function execute_create($form, $errordestination) {
$this->prepost->reviewed = 1;
}
+ // Get the discussion subject.
+ $this->prepost->subject = $form->subject;
+
// Create the discussion object.
$discussion = discussion::construct_without_id($this->prepost->courseid, $this->prepost->moodleoverflowid,
- $this->prepost->subject, null, $this->prepost->userid,
+ $this->prepost->subject, 0, $this->prepost->userid,
$this->prepost->timenow, $this->prepost->timenow, $this->prepost->userid);
if (!$discussion->moodleoverflow_add_discussion($this->prepost)) {
throw new \moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
@@ -397,13 +391,16 @@ private function execute_create($form, $errordestination) {
$redirectmessage = '' . get_string("postaddedsuccess", "moodleoverflow") . '
';
// Trigger the discussion created event.
- $params = array( 'context' => $this->info->modulecontext, 'objectid' => $discussion->id,);
+ $params = array( 'context' => $this->info->modulecontext, 'objectid' => $discussion->get_id());
$event = \mod_moodleoverflow\event\discussion_created::create($params);
$event->trigger();
// Subscribe to this thread.
- //\mod_moodleoverflow\subscriptions::moodleoverflow_post_subscription($form, $this->info->moodleoverflow,
- //$discussion, $this->info->modulecontext);
+ // Please be aware that in future the use of get_db_object() should be replaced with only $this->info->discussion,
+ // as the subscription class should be refactored with the new way of working with posts.
+ \mod_moodleoverflow\subscriptions::moodleoverflow_post_subscription($form, $this->info->moodleoverflow,
+ $discussion->get_db_object(),
+ $this->info->modulecontext);
// Define the location to redirect the user after successfully posting.
$redirectto = new \moodle_url('/mod/moodleoverflow/view.php', array('m' => $form->moodleoverflow));
@@ -413,7 +410,7 @@ private function execute_create($form, $errordestination) {
private function execute_reply($form, $errordestination) {
// Check if the user has the capability to write a reply.
$this->check_user_can_create_reply();
-
+
// Set to not reviewed, if posts should be reviewed, and user is not a reviewer themselves.
if (review::get_review_level($this->info->moodleoverflow) == review::EVERYTHING &&
!has_capability('mod/moodleoverflow:reviewpost', \context_module::instance($this->info->cm->id))) {
@@ -431,7 +428,7 @@ private function execute_reply($form, $errordestination) {
$redirectmessage = '' . get_string("postaddedsuccess", "moodleoverflow") . '
';
$redirectmessage .= '' . get_string("postaddedtimeleft", "moodleoverflow",
format_time(get_config('moodleoverflow', 'maxeditingtime'))) . '
';
-
+
// Trigger the post created event.
$params = array('context' => $this->info->modulecontext, 'objectid' => $newpostid,
'other' => array('discussionid' => $this->prepost->discussionid,
@@ -440,30 +437,33 @@ private function execute_reply($form, $errordestination) {
$event = \mod_moodleoverflow\event\post_created::create($params);
$event->trigger();
- // Subscribe to this thread;
- // \mod_moodleoverflow\subscriptions::moodleoverflow_post_subscription(form, $this->info->moodleoverflow,
- //$this->info->discussion, $this->info->modulecontext);
-
+ // Subscribe to this thread.
+ // Please be aware that in future the use of build_db_object() should be replaced with only $this->info->discussion,
+ // as the subscription class should be refactored with the new way of working with posts.
+ \mod_moodleoverflow\subscriptions::moodleoverflow_post_subscription($form, $this->info->moodleoverflow,
+ $this->info->discussion->get_db_object(),
+ $this->info->modulecontext);
+
// Define the location to redirect the user after successfully posting.
- $redirectto = new \moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->prepost->discussionid, 'p' => $newpostid));
+ $redirectto = new \moodle_url('/mod/moodleoverflow/discussion.php',
+ array('d' => $this->prepost->discussionid, 'p' => $newpostid));
redirect(\moodleoverflow_go_back_to($redirectto->out()), $redirectmessage, null, \core\output\notification::NOTIFY_SUCCESS);
-
}
private function execute_edit($form, $errordestination) {
- global $USER;
+ global $USER, $DB;
// Check if the user has the capability to edit his post.
$this->check_user_can_edit_post();
-
+
// Update the post.
if (!$this->info->discussion->moodleoverflow_edit_post_from_discussion($this->prepost)) {
throw new \moodle_exception('couldnotupdate', 'moodleoverflow', $errordestination);
}
-
- // The edit was successful.
+
+ // The edit was successful.
$redirectmessage = get_string('postupdated', 'moodleoverflow');
- /*if ($this->prepost->userid == $USER->id) {
+ if ($this->prepost->userid == $USER->id) {
$redirectmessage = get_string('postupdated', 'moodleoverflow');
} else {
if (\mod_moodleoverflow\anonymous::is_post_anonymous($this->info->discussion, $this->info->moodleoverflow,
@@ -474,7 +474,7 @@ private function execute_edit($form, $errordestination) {
$name = fullname($realuser);
}
$redirectmessage = get_string('editedpostupdated', 'moodleoverflow', $name);
- }*/
+ }
// Trigger the post updated event.
$params = array('context' => $this->info->modulecontext, 'objectid' => $form->edit,
@@ -486,7 +486,8 @@ private function execute_edit($form, $errordestination) {
$event->trigger();
// Define the location to redirect the user after successfully editing.
- $redirectto = new \moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->prepost->discussionid, 'p' => $form->edit));
+ $redirectto = new \moodle_url('/mod/moodleoverflow/discussion.php',
+ array('d' => $this->prepost->discussionid, 'p' => $form->edit));
redirect(moodleoverflow_go_back_to($redirectto->out()), $redirectmessage, null, \core\output\notification::NOTIFY_SUCCESS);
}
@@ -501,16 +502,18 @@ public function execute_delete() {
}
// A normal user cannot delete his post if there are direct replies.
- if ($this->infro->replycount && !$this->info->deleteanypost) {
+ if ($this->info->replycount && !$this->info->deleteanypost) {
throw new \moodle_exception('cannotdeletereplies', 'moodleoverflow', moodleoverflow_go_back_to($url));
}
// Check if the post is a parent post or not.
if ($this->prepost->parentid == 0) {
+ // Save the moodleoverflowid. Then delete the discussion.
+ $moodleoverflowid = $this->info->discussion->get_moodleoverflowid();
$this->info->discussion->moodleoverflow_delete_discussion($this->prepost);
// Redirect the user back to the start page of the moodleoverflow instance.
- redirect('view.php?m=' . $this->info->discussion->get_moodleoverflowid());
+ redirect('view.php?m=' . $moodleoverflowid);
} else {
$this->info->discussion->moodleoverflow_delete_post_from_discussion($this->prepost);
$discussionurl = new \moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->info->discussion->get_id()));
@@ -645,13 +648,6 @@ private function collect_information($postid = false, $moodleoverflowid = false)
} else {
$localmoodleoverflowid = $moodleoverflowid;
}
- /*
- var_dump($moodleoverflowid);
- var_dump($postid);
- var_dump($this->info->relatedpost);
- var_dump($this->info->discussion);
- var_dump($localmoodleoverflowid);
- */
$this->info->moodleoverflow = $this->check_moodleoverflow_exists($localmoodleoverflowid);
$this->info->course = $this->check_course_exists($this->info->moodleoverflow->course);
$this->info->cm = $this->check_coursemodule_exists($this->info->moodleoverflow->id, $this->info->course->id);
@@ -796,7 +792,7 @@ private function check_user_can_create_reply() {
* Checks if a user can edit a post.
* A user can edit if he can edit any post of if he edits his own post and has the ability to:
* start a new discussion or to reply to a post.
- *
+ *
* @return true
* @throws moodle_exception
*/
@@ -811,4 +807,20 @@ private function check_user_can_edit_post() {
}
return true;
}
+
+ /**
+ * Checks if a user can edit a post.
+ * @return true
+ * @thorws moodle_exception
+ */
+ private function check_user_can_delete_post() {
+ global $USER;
+ $this->info->deleteownpost = has_capability('mod/moodleoverflow:deleteownpost', $this->info->modulecontext);
+ $this->info->deleteanypost = has_capability('mod/moodleoverflow:deleteanypost', $this->info->modulecontext);
+ if (!(($this->info->relatedpost->get_userid() == $USER->id && $this->info->deleteownpost) || $this->info->deleteanypost)) {
+
+ throw new \moodle_exception('cannotdeletepost', 'moodleoverflow');
+ }
+ return true;
+ }
}
diff --git a/classes/subscriptions.php b/classes/subscriptions.php
index eb44389462..8ea2981846 100644
--- a/classes/subscriptions.php
+++ b/classes/subscriptions.php
@@ -761,6 +761,7 @@ public static function unsubscribe_user($userid, $moodleoverflow, $context, $use
/**
* Subscribes the user to the specified discussion.
*
+ * TODO: Refactor this function to the new way of working with discussion and posts.
* @param int $userid The user ID
* @param \stdClass $discussion The discussion record
* @param \context_module $context The module context
@@ -985,6 +986,7 @@ public static function moodleoverflow_get_subscribe_link($moodleoverflow, $conte
/**
* Given a new post, subscribes the user to the thread the post was posted in.
*
+ * TODO: Refactor this function to the new way of working with discussion and posts.
* @param object $fromform The submitted form
* @param \stdClass $moodleoverflow The moodleoverflow record
* @param \stdClass $discussion The discussion record
diff --git a/locallib.php b/locallib.php
index 1187827aa2..f1f01528a9 100644
--- a/locallib.php
+++ b/locallib.php
@@ -944,8 +944,8 @@ function moodleoverflow_print_discussion($course, $cm, $moodleoverflow, $discuss
$istracked = readtracking::moodleoverflow_is_tracked($moodleoverflow);
// Retrieve all posts of the discussion.
+ // This part is adapted/refactored to the new way of working with posts (use of get_id() function and discussion object).
$posts = moodleoverflow_get_all_discussion_posts($discussionobject->get_id(), $istracked, $modulecontext);
- //$posts = $discussionobjects->posts;
$usermapping = anonymous::get_userid_mapping($moodleoverflow, $discussionobject->get_id());
@@ -1773,6 +1773,7 @@ function moodleoverflow_update_post($newpost) {
/**
* Count all replies of a post.
*
+ * INFO: This Function is adapted to the new way of working with posts (using the post classes)
* @param object $post The post object
* @param bool $onlyreviewed Whether to count only reviewed posts.
*
@@ -1781,7 +1782,7 @@ function moodleoverflow_update_post($newpost) {
function moodleoverflow_count_replies($post, $onlyreviewed) {
global $DB;
- $conditions = ['parent' => $post->id];
+ $conditions = ['parent' => $post->get_id()];
if ($onlyreviewed) {
$conditions['reviewed'] = '1';
diff --git a/post.php b/post.php
index 3a59050729..e2ec14e042 100644
--- a/post.php
+++ b/post.php
@@ -55,7 +55,6 @@
// Create a post_control object to control and lead the process.
$postcontrol = new post_control();
-//$postcontrol = new post_control();
// Put all interaction parameters in one object for the post_control.
$urlparameter = new \stdClass();
From 29e3a0961a92f603bd1cc428a82695604b6a7617 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 10 Aug 2023 13:03:22 +0200
Subject: [PATCH 23/56] little compatibility fixes with new post structure
---
classes/post/post.php | 10 +++++++---
classes/post/post_control.php | 6 ++++--
classes/readtracking.php | 2 +-
classes/review.php | 2 +-
locallib.php | 17 ++++-------------
5 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/classes/post/post.php b/classes/post/post.php
index 16e0ff6591..7bb5a26505 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -270,7 +270,9 @@ public function moodleoverflow_add_new_post() {
$cantrack = readtracking::moodleoverflow_can_track_moodleoverflows($this->get_moodleoverflow());
$istracked = readtracking::moodleoverflow_is_tracked($this->get_moodleoverflow());
if ($cantrack && $istracked) {
- readtracking::moodleoverflow_mark_post_read($this->userid, $this);
+ // Please be aware that in future the use of get_db_object() should be replaced with only $this,
+ // as the readtracking class should be refactored with the new way of working with posts.
+ readtracking::moodleoverflow_mark_post_read($this->userid, $this->get_db_object());
}
// Return the id of the created post.
@@ -614,7 +616,7 @@ public function moodleoverflow_get_childposts() {
*/
public function get_db_object() {
$this->existence_check();
- return $this->build_db_object;
+ return $this->build_db_object();
}
// Helper Functions.
@@ -649,7 +651,9 @@ public function mark_post_read() {
$cantrack = readtracking::moodleoverflow_can_track_moodleoverflows($this->get_moodleoverflow());
$istracked = readtracking::moodleoverflow_is_tracked($this->get_moodleoverflow());
if ($cantrack && $istracked) {
- readtracking::moodleoverflow_mark_post_read($USER->id, $this);
+ // Please be aware that in future the use of get_db_object() should be replaced with only $this,
+ // as the readtracking class should be refactored with the new way of working with posts.
+ readtracking::moodleoverflow_mark_post_read($USER->id, $this->get_db_object());
}
}
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index 33a7be9ab5..12e9222a0f 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -305,11 +305,13 @@ private function build_prepost_edit($editpostid) {
// Check if the post can be edited.
$beyondtime = ((time() - $this->info->relatedpost->created) > get_config('moodleoverflow', 'maxeditingtime'));
- $alreadyreviewed = review::should_post_be_reviewed($this->info->relatedpost, $this->info->moodleoverflow)
+
+ // Please be aware that in future the use of get_db_object() should be replaced with $this->info->relatedpost,
+ // as the review class should be refactored with the new way of working with posts.
+ $alreadyreviewed = review::should_post_be_reviewed($this->info->relatedpost->get_db_object(), $this->info->moodleoverflow)
&& $this->info->relatedpost->reviewed;
if (($beyondtime || $alreadyreviewed) && !has_capability('mod/moodleoverflow:editanypost',
$this->info->modulecontext)) {
-
throw new \moodle_exception('maxtimehaspassed', 'moodleoverflow', '',
format_time(get_config('moodleoverflow', 'maxeditingtime')));
}
diff --git a/classes/readtracking.php b/classes/readtracking.php
index 519fcd397f..54a5e57e65 100644
--- a/classes/readtracking.php
+++ b/classes/readtracking.php
@@ -201,7 +201,7 @@ public static function moodleoverflow_mark_post_read($userid, $post) {
}
// Create a new read record.
- return self::moodleoverflow_add_read_record($userid, $post->get_id());
+ return self::moodleoverflow_add_read_record($userid, $post->id);
}
/**
diff --git a/classes/review.php b/classes/review.php
index b975bfbf0b..30b92eb71e 100644
--- a/classes/review.php
+++ b/classes/review.php
@@ -132,7 +132,7 @@ public static function get_first_review_post($moodleoverflowid, $afterpostid = n
*/
public static function should_post_be_reviewed($post, $moodleoverflow): bool {
$reviewlevel = self::get_review_level($moodleoverflow);
- if (/*$post->parent != 0 */$post->get_parentid() != 0) {
+ if ($post->parent != 0) {
return $reviewlevel == self::EVERYTHING;
} else {
return $reviewlevel >= self::QUESTIONS;
diff --git a/locallib.php b/locallib.php
index f1f01528a9..acecbf781e 100644
--- a/locallib.php
+++ b/locallib.php
@@ -917,6 +917,7 @@ function moodleoverflow_user_can_post($modulecontext, $posttoreplyto, $considerr
/**
* Prints a moodleoverflow discussion.
+ * TODO: REFACTOR WITH NEW POST AND DISCUSSION STRUCTURE.
*
* @param stdClass $course The course object
* @param object $cm
@@ -928,12 +929,6 @@ function moodleoverflow_user_can_post($modulecontext, $posttoreplyto, $considerr
function moodleoverflow_print_discussion($course, $cm, $moodleoverflow, $discussion, $post, $multiplemarks = false) {
global $USER, $DB;
- // TODO: REFACTOR WITH NEW POST AND DISCUSSION STRUCTURE.
-
- // THE NEXT STEP IS NECESSARY UNTIL THE REFACTORING IS COMPLETE.
- $discussionrecord = $DB->get_record('moodleoverflow_discussions', array('id' => $discussion->id));
- $discussionobject = \mod_moodleoverflow\discussion\discussion::from_record($discussionrecord);
-
// Check if the current is the starter of the discussion.
$ownpost = (isloggedin() && ($USER->id == $post->userid));
@@ -945,9 +940,9 @@ function moodleoverflow_print_discussion($course, $cm, $moodleoverflow, $discuss
// Retrieve all posts of the discussion.
// This part is adapted/refactored to the new way of working with posts (use of get_id() function and discussion object).
- $posts = moodleoverflow_get_all_discussion_posts($discussionobject->get_id(), $istracked, $modulecontext);
+ $posts = moodleoverflow_get_all_discussion_posts($discussion->id, $istracked, $modulecontext);
- $usermapping = anonymous::get_userid_mapping($moodleoverflow, $discussionobject->get_id());
+ $usermapping = anonymous::get_userid_mapping($moodleoverflow, $discussion->id);
// Start with the parent post.
$post = $posts[$post->id];
@@ -1294,13 +1289,9 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co
// Calculate the age of the post.
$age = time() - $post->created;
- // TODO: REFACTOR FOR NEW POST STRUCTURE: FOR A TIME, THIS IS THE FIX.
- $postrecord = $DB->get_record('moodleoverflow_posts', array('id' => $post->id));
- $postobject = \mod_moodleoverflow\post\post::from_record($postrecord);
-
// Make a link to edit your own post within the given time and not already reviewed.
if (($ownpost && ($age < get_config('moodleoverflow', 'maxeditingtime')) &&
- (!review::should_post_be_reviewed($postobject, $moodleoverflow) || !$post->reviewed))
+ (!review::should_post_be_reviewed($post, $moodleoverflow) || !$post->reviewed))
|| capabilities::has(capabilities::EDIT_ANY_POST, $modulecontext)
) {
$editurl = new moodle_url('/mod/moodleoverflow/post.php', array('edit' => $post->id));
From 5b614891ab1ac3fdef1c8933080f37c4a3e07cf8 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 10 Aug 2023 14:52:19 +0200
Subject: [PATCH 24/56] deleting unnecessary functions in the locallib
---
classes/discussion/discussion.php | 2 +
classes/post/post.php | 29 +-
classes/post/post_control.php | 10 +-
classes/post/structure.drawio | 192 --------
externallib.php | 1 +
lib.php | 2 +
locallib.php | 87 +---
post.php | 1 +
post_old.php | 792 ------------------------------
tests/post_test.php | 2 +-
10 files changed, 41 insertions(+), 1077 deletions(-)
delete mode 100644 classes/post/structure.drawio
delete mode 100644 post_old.php
diff --git a/classes/discussion/discussion.php b/classes/discussion/discussion.php
index c7957a705d..2115bae1e7 100644
--- a/classes/discussion/discussion.php
+++ b/classes/discussion/discussion.php
@@ -233,6 +233,7 @@ public function moodleoverflow_add_discussion($prepost) {
'context' => $prepost->modulecontext,
'objectid' => $this->id,
);
+ // TODO: check if the event functions.
$event = \mod_moodleoverflow\event\discussion_viewed::create($params);
$event->trigger();
@@ -532,6 +533,7 @@ public function get_moodleoverflow() {
* @return object $cmobject
*/
public function get_coursemodule() {
+ global $DB;
$this->existence_check();
if (empty($this->cmobject)) {
diff --git a/classes/post/post.php b/classes/post/post.php
index 7bb5a26505..f1255caeb2 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -270,8 +270,8 @@ public function moodleoverflow_add_new_post() {
$cantrack = readtracking::moodleoverflow_can_track_moodleoverflows($this->get_moodleoverflow());
$istracked = readtracking::moodleoverflow_is_tracked($this->get_moodleoverflow());
if ($cantrack && $istracked) {
- // Please be aware that in future the use of get_db_object() should be replaced with only $this,
- // as the readtracking class should be refactored with the new way of working with posts.
+ // Please be aware that in future the use of get_db_object() should be replaced with only $this,
+ // as the readtracking class should be refactored with the new way of working with posts.
readtracking::moodleoverflow_mark_post_read($this->userid, $this->get_db_object());
}
@@ -392,7 +392,7 @@ public function moodleoverflow_edit_post($time, $postmessage, $messageformat, $f
}
/**
- * // RETHINK THIS FUNCTION.
+ * // TODO: RETHINK THIS FUNCTION.
* Gets a post with all info ready for moodleoverflow_print_post.
* Most of these joins are just to get the forum id.
*
@@ -651,8 +651,8 @@ public function mark_post_read() {
$cantrack = readtracking::moodleoverflow_can_track_moodleoverflows($this->get_moodleoverflow());
$istracked = readtracking::moodleoverflow_is_tracked($this->get_moodleoverflow());
if ($cantrack && $istracked) {
- // Please be aware that in future the use of get_db_object() should be replaced with only $this,
- // as the readtracking class should be refactored with the new way of working with posts.
+ // Please be aware that in future the use of get_db_object() should be replaced with only $this,
+ // as the readtracking class should be refactored with the new way of working with posts.
readtracking::moodleoverflow_mark_post_read($USER->id, $this->get_db_object());
}
}
@@ -679,6 +679,25 @@ private function build_db_object() {
return $dbobject;
}
+ /*
+ * Count all replies of a post.
+ *
+ * @param bool $onlyreviewed Whether to count only reviewed posts.
+ * @return int Amount of replies
+ */
+ public function moodleoverflow_count_replies($onlyreviewed) {
+ global $DB;
+
+ $conditions = ['parent' => $this->id];
+
+ if ($onlyreviewed) {
+ $conditions['reviewed'] = '1';
+ }
+
+ // Return the amount of replies.
+ return $DB->count_records('moodleoverflow_posts', $conditions);
+ }
+
// Security.
/**
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index 12e9222a0f..75e9de77e0 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -201,7 +201,7 @@ private function build_prepost_create($moodleoverflowid) {
$this->collect_information(false, $moodleoverflowid);
// Check if the user can start a new discussion.
- if (!moodleoverflow_user_can_post_discussion($this->info->moodleoverflow, $this->info->cm, $this->info->modulecontext)) {
+ if (!$this->check_user_can_create_discussion()) {
// Catch unenrolled user.
if (!isguestuser() && !is_enrolled($this->info->coursecontext)) {
@@ -306,8 +306,8 @@ private function build_prepost_edit($editpostid) {
// Check if the post can be edited.
$beyondtime = ((time() - $this->info->relatedpost->created) > get_config('moodleoverflow', 'maxeditingtime'));
- // Please be aware that in future the use of get_db_object() should be replaced with $this->info->relatedpost,
- // as the review class should be refactored with the new way of working with posts.
+ // Please be aware that in future the use of get_db_object() should be replaced with $this->info->relatedpost,
+ // as the review class should be refactored with the new way of working with posts.
$alreadyreviewed = review::should_post_be_reviewed($this->info->relatedpost->get_db_object(), $this->info->moodleoverflow)
&& $this->info->relatedpost->reviewed;
if (($beyondtime || $alreadyreviewed) && !has_capability('mod/moodleoverflow:editanypost',
@@ -352,7 +352,7 @@ private function build_prepost_delete($deletepostid) {
$this->check_user_can_delete_post();
// Count all replies of this post.
- $this->info->replycount = moodleoverflow_count_replies($this->info->relatedpost, false);
+ $this->info->replycount = $this->info->relatedpost->moodleoverflow_count_replies(false);
if ($this->info->replycount >= 1) {
$this->info->deletetype = 'plural';
} else {
@@ -539,6 +539,8 @@ public function confirm_delete() {
}
/**
+ *
+ * TODO: use html_writer:: instead of writing pure html code.
* Builds and returns a post_form object where the users enters/edits the message and attachments of the post.
* @param array $pageparams An object that the post.php created.
* @return object a mod_moodleoverflow_post_form object.
diff --git a/classes/post/structure.drawio b/classes/post/structure.drawio
deleted file mode 100644
index 691bd360a6..0000000000
--- a/classes/post/structure.drawio
+++ /dev/null
@@ -1,192 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/externallib.php b/externallib.php
index a7c29fb75f..22255637cd 100644
--- a/externallib.php
+++ b/externallib.php
@@ -39,6 +39,7 @@
*/
class mod_moodleoverflow_external extends external_api {
+ // TODO: Adapt the functions to the new way of working with posts.
/**
* Returns description of method parameters
* @return external_function_parameters
diff --git a/lib.php b/lib.php
index 7651957cd6..28eb3fa794 100644
--- a/lib.php
+++ b/lib.php
@@ -29,6 +29,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
+// TODO: Adapt functions to the new way of working with posts and discussions (Replace the post/discussion functions).
+
defined('MOODLE_INTERNAL') || die();
require_once(dirname(__FILE__) . '/locallib.php');
diff --git a/locallib.php b/locallib.php
index acecbf781e..80693d9eb4 100644
--- a/locallib.php
+++ b/locallib.php
@@ -524,8 +524,8 @@ function moodleoverflow_count_discussion_replies($cm) {
}
/**
+ * TODO: Delete this function when adapting the print-functions to the new post and discussion structure.
* Check if the user is capable of starting a new discussion.
- *
* @param object $moodleoverflow
* @param object $cm
* @param object $context
@@ -1568,6 +1568,7 @@ function moodleoverflow_print_posts_nested($course, &$cm, $moodleoverflow, $disc
}
/**
+ * TODO: Delete this function after adapting the print_post function to the new post structure
* Returns attachments with information for the template
*
* @param object $post
@@ -1649,6 +1650,7 @@ function moodleoverflow_add_attachment($post, $forum, $cm) {
}
/**
+ * WARNING: this function is only used in the lib.php. For other uses this function is deprecated.
* Adds a new post in an existing discussion.
* @param object $post The post object
* @return bool|int The Id of the post if operation was successful
@@ -1701,88 +1703,6 @@ function moodleoverflow_add_new_post($post) {
return $post->id;
}
-/**
- * Updates a specific post.
- *
- * Capabilities are not checked, because this is happening in the post.php.
- *
- * @param object $newpost The new post object
- *
- * @return bool Whether the update was successful
- */
-function moodleoverflow_update_post($newpost) {
- global $DB, $USER;
-
- // Retrieve not submitted variables.
- $post = $DB->get_record('moodleoverflow_posts', array('id' => $newpost->id));
- $discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $post->discussion));
- $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow));
-
- // Allowed modifiable fields.
- $modifiablefields = [
- 'message',
- 'messageformat',
- ];
-
- // Iteratate through all modifiable fields and update the values.
- foreach ($modifiablefields as $field) {
- if (isset($newpost->{$field})) {
- $post->{$field} = $newpost->{$field};
- }
- }
-
- $post->modified = time();
- if ($newpost->reviewed ?? $post->reviewed) {
- // Update the date and the user of the post and the discussion.
- $discussion->timemodified = $post->modified;
- $discussion->usermodified = $post->userid;
- }
-
- // When editing the starting post of a discussion.
- if (!$post->parent) {
- $discussion->name = $newpost->subject;
- }
-
- // Update the post and the corresponding discussion.
- $DB->update_record('moodleoverflow_posts', $post);
- $DB->update_record('moodleoverflow_discussions', $discussion);
-
- $cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id);
- moodleoverflow_add_attachment($newpost, $moodleoverflow, $cm);
-
- // Mark the edited post as read.
- $cantrack = readtracking::moodleoverflow_can_track_moodleoverflows($moodleoverflow);
- $istracked = readtracking::moodleoverflow_is_tracked($moodleoverflow);
- if ($cantrack && $istracked) {
- readtracking::moodleoverflow_mark_post_read($USER->id, $post);
- }
-
- // The post has been edited successfully.
- return true;
-}
-
-/**
- * Count all replies of a post.
- *
- * INFO: This Function is adapted to the new way of working with posts (using the post classes)
- * @param object $post The post object
- * @param bool $onlyreviewed Whether to count only reviewed posts.
- *
- * @return int Amount of replies
- */
-function moodleoverflow_count_replies($post, $onlyreviewed) {
- global $DB;
-
- $conditions = ['parent' => $post->get_id()];
-
- if ($onlyreviewed) {
- $conditions['reviewed'] = '1';
- }
-
- // Return the amount of replies.
- return $DB->count_records('moodleoverflow_posts', $conditions);
-}
-
/**
* Deletes a discussion and handles all associated cleanups.
*
@@ -1911,6 +1831,7 @@ function moodleoverflow_delete_post($post, $deletechildren, $cm, $moodleoverflow
}
/**
+ * WARNING: this function is only used in the lib.php. For other uses this function is deprecated.
* Sets the last post for a given discussion.
*
* @param int $discussionid The discussion ID
diff --git a/post.php b/post.php
index e2ec14e042..e204e5ee17 100644
--- a/post.php
+++ b/post.php
@@ -78,6 +78,7 @@
}
// Require a general login to post something.
+// TODO: should course or id really be zero?.
require_login(0, false);
// Now the post_control checks which interaction is wanted and builds a prepost.
diff --git a/post_old.php b/post_old.php
deleted file mode 100644
index 5baa519ba5..0000000000
--- a/post_old.php
+++ /dev/null
@@ -1,792 +0,0 @@
-.
-
-/**
- * The file to manage posts.
- *
- * @package mod_moodleoverflow
- * @copyright 2017 Kennet Winter
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-// TODO refactor this. For more readability, and to avoid security issues.
-
-// Include config and locallib.
-use mod_moodleoverflow\review;
-
-require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
-global $CFG, $USER, $DB, $PAGE, $SESSION, $OUTPUT;
-require_once(dirname(__FILE__) . '/locallib.php');
-require_once($CFG->libdir . '/completionlib.php');
-
-// Declare optional parameters.
-$moodleoverflow = optional_param('moodleoverflow', 0, PARAM_INT);
-$reply = optional_param('reply', 0, PARAM_INT);
-$edit = optional_param('edit', 0, PARAM_INT);
-$delete = optional_param('delete', 0, PARAM_INT);
-$confirm = optional_param('confirm', 0, PARAM_INT);
-
-$count = 0;
-$count += $moodleoverflow ? 1 : 0;
-$count += $reply ? 1 : 0;
-$count += $edit ? 1 : 0;
-$count += $delete ? 1 : 0;
-
-if ($count !== 1) {
- throw new coding_exception('Exactly one parameter should be specified!');
-}
-
-// Set the URL that should be used to return to this page.
-$PAGE->set_url('/mod/moodleoverflow/post.php', array(
- 'moodleoverflow' => $moodleoverflow,
- 'reply' => $reply,
- 'edit' => $edit,
- 'delete' => $delete,
- 'confirm' => $confirm,
-));
-
-// These params will be passed as hidden variables later in the form.
-$pageparams = array('moodleoverflow' => $moodleoverflow, 'reply' => $reply, 'edit' => $edit);
-
-// Get the system context instance.
-$systemcontext = context_system::instance();
-
-// Catch guests.
-if (!isloggedin() || isguestuser()) {
-
- // The user is starting a new discussion in a moodleoverflow instance.
- if (!empty($moodleoverflow)) {
-
- // Check the moodleoverflow instance is valid.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
-
- // The user is replying to an existing moodleoverflow discussion.
- } else if (!empty($reply)) {
-
- // Check if the related post exists.
- if (!$parent = moodleoverflow_get_post_full($reply)) {
- throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
- }
-
- // Check if the post is part of a valid discussion.
- if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $parent->discussion))) {
- throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
- }
-
- // Check if the post is related to a valid moodleoverflow instance.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
- }
-
- // Get the related course.
- if (!$course = $DB->get_record('course', array('id' => $moodleoverflow->course))) {
- throw new moodle_exception('invalidcourseid');
- }
-
- // Get the related coursemodule and its context.
- if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $course->id)) {
- throw new moodle_exception('invalidcoursemodule');
- }
-
- // Get the context of the module.
- $modulecontext = context_module::instance($cm->id);
-
- // Set parameters for the page.
- $PAGE->set_cm($cm, $course, $moodleoverflow);
- $PAGE->set_context($modulecontext);
- $PAGE->set_title($course->shortname);
- $PAGE->set_heading($course->fullname);
-
- // The page should not be large, only pages containing broad tables are usually.
- $PAGE->add_body_class('limitedwidth');
-
- // The guest needs to login.
- echo $OUTPUT->header();
- $strlogin = get_string('noguestpost', 'forum') . '
' . get_string('liketologin');
- echo $OUTPUT->confirm($strlogin, get_login_url(), $CFG->wwwroot . '/mod/moodleoverflow/view.php?m=' . $moodleoverflow->id);
- echo $OUTPUT->footer();
- exit;
-}
-
-// First step: A general login is needed to post something.
-require_login(0, false);
-
-// First possibility: User is starting a new discussion in a moodleoverflow instance.
-if (!empty($moodleoverflow)) {
-
- // Check the moodleoverflow instance is valid.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
-
- // Get the related course.
- if (!$course = $DB->get_record('course', array('id' => $moodleoverflow->course))) {
- throw new moodle_exception('invalidcourseid');
- }
-
- // Get the related coursemodule.
- if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $course->id)) {
- throw new moodle_exception('invalidcoursemodule');
- }
-
- // Retrieve the contexts.
- $modulecontext = context_module::instance($cm->id);
- $coursecontext = context_course::instance($course->id);
-
- // Check if the user can start a new discussion.
- if (!moodleoverflow_user_can_post_discussion($moodleoverflow, $cm, $modulecontext)) {
-
- // Catch unenrolled user.
- if (!isguestuser() && !is_enrolled($coursecontext)) {
- if (enrol_selfenrol_available($course->id)) {
- $SESSION->wantsurl = qualified_me();
- $SESSION->enrolcancel = get_local_referer(false);
- redirect(new moodle_url('/enrol/index.php', array(
- 'id' => $course->id,
- 'returnurl' => '/mod/moodleoverflow/view.php?m=' . $moodleoverflow->id
- )), get_string('youneedtoenrol'));
- }
- }
-
- // Notify the user, that he can not post a new discussion.
- throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
- }
-
- // Where is the user coming from?
- $SESSION->fromurl = get_local_referer(false);
-
- // Load all the $post variables.
- $post = new stdClass();
- $post->course = $course->id;
- $post->moodleoverflow = $moodleoverflow->id;
- $post->discussion = 0;
- $post->parent = 0;
- $post->subject = '';
- $post->userid = $USER->id;
- $post->message = '';
-
- // Unset where the user is coming from.
- // Allows to calculate the correct return url later.
- unset($SESSION->fromdiscussion);
-
-} else if (!empty($reply)) {
- // Second possibility: The user is writing a new reply.
-
- // Check if the post exists.
- if (!$parent = moodleoverflow_get_post_full($reply)) {
- throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
- }
-
- // Check if the post is part of a discussion.
- if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $parent->discussion))) {
- throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
- }
-
- // Check if the discussion is part of a moodleoverflow instance.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
-
- // Check if the moodleoverflow instance is part of a course.
- if (!$course = $DB->get_record('course', array('id' => $discussion->course))) {
- throw new moodle_exception('invalidcourseid');
- }
-
- // Retrieve the related coursemodule.
- if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $course->id)) {
- throw new moodle_exception('invalidcoursemodule');
- }
-
- // Ensure the coursemodule is set correctly.
- $PAGE->set_cm($cm, $course, $moodleoverflow);
-
- // Retrieve the other contexts.
- $modulecontext = context_module::instance($cm->id);
- $coursecontext = context_course::instance($course->id);
-
- // Check whether the user is allowed to post.
- if (!moodleoverflow_user_can_post($modulecontext, $parent)) {
-
- // Give the user the chance to enroll himself to the course.
- if (!isguestuser() && !is_enrolled($coursecontext)) {
- $SESSION->wantsurl = qualified_me();
- $SESSION->enrolcancel = get_local_referer(false);
- redirect(new moodle_url('/enrol/index.php',
- array('id' => $course->id, 'returnurl' => '/mod/moodleoverflow/view.php?m=' . $moodleoverflow->id)),
- get_string('youneedtoenrol'));
- }
-
- // Print the error message.
- throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
- }
-
- // Make sure the user can post here.
- if (!$cm->visible && !has_capability('moodle/course:viewhiddenactivities', $modulecontext)) {
- throw new moodle_exception('activityiscurrentlyhidden');
- }
-
- // Load the $post variable.
- $post = new stdClass();
- $post->course = $course->id;
- $post->moodleoverflow = $moodleoverflow->id;
- $post->discussion = $parent->discussion;
- $post->parent = $parent->id;
- $post->subject = $discussion->name;
- $post->userid = $USER->id;
- $post->message = '';
-
- // Append 'RE: ' to the discussions subject.
- $strre = get_string('re', 'moodleoverflow');
- if (!(substr($post->subject, 0, strlen($strre)) == $strre)) {
- $post->subject = $strre . ' ' . $post->subject;
- }
-
- // Unset where the user is coming from.
- // Allows to calculate the correct return url later.
- unset($SESSION->fromdiscussion);
-
-
-} else if (!empty($edit)) {
- // Third possibility: The user is editing his own post.
-
- // Check if the submitted post exists.
- if (!$post = moodleoverflow_get_post_full($edit)) {
- throw new moodle_exception('invalidpostid', 'moodleoverflow');
- }
-
- // Get the parent post of this post if it is not the starting post of the discussion.
- if ($post->parent) {
- if (!$parent = moodleoverflow_get_post_full($post->parent)) {
- throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
- }
- }
-
- // Check if the post refers to a valid discussion.
- if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $post->discussion))) {
- throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
- }
-
- // Check if the post refers to a valid moodleoverflow instance.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
-
- // Check if the post refers to a valid course.
- if (!$course = $DB->get_record('course', array('id' => $discussion->course))) {
- throw new moodle_exception('invalidcourseid');
- }
-
- // Retrieve the related coursemodule.
- if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $course->id)) {
- throw new moodle_exception('invalidcoursemodule');
- } else {
- $modulecontext = context_module::instance($cm->id);
- }
-
- // Set the pages context.
- $PAGE->set_cm($cm, $course, $moodleoverflow);
-
- // Check if the post can be edited.
- $beyondtime = ((time() - $post->created) > get_config('moodleoverflow', 'maxeditingtime'));
- $alreadyreviewed = review::should_post_be_reviewed($post, $moodleoverflow) && $post->reviewed;
- if (($beyondtime || $alreadyreviewed) && !has_capability('mod/moodleoverflow:editanypost', $modulecontext)) {
- throw new moodle_exception('maxtimehaspassed', 'moodleoverflow', '',
- format_time(get_config('moodleoverflow', 'maxeditingtime')));
- }
-
-
-
- // If the current user is not the one who posted this post.
- if ($post->userid <> $USER->id) {
-
- // Check if the current user has not the capability to edit any post.
- if (!has_capability('mod/moodleoverflow:editanypost', $modulecontext)) {
-
- // Display the error. Capabilities are missing.
- throw new moodle_exception('cannoteditposts', 'moodleoverflow');
- }
- }
-
- // Load the $post variable.
- $post->edit = $edit;
- $post->course = $course->id;
- $post->moodleoverflow = $moodleoverflow->id;
-
- // Unset where the user is coming from.
- // Allows to calculate the correct return url later.
- unset($SESSION->fromdiscussion);
-
-} else if (!empty($delete)) {
- // Fourth possibility: The user is deleting a post.
- // Check if the post is existing.
- if (!$post = moodleoverflow_get_post_full($delete)) {
- throw new moodle_exception('invalidpostid', 'moodleoverflow');
- }
-
- // Get the related discussion.
- if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $post->discussion))) {
- throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
- }
-
- // Get the related moodleoverflow instance.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoveflow');
- }
-
- // Get the related coursemodule.
- if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $moodleoverflow->course)) {
- throw new moodle_exception('invalidcoursemodule');
- }
-
- // Get the related course.
- if (!$course = $DB->get_record('course', array('id' => $moodleoverflow->course))) {
- throw new moodle_exception('invalidcourseid');
- }
-
- // Require a login and retrieve the modulecontext.
- require_login($course, false, $cm);
- $modulecontext = context_module::instance($cm->id);
-
- // Check some capabilities.
- $deleteownpost = has_capability('mod/moodleoverflow:deleteownpost', $modulecontext);
- $deleteanypost = has_capability('mod/moodleoverflow:deleteanypost', $modulecontext);
- if (!(($post->userid == $USER->id && $deleteownpost) || $deleteanypost)) {
- throw new moodle_exception('cannotdeletepost', 'moodleoverflow');
- }
-
- // Count all replies of this post.
- $replycount = moodleoverflow_count_replies($post, false);
-
- // Has the user confirmed the deletion?
- if (!empty($confirm) && confirm_sesskey()) {
-
- // Check if the user has the capability to delete the post.
- $timepassed = time() - $post->created;
- if (($timepassed > get_config('moodleoverflow', 'maxeditingtime')) && !$deleteanypost) {
- $url = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $post->discussion));
- throw new moodle_exception('cannotdeletepost', 'moodleoverflow', moodleoverflow_go_back_to($url));
- }
-
- // A normal user cannot delete his post if there are direct replies.
- if ($replycount && !$deleteanypost) {
- $url = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $post->discussion));
- throw new moodle_exception('couldnotdeletereplies', 'moodleoverflow', moodleoverflow_go_back_to($url));
- } else {
- // Delete the post.
-
- // The post is the starting post of a discussion. Delete the topic as well.
- if (!$post->parent) {
- moodleoverflow_delete_discussion($discussion, $course, $cm, $moodleoverflow);
-
- // Trigger the discussion deleted event.
- $params = array(
- 'objectid' => $discussion->id,
- 'context' => $modulecontext,
- );
-
- $event = \mod_moodleoverflow\event\discussion_deleted::create($params);
- $event->trigger();
-
- // Redirect the user back to start page of the moodleoverflow instance.
- redirect("view.php?m=$discussion->moodleoverflow");
- exit;
-
- } else if (moodleoverflow_delete_post($post, $deleteanypost, $cm, $moodleoverflow)) {
- // Delete a single post.
- // Redirect back to the discussion.
- $discussionurl = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $discussion->id));
- redirect(moodleoverflow_go_back_to($discussionurl));
- exit;
-
- } else {
- // Something went wrong.
- throw new moodle_exception('errorwhiledelete', 'moodleoverflow');
- }
- }
- } else {
- // Deletion needs to be confirmed.
-
- moodleoverflow_set_return();
- $PAGE->navbar->add(get_string('delete', 'moodleoverflow'));
- $PAGE->set_title($course->shortname);
- $PAGE->set_heading($course->fullname);
-
- // The page should not be large, only pages containing broad tables are usually.
- $PAGE->add_body_class('limitedwidth');
-
- // Check if there are replies for the post.
- if ($replycount) {
-
- // Check if the user has capabilities to delete more than one post.
- if (!$deleteanypost) {
- throw new moodle_exception('couldnotdeletereplies', 'moodleoverflow',
- moodleoverflow_go_back_to(new moodle_url('/mod/moodleoverflow/discussion.php',
- array('d' => $post->discussion, 'p' . $post->id))));
- }
-
- // Request a confirmation to delete the post.
- echo $OUTPUT->header();
- echo $OUTPUT->confirm(get_string("deletesureplural", "moodleoverflow", $replycount + 1),
- "post.php?delete=$delete&confirm=$delete", $CFG->wwwroot . '/mod/moodleoverflow/discussion.php?d=' .
- $post->discussion . '#p' . $post->id);
-
- } else {
- // Delete a single post.
-
- // Print a confirmation message.
- echo $OUTPUT->header();
- echo $OUTPUT->confirm(get_string("deletesure", "moodleoverflow", $replycount),
- "post.php?delete=$delete&confirm=$delete",
- $CFG->wwwroot . '/mod/moodleoverflow/discussion.php?d=' . $post->discussion . '#p' . $post->id);
- }
- }
- echo $OUTPUT->footer();
- exit;
-
-} else {
- // Last posibility: the action is not known.
-
- throw new moodle_exception('unknownaction');
-}
-
-// Second step: The user must be logged on properly. Must be enrolled to the course as well.
-require_login($course, false, $cm);
-
-// Get the contexts.
-$modulecontext = context_module::instance($cm->id);
-$coursecontext = context_course::instance($course->id);
-
-// Get the subject.
-if ($edit) {
- $subject = $discussion->name;
-} else if ($reply) {
- $subject = $post->subject;
-} else if ($moodleoverflow) {
- $subject = $post->subject;
-}
-
-// Get attachments.
-$draftitemid = file_get_submitted_draft_itemid('attachments');
-file_prepare_draft_area($draftitemid,
- $modulecontext->id,
- 'mod_moodleoverflow',
- 'attachment',
- empty($post->id) ? null : $post->id,
- mod_moodleoverflow_post_form::attachment_options($moodleoverflow));
-
-// Prepare the form.
-$formarray = array(
- 'course' => $course,
- 'cm' => $cm,
- 'coursecontext' => $coursecontext,
- 'modulecontext' => $modulecontext,
- 'moodleoverflow' => $moodleoverflow,
- 'post' => $post,
- 'edit' => $edit,
-);
-$mformpost = new mod_moodleoverflow_post_form('post.php', $formarray, 'post', '', array('id' => 'mformmoodleoverflow'));
-
-// The current user is not the original author.
-// Append the message to the end of the message.
-if ($USER->id != $post->userid) {
-
- // Create a temporary object.
- $data = new stdClass();
- $data->date = userdate($post->modified);
- $post->messageformat = editors_get_preferred_format();
-
- // Append the message depending on the messages format.
- if ($post->messageformat == FORMAT_HTML) {
- $data->name = '' . fullname($USER) . '';
- $post->message .= '(' . get_string('editedby', 'moodleoverflow', $data) . ')
';
- } else {
- $data->name = fullname($USER);
- $post->message .= "\n\n(" . get_string('editedby', 'moodleoverflow', $data) . ')';
- }
-
- // Delete the temporary object.
- unset($data);
-}
-
-// Define the heading for the form.
-$formheading = '';
-if (!empty($parent)) {
- $heading = get_string('yourreply', 'moodleoverflow');
- $formheading = get_string('reply', 'moodleoverflow');
-} else {
- $heading = get_string('yournewtopic', 'moodleoverflow');
-}
-
-// Get the original post.
-$postid = empty($post->id) ? null : $post->id;
-$postmessage = empty($post->message) ? null : $post->message;
-
-// Set data for the form.
-// TODO Refactor.
-$param1 = (isset($discussion->id) ? array($discussion->id) : array());
-$param2 = (isset($post->format) ? array('format' => $post->format) : array());
-$param3 = (isset($discussion->timestart) ? array('timestart' => $discussion->timestart) : array());
-$param4 = (isset($discussion->timeend) ? array('timeend' => $discussion->timeend) : array());
-$param5 = (isset($discussion->id) ? array('discussion' => $discussion->id) : array());
-$mformpost->set_data(array(
- 'attachments' => $draftitemid,
- 'general' => $heading,
- 'subject' => $subject,
- 'message' => array(
- 'text' => $postmessage,
- 'format' => editors_get_preferred_format(),
- 'itemid' => $postid,
- ),
- 'userid' => $post->userid,
- 'parent' => $post->parent,
- 'discussion' => $post->discussion,
- 'course' => $course->id
- ) + $pageparams + $param1 + $param2 + $param3 + $param4 + $param5);
-
-// Is it canceled?
-if ($mformpost->is_cancelled()) {
-
- // Redirect the user back.
- if (!isset($discussion->id)) {
- redirect(new moodle_url('/mod/moodleoverflow/view.php', array('m' => $moodleoverflow->id)));
- } else {
- redirect(new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $discussion->id)));
- }
-
- // Cancel.
- exit();
-}
-
-// Is it submitted?
-if ($fromform = $mformpost->get_data()) {
-
- // Redirect url in case of occuring errors.
- if (empty($SESSION->fromurl)) {
- $errordestination = "$CFG->wwwroot/mod/moodleoverflow/view.php?m=$moodleoverflow->id";
- } else {
- $errordestination = $SESSION->fromurl;
- }
-
- // Format the submitted data.
- $fromform->messageformat = $fromform->message['format'];
- $fromform->message = $fromform->message['text'];
- $fromform->messagetrust = trusttext_trusted($modulecontext);
-
- // If we are updating a post.
- if ($fromform->edit) {
-
- // Initiate some variables.
- unset($fromform->groupid);
- $fromform->id = $fromform->edit;
- $message = '';
-
- // The FORUM-Plugin had an bug: https://tracker.moodle.org/browse/MDL-4314
- // This is a fix for it.
- if (!$realpost = $DB->get_record('moodleoverflow_posts', array('id' => $fromform->id))) {
- $realpost = new stdClass();
- $realpost->userid = -1;
- }
-
- // Check the capabilities of the user.
- // He may proceed if he can edit any post or if he has the startnewdiscussion
- // capability or the capability to reply and is editing his own post.
- $editanypost = has_capability('mod/moodleoverflow:editanypost', $modulecontext);
- $replypost = has_capability('mod/moodleoverflow:replypost', $modulecontext);
- $startdiscussion = has_capability('mod/moodleoverflow:startdiscussion', $modulecontext);
- $ownpost = ($realpost->userid == $USER->id);
- if (!(($ownpost && ($replypost || $startdiscussion)) || $editanypost)) {
- throw new moodle_exception('cannotupdatepost', 'moodleoverflow');
- }
-
- // Update the post or print an error message.
- $updatepost = $fromform;
- $updatepost->moodleoverflow = $moodleoverflow->id;
- if (!moodleoverflow_update_post($updatepost, $mformpost)) {
- throw new moodle_exception('couldnotupdate', 'moodleoverflow', $errordestination);
- }
-
- // Create a success-message.
- if ($realpost->userid == $USER->id) {
- $message .= get_string('postupdated', 'moodleoverflow');
- } else {
- if (\mod_moodleoverflow\anonymous::is_post_anonymous($discussion, $moodleoverflow, $realpost->userid)) {
- $name = get_string('anonymous', 'moodleoverflow');
- } else {
- $realuser = $DB->get_record('user', array('id' => $realpost->userid));
- $name = fullname($realuser);
- }
- $message .= get_string('editedpostupdated', 'moodleoverflow', $name);
- }
-
- // Create a link to go back to the discussion.
- $discussionurl = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $discussion->id), 'p' . $fromform->id);
-
- // Set some parameters.
- $params = array(
- 'context' => $modulecontext,
- 'objectid' => $fromform->id,
- 'other' => array(
- 'discussionid' => $discussion->id,
- 'moodleoverflowid' => $moodleoverflow->id,
- ));
-
- // If the editing user is not the original author, add the original author to the params.
- if ($realpost->userid != $USER->id) {
- $params['relateduserid'] = $realpost->userid;
- }
-
- // Trigger post updated event.
- $event = \mod_moodleoverflow\event\post_updated::create($params);
- $event->trigger();
-
- // Redirect back to the discussion.
- redirect(moodleoverflow_go_back_to($discussionurl), $message, null, \core\output\notification::NOTIFY_SUCCESS);
-
- // Cancel.
- exit;
-
- } else if ($fromform->discussion) {
- // Add a new post to an existing discussion.
-
- // Set some basic variables.
- unset($fromform->groupid);
- $message = '';
- $addpost = $fromform;
- $addpost->moodleoverflow = $moodleoverflow->id;
-
- // Create the new post.
- if ($fromform->id = moodleoverflow_add_new_post($addpost)) {
-
- // Subscribe to this thread.
- $discussion = new \stdClass();
- $discussion->id = $fromform->discussion;
- $discussion->moodleoverflow = $moodleoverflow->id;
- \mod_moodleoverflow\subscriptions::moodleoverflow_post_subscription($fromform,
- $moodleoverflow, $discussion, $modulecontext);
-
- // Print a success-message.
- $message .= '' . get_string("postaddedsuccess", "moodleoverflow") . '
';
- $message .= '' . get_string("postaddedtimeleft", "moodleoverflow",
- format_time(get_config('moodleoverflow', 'maxeditingtime'))) . '
';
-
- // Set the URL that links back to the discussion.
- $link = '/mod/moodleoverflow/discussion.php';
- $discussionurl = new moodle_url($link, array('d' => $discussion->id), 'p' . $fromform->id);
-
- // Trigger post created event.
- $params = array(
- 'context' => $modulecontext,
- 'objectid' => $fromform->id,
- 'other' => array(
- 'discussionid' => $discussion->id,
- 'moodleoverflowid' => $moodleoverflow->id,
- ));
- $event = \mod_moodleoverflow\event\post_created::create($params);
- $event->trigger();
- redirect(
- moodleoverflow_go_back_to($discussionurl),
- $message,
- \core\output\notification::NOTIFY_SUCCESS
- );
-
- // Print an error if the answer could not be added.
- } else {
- throw new moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
- }
-
- // The post has been added.
- exit;
-
- } else {
- // Add a new discussion.
-
- // The location to redirect the user after successfully posting.
- $redirectto = new moodle_url('view.php', array('m' => $fromform->moodleoverflow));
-
- $discussion = $fromform;
- $discussion->name = $fromform->subject;
-
- // Check if the user is allowed to post here.
- if (!moodleoverflow_user_can_post_discussion($moodleoverflow)) {
- throw new moodle_exception('cannotcreatediscussion', 'moodleoverflow');
- }
-
- // Check if the creation of the new discussion failed.
- if (!$discussion->id = moodleoverflow_add_discussion($discussion, $modulecontext)) {
-
- throw new moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
-
- } else { // The creation of the new discussion was successful.
-
- $params = array(
- 'context' => $modulecontext,
- 'objectid' => $discussion->id,
- 'other' => array(
- 'moodleoverflowid' => $moodleoverflow->id,
- )
- );
-
- $message = '' . get_string("postaddedsuccess", "moodleoverflow") . '
';
-
- // Trigger the discussion created event.
- $params = array(
- 'context' => $modulecontext,
- 'objectid' => $discussion->id,
- );
- $event = \mod_moodleoverflow\event\discussion_created::create($params);
- $event->trigger();
- // Subscribe to this thread.
- $discussion->moodleoverflow = $moodleoverflow->id;
- \mod_moodleoverflow\subscriptions::moodleoverflow_post_subscription($fromform,
- $moodleoverflow, $discussion, $modulecontext);
- }
-
- // Redirect back to te discussion.
- redirect(moodleoverflow_go_back_to($redirectto->out()), $message, null, \core\output\notification::NOTIFY_SUCCESS);
-
- // Do not continue.
- exit;
- }
-}
-
-// If the script gets to this point, nothing has been submitted.
-// We have to display the form.
-// $course and $moodleoverflow are defined.
-// $discussion is only used for replying and editing.
-
-// Define the message to be displayed above the form.
-$toppost = new stdClass();
-$toppost->subject = get_string("addanewdiscussion", "moodleoverflow");
-
-// Initiate the page.
-$PAGE->set_title("$course->shortname: $moodleoverflow->name " . format_string($toppost->subject));
-$PAGE->set_heading($course->fullname);
-
-// The page should not be large, only pages containing broad tables are usually.
-$PAGE->add_body_class('limitedwidth');
-
-// Display the header.
-echo $OUTPUT->header();
-
-// Display the form.
-$mformpost->display();
-
-// Display the footer.
-echo $OUTPUT->footer();
diff --git a/tests/post_test.php b/tests/post_test.php
index e5c1d0e55d..e41ade0428 100644
--- a/tests/post_test.php
+++ b/tests/post_test.php
@@ -27,6 +27,7 @@
require_once(__DIR__ . '/../locallib.php');
/**
+ * TODO: THIS TEST CLASS IS USELESS, needs to be refactored to the new way of working with posts.
* PHP Unit test for post related functions in the locallib.
*
* @package mod_moodleoverflow
@@ -34,7 +35,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class post_test extends \advanced_testcase {
-
/** @var \stdClass test course */
private $course;
From 1ffeb5b6f8e786cf5c50d09fd91c04f3e909fff5 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 17 Aug 2023 22:39:45 +0200
Subject: [PATCH 25/56] new post_test class
---
classes/post/post.php | 4 +-
tests/post_test.php | 144 ++++++++++++++++++++++++++++--------------
2 files changed, 98 insertions(+), 50 deletions(-)
diff --git a/classes/post/post.php b/classes/post/post.php
index f1255caeb2..7aaa0f97b5 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -361,9 +361,9 @@ public function moodleoverflow_delete_post($deletechildren) {
/**
* Edits the message from this instance.
- * @param timestamp $time The time the post was modified (given from the discussion class).
+ * @param int $time The time the post was modified (given from the discussion class).
* @param string $postmessage The new message
- * @param object $messageformat
+ * @param int $messageformat
* @param object $formattachments Information about attachments from the post_form
*
* @return true if the post has been edited successfully
diff --git a/tests/post_test.php b/tests/post_test.php
index e41ade0428..9d7d7fc597 100644
--- a/tests/post_test.php
+++ b/tests/post_test.php
@@ -15,7 +15,7 @@
// along with Moodle. If not, see .
/**
- * PHP Unit test for post related functions in the locallib.
+ * PHP Unit Tests for the Post class.
*
* @package mod_moodleoverflow
* @copyright 2023 Tamaro Walter
@@ -23,43 +23,48 @@
*/
namespace mod_moodleoverflow;
+// Use the post class.
+use mod_moodleoverflow\post\post;
+use mod_moodleoverflow\discussion\discussion;
+
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__ . '/../locallib.php');
/**
- * TODO: THIS TEST CLASS IS USELESS, needs to be refactored to the new way of working with posts.
- * PHP Unit test for post related functions in the locallib.
+ *
+ * Tests if the functions from the post class are working correctly.
*
* @package mod_moodleoverflow
* @copyright 2023 Tamaro Walter
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @covers \mod_moodleoverflow\post\post
*/
class post_test extends \advanced_testcase {
+
/** @var \stdClass test course */
private $course;
/** @var \stdClass coursemodule */
private $coursemodule;
+ /** @var \stdClass modulecontext */
+ private $modulecontext;
+
/** @var \stdClass test moodleoverflow */
private $moodleoverflow;
/** @var \stdClass test teacher */
private $teacher;
- /** @var \stdClass a discussion */
+ /** @var discussion a discussion */
private $discussion;
- /** @var \stdClass a post */
+ /** @var post a post */
private $post;
- /** @var \stdClass an attachment */
- private $attachment;
-
/** @var \mod_moodleoverflow_generator $generator */
private $generator;
-
public function setUp(): void {
$this->resetAfterTest();
$this->helper_course_set_up();
@@ -67,46 +72,77 @@ public function setUp(): void {
public function tearDown(): void {
// Clear all caches.
- \mod_moodleoverflow\subscriptions::reset_moodleoverflow_cache();
- \mod_moodleoverflow\subscriptions::reset_discussion_cache();
+ subscriptions::reset_moodleoverflow_cache();
+ subscriptions::reset_discussion_cache();
}
/**
- * Test if a post and its attachment are deleted successfully.
- * @covers ::moodleoverflow_delete_post
+ * Test, if a post is being created correctly
*/
- public function test_moodleoverflow_delete_post() {
+ public function test_create_post() {
global $DB;
+ // Build a new post object.
+ $time = time();
+ $message = 'a unique message';
+ $post = post::construct_without_id($this->discussion->get_id(), $this->post->get_id(), $this->teacher->id, $time,
+ $time, $message, 0, '', 0, 1, null);
+ $post->moodleoverflow_add_new_post();
+
+ // The post should be in the database.
+ $postscount = count($DB->get_records('moodleoverflow_posts', array('id' => $post->get_id())));
+ $this->assertEquals(1, $postscount);
+ }
- // The attachment should exist.
- $numberofattachments = count($DB->get_records('files', array('itemid' => $this->post->id)));
- $this->assertEquals(2, $numberofattachments);
+ /**
+ * Test, if the message of a post can be edited successfully.
+ */
+ public function test_edit_post() {
+ global $DB;
- // Delete the post from the teacher with its attachment.
- moodleoverflow_delete_post($this->post, false, $this->coursemodule, $this->moodleoverflow);
+ // The post and the attachment should exist.
+ $numberofattachments = count($DB->get_records('files', array('itemid' => $this->post->get_id())));
+ $this->assertEquals(2, $numberofattachments); // One Attachment is saved twice in 'files'.
+ $post = count($DB->get_records('moodleoverflow_posts', array('id' => $this->post->get_id())));
+ $this->assertEquals(1, $post);
- // Now try to get the attachment.
- $numberofattachments = count($DB->get_records('files', array('itemid' => $this->post->id)));
+ // Gather important parameters.
+ $message = 'a new message';
- $this->assertEquals(0, $numberofattachments);
+ $time = time();
+ // Update the post.
+ $this->post->moodleoverflow_edit_post($time, $message, $this->post->messageformat, $this->post->formattachments);
+
+ // The message and modified time should be changed.
+ $post = $DB->get_record('moodleoverflow_posts', array('id' => $this->post->get_id()));
+ $this->assertEquals($message, $post->message);
+ $this->assertEquals($time, $post->modified);
}
/**
- * Test if a post and its attachment are deleted successfully.
- * @covers ::moodleoverflow_delete_discussion
+ * Test, if a post and its attachment are deleted successfully.
+ * @covers ::moodleoverflow_delete_post
*/
- public function test_moodleoverflow_delete_discussion() {
+ public function test_delete_post() {
global $DB;
- $numberofattachments = count($DB->get_records('files', array('itemid' => $this->post->id, 'filearea' => 'attachment')));
- $this->assertEquals(2, $numberofattachments);
+ // The post and the attachment should exist.
+ $numberofattachments = count($DB->get_records('files', array('itemid' => $this->post->get_id())));
+ $this->assertEquals(2, $numberofattachments); // One Attachment is saved twice in 'files'.
+ $post = count($DB->get_records('moodleoverflow_posts', array('id' => $this->post->get_id())));
+ $this->assertEquals(1, $post);
- // Delete the post from the teacher with its attachment.
- moodleoverflow_delete_discussion($this->discussion[0], $this->course, $this->coursemodule, $this->moodleoverflow);
+ // Delete the post with its attachment.
+ // Save the post id as it gets unsettled by the post object after being deleted.
+ $postid = $this->post->get_id();
+ $this->post->moodleoverflow_delete_post(true);
- // Now try to get the attachment.
- $numberofattachments = count($DB->get_records('files', array('itemid' => $this->post->id)));
+ // Now try to get the attachment, it should be deleted from the database.
+ $numberofattachments = count($DB->get_records('files', array('itemid' => $postid)));
$this->assertEquals(0, $numberofattachments);
+
+ // Try to find the post, it should be deleted.
+ $post = count($DB->get_records('moodleoverflow_posts', array('id' => $postid)));
+ $this->assertEquals(0, $post);
}
/**
@@ -121,6 +157,7 @@ private function helper_course_set_up() {
$location = array('course' => $this->course->id);
$this->moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $location);
$this->coursemodule = get_coursemodule_from_instance('moodleoverflow', $this->moodleoverflow->id);
+ $this->modulecontext = \context_module::instance($this->coursemodule->id);
// Create a teacher.
$this->teacher = $this->getDataGenerator()->create_user(array('firstname' => 'Tamaro', 'lastname' => 'Walter'));
@@ -128,29 +165,40 @@ private function helper_course_set_up() {
// Create a discussion started from the teacher.
$this->generator = $this->getDataGenerator()->get_plugin_generator('mod_moodleoverflow');
- $this->discussion = $this->generator->post_to_forum($this->moodleoverflow, $this->teacher);
- $this->post = $DB->get_record('moodleoverflow_posts', array('id' => $this->discussion[0]->firstpost), '*');
+ $discussion = $this->generator->post_to_forum($this->moodleoverflow, $this->teacher);
+ $discussionrecord = $DB->get_record('moodleoverflow_discussions', array('id' => $discussion[0]->id));
+ $this->discussion = discussion::from_record($discussionrecord);
+
+ // Get a temporary post from the DB to add the attachment.
+ $temppost = $DB->get_record('moodleoverflow_posts', array('id' => $this->discussion->get_firstpostid()));
// Create an attachment by inserting it directly in the database and update the post record.
+ $this->add_new_attachment($temppost, $this->modulecontext, 'world.txt', 'hello world');
- $modulecontext = \context_module::instance($this->coursemodule->id);
+ // Build the real post object now. That is the object that will be tested.
+ $postrecord = $DB->get_record('moodleoverflow_posts', array('id' => $this->discussion->get_firstpostid()));
+ $this->post = post::from_record($postrecord);
+ }
+ /**
+ * @param object $object // The object that will have the attachment
+ * @param $modulecontext
+ * @param string $filename
+ * @param $filecontent
+ * @return void
+ */
+ private function add_new_attachment($object, $modulecontext, $filename, $filecontent) {
+ global $DB;
$fileinfo = [
- 'contextid' => $modulecontext->id, // ID of the context.
- 'component' => 'mod_moodleoverflow', // Your component name.
- 'filearea' => 'attachment', // Usually = table name.
- 'itemid' => $this->post->id, // Usually = ID of row in table.
- 'filepath' => '/', // Any path beginning and ending in /.
- 'filename' => 'NH.jpg', // Any filename.
+ 'contextid' => $modulecontext->id, // ID of the context.
+ 'component' => 'mod_moodleoverflow', // Your component name.
+ 'filearea' => 'attachment', // Usually = table name.
+ 'itemid' => $object->id, // Usually = ID of the item (e.g. the post.
+ 'filepath' => '/', // Any path beginning and ending in /.
+ 'filename' => $filename, // Any filename.
];
-
$fs = get_file_storage();
-
- // Create a new file containing the text 'hello world'.
- $fs->create_file_from_string($fileinfo, 'hello world');
-
- $this->post->attachment = 1;
- $DB->update_record('moodleoverflow_posts', $this->post);
-
+ $fs->create_file_from_string($fileinfo, $filecontent); // Creates a new file containing the text 'hello world'.
+ $DB->update_record('moodleoverflow_posts', $object);
}
}
From 104a8dc86d3a46776e0b22a0d90bc82111fd0704 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Fri, 18 Aug 2023 14:26:25 +0200
Subject: [PATCH 26/56] new phpunit tests for discussion class
---
classes/post/post.php | 4 +-
tests/discussion_test.php | 162 ++++++++++++++++++++++++++++++++++++++
2 files changed, 164 insertions(+), 2 deletions(-)
create mode 100644 tests/discussion_test.php
diff --git a/classes/post/post.php b/classes/post/post.php
index 7aaa0f97b5..efe83276e6 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -574,7 +574,7 @@ public function get_coursemodule() {
/**
* Returns the parent post
- * @return object $post
+ * @return object|false $post|false
*/
public function moodleoverflow_get_parentpost() {
global $DB;
@@ -596,7 +596,7 @@ public function moodleoverflow_get_parentpost() {
/**
* Returns children posts (answers) as DB-records.
*
- * @return object children/answer posts.
+ * @return array|false children/answer posts.
*/
public function moodleoverflow_get_childposts() {
global $DB;
diff --git a/tests/discussion_test.php b/tests/discussion_test.php
new file mode 100644
index 0000000000..a23af66642
--- /dev/null
+++ b/tests/discussion_test.php
@@ -0,0 +1,162 @@
+.
+
+/**
+ * PHP Unit Tests for the Discussion class.
+ * @package mod_moodleoverflow
+ * @copyright 2023 Tamaro Walter
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace mod_moodleoverflow;
+
+use mod_moodleoverflow\post\post;
+use mod_moodleoverflow\discussion\discussion;
+
+/**
+ * Tests if the functions from the discussion class are working correctly.
+ * As the discussion class works as an administrator of the post class, most of the testcases are already realized in the
+ * post_test.php file.
+ * @package mod_moodleoverflow
+ * @copyright 2023 Tamaro Walter
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @covers \mod_moodleoverflow\discussion\discussion
+ */
+class discussion_test extends \advanced_testcase {
+
+ /** @var \stdClass test course */
+ private $course;
+
+ /** @var \stdClass coursemodule */
+ private $coursemodule;
+
+ /** @var \stdClass modulecontext */
+ private $modulecontext;
+
+ /** @var \stdClass test moodleoverflow */
+ private $moodleoverflow;
+
+ /** @var \stdClass test teacher */
+ private $teacher;
+
+ /** @var discussion a discussion */
+ private $discussion;
+
+ /** @var post the post from the discussion */
+ private $post;
+
+ /** @var \mod_moodleoverflow_generator $generator */
+ private $generator;
+
+ public function setUp(): void {
+ $this->resetAfterTest();
+ $this->helper_course_set_up();
+ }
+
+ public function tearDown(): void {
+ // Clear all caches.
+ subscriptions::reset_moodleoverflow_cache();
+ subscriptions::reset_discussion_cache();
+ }
+
+ /**
+ * Test, if a discussion is being created correctly
+ */
+ public function test_create_discussion() {
+ global $DB;
+
+ // Build a prepost object with important information.
+ $time = time();
+ $prepost = new \stdClass();
+ $prepost->userid = $this->teacher->id;
+ $prepost->timenow = $time;
+ $prepost->message = 'a message';
+ $prepost->messageformat = 1;
+ $prepost->reviewed = 0;
+ $prepost->formattachments = '';
+ $prepost->modulecontext = $this->modulecontext;
+
+ // Build a new discussion object.
+ $discussion = discussion::construct_without_id($this->course->id, $this->moodleoverflow->id, 'Discussion Topic',
+ 0, $this->teacher->id, $time, $time, $this->teacher->id);
+ $discussionid = $discussion->moodleoverflow_add_discussion($prepost);
+ $posts = $discussion->moodleoverflow_get_discussion_posts();
+ $post = $posts[$discussion->get_firstpostid()];
+
+ // The discussion and the firstpost should be in the DB.
+ $dbdiscussion = $DB->get_record('moodleoverflow_discussions', array('id' => $discussion->get_id()));
+ $this->assertEquals($dbdiscussion->id, $discussionid);
+ $this->assertEquals('Discussion Topic', $dbdiscussion->name);
+
+ $dbpost = $DB->get_record('moodleoverflow_posts', array('id' => $discussion->get_firstpostid()));
+ $this->assertEquals($dbpost->id, $post->get_id());
+ $this->assertEquals($dbpost->discussion, $post->get_discussionid());
+ $this->assertEquals($prepost->message, $dbpost->message);
+ }
+
+ /**
+ * Test, if a post and its attachment are deleted successfully.
+ * @covers ::moodleoverflow_delete_post
+ */
+ public function test_delete_discussion() {
+ global $DB;
+ // Build the prepost object with necessary information.
+ $prepost = new \stdClass();
+ $prepost->modulecontext = $this->modulecontext;
+
+ // Delete the discussion, but save the IDs first.
+ $discussionid = $this->discussion->get_id();
+ $postid = $this->discussion->get_firstpostid();
+ $this->discussion->moodleoverflow_delete_discussion($prepost);
+
+ // The discussion and the post should not be in the DB anymore.
+ $discussion = count($DB->get_records('moodleoverflow_discussions', array('id' => $discussionid)));
+ $this->assertEquals(0, $discussion);
+
+ $post = count($DB->get_records('moodleoverflow_posts', array('id' => $postid)));
+ $this->assertEquals(0, $post);
+ }
+
+ /**
+ * This function creates:
+ * - a course with a moodleoverflow
+ * - a new discussion with a post. The post has an attachment.
+ */
+ private function helper_course_set_up() {
+ global $DB;
+ // Create a new course with a moodleoverflow forum.
+ $this->course = $this->getDataGenerator()->create_course();
+ $location = array('course' => $this->course->id);
+ $this->moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $location);
+ $this->coursemodule = get_coursemodule_from_instance('moodleoverflow', $this->moodleoverflow->id);
+ $this->modulecontext = \context_module::instance($this->coursemodule->id);
+
+ // Create a teacher.
+ $this->teacher = $this->getDataGenerator()->create_user(array('firstname' => 'Tamaro', 'lastname' => 'Walter'));
+ $this->getDataGenerator()->enrol_user($this->teacher->id, $this->course->id, 'student');
+
+ // Create a discussion started from the teacher.
+ $this->generator = $this->getDataGenerator()->get_plugin_generator('mod_moodleoverflow');
+ $discussion = $this->generator->post_to_forum($this->moodleoverflow, $this->teacher);
+
+ // Get the discussion and post object.
+ $discussionrecord = $DB->get_record('moodleoverflow_discussions', array('id' => $discussion[0]->id));
+ $postrecord = $DB->get_record('moodleoverflow_posts', array('id' => $discussion[1]->id));
+
+ $this->discussion = discussion::from_record($discussionrecord);
+ $this->post = post::from_record($postrecord);
+ }
+}
From 95b665c0abb08a53d067d2b1fba793ee547fbc68 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 7 Sep 2023 10:51:20 +0200
Subject: [PATCH 27/56] behat fails in older versions fixed
---
classes/post/post.php | 3 ++-
locallib.php | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/classes/post/post.php b/classes/post/post.php
index efe83276e6..e9e2fa2f18 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -392,7 +392,8 @@ public function moodleoverflow_edit_post($time, $postmessage, $messageformat, $f
}
/**
- * // TODO: RETHINK THIS FUNCTION.
+ * // NOTE: This function replaces the get_post_full() function and is not used until the print and print-related function for
+ * // printing the discussion and a post are adapted to the new post and discussion class.
* Gets a post with all info ready for moodleoverflow_print_post.
* Most of these joins are just to get the forum id.
*
diff --git a/locallib.php b/locallib.php
index 80693d9eb4..c70935b1a2 100644
--- a/locallib.php
+++ b/locallib.php
@@ -655,7 +655,7 @@ function moodleoverflow_get_post_full($postid) {
if ($CFG->branch >= 311) {
$allnames = \core_user\fields::for_name()->get_sql('u', false, '', '', false)->selects;
} else {
- $allnames = get_all_user_name_fields(true, 'u');
+ $allnames = implode(', ', fields::get_name_fields());
}
$sql = "SELECT p.*, d.moodleoverflow, $allnames, u.email, u.picture, u.imagealt
FROM {moodleoverflow_posts} p
From e5131ea8086add0af8d5c3ead469aa66517943b3 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 7 Sep 2023 11:18:47 +0200
Subject: [PATCH 28/56] capability fixed in post_control
---
classes/post/post.php | 2 +-
classes/post/post_control.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/classes/post/post.php b/classes/post/post.php
index e9e2fa2f18..0046967637 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -392,7 +392,7 @@ public function moodleoverflow_edit_post($time, $postmessage, $messageformat, $f
}
/**
- * // NOTE: This function replaces the get_post_full() function and is not used until the print and print-related function for
+ * // NOTE: This function replaces the get_post_full() function but is not used until the print and print-related function for
* // printing the discussion and a post are adapted to the new post and discussion class.
* Gets a post with all info ready for moodleoverflow_print_post.
* Most of these joins are just to get the forum id.
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index 75e9de77e0..994baf2630 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -806,7 +806,7 @@ private function check_user_can_edit_post() {
$replypost = has_capability('mod/moodleoverflow:replypost', $this->info->modulecontext);
$startdiscussion = has_capability('mod/moodleoverflow:startdiscussion', $this->info->modulecontext);
$ownpost = ($this->prepost->userid == $USER->id);
- if (!(($ownpost && ($replypost || $startdiscussion)) || $editanypost)) {
+ if ((($ownpost && ($replypost || $startdiscussion)) || $editanypost)) {
throw new \moodle_exception('cannotupdatepost', 'moodleoverflow');
}
return true;
From 8ffc2f0fb8d8301d47c116ffaa2ea541bbb9ace5 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 7 Sep 2023 11:46:56 +0200
Subject: [PATCH 29/56] replace html with html_writer
---
classes/post/post_control.php | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index 994baf2630..f4602a4a19 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -390,7 +390,7 @@ private function execute_create($form, $errordestination) {
}
// The creation was successful.
- $redirectmessage = '' . get_string("postaddedsuccess", "moodleoverflow") . '
';
+ $redirectmessage = \html_writer::tag('p', get_string("postaddedsuccess", "moodleoverflow"));
// Trigger the discussion created event.
$params = array( 'context' => $this->info->modulecontext, 'objectid' => $discussion->get_id());
@@ -427,9 +427,9 @@ private function execute_reply($form, $errordestination) {
}
// The creation was successful.
- $redirectmessage = '' . get_string("postaddedsuccess", "moodleoverflow") . '
';
- $redirectmessage .= '' . get_string("postaddedtimeleft", "moodleoverflow",
- format_time(get_config('moodleoverflow', 'maxeditingtime'))) . '
';
+ $redirectmessage = \html_writer::tag('p', get_string("postaddedsuccess", "moodleoverflow"));
+ $redirectmessage .= \html_writer::tag('p', get_string("postaddedtimeleft", "moodleoverflow",
+ format_time(get_config('moodleoverflow', 'maxeditingtime'))));
// Trigger the post created event.
$params = array('context' => $this->info->modulecontext, 'objectid' => $newpostid,
@@ -540,7 +540,6 @@ public function confirm_delete() {
/**
*
- * TODO: use html_writer:: instead of writing pure html code.
* Builds and returns a post_form object where the users enters/edits the message and attachments of the post.
* @param array $pageparams An object that the post.php created.
* @return object a mod_moodleoverflow_post_form object.
@@ -572,10 +571,10 @@ public function build_postform($pageparams) {
$data->date = userdate(time());
$this->prepost->messageformat = editors_get_preferred_format();
if ($this->prepost->messageformat == FORMAT_HTML) {
- $data->name = '' . fullname($USER) . '';
- $this->prepost->message .= '(' . get_string('editedby', 'moodleoverflow', $data) .
- ')
';
+ $data->name = \html_writer::tag('a', $CFG->wwwroot . '/user/view.php?id' . $USER->id .
+ '&course=' . $this->prepost->courseid . '">' . fullname($USER));
+ $this->prepost->message .= \html_writer::tag('p', \html_writer::tag('span',
+ get_string('editedby', 'moodleoverflow', $data),array("class" => "edited") ));
} else {
$data->name = fullname($USER);
$this->prepost->message .= "\n\n(" . get_string('editedby', 'moodleoverflow', $data) . ')';
@@ -806,7 +805,7 @@ private function check_user_can_edit_post() {
$replypost = has_capability('mod/moodleoverflow:replypost', $this->info->modulecontext);
$startdiscussion = has_capability('mod/moodleoverflow:startdiscussion', $this->info->modulecontext);
$ownpost = ($this->prepost->userid == $USER->id);
- if ((($ownpost && ($replypost || $startdiscussion)) || $editanypost)) {
+ if (!(($ownpost && ($replypost || $startdiscussion)) || $editanypost)) {
throw new \moodle_exception('cannotupdatepost', 'moodleoverflow');
}
return true;
@@ -815,7 +814,7 @@ private function check_user_can_edit_post() {
/**
* Checks if a user can edit a post.
* @return true
- * @thorws moodle_exception
+ * @throws moodle_exception
*/
private function check_user_can_delete_post() {
global $USER;
From ac6167937a080243891fcbfbc6eec96a462e6d77 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 7 Sep 2023 12:03:58 +0200
Subject: [PATCH 30/56] edit a discussion subject fixed
---
classes/post/post_control.php | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index f4602a4a19..9106fa9a01 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -458,6 +458,11 @@ private function execute_edit($form, $errordestination) {
// Check if the user has the capability to edit his post.
$this->check_user_can_edit_post();
+ // If the post that is being edited is the parent post, the subject can be edited too.
+ if ($this->prepost->parentid == 0) {
+ $this->prepost->subject = $form->subject;
+ }
+
// Update the post.
if (!$this->info->discussion->moodleoverflow_edit_post_from_discussion($this->prepost)) {
throw new \moodle_exception('couldnotupdate', 'moodleoverflow', $errordestination);
From aedb836d04406d2fb081ac750412f8b71e709c37 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 7 Sep 2023 12:08:30 +0200
Subject: [PATCH 31/56] moodlechecker fixes
---
classes/post/post_control.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index 9106fa9a01..45ed8e1aed 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -579,7 +579,7 @@ public function build_postform($pageparams) {
$data->name = \html_writer::tag('a', $CFG->wwwroot . '/user/view.php?id' . $USER->id .
'&course=' . $this->prepost->courseid . '">' . fullname($USER));
$this->prepost->message .= \html_writer::tag('p', \html_writer::tag('span',
- get_string('editedby', 'moodleoverflow', $data),array("class" => "edited") ));
+ get_string('editedby', 'moodleoverflow', $data), array("class" => "edited")));
} else {
$data->name = fullname($USER);
$this->prepost->message .= "\n\n(" . get_string('editedby', 'moodleoverflow', $data) . ')';
From 1c7c208ed8134d5d5dba32eff1e612440d595793 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 7 Sep 2023 12:25:27 +0200
Subject: [PATCH 32/56] function in locallib changed for behat testing
environment
---
locallib.php | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/locallib.php b/locallib.php
index c70935b1a2..98b4451ba9 100644
--- a/locallib.php
+++ b/locallib.php
@@ -654,8 +654,12 @@ function moodleoverflow_get_post_full($postid) {
if ($CFG->branch >= 311) {
$allnames = \core_user\fields::for_name()->get_sql('u', false, '', '', false)->selects;
- } else {
+ } else if ($CFG->branch > 309) {
$allnames = implode(', ', fields::get_name_fields());
+ } else {
+ // TODO: remove this else branch when support for version 3.9 ends and replace the else if branch with 'else' only.
+ // Note that get_all_user_name_fields is a deprecated function and should not be used in newer versions.
+ $allnames = get_all_user_name_fields(true, 'u');
}
$sql = "SELECT p.*, d.moodleoverflow, $allnames, u.email, u.picture, u.imagealt
FROM {moodleoverflow_posts} p
From 23794669b751008003d3ffc6bc6bf7d75ce16f0f Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 7 Sep 2023 12:39:48 +0200
Subject: [PATCH 33/56] fix in post control for behat testing environment
---
classes/post/post_control.php | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index 45ed8e1aed..6e3331578d 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -242,7 +242,7 @@ private function build_prepost_create($moodleoverflowid) {
* @param int $replypostid The ID of the post that is being answered.
*/
private function build_prepost_reply($replypostid) {
- global $DB, $PAGE, $SESSION, $USER;
+ global $DB, $PAGE, $SESSION, $USER, $CFG;
// Get the related poost, discussion, moodleoverflow, course, coursemodule and contexts.
$this->collect_information($replypostid, false);
@@ -280,8 +280,15 @@ private function build_prepost_reply($replypostid) {
// Append 'RE: ' to the discussions subject.
$strre = get_string('re', 'moodleoverflow');
- if (!(str_starts_with($this->prepost->subject, $strre))) {
- $this->prepost->subject = $strre . ' ' . $this->prepost->subject;
+ if ($CFG->branch > 309) {
+ if (!(str_starts_with($this->prepost->subject, $strre))) {
+ $this->prepost->subject = $strre . ' ' . $this->prepost->subject;
+ }
+ } else {
+ // TODO: remove this else branch when support for version 3.9 ends and delete the branch check.
+ if (!(substr($this->prepost->subject, 0, strlen($strre)) == $strre)) {
+ $this->prepost->subject = $strre . ' ' . $this->prepost->subject;
+ }
}
// Unset where the user is coming from.
From eaa2611794a6708f82311e23d21899ed3c858dd3 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Fri, 27 Oct 2023 12:33:16 +0200
Subject: [PATCH 34/56] code cleaning: long array syntax to short array syntax
---
amd/src/rating.js | 2 +-
.../backup_moodleoverflow_stepslib.php | 47 ++--
...ore_moodleoverflow_activity_task.class.php | 16 +-
.../restore_moodleoverflow_stepslib.php | 4 +-
classes/anonymous.php | 2 +-
classes/discussion/discussion.php | 18 +-
classes/event/readtracking_disabled.php | 2 +-
classes/event/readtracking_enabled.php | 2 +-
classes/observer.php | 10 +-
classes/output/moodleoverflow_email.php | 54 ++---
classes/post/post.php | 38 ++--
classes/post/post_control.php | 134 ++++++------
classes/post_form.php | 6 +-
classes/privacy/data_export_helper.php | 18 +-
classes/privacy/provider.php | 36 ++--
classes/ratings.php | 66 +++---
classes/readtracking.php | 22 +-
classes/review.php | 8 +-
classes/subscriptions.php | 172 +++++++--------
classes/tables/userstats_table.php | 34 +--
classes/task/send_daily_mail.php | 24 +--
classes/task/send_mails.php | 4 +-
db/access.php | 176 +++++++--------
db/events.php | 16 +-
db/messages.php | 7 +-
db/services.php | 18 +-
db/tasks.php | 22 +-
db/upgrade.php | 15 +-
discussion.php | 18 +-
externallib.php | 28 +--
index.php | 40 ++--
lib.php | 98 ++++-----
locallib.php | 164 +++++++-------
markposts.php | 12 +-
mod_form.php | 18 +-
post.php | 15 +-
settings.php | 4 +-
subscribe.php | 24 +--
tests/behat/behat_mod_moodleoverflow.php | 2 +-
tests/dailymail_test.php | 6 +-
tests/discussion_test.php | 16 +-
tests/generator/lib.php | 16 +-
tests/locallib_test.php | 24 +--
tests/post_test.php | 26 +--
tests/privacy_provider_test.php | 38 ++--
tests/ratings_test.php | 109 +++++-----
tests/readtracking_test.php | 12 +-
tests/review_test.php | 23 +-
tests/subscriptions_test.php | 202 +++++++++---------
tests/userstats_test.php | 24 +--
tracking.php | 12 +-
userstats.php | 8 +-
version.php | 3 +-
view.php | 24 +--
54 files changed, 971 insertions(+), 968 deletions(-)
diff --git a/amd/src/rating.js b/amd/src/rating.js
index 0f44f3ba77..f1cce7a268 100644
--- a/amd/src/rating.js
+++ b/amd/src/rating.js
@@ -149,7 +149,7 @@ export function init(userid, allowmultiplemarks) {
/**
* Function to change the String of the post data-action button.
- * Only used if mulitplemarks are allowed.
+ * Only used if multiplemarks are allowed.
* @param {string} htmlclass the class where the String is being updated
* @param {string} action helpful or solved mark
*/
diff --git a/backup/moodle2/backup_moodleoverflow_stepslib.php b/backup/moodle2/backup_moodleoverflow_stepslib.php
index ed5d83f729..24286e4ff9 100644
--- a/backup/moodle2/backup_moodleoverflow_stepslib.php
+++ b/backup/moodle2/backup_moodleoverflow_stepslib.php
@@ -44,49 +44,46 @@ protected function define_structure() {
$userinfo = $this->get_setting_value('userinfo');
// Define the root element describing the moodleoverflow instance.
- $moodleoverflow = new backup_nested_element('moodleoverflow', array('id'), array(
+ $moodleoverflow = new backup_nested_element('moodleoverflow', ['id'], [
'name', 'intro', 'introformat', 'maxbytes', 'maxattachments',
'forcesubscribe', 'trackingtype', 'timecreated', 'timemodified',
- 'ratingpreference', 'coursewidereputation', 'allownegativereputation'));
+ 'ratingpreference', 'coursewidereputation', 'allownegativereputation',
+ ]);
// Define each element separated.
$discussions = new backup_nested_element('discussions');
- $discussion = new backup_nested_element('discussion', array('id'), array(
- 'name', 'firstpost', 'userid', 'timemodified', 'usermodified', 'timestart'));
+ $discussion = new backup_nested_element('discussion', ['id'], [
+ 'name', 'firstpost', 'userid', 'timemodified', 'usermodified', 'timestart', ]);
$posts = new backup_nested_element('posts');
- $post = new backup_nested_element('post', array('id'), array(
+ $post = new backup_nested_element('post', ['id'], [
'parent', 'userid', 'created', 'modified',
- 'mailed', 'message', 'messageformat', 'attachment'));
+ 'mailed', 'message', 'messageformat', 'attachment', ]);
$ratings = new backup_nested_element('ratings');
- $rating = new backup_nested_element('rating', array('id'), array(
- 'userid', 'rating', 'firstrated', 'lastchanged'));
+ $rating = new backup_nested_element('rating', ['id'], [
+ 'userid', 'rating', 'firstrated', 'lastchanged', ]);
$discussionsubs = new backup_nested_element('discuss_subs');
- $discussionsub = new backup_nested_element('discuss_sub', array('id'), array(
+ $discussionsub = new backup_nested_element('discuss_sub', ['id'], [
'userid',
'preference',
- ));
+ ]);
$subscriptions = new backup_nested_element('subscriptions');
- $subscription = new backup_nested_element('subscription', array('id'), array(
- 'userid'));
+ $subscription = new backup_nested_element('subscription', ['id'], ['userid']);
$readposts = new backup_nested_element('readposts');
- $read = new backup_nested_element('read', array('id'), array(
- 'userid', 'discussionid', 'postid', 'firstread',
- 'lastread'));
+ $read = new backup_nested_element('read', ['id'], ['userid', 'discussionid', 'postid', 'firstread', 'lastread']);
$tracking = new backup_nested_element('tracking');
- $track = new backup_nested_element('track', array('id'), array(
- 'userid'));
+ $track = new backup_nested_element('track', ['id'], ['userid']);
// Build the tree.
$moodleoverflow->add_child($discussions);
@@ -111,7 +108,7 @@ protected function define_structure() {
$tracking->add_child($track);
// Define data sources.
- $moodleoverflow->set_source_table('moodleoverflow', array('id' => backup::VAR_ACTIVITYID));
+ $moodleoverflow->set_source_table('moodleoverflow', ['id' => backup::VAR_ACTIVITYID]);
// All these source definitions only happen if we are including user info.
if ($userinfo) {
@@ -119,15 +116,15 @@ protected function define_structure() {
SELECT *
FROM {moodleoverflow_discussions}
WHERE moodleoverflow = ?',
- array(backup::VAR_PARENTID));
+ [backup::VAR_PARENTID]);
// Need posts ordered by id so parents are always before childs on restore.
- $post->set_source_table('moodleoverflow_posts', array('discussion' => backup::VAR_PARENTID), 'id ASC');
- $rating->set_source_table('moodleoverflow_ratings', array('postid' => backup::VAR_PARENTID));
- $discussionsub->set_source_table('moodleoverflow_discuss_subs', array('discussion' => backup::VAR_PARENTID));
- $subscription->set_source_table('moodleoverflow_subscriptions', array('moodleoverflow' => backup::VAR_PARENTID));
- $read->set_source_table('moodleoverflow_read', array('moodleoverflowid' => backup::VAR_PARENTID));
- $track->set_source_table('moodleoverflow_tracking', array('moodleoverflowid' => backup::VAR_PARENTID));
+ $post->set_source_table('moodleoverflow_posts', ['discussion' => backup::VAR_PARENTID], 'id ASC');
+ $rating->set_source_table('moodleoverflow_ratings', ['postid' => backup::VAR_PARENTID]);
+ $discussionsub->set_source_table('moodleoverflow_discuss_subs', ['discussion' => backup::VAR_PARENTID]);
+ $subscription->set_source_table('moodleoverflow_subscriptions', ['moodleoverflow' => backup::VAR_PARENTID]);
+ $read->set_source_table('moodleoverflow_read', ['moodleoverflowid' => backup::VAR_PARENTID]);
+ $track->set_source_table('moodleoverflow_tracking', ['moodleoverflowid' => backup::VAR_PARENTID]);
}
// Define id annotations.
diff --git a/backup/moodle2/restore_moodleoverflow_activity_task.class.php b/backup/moodle2/restore_moodleoverflow_activity_task.class.php
index a02b4483a5..69b3703f34 100644
--- a/backup/moodle2/restore_moodleoverflow_activity_task.class.php
+++ b/backup/moodle2/restore_moodleoverflow_activity_task.class.php
@@ -59,10 +59,10 @@ protected function define_my_steps() {
* processed by the link decoder
*/
public static function define_decode_contents() {
- $contents = array();
+ $contents = [];
- $contents[] = new restore_decode_content('moodleoverflow', array('intro'), 'moodleoverflow');
- $contents[] = new restore_decode_content('moodleoverflow_posts', array('message'), 'moodleoverflow_post');
+ $contents[] = new restore_decode_content('moodleoverflow', ['intro'], 'moodleoverflow');
+ $contents[] = new restore_decode_content('moodleoverflow_posts', ['message'], 'moodleoverflow_post');
return $contents;
}
@@ -72,7 +72,7 @@ public static function define_decode_contents() {
* to the activity to be executed by the link decoder
*/
public static function define_decode_rules() {
- $rules = array();
+ $rules = [];
$rules[] = new restore_decode_rule('MOODLEOVERFLOWVIEWBYID', '/mod/moodleoverflow/view.php?id=$1', 'course_module');
$rules[] = new restore_decode_rule('MOODLEOVERFLOWINDEX', '/mod/moodleoverflow/index.php?id=$1', 'course');
@@ -85,9 +85,9 @@ public static function define_decode_rules() {
// Link to discussion with parent and with anchor posts.
$rules[] = new restore_decode_rule('MOODLEOVERFLOWDISCUSSIONVIEWPARENT',
'/mod/moodleoverflow/discussion.php?d=$1&parent=$2',
- array('moodleoverflow_discussion', 'moodleoverflow_post'));
+ ['moodleoverflow_discussion', 'moodleoverflow_post']);
$rules[] = new restore_decode_rule('MOODLEOVERFLOWDISCUSSIONVIEWINSIDE', '/mod/moodleoverflow/discussion.php?d=$1#$2',
- array('moodleoverflow_discussion', 'moodleoverflow_post'));
+ ['moodleoverflow_discussion', 'moodleoverflow_post']);
return $rules;
@@ -100,7 +100,7 @@ public static function define_decode_rules() {
* of { restore_log_rule} objects
*/
public static function define_restore_log_rules() {
- $rules = array();
+ $rules = [];
$rules[] = new restore_log_rule('moodleoverflow', 'add',
'view.php?id={course_module}', '{moodleoverflow}');
@@ -160,7 +160,7 @@ public static function define_restore_log_rules() {
* 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 = [];
$rules[] = new restore_log_rule('moodleoverflow', 'view all', 'index.php?id={course}', null);
diff --git a/backup/moodle2/restore_moodleoverflow_stepslib.php b/backup/moodle2/restore_moodleoverflow_stepslib.php
index fabc49a080..590a37f886 100644
--- a/backup/moodle2/restore_moodleoverflow_stepslib.php
+++ b/backup/moodle2/restore_moodleoverflow_stepslib.php
@@ -40,7 +40,7 @@ class restore_moodleoverflow_activity_structure_step extends restore_activity_st
*/
protected function define_structure() {
- $paths = array();
+ $paths = [];
$userinfo = $this->get_setting_value('userinfo');
$paths[] = new restore_path_element('moodleoverflow', '/activity/moodleoverflow');
@@ -138,7 +138,7 @@ protected function process_moodleoverflow_post($data) {
// If !post->parent, it's the 1st post. Set it in discussion.
if (empty($data->parent)) {
- $DB->set_field('moodleoverflow_discussions', 'firstpost', $newitemid, array('id' => $data->discussion));
+ $DB->set_field('moodleoverflow_discussions', 'firstpost', $newitemid, ['id' => $data->discussion]);
}
}
diff --git a/classes/anonymous.php b/classes/anonymous.php
index c098dc8bce..cbb3188da3 100644
--- a/classes/anonymous.php
+++ b/classes/anonymous.php
@@ -87,7 +87,7 @@ public static function get_userid_mapping($moodleoverflow, $discussionid) {
if ($moodleoverflow->anonymous == self::QUESTION_ANONYMOUS) {
return [
$DB->get_field('moodleoverflow_posts', 'userid',
- ['parent' => 0, 'discussion' => $discussionid]) => get_string('questioner', 'mod_moodleoverflow')
+ ['parent' => 0, 'discussion' => $discussionid]) => get_string('questioner', 'mod_moodleoverflow'),
];
}
diff --git a/classes/discussion/discussion.php b/classes/discussion/discussion.php
index 2115bae1e7..bdc887eeac 100644
--- a/classes/discussion/discussion.php
+++ b/classes/discussion/discussion.php
@@ -118,7 +118,7 @@ public function __construct($id, $course, $moodleoverflow, $name, $firstpost,
$this->timemodified = $timemodified;
$this->timestart = $timestart;
$this->usermodified = $usermodified;
- $this->posts = array();
+ $this->posts = [];
$this->postsbuild = false;
}
@@ -222,17 +222,17 @@ public function moodleoverflow_add_discussion($prepost) {
$this->firstpost = $post->moodleoverflow_add_new_post();
// Save the id of the first/parent post in the DB.
- $DB->set_field('moodleoverflow_discussions', 'firstpost', $this->firstpost, array('id' => $this->id));
+ $DB->set_field('moodleoverflow_discussions', 'firstpost', $this->firstpost, ['id' => $this->id]);
// Add the parent post to the $posts array.
$this->posts[$this->firstpost] = $post;
$this->postsbuild = true;
// Trigger event.
- $params = array(
+ $params = [
'context' => $prepost->modulecontext,
'objectid' => $this->id,
- );
+ ];
// TODO: check if the event functions.
$event = \mod_moodleoverflow\event\discussion_viewed::create($params);
$event->trigger();
@@ -266,16 +266,16 @@ public function moodleoverflow_delete_discussion($prepost) {
readtracking::moodleoverflow_delete_read_records(-1, -1, $this->id);
// Remove the subscriptions for the discussion.
- $DB->delete_records('moodleoverflow_discuss_subs', array('discussion' => $this->id));
+ $DB->delete_records('moodleoverflow_discuss_subs', ['discussion' => $this->id]);
// Delete the discussion from the database.
- $DB->delete_records('moodleoverflow_discussions', array('id' => $this->id));
+ $DB->delete_records('moodleoverflow_discussions', ['id' => $this->id]);
// Trigger the discussion deleted event.
- $params = array(
+ $params = [
'objectid' => $this->id,
'context' => $prepost->modulecontext,
- );
+ ];
$event = \mod_moodleoverflow\event\discussion_deleted::create($params);
$event->trigger();
@@ -521,7 +521,7 @@ public function get_moodleoverflow() {
$this->existence_check();
if (empty($this->moodleoverflowobject)) {
- $this->moodleoverflowobject = $DB->get_records('moodleoverflow', array('id' => $this->moodleoverflow));
+ $this->moodleoverflowobject = $DB->get_records('moodleoverflow', ['id' => $this->moodleoverflow]);
}
return $this->moodleoverflowobject;
diff --git a/classes/event/readtracking_disabled.php b/classes/event/readtracking_disabled.php
index 3ff1a02f12..360321ca81 100644
--- a/classes/event/readtracking_disabled.php
+++ b/classes/event/readtracking_disabled.php
@@ -74,6 +74,6 @@ public static function get_name() {
* @return \moodle_url
*/
public function get_url() {
- return new \moodle_url('/mod/moodleoverflow/view.php', array('m' => $this->other['moodleoverflowid']));
+ return new \moodle_url('/mod/moodleoverflow/view.php', ['m' => $this->other['moodleoverflowid']]);
}
}
diff --git a/classes/event/readtracking_enabled.php b/classes/event/readtracking_enabled.php
index c6d7f146d2..afe4f16449 100644
--- a/classes/event/readtracking_enabled.php
+++ b/classes/event/readtracking_enabled.php
@@ -74,6 +74,6 @@ public static function get_name() {
* @return \moodle_url
*/
public function get_url() {
- return new \moodle_url('/mod/moodleoverflow/view.php', array('m' => $this->other['moodleoverflowid']));
+ return new \moodle_url('/mod/moodleoverflow/view.php', ['m' => $this->other['moodleoverflowid']]);
}
}
diff --git a/classes/observer.php b/classes/observer.php
index ade917acec..6055ca99f4 100644
--- a/classes/observer.php
+++ b/classes/observer.php
@@ -44,7 +44,7 @@ public static function user_enrolment_deleted(\core\event\user_enrolment_deleted
if ($cp->lastenrol) {
// Get the moodleoverflow instances from which the user was unenrolled from.
- $moodleoverflows = $DB->get_records('moodleoverflow', array('course' => $cp->courseid), '', 'id');
+ $moodleoverflows = $DB->get_records('moodleoverflow', ['course' => $cp->courseid], '', 'id');
// Do not continue if there are no connected moodleoverflow instances.
if (!$moodleoverflows) {
@@ -93,9 +93,9 @@ public static function role_assigned(\core\event\role_assigned $event) {
JOIN {modules} mo ON (mo.id = cm.module)
LEFT JOIN {moodleoverflow_subscriptions} ms ON (ms.moodleoverflow = m.id AND ms.userid = :userid)
WHERE m.course = :courseid AND m.forcesubscribe = :initial AND mo.name = 'moodleoverflow' AND ms.id IS NULL";
- $params = array('courseid' => $context->instanceid,
- 'userid' => $userid,
- 'initial' => MOODLEOVERFLOW_INITIALSUBSCRIBE);
+ $params = ['courseid' => $context->instanceid,
+ 'userid' => $userid,
+ 'initial' => MOODLEOVERFLOW_INITIALSUBSCRIBE, ];
$moodleoverflows = $DB->get_records_sql($sql, $params);
// Loop through all moodleoverflows.
@@ -133,7 +133,7 @@ public static function course_module_created(\core\event\course_module_created $
require_once($CFG->dirroot . '/mod/moodleoverflow/lib.php');
// Create a snapshot of the created moodleoverflow record.
- $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $event->other['instanceid']));
+ $moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $event->other['instanceid']]);
// Trigger the function for a created moodleoverflow instance.
moodleoverflow_instance_created($event->get_context(), $moodleoverflow);
diff --git a/classes/output/moodleoverflow_email.php b/classes/output/moodleoverflow_email.php
index b52d653be9..47f2651b9f 100644
--- a/classes/output/moodleoverflow_email.php
+++ b/classes/output/moodleoverflow_email.php
@@ -102,9 +102,9 @@ class moodleoverflow_email implements \renderable, \templatable {
*
* @var array $writablekeys
*/
- protected $writablekeys = array(
+ protected $writablekeys = [
'viewfullnames' => true,
- );
+ ];
/**
* Builds a renderable moodleoverflow mail.
@@ -154,7 +154,7 @@ public function export_for_template(\renderer_base $renderer, $plaintext = false
*/
protected function export_for_template_text(\mod_moodleoverflow_renderer $renderer) {
- return array(
+ return [
'id' => html_entity_decode($this->post->id, ENT_COMPAT),
'coursename' => html_entity_decode($this->get_coursename(), ENT_COMPAT),
'courselink' => html_entity_decode($this->get_courselink(), ENT_COMPAT),
@@ -180,7 +180,7 @@ protected function export_for_template_text(\mod_moodleoverflow_renderer $render
// Format some components according to the renderer.
'message' => html_entity_decode($renderer->format_message_text($this->cm, $this->post), ENT_COMPAT),
- );
+ ];
}
/**
@@ -188,10 +188,10 @@ protected function export_for_template_text(\mod_moodleoverflow_renderer $render
*
* @param \mod_moodleoverflow_renderer $renderer The render to be used for formatting the message and attachments
*
- * @return stdClass Data ready for use in a mustache template
+ * @return array Data ready for use in a mustache template
*/
protected function export_for_template_html(\mod_moodleoverflow_renderer $renderer) {
- return array(
+ return [
'id' => $this->post->id,
'coursename' => $this->get_coursename(),
'courselink' => $this->get_courselink(),
@@ -217,7 +217,7 @@ protected function export_for_template_html(\mod_moodleoverflow_renderer $render
// Format some components according to the renderer.
'message' => $renderer->format_message_text($this->cm, $this->post),
- );
+ ];
}
/**
@@ -263,7 +263,7 @@ public function get_unsubscribediscussionlink() {
$url = '/mod/moodleoverflow/subscribe.php';
// Generate a link to unsubscribe from the discussion.
- $link = new \moodle_url($url, array('id' => $id, 'd' => $d));
+ $link = new \moodle_url($url, ['id' => $id, 'd' => $d]);
return $link->out(false);
}
@@ -292,9 +292,9 @@ public function get_courseidnumber() {
* @return string
*/
public function get_coursefullname() {
- return format_string($this->course->fullname, true, array(
+ return format_string($this->course->fullname, true, [
'context' => \context_course::instance($this->course->id),
- ));
+ ]);
}
/**
@@ -303,9 +303,9 @@ public function get_coursefullname() {
* @return string
*/
public function get_coursename() {
- return format_string($this->course->shortname, true, array(
+ return format_string($this->course->shortname, true, [
'context' => \context_course::instance($this->course->id),
- ));
+ ]);
}
/**
@@ -316,9 +316,9 @@ public function get_coursename() {
public function get_courselink() {
$link = new \moodle_url(
// Posts are viewed on the topic.
- '/course/view.php', array(
+ '/course/view.php', [
'id' => $this->course->id,
- )
+ ]
);
return $link->out(false);
@@ -420,9 +420,9 @@ public function is_firstpost() {
*/
public function get_replylink() {
return new \moodle_url(
- '/mod/moodleoverflow/post.php', array(
+ '/mod/moodleoverflow/post.php', [
'reply' => $this->post->id,
- )
+ ]
);
}
@@ -437,9 +437,9 @@ public function get_unsubscribemoodleoverflowlink() {
return null;
}
$link = new \moodle_url(
- '/mod/moodleoverflow/subscribe.php', array(
+ '/mod/moodleoverflow/subscribe.php', [
'id' => $this->moodleoverflow->id,
- )
+ ]
);
return $link->out(false);
@@ -465,10 +465,10 @@ public function get_parentpostlink() {
protected function get_discussionurl() {
return new \moodle_url(
// Posts are viewed on the topic.
- '/mod/moodleoverflow/discussion.php', array(
+ '/mod/moodleoverflow/discussion.php', [
// Within a discussion.
'd' => $this->discussion->id,
- )
+ ]
);
}
@@ -491,9 +491,9 @@ public function get_discussionlink() {
public function get_moodleoverflowindexlink() {
$link = new \moodle_url(
// Posts are viewed on the topic.
- '/mod/moodleoverflow/index.php', array(
+ '/mod/moodleoverflow/index.php', [
'id' => $this->course->id,
- )
+ ]
);
return $link->out(false);
@@ -507,9 +507,9 @@ public function get_moodleoverflowindexlink() {
public function get_moodleoverflowviewlink() {
$link = new \moodle_url(
// Posts are viewed on the topic.
- '/mod/moodleoverflow/view.php', array(
+ '/mod/moodleoverflow/view.php', [
'm' => $this->moodleoverflow->id,
- )
+ ]
);
return $link->out(false);
@@ -526,10 +526,10 @@ public function get_authorlink() {
}
$link = new \moodle_url(
- '/user/view.php', array(
+ '/user/view.php', [
'id' => $this->post->userid,
'course' => $this->course->id,
- )
+ ]
);
return $link->out(false);
@@ -546,7 +546,7 @@ public function get_author_picture() {
return '';
}
- return $OUTPUT->user_picture($this->author, array('courseid' => $this->course->id));
+ return $OUTPUT->user_picture($this->author, ['courseid' => $this->course->id]);
}
/**
diff --git a/classes/post/post.php b/classes/post/post.php
index 0046967637..b054a55595 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -262,8 +262,8 @@ public function moodleoverflow_add_new_post() {
if ($this->reviewed) {
// Update the discussion.
- $DB->set_field('moodleoverflow_discussions', 'timemodified', $this->modified, array('id' => $this->discussion));
- $DB->set_field('moodleoverflow_discussions', 'usermodified', $this->userid, array('id' => $this->discussion));
+ $DB->set_field('moodleoverflow_discussions', 'timemodified', $this->modified, ['id' => $this->discussion]);
+ $DB->set_field('moodleoverflow_discussions', 'usermodified', $this->userid, ['id' => $this->discussion]);
}
// Mark the created post as read if the user is tracking the discussion.
@@ -307,10 +307,10 @@ public function moodleoverflow_delete_post($deletechildren) {
}
// Delete the ratings.
- $DB->delete_records('moodleoverflow_ratings', array('postid' => $this->id));
+ $DB->delete_records('moodleoverflow_ratings', ['postid' => $this->id]);
// Delete the post.
- if ($DB->delete_records('moodleoverflow_posts', array('id' => $this->id))) {
+ if ($DB->delete_records('moodleoverflow_posts', ['id' => $this->id])) {
// Delete the read records.
readtracking::moodleoverflow_delete_read_records(-1, $this->id);
@@ -330,14 +330,14 @@ public function moodleoverflow_delete_post($deletechildren) {
}
// Trigger the post deletion event.
- $params = array(
+ $params = [
'context' => $context,
'objectid' => $this->id,
- 'other' => array(
+ 'other' => [
'discussionid' => $this->discussion,
- 'moodleoverflowid' => $this->get_moodleoverflow()->id
- )
- );
+ 'moodleoverflowid' => $this->get_moodleoverflow()->id,
+ ],
+ ];
if ($this->userid !== $USER->id) {
$params['relateduserid'] = $this->userid;
}
@@ -439,7 +439,7 @@ public function moodleoverflow_add_attachment() {
$present = ($info['filecount'] > 0) ? '1' : '';
file_save_draft_area_files($this->formattachments, $context->id, 'mod_moodleoverflow', 'attachment', $this->id,
\mod_moodleoverflow_post_form::attachment_options($this->get_moodleoverflow()));
- $DB->set_field('moodleoverflow_posts', 'attachment', $present, array('id' => $this->id));
+ $DB->set_field('moodleoverflow_posts', 'attachment', $present, ['id' => $this->id]);
}
/**
@@ -453,10 +453,10 @@ public function moodleoverflow_get_attachments() {
$this->existence_check();
if (empty($this->attachment) || (!$context = \context_module::instance($this->get_coursemodule()->id))) {
- return array();
+ return [];
}
- $attachments = array();
+ $attachments = [];
$fs = get_file_storage();
// We retrieve all files according to the time that they were created. In the case that several files were uploaded
@@ -465,18 +465,18 @@ public function moodleoverflow_get_attachments() {
if ($files) {
$i = 0;
foreach ($files as $file) {
- $attachments[$i] = array();
+ $attachments[$i] = [];
$attachments[$i]['filename'] = $file->get_filename();
$mimetype = $file->get_mimetype();
$iconimage = $OUTPUT->pix_icon(file_file_icon($file),
get_mimetype_description($file), 'moodle',
- array('class' => 'icon'));
+ ['class' => 'icon']);
$path = moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(), $file->get_filearea(),
$file->get_itemid(), $file->get_filepath(), $file->get_filename());
$attachments[$i]['icon'] = $iconimage;
$attachments[$i]['filepath'] = $path;
- if (in_array($mimetype, array('image/gif', 'image/jpeg', 'image/png'))) {
+ if (in_array($mimetype, ['image/gif', 'image/jpeg', 'image/png'])) {
// Image attachments don't get printed as links.
$attachments[$i]['image'] = true;
} else {
@@ -536,7 +536,7 @@ public function get_moodleoverflow() {
if (empty($this->moodleoverflowobject)) {
$discussion = $this->get_discussion();
- $this->moodleoverflowobject = $DB->get_record('moodleoverflow', array('id' => $discussion->get_moodleoverflowid()));
+ $this->moodleoverflowobject = $DB->get_record('moodleoverflow', ['id' => $discussion->get_moodleoverflowid()]);
}
return $this->moodleoverflowobject;
@@ -552,7 +552,7 @@ public function get_discussion() {
$this->existence_check();
if (empty($this->discussionobject)) {
- $record = $DB->get_record('moodleoverflow_discussions', array('id' => $this->discussion));
+ $record = $DB->get_record('moodleoverflow_discussions', ['id' => $this->discussion]);
$this->discussionobject = discussion::from_record($record);
}
return $this->discussionobject;
@@ -588,7 +588,7 @@ public function moodleoverflow_get_parentpost() {
}
if (empty($this->parentpost)) {
- $parentpostrecord = $DB->get_record('moodleoverflow_post', array('id' => $this->parent));
+ $parentpostrecord = $DB->get_record('moodleoverflow_post', ['id' => $this->parent]);
$this->parentpost = $this->from_record($parentpostrecord);
}
return $this->parentpost;
@@ -603,7 +603,7 @@ public function moodleoverflow_get_childposts() {
global $DB;
$this->existence_check();
- if ($childposts = $DB->get_records('moodleoverflow_posts', array('parent' => $this->id))) {
+ if ($childposts = $DB->get_records('moodleoverflow_posts', ['parent' => $this->id])) {
return $childposts;
}
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index 6e3331578d..91da39cff8 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -31,6 +31,7 @@
use mod_moodleoverflow\post\post;
use mod_moodleoverflow\discussion\discussion;
+use moodle_exception;
defined('MOODLE_INTERNAL') || die();
global $CFG;
@@ -121,7 +122,7 @@ public function detect_interaction($urlparameter) {
$this->info->deletepostid = $urlparameter->delete;
$this->build_prepost_delete($this->info->deletepostid);
} else {
- throw new \moodle_exception('unknownaction');
+ throw new moodle_exception('unknownaction');
}
}
@@ -155,7 +156,7 @@ public function execute_interaction($form) {
} else if ($this->interaction == 'edit' && $form->edit == $this->prepost->postid) {
$this->execute_edit($form, $errordestination);
} else {
- throw new \moodle_exception('unexpectedinteractionerror', 'moodleoverflow', $errordestination);
+ throw new moodle_exception('unexpectedinteractionerror', 'moodleoverflow', $errordestination);
}
}
@@ -169,7 +170,7 @@ public function execute_interaction($form) {
public function catch_guest($postid = false, $moodleoverflowid = false) {
global $PAGE;
if ((!$postid && !$moodleoverflowid) || ($postid && $moodleoverflowid)) {
- throw new \moodle_exception('inaccurateparameter', 'moodleoverflow');
+ throw new moodle_exception('inaccurateparameter', 'moodleoverflow');
}
if ($postid) {
$this->collect_information($postid, false);
@@ -208,15 +209,13 @@ private function build_prepost_create($moodleoverflowid) {
if (enrol_selfenrol_available($this->info->course->id)) {
$SESSION->wantsurl = qualified_me();
$SESSION->enrolcancel = get_local_referer(false);
- redirect(new \moodle_url('/enrol/index.php',
- array('id' => $this->info->course->id,
- 'returnurl' => '/mod/moodleoverflow/view.php?m=' .
- $this->info->moodleoverflow->id)),
- get_string('youneedtoenrol'));
+ redirect(new \moodle_url('/enrol/index.php', ['id' => $this->info->course->id,
+ 'returnurl' => '/mod/moodleoverflow/view.php?m=' . $this->info->moodleoverflow->id, ]),
+ get_string('youneedtoenrol'));
}
}
// Notify the user, that he can not post a new discussion.
- throw new \moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
+ throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
}
// Where is the user coming from?
@@ -265,17 +264,16 @@ private function build_prepost_reply($replypostid) {
$SESSION->wantsurl = qualified_me();
$SESSION->enrolcancel = get_local_referer(false);
redirect(new \moodle_url('/enrol/index.php',
- array('id' => $this->info->course->id,
- 'returnurl' => '/mod/moodleoverflow/view.php?m=' .
- $this->info->moodleoverflow->id)),
- get_string('youneedtoenrol'));
+ ['id' => $this->info->course->id,
+ 'returnurl' => '/mod/moodleoverflow/view.php?m=' . $this->info->moodleoverflow->id,
+ ]), get_string('youneedtoenrol'));
}
// Print the error message.
- throw new \moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
+ throw new moodle_exception('nopostmoodleoverflow', 'moodleoverflow');
}
// Make sure the user can post here.
if (!$this->info->cm->visible && !has_capability('moodle/course:viewhiddenactivities', $this->info->modulecontext)) {
- throw new \moodle_exception('activityiscurrentlyhidden');
+ throw new moodle_exception('activityiscurrentlyhidden');
}
// Append 'RE: ' to the discussions subject.
@@ -319,7 +317,7 @@ private function build_prepost_edit($editpostid) {
&& $this->info->relatedpost->reviewed;
if (($beyondtime || $alreadyreviewed) && !has_capability('mod/moodleoverflow:editanypost',
$this->info->modulecontext)) {
- throw new \moodle_exception('maxtimehaspassed', 'moodleoverflow', '',
+ throw new moodle_exception('maxtimehaspassed', 'moodleoverflow', '',
format_time(get_config('moodleoverflow', 'maxeditingtime')));
}
@@ -330,7 +328,7 @@ private function build_prepost_edit($editpostid) {
if (!has_capability('mod/moodleoverflow:editanypost', $this->info->modulecontext)) {
// Display the error. Capabilities are missing.
- throw new \moodle_exception('cannoteditposts', 'moodleoverflow');
+ throw new moodle_exception('cannoteditposts', 'moodleoverflow');
}
}
@@ -393,14 +391,14 @@ private function execute_create($form, $errordestination) {
$this->prepost->subject, 0, $this->prepost->userid,
$this->prepost->timenow, $this->prepost->timenow, $this->prepost->userid);
if (!$discussion->moodleoverflow_add_discussion($this->prepost)) {
- throw new \moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
+ throw new moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
}
// The creation was successful.
$redirectmessage = \html_writer::tag('p', get_string("postaddedsuccess", "moodleoverflow"));
// Trigger the discussion created event.
- $params = array( 'context' => $this->info->modulecontext, 'objectid' => $discussion->get_id());
+ $params = ['context' => $this->info->modulecontext, 'objectid' => $discussion->get_id()];
$event = \mod_moodleoverflow\event\discussion_created::create($params);
$event->trigger();
@@ -412,7 +410,7 @@ private function execute_create($form, $errordestination) {
$this->info->modulecontext);
// Define the location to redirect the user after successfully posting.
- $redirectto = new \moodle_url('/mod/moodleoverflow/view.php', array('m' => $form->moodleoverflow));
+ $redirectto = new \moodle_url('/mod/moodleoverflow/view.php', ['m' => $form->moodleoverflow]);
redirect(moodleoverflow_go_back_to($redirectto->out()), $redirectmessage, null, \core\output\notification::NOTIFY_SUCCESS);
}
@@ -430,7 +428,7 @@ private function execute_reply($form, $errordestination) {
// Create the new post.
if (!$newpostid = $this->info->discussion->moodleoverflow_add_post_to_discussion($this->prepost)) {
- throw new \moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
+ throw new moodle_exception('couldnotadd', 'moodleoverflow', $errordestination);
}
// The creation was successful.
@@ -439,10 +437,11 @@ private function execute_reply($form, $errordestination) {
format_time(get_config('moodleoverflow', 'maxeditingtime'))));
// Trigger the post created event.
- $params = array('context' => $this->info->modulecontext, 'objectid' => $newpostid,
- 'other' => array('discussionid' => $this->prepost->discussionid,
- 'moodleoverflowid' => $this->prepost->moodleoverflowid)
- );
+ $params = ['context' => $this->info->modulecontext, 'objectid' => $newpostid,
+ 'other' => ['discussionid' => $this->prepost->discussionid,
+ 'moodleoverflowid' => $this->prepost->moodleoverflowid,
+ ],
+ ];
$event = \mod_moodleoverflow\event\post_created::create($params);
$event->trigger();
@@ -455,7 +454,7 @@ private function execute_reply($form, $errordestination) {
// Define the location to redirect the user after successfully posting.
$redirectto = new \moodle_url('/mod/moodleoverflow/discussion.php',
- array('d' => $this->prepost->discussionid, 'p' => $newpostid));
+ ['d' => $this->prepost->discussionid, 'p' => $newpostid]);
redirect(\moodleoverflow_go_back_to($redirectto->out()), $redirectmessage, null, \core\output\notification::NOTIFY_SUCCESS);
}
@@ -472,7 +471,7 @@ private function execute_edit($form, $errordestination) {
// Update the post.
if (!$this->info->discussion->moodleoverflow_edit_post_from_discussion($this->prepost)) {
- throw new \moodle_exception('couldnotupdate', 'moodleoverflow', $errordestination);
+ throw new moodle_exception('couldnotupdate', 'moodleoverflow', $errordestination);
}
// The edit was successful.
@@ -484,24 +483,25 @@ private function execute_edit($form, $errordestination) {
$this->prepost->userid)) {
$name = get_string('anonymous', 'moodleoverflow');
} else {
- $realuser = $DB->get_record('user', array('id' => $this->prepost->userid));
+ $realuser = $DB->get_record('user', ['id' => $this->prepost->userid]);
$name = fullname($realuser);
}
$redirectmessage = get_string('editedpostupdated', 'moodleoverflow', $name);
}
// Trigger the post updated event.
- $params = array('context' => $this->info->modulecontext, 'objectid' => $form->edit,
- 'other' => array('discussionid' => $this->prepost->discussionid,
- 'moodleoverflowid' => $this->prepost->moodleoverflowid),
- 'relateduserid' => $this->prepost->userid == $USER->id ? $this->prepost->userid : null
- );
+ $params = ['context' => $this->info->modulecontext, 'objectid' => $form->edit,
+ 'other' => ['discussionid' => $this->prepost->discussionid,
+ 'moodleoverflowid' => $this->prepost->moodleoverflowid,
+ ],
+ 'relateduserid' => $this->prepost->userid == $USER->id ? $this->prepost->userid : null,
+ ];
$event = \mod_moodleoverflow\event\post_updated::create($params);
$event->trigger();
// Define the location to redirect the user after successfully editing.
$redirectto = new \moodle_url('/mod/moodleoverflow/discussion.php',
- array('d' => $this->prepost->discussionid, 'p' => $form->edit));
+ ['d' => $this->prepost->discussionid, 'p' => $form->edit]);
redirect(moodleoverflow_go_back_to($redirectto->out()), $redirectmessage, null, \core\output\notification::NOTIFY_SUCCESS);
}
@@ -510,14 +510,14 @@ public function execute_delete() {
// Check if the user has the capability to delete the post.
$timepassed = time() - $this->info->relatedpost->created;
- $url = new \moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->info->discussion->get_id()));
+ $url = new \moodle_url('/mod/moodleoverflow/discussion.php', ['d' => $this->info->discussion->get_id()]);
if (($timepassed > get_config('moodleoverflow', 'maxeditingtime')) && !$this->info->deleteanypost) {
- throw new \moodle_exception('cannotdeletepost', 'moodleoverflow', moodleoverflow_go_back_to($url));
+ throw new moodle_exception('cannotdeletepost', 'moodleoverflow', moodleoverflow_go_back_to($url));
}
// A normal user cannot delete his post if there are direct replies.
if ($this->info->replycount && !$this->info->deleteanypost) {
- throw new \moodle_exception('cannotdeletereplies', 'moodleoverflow', moodleoverflow_go_back_to($url));
+ throw new moodle_exception('cannotdeletereplies', 'moodleoverflow', moodleoverflow_go_back_to($url));
}
// Check if the post is a parent post or not.
@@ -530,7 +530,7 @@ public function execute_delete() {
redirect('view.php?m=' . $moodleoverflowid);
} else {
$this->info->discussion->moodleoverflow_delete_post_from_discussion($this->prepost);
- $discussionurl = new \moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $this->info->discussion->get_id()));
+ $discussionurl = new \moodle_url('/mod/moodleoverflow/discussion.php', ['d' => $this->info->discussion->get_id()]);
redirect(moodleoverflow_go_back_to($discussionurl));
}
}
@@ -569,12 +569,13 @@ public function build_postform($pageparams) {
// Prepare the form.
$edit = $this->interaction == 'edit';
- $formarray = array( 'course' => $this->info->course, 'cm' => $this->info->cm, 'coursecontext' => $this->info->coursecontext,
- 'modulecontext' => $this->info->modulecontext, 'moodleoverflow' => $this->info->moodleoverflow,
- 'post' => $this->prepost, 'edit' => $edit);
+ $formarray = ['course' => $this->info->course, 'cm' => $this->info->cm, 'coursecontext' => $this->info->coursecontext,
+ 'modulecontext' => $this->info->modulecontext, 'moodleoverflow' => $this->info->moodleoverflow,
+ 'post' => $this->prepost, 'edit' => $edit,
+ ];
// Declare the post_form.
- $mformpost = new \mod_moodleoverflow_post_form('post.php', $formarray, 'post', '', array('id' => 'mformmoodleoverflow'));
+ $mformpost = new \mod_moodleoverflow_post_form('post.php', $formarray, 'post', '', ['id' => 'mformmoodleoverflow']);
// If the user is not the original author append an extra message to the message. (Happens when interaction = 'edit').
if ($USER->id != $this->prepost->userid) {
@@ -586,7 +587,7 @@ public function build_postform($pageparams) {
$data->name = \html_writer::tag('a', $CFG->wwwroot . '/user/view.php?id' . $USER->id .
'&course=' . $this->prepost->courseid . '">' . fullname($USER));
$this->prepost->message .= \html_writer::tag('p', \html_writer::tag('span',
- get_string('editedby', 'moodleoverflow', $data), array("class" => "edited")));
+ get_string('editedby', 'moodleoverflow', $data), ["class" => "edited"]));
} else {
$data->name = fullname($USER);
$this->prepost->message .= "\n\n(" . get_string('editedby', 'moodleoverflow', $data) . ')';
@@ -605,13 +606,18 @@ public function build_postform($pageparams) {
}
// Set data for the form.
- $mformpost->set_data(array(
- 'attachments' => $draftitemid, 'general' => $heading, 'subject' => $this->prepost->subject,
- 'message' => array('text' => $this->prepost->message,
- 'format' => editors_get_preferred_format(),
- 'itemid' => $this->prepost->postid),
- 'userid' => $this->prepost->userid, 'parent' => $this->prepost->parentid, 'discussion' => $this->prepost->discussionid,
- 'course' => $this->prepost->courseid)
+ $mformpost->set_data([
+ 'attachments' => $draftitemid,
+ 'general' => $heading,
+ 'subject' => $this->prepost->subject,
+ 'message' => ['text' => $this->prepost->message,
+ 'format' => editors_get_preferred_format(),
+ 'itemid' => $this->prepost->postid, ],
+ 'userid' => $this->prepost->userid,
+ 'parent' => $this->prepost->parentid,
+ 'discussion' => $this->prepost->discussionid,
+ 'course' => $this->prepost->courseid,
+ ]
+ $pageparams
);
@@ -703,7 +709,7 @@ private function assemble_prepost() {
*/
private function check_interaction($interaction) {
if ($this->interaction != $interaction) {
- throw new \moodle_exception('wronginteraction' , 'moodleoverflow');
+ throw new moodle_exception('wronginteraction' , 'moodleoverflow');
}
return true;
}
@@ -717,8 +723,8 @@ private function check_interaction($interaction) {
*/
private function check_course_exists($courseid) {
global $DB;
- if (!$course = $DB->get_record('course', array('id' => $courseid))) {
- throw new \moodle_exception('invalidcourseid');
+ if (!$course = $DB->get_record('course', ['id' => $courseid])) {
+ throw new moodle_exception('invalidcourseid');
}
return $course;
}
@@ -732,7 +738,7 @@ private function check_course_exists($courseid) {
private function check_coursemodule_exists($moodleoverflowid, $courseid) {
if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflowid,
$courseid)) {
- throw new \moodle_exception('invalidcoursemodule');
+ throw new moodle_exception('invalidcoursemodule');
}
return $cm;
}
@@ -745,8 +751,8 @@ private function check_coursemodule_exists($moodleoverflowid, $courseid) {
private function check_moodleoverflow_exists($moodleoverflowid) {
// Get the related moodleoverflow instance.
global $DB;
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflowid))) {
- throw new \moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflowid])) {
+ throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
}
return $moodleoverflow;
}
@@ -758,8 +764,8 @@ private function check_moodleoverflow_exists($moodleoverflowid) {
*/
private function check_discussion_exists($discussionid) {
global $DB;
- if (!$discussionrecord = $DB->get_record('moodleoverflow_discussions', array('id' => $discussionid))) {
- throw new \moodle_exception('invaliddiscussionid', 'moodleoverflow');
+ if (!$discussionrecord = $DB->get_record('moodleoverflow_discussions', ['id' => $discussionid])) {
+ throw new moodle_exception('invaliddiscussionid', 'moodleoverflow');
}
return discussion::from_record($discussionrecord);
}
@@ -771,8 +777,8 @@ private function check_discussion_exists($discussionid) {
*/
private function check_post_exists($postid) {
global $DB;
- if (!$postrecord = $DB->get_record('moodleoverflow_posts', array('id' => $postid))) {
- throw new \moodle_exception('invalidpostid', 'moodleoverflow');
+ if (!$postrecord = $DB->get_record('moodleoverflow_posts', ['id' => $postid])) {
+ throw new moodle_exception('invalidpostid', 'moodleoverflow');
}
return post::from_record($postrecord);
}
@@ -786,7 +792,7 @@ private function check_post_exists($postid) {
*/
private function check_user_can_create_discussion() {
if (!has_capability('mod/moodleoverflow:startdiscussion', $this->info->modulecontext)) {
- throw new \moodle_exception('cannotcreatediscussion', 'moodleoverflow');
+ throw new moodle_exception('cannotcreatediscussion', 'moodleoverflow');
}
return true;
}
@@ -798,7 +804,7 @@ private function check_user_can_create_discussion() {
*/
private function check_user_can_create_reply() {
if (!has_capability('mod/moodleoverflow:replypost', $this->info->modulecontext, $this->prepost->userid)) {
- throw new \moodle_exception('cannotreply', 'moodleoverflow');
+ throw new moodle_exception('cannotreply', 'moodleoverflow');
}
return true;
}
@@ -818,7 +824,7 @@ private function check_user_can_edit_post() {
$startdiscussion = has_capability('mod/moodleoverflow:startdiscussion', $this->info->modulecontext);
$ownpost = ($this->prepost->userid == $USER->id);
if (!(($ownpost && ($replypost || $startdiscussion)) || $editanypost)) {
- throw new \moodle_exception('cannotupdatepost', 'moodleoverflow');
+ throw new moodle_exception('cannotupdatepost', 'moodleoverflow');
}
return true;
}
@@ -834,7 +840,7 @@ private function check_user_can_delete_post() {
$this->info->deleteanypost = has_capability('mod/moodleoverflow:deleteanypost', $this->info->modulecontext);
if (!(($this->info->relatedpost->get_userid() == $USER->id && $this->info->deleteownpost) || $this->info->deleteanypost)) {
- throw new \moodle_exception('cannotdeletepost', 'moodleoverflow');
+ throw new moodle_exception('cannotdeletepost', 'moodleoverflow');
}
return true;
}
diff --git a/classes/post_form.php b/classes/post_form.php
index 6631f326e6..97e49d5716 100644
--- a/classes/post_form.php
+++ b/classes/post_form.php
@@ -134,12 +134,12 @@ public static function attachment_options($moodleoverflow) {
global $COURSE, $PAGE, $CFG;
$maxbytes = get_user_max_upload_file_size($PAGE->context, $CFG->maxbytes, $COURSE->maxbytes, $moodleoverflow->maxbytes);
- return array(
+ return [
'subdirs' => 0,
'maxbytes' => $maxbytes,
'maxfiles' => $moodleoverflow->maxattachments,
'accepted_types' => '*',
- 'return_types' => FILE_INTERNAL | FILE_CONTROLLED_LINK
- );
+ 'return_types' => FILE_INTERNAL | FILE_CONTROLLED_LINK,
+ ];
}
}
diff --git a/classes/privacy/data_export_helper.php b/classes/privacy/data_export_helper.php
index 750903a5ac..858ae859f0 100644
--- a/classes/privacy/data_export_helper.php
+++ b/classes/privacy/data_export_helper.php
@@ -22,7 +22,7 @@
*/
namespace mod_moodleoverflow\privacy;
use core_privacy\local\request\transform;
-use \core_privacy\local\request\writer;
+use core_privacy\local\request\writer;
use mod_moodleoverflow\ratings;
/**
@@ -51,7 +51,7 @@ public static function export_discussion_data($userid, array $mappings) {
FROM {moodleoverflow} mof
INNER JOIN {moodleoverflow_discussions} d ON d.moodleoverflow = mof.id
LEFT JOIN {moodleoverflow_discuss_subs} dsub ON dsub.discussion = d.id
- WHERE mof.id ${foruminsql}
+ WHERE mof.id {$foruminsql}
AND (
d.userid = :discussionuserid OR
d.usermodified = :dmuserid OR
@@ -78,7 +78,7 @@ public static function export_discussion_data($userid, array $mappings) {
'name' => format_string($discussion->name, true),
'timemodified' => transform::datetime($discussion->timemodified),
'creator_was_you' => transform::yesno($discussion->userid == $userid),
- 'last_modifier_was_you' => transform::yesno($discussion->usermodified == $userid)
+ 'last_modifier_was_you' => transform::yesno($discussion->usermodified == $userid),
];
// Store the discussion content.
writer::with_context($context)->export_data(
@@ -113,7 +113,7 @@ public static function export_all_posts($userid, array $mappings) {
INNER JOIN {moodleoverflow_posts} p ON p.discussion = d.id
LEFT JOIN {moodleoverflow_read} fr ON fr.postid = p.id
LEFT JOIN {moodleoverflow_ratings} rat ON rat.postid = p.id
- WHERE mof.id ${foruminsql} AND
+ WHERE mof.id {$foruminsql} AND
(
p.userid = :postuserid OR
fr.userid = :readuserid OR
@@ -164,7 +164,7 @@ protected static function export_all_posts_in_discussion($userid, \context $cont
$params = [
'discussionid' => $discussionid,
'readuserid' => $userid,
- 'ratinguserid' => $userid
+ 'ratinguserid' => $userid,
];
// Keep track of the forums which have data.
@@ -237,7 +237,7 @@ protected static function export_post_data($userid, \context $context, $postarea
$postdata = (object) [
'created' => transform::datetime($post->created),
'modified' => transform::datetime($post->modified),
- 'author_was_you' => transform::yesno($post->userid == $userid)
+ 'author_was_you' => transform::yesno($post->userid == $userid),
];
$postdata->message = writer::with_context($context)->rewrite_pluginfile_urls(
$postarea, 'mod_moodleoverflow', 'attachment', $post->id, $post->message);
@@ -285,11 +285,11 @@ protected static function export_rating_data($postid, $onlyuser, $userid) {
'userid' => $userid,
'postid' => $postid,
]);
- $userratings = array();
+ $userratings = [];
foreach ($ownratings as $rating) {
$userratings[] = (object) [
'firstrated' => $rating->firstrated,
- 'rating' => $rating->rating
+ 'rating' => $rating->rating,
];
}
@@ -298,7 +298,7 @@ protected static function export_rating_data($postid, $onlyuser, $userid) {
'downvotes' => $ratingpost->downvotes,
'upvotes' => $ratingpost->upvotes,
'was_rated_as_helpful' => transform::yesno($ratingpost->ishelpful),
- 'was_rated_as_solved' => transform::yesno($ratingpost->issolved)
+ 'was_rated_as_solved' => transform::yesno($ratingpost->issolved),
];
}
$ratingdata['your_rating'] = (object) $userratings;
diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php
index 139ec513c4..d1bf9e7644 100644
--- a/classes/privacy/provider.php
+++ b/classes/privacy/provider.php
@@ -25,12 +25,12 @@
namespace mod_moodleoverflow\privacy;
use core_privacy\local\request\approved_userlist;
-use \core_privacy\local\request\userlist;
+use core_privacy\local\request\userlist;
use core_privacy\local\metadata\collection;
use core_privacy\local\request\approved_contextlist;
use core_privacy\local\request\contextlist;
use core_privacy\local\request\writer;
-use \core_privacy\local\request\helper as request_helper;
+use core_privacy\local\request\helper as request_helper;
/**
* Privacy Subsystem for mod_moodleoverflow implementing provider.
@@ -56,7 +56,7 @@ public static function get_metadata(collection $collection) : collection {
'name' => 'privacy:metadata:moodleoverflow_discussions:name',
'userid' => 'privacy:metadata:moodleoverflow_discussions:userid',
'timemodified' => 'privacy:metadata:moodleoverflow_discussions:timemodified',
- 'usermodified' => 'privacy:metadata:moodleoverflow_discussions:usermodified'
+ 'usermodified' => 'privacy:metadata:moodleoverflow_discussions:usermodified',
],
'privacy:metadata:moodleoverflow_discussions');
@@ -67,7 +67,7 @@ public static function get_metadata(collection $collection) : collection {
'userid' => 'privacy:metadata:moodleoverflow_posts:userid',
'created' => 'privacy:metadata:moodleoverflow_posts:created',
'modified' => 'privacy:metadata:moodleoverflow_posts:modified',
- 'message' => 'privacy:metadata:moodleoverflow_posts:message'
+ 'message' => 'privacy:metadata:moodleoverflow_posts:message',
],
'privacy:metadata:moodleoverflow_posts');
@@ -77,14 +77,14 @@ public static function get_metadata(collection $collection) : collection {
'discussionid' => 'privacy:metadata:moodleoverflow_read:discussionid',
'postid' => 'privacy:metadata:moodleoverflow_read:postid',
'firstread' => 'privacy:metadata:moodleoverflow_read:firstread',
- 'lastread' => 'privacy:metadata:moodleoverflow_read:lastread'
+ 'lastread' => 'privacy:metadata:moodleoverflow_read:lastread',
],
'privacy:metadata:moodleoverflow_read');
$collection->add_database_table('moodleoverflow_subscriptions',
[
'userid' => 'privacy:metadata:moodleoverflow_subscriptions:userid',
- 'moodleoverflow' => 'privacy:metadata:moodleoverflow_subscriptions:moodleoverflow'
+ 'moodleoverflow' => 'privacy:metadata:moodleoverflow_subscriptions:moodleoverflow',
],
'privacy:metadata:moodleoverflow_subscriptions');
@@ -92,7 +92,7 @@ public static function get_metadata(collection $collection) : collection {
[
'userid' => 'privacy:metadata:moodleoverflow_discuss_subs:userid',
'discussion' => 'privacy:metadata:moodleoverflow_discuss_subs:discussion',
- 'preference' => 'privacy:metadata:moodleoverflow_discuss_subs:preference'
+ 'preference' => 'privacy:metadata:moodleoverflow_discuss_subs:preference',
],
'privacy:metadata:moodleoverflow_discuss_subs');
@@ -102,14 +102,14 @@ public static function get_metadata(collection $collection) : collection {
'postid' => 'privacy:metadata:moodleoverflow_ratings:postid',
'rating' => 'privacy:metadata:moodleoverflow_ratings:rating',
'firstrated' => 'privacy:metadata:moodleoverflow_ratings:firstrated',
- 'lastchanged' => 'privacy:metadata:moodleoverflow_ratings:lastchanged'
+ 'lastchanged' => 'privacy:metadata:moodleoverflow_ratings:lastchanged',
],
'privacy:metadata:moodleoverflow_ratings');
$collection->add_database_table('moodleoverflow_tracking',
[
'userid' => 'privacy:metadata:moodleoverflow_tracking:userid',
- 'moodleoverflowid' => 'privacy:metadata:moodleoverflow_tracking:moodleoverflowid'
+ 'moodleoverflowid' => 'privacy:metadata:moodleoverflow_tracking:moodleoverflowid',
],
'privacy:metadata:moodleoverflow_tracking');
@@ -177,7 +177,7 @@ public static function get_contexts_for_userid(int $userid) : contextlist {
'dsuserid' => $userid,
'rauserid' => $userid,
'tuserid' => $userid,
- 'guserid' => $userid
+ 'guserid' => $userid,
];
$contextlist = new \core_privacy\local\request\contextlist();
@@ -225,7 +225,7 @@ public static function export_user_data(approved_contextlist $contextlist) {
$params = [
'suserid' => $userid,
'userid' => $userid,
- 'guserid' => $userid
+ 'guserid' => $userid,
];
$params += $contextparams;
@@ -324,29 +324,29 @@ public static function delete_data_for_user(approved_contextlist $contextlist) {
$DB->delete_records('moodleoverflow_read', [
'moodleoverflowid' => $forum->id,
- 'userid' => $userid]);
+ 'userid' => $userid, ]);
$DB->delete_records('moodleoverflow_subscriptions', [
'moodleoverflow' => $forum->id,
- 'userid' => $userid]);
+ 'userid' => $userid, ]);
$DB->delete_records('moodleoverflow_discuss_subs', [
'moodleoverflow' => $forum->id,
- 'userid' => $userid]);
+ 'userid' => $userid, ]);
$DB->delete_records('moodleoverflow_tracking', [
'moodleoverflowid' => $forum->id,
- 'userid' => $userid]);
+ 'userid' => $userid, ]);
$DB->delete_records('moodleoverflow_grades', [
'moodleoverflowid' => $forum->id,
- 'userid' => $userid]);
+ 'userid' => $userid, ]);
// Do not delete ratings but reset userid.
$ratingsql = "userid = :userid AND discussionid IN
(SELECT id FROM {moodleoverflow_discussions} WHERE moodleoverflow = :forum)";
$ratingparams = [
'forum' => $forum->id,
- 'userid' => $userid
+ 'userid' => $userid,
];
$DB->set_field_select('moodleoverflow_ratings', 'userid', 0, $ratingsql, $ratingparams);
@@ -355,7 +355,7 @@ public static function delete_data_for_user(approved_contextlist $contextlist) {
$postidsql = "SELECT p.id FROM {moodleoverflow_posts} p WHERE {$postsql}";
$postparams = [
'forum' => $forum->id,
- 'userid' => $userid
+ 'userid' => $userid,
];
// Delete all files from the posts.
diff --git a/classes/ratings.php b/classes/ratings.php
index 6db3641bf7..056dd64f87 100644
--- a/classes/ratings.php
+++ b/classes/ratings.php
@@ -55,30 +55,30 @@ public static function moodleoverflow_add_rating($moodleoverflow, $postid, $rati
}
// Is the submitted rating valid?
- $possibleratings = array(RATING_NEUTRAL, RATING_DOWNVOTE, RATING_UPVOTE, RATING_SOLVED,
+ $possibleratings = [RATING_NEUTRAL, RATING_DOWNVOTE, RATING_UPVOTE, RATING_SOLVED,
RATING_HELPFUL, RATING_REMOVE_DOWNVOTE, RATING_REMOVE_UPVOTE,
- RATING_REMOVE_SOLVED, RATING_REMOVE_HELPFUL);
+ RATING_REMOVE_SOLVED, RATING_REMOVE_HELPFUL, ];
if (!in_array($rating, $possibleratings)) {
throw new moodle_exception('invalidratingid', 'moodleoverflow');
}
// Get the related discussion.
- if (!$post = $DB->get_record('moodleoverflow_posts', array('id' => $postid))) {
+ if (!$post = $DB->get_record('moodleoverflow_posts', ['id' => $postid])) {
throw new moodle_exception('invalidparentpostid', 'moodleoverflow');
}
// Check if the post belongs to a discussion.
- if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $post->discussion))) {
+ if (!$discussion = $DB->get_record('moodleoverflow_discussions', ['id' => $post->discussion])) {
throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
}
// Get the related course.
- if (!$course = $DB->get_record('course', array('id' => $moodleoverflow->course))) {
+ if (!$course = $DB->get_record('course', ['id' => $moodleoverflow->course])) {
throw new moodle_exception('invalidcourseid');
}
// Are multiple marks allowed?
- $markssetting = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow->id), 'allowmultiplemarks');
+ $markssetting = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow->id], 'allowmultiplemarks');
$multiplemarks = (bool) $markssetting->allowmultiplemarks;
// Retrieve the contexts.
@@ -93,10 +93,10 @@ public static function moodleoverflow_add_rating($moodleoverflow, $postid, $rati
if (!isguestuser() && !is_enrolled($coursecontext)) {
$SESSION->wantsurl = qualified_me();
$SESSION->enrolcancel = get_local_referer(false);
- redirect(new \moodle_url('/enrol/index.php', array(
+ redirect(new \moodle_url('/enrol/index.php', [
'id' => $course->id,
- 'returnurl' => '/mod/moodleoverflow/view.php?m' . $moodleoverflow->id
- )), get_string('youneedtoenrol'));
+ 'returnurl' => '/mod/moodleoverflow/view.php?m' . $moodleoverflow->id,
+ ]), get_string('youneedtoenrol'));
}
// Notify the user, that he can not post a new discussion.
@@ -212,7 +212,7 @@ public static function moodleoverflow_get_reputation($moodleoverflowid, $userid
}
// Check the moodleoverflow instance.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflowid))) {
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflowid])) {
throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
}
@@ -236,7 +236,7 @@ public static function moodleoverflow_sort_answers_by_ratings($posts) {
$parentpost = array_shift($answerposts);
// Create an empty array for the sorted posts and add the parent post.
- $sortedposts = array();
+ $sortedposts = [];
$sortedposts[0] = $parentpost;
// Check if solved posts are preferred over helpful posts.
@@ -343,7 +343,7 @@ public static function moodleoverflow_sort_answers_by_ratings($posts) {
// Rearrange the indices and return the sorted posts.
- $neworder = array();
+ $neworder = [];
foreach ($sortedposts as $post) {
$neworder[$post->id] = $post;
}
@@ -387,7 +387,7 @@ public static function moodleoverflow_get_rating($postid) {
global $DB;
// Retrieve the full post.
- if (!$post = $DB->get_record('moodleoverflow_posts', array('id' => $postid))) {
+ if (!$post = $DB->get_record('moodleoverflow_posts', ['id' => $postid])) {
throw new moodle_exception('postnotexist', 'moodleoverflow');
}
@@ -448,10 +448,10 @@ public static function moodleoverflow_discussion_is_solved($discussionid, $teach
if ($teacher) {
// Check if a teacher marked a solution as solved.
- if ($DB->record_exists('moodleoverflow_ratings', array('discussionid' => $discussionid, 'rating' => 3))) {
+ if ($DB->record_exists('moodleoverflow_ratings', ['discussionid' => $discussionid, 'rating' => 3])) {
// Return the rating records.
- return $DB->get_records('moodleoverflow_ratings', array('discussionid' => $discussionid, 'rating' => 3));
+ return $DB->get_records('moodleoverflow_ratings', ['discussionid' => $discussionid, 'rating' => 3]);
}
// The teacher has not marked the discussion as solved.
@@ -459,10 +459,10 @@ public static function moodleoverflow_discussion_is_solved($discussionid, $teach
}
// Check if the topic starter marked a solution as helpful.
- if ($DB->record_exists('moodleoverflow_ratings', array('discussionid' => $discussionid, 'rating' => 4))) {
+ if ($DB->record_exists('moodleoverflow_ratings', ['discussionid' => $discussionid, 'rating' => 4])) {
// Return the rating records.
- return $DB->get_records('moodleoverflow_ratings', array('discussionid' => $discussionid, 'rating' => 4));
+ return $DB->get_records('moodleoverflow_ratings', ['discussionid' => $discussionid, 'rating' => 4]);
}
// The topic starter has not marked a solution as helpful.
@@ -486,7 +486,7 @@ public static function moodleoverflow_get_reputation_instance($moodleoverflowid,
}
// Check the moodleoverflow instance.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflowid))) {
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflowid])) {
throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
}
@@ -508,11 +508,11 @@ public static function moodleoverflow_get_reputation_instance($moodleoverflowid,
$sql .= "ORDER BY r.postid ASC";
- $params = array($userid, $userid, $moodleoverflowid);
+ $params = [$userid, $userid, $moodleoverflowid];
$records = $DB->get_records_sql($sql, $params);
// Check if there are results.
- $records = (isset($records)) ? $records : array();
+ $records = (isset($records)) ? $records : [];
// Iterate through all ratings.
foreach ($records as $record) {
@@ -551,7 +551,7 @@ public static function moodleoverflow_get_reputation_instance($moodleoverflowid,
$sql = "SELECT COUNT(id) as amount
FROM {moodleoverflow_ratings}
WHERE userid = ? AND moodleoverflowid = ? AND (rating = 1 OR rating = 2)";
- $params = array($userid, $moodleoverflowid);
+ $params = [$userid, $moodleoverflowid];
$votes = $DB->get_record_sql($sql, $params);
// Add reputation for the votes.
@@ -586,7 +586,7 @@ public static function moodleoverflow_get_reputation_course($courseid, $userid =
$reputation = 0;
// Check if the course exists.
- if (!$course = $DB->get_record('course', array('id' => $courseid))) {
+ if (!$course = $DB->get_record('course', ['id' => $courseid])) {
throw new moodle_exception('invalidcourseid');
}
@@ -595,11 +595,11 @@ public static function moodleoverflow_get_reputation_course($courseid, $userid =
FROM {moodleoverflow}
WHERE course = ?
AND coursewidereputation = 1";
- $params = array($course->id);
+ $params = [$course->id];
$instances = $DB->get_records_sql($sql, $params);
// Check if there are instances in this course.
- $instances = (isset($instances)) ? $instances : array();
+ $instances = (isset($instances)) ? $instances : [];
// Sum the reputation of each individual instance.
foreach ($instances as $instance) {
@@ -623,7 +623,7 @@ private static function moodleoverflow_check_old_rating($postid, $userid, $oldra
global $DB;
// Initiate the array.
- $rating = array();
+ $rating = [];
// Get the normal rating.
$sql = "SELECT *
@@ -705,16 +705,16 @@ private static function moodleoverflow_remove_rating($postid, $rating, $userid,
$oldrecord = self::moodleoverflow_check_old_rating($postid, $userid, $rating);
// Trigger an event.
- $params = array(
+ $params = [
'objectid' => $oldrecord->id,
'context' => $modulecontext,
- );
+ ];
$event = \mod_moodleoverflow\event\rating_deleted::create($params);
$event->add_record_snapshot('moodleoverflow_ratings', $oldrecord);
$event->trigger();
// Remove the rating record.
- return $DB->delete_records('moodleoverflow_ratings', array('id' => $oldrecord->id));
+ return $DB->delete_records('moodleoverflow_ratings', ['id' => $oldrecord->id]);
}
/**
@@ -746,10 +746,10 @@ private static function moodleoverflow_add_rating_record($moodleoverflowid, $dis
$recordid = $DB->insert_record('moodleoverflow_ratings', $record);
// Trigger an event.
- $params = array(
+ $params = [
'objectid' => $recordid,
'context' => $mod,
- );
+ ];
$event = \mod_moodleoverflow\event\rating_created::create($params);
$event->trigger();
@@ -777,14 +777,14 @@ private static function moodleoverflow_update_rating_record($postid, $rating, $u
WHERE id = ?";
// Trigger an event.
- $params = array(
+ $params = [
'objectid' => $ratingid,
'context' => $modulecontext,
- );
+ ];
$event = \mod_moodleoverflow\event\rating_updated::create($params);
$event->trigger();
- return $DB->execute($sql, array($postid, $userid, $rating, time(), $ratingid));
+ return $DB->execute($sql, [$postid, $userid, $rating, time(), $ratingid]);
}
/**
diff --git a/classes/readtracking.php b/classes/readtracking.php
index 54a5e57e65..24d4530498 100644
--- a/classes/readtracking.php
+++ b/classes/readtracking.php
@@ -106,7 +106,7 @@ public static function moodleoverflow_is_tracked($moodleoverflow, $user = null)
// Check the preferences of the user.
$userpreference = $DB->get_record('moodleoverflow_tracking',
- array('userid' => $user->id, 'moodleoverflowid' => $moodleoverflow->id));
+ ['userid' => $user->id, 'moodleoverflowid' => $moodleoverflow->id]);
// Return the boolean.
if (get_config('moodleoverflow', 'allowforcedreadtracking')) {
@@ -242,7 +242,7 @@ public static function moodleoverflow_add_read_record($userid, $postid) {
$cutoffdate = $now - (get_config('moodleoverflow', 'oldpostdays') * 24 * 3600);
// Check for read records for this user an this post.
- $oldrecord = $DB->get_record('moodleoverflow_read', array('postid' => $postid, 'userid' => $userid));
+ $oldrecord = $DB->get_record('moodleoverflow_read', ['postid' => $postid, 'userid' => $userid]);
if (!$oldrecord) {
// If there are no old records, create a new one.
@@ -252,7 +252,7 @@ public static function moodleoverflow_add_read_record($userid, $postid) {
JOIN {moodleoverflow_discussions} d ON d.id = p.discussion
WHERE p.id = ? AND p.modified >= ?";
- return $DB->execute($sql, array($userid, $now, $now, $postid, $cutoffdate));
+ return $DB->execute($sql, [$userid, $now, $now, $postid, $cutoffdate]);
}
// Else update the existing one.
@@ -260,7 +260,7 @@ public static function moodleoverflow_add_read_record($userid, $postid) {
SET lastread = ?
WHERE userid = ? AND postid = ?";
- return $DB->execute($sql, array($now, $userid, $userid));
+ return $DB->execute($sql, [$now, $userid, $userid]);
}
/**
@@ -278,7 +278,7 @@ public static function moodleoverflow_delete_read_records($userid = -1, $postid
global $DB;
// Initiate variables.
- $params = array();
+ $params = [];
$select = '';
// Create the sql-Statement depending on the submitted parameters.
@@ -351,7 +351,7 @@ public static function moodleoverflow_clean_read_records() {
WHERE postid IN (SELECT p.id
FROM {moodleoverflow_posts} p
WHERE p.modified >= ? AND p.modified < ?)";
- $DB->execute($sql, array($first, $cutoffdate));
+ $DB->execute($sql, [$first, $cutoffdate]);
}
/**
@@ -371,7 +371,7 @@ public static function moodleoverflow_stop_tracking($moodleoverflowid, $userid =
}
// Check if the user already stopped to track the moodleoverflow.
- $params = array('userid' => $userid, 'moodleoverflowid' => $moodleoverflowid);
+ $params = ['userid' => $userid, 'moodleoverflowid' => $moodleoverflowid];
$isstopped = $DB->record_exists('moodleoverflow_tracking', $params);
// Stop tracking the moodleoverflow if not already stopped.
@@ -410,7 +410,7 @@ public static function moodleoverflow_start_tracking($moodleoverflowid, $userid
}
// Delete the tracking setting of this user for this moodleoverflow.
- return $DB->delete_records('moodleoverflow_tracking', array('userid' => $userid, 'moodleoverflowid' => $moodleoverflowid));
+ return $DB->delete_records('moodleoverflow_tracking', ['userid' => $userid, 'moodleoverflowid' => $moodleoverflowid]);
}
/**
@@ -446,11 +446,11 @@ public static function get_untracked_moodleoverflows($userid, $courseid) {
WHERE m.course = ? $trackingsql";
// Get all untracked moodleoverflows from the database.
- $moodleoverflows = $DB->get_records_sql($sql, array($userid, $courseid, $userid));
+ $moodleoverflows = $DB->get_records_sql($sql, [$userid, $courseid, $userid]);
// Check whether there are no untracked moodleoverflows.
if (!$moodleoverflows) {
- return array();
+ return [];
}
// Loop through all moodleoverflows.
@@ -491,7 +491,7 @@ public static function moodleoverflow_count_unread_posts_moodleoverflow($cm) {
$cutoffdate = $now - (get_config('moodleoverflow', 'oldpostdays') * 24 * 60 * 60);
// Define a sql-query.
- $params = array($USER->id, $cm->instance, $cutoffdate);
+ $params = [$USER->id, $cm->instance, $cutoffdate];
$sql = "SELECT COUNT(p.id)
FROM {moodleoverflow_posts} p
JOIN {moodleoverflow_discussions} d ON p.discussion = d.id
diff --git a/classes/review.php b/classes/review.php
index 30b92eb71e..833969f960 100644
--- a/classes/review.php
+++ b/classes/review.php
@@ -72,7 +72,7 @@ public static function get_short_review_info_for_discussion(int $discussionid) {
'FROM {moodleoverflow_posts} ' .
'WHERE discussion = :discussionid AND reviewed = 0 AND created < :cutofftime', [
'discussionid' => $discussionid,
- 'cutofftime' => time() - get_config('moodleoverflow', 'reviewpossibleaftertime')
+ 'cutofftime' => time() - get_config('moodleoverflow', 'reviewpossibleaftertime'),
]
);
}
@@ -89,7 +89,7 @@ public static function get_first_review_post($moodleoverflowid, $afterpostid = n
$params = [
'moodleoverflowid' => $moodleoverflowid,
- 'reviewtime' => time() - get_config('moodleoverflow', 'reviewpossibleaftertime')
+ 'reviewtime' => time() - get_config('moodleoverflow', 'reviewpossibleaftertime'),
];
$orderby = '';
$addwhere = '';
@@ -117,7 +117,7 @@ public static function get_first_review_post($moodleoverflowid, $afterpostid = n
);
if ($record) {
return (new \moodle_url('/mod/moodleoverflow/discussion.php', [
- 'd' => $record->discussionid
+ 'd' => $record->discussionid,
], 'p' . $record->postid))->out(false);
} else {
return null;
@@ -162,7 +162,7 @@ public static function count_outstanding_reviews_in_moodleoverflow($moodleoverfl
'JOIN {moodleoverflow_discussions} d ON d.id = p.discussion ' .
'WHERE d.moodleoverflow = :moodleoverflowid AND p.created < :cutofftime AND reviewed = 0', [
'moodleoverflowid' => $moodleoverflowid,
- 'cutofftime' => time() - get_config('moodleoverflow', 'reviewpossibleaftertime')
+ 'cutofftime' => time() - get_config('moodleoverflow', 'reviewpossibleaftertime'),
]
);
}
diff --git a/classes/subscriptions.php b/classes/subscriptions.php
index 8ea2981846..8799d30f5e 100644
--- a/classes/subscriptions.php
+++ b/classes/subscriptions.php
@@ -26,6 +26,9 @@
namespace mod_moodleoverflow;
+use context_module;
+use stdClass;
+
/**
* Moodleoverflow subscription manager.
*
@@ -51,7 +54,7 @@ class subscriptions {
*
* @var array[] An array of arrays.
*/
- protected static $moodleoverflowcache = array();
+ protected static $moodleoverflowcache = [];
/**
* The list of moodleoverflows which have been wholly retrieved for the subscription cache.
@@ -61,7 +64,7 @@ class subscriptions {
*
* @var bool[]
*/
- protected static $fetchedmoodleoverflows = array();
+ protected static $fetchedmoodleoverflows = [];
/**
* The subscription cache for moodleoverflow discussions.
@@ -73,7 +76,7 @@ class subscriptions {
*
* @var array[]
*/
- protected static $discussioncache = array();
+ protected static $discussioncache = [];
/**
* The list of moodleoverflows which have been wholly retrieved for the discussion subscription cache.
@@ -83,7 +86,7 @@ class subscriptions {
*
* @var bool[]
*/
- protected static $fetcheddiscussions = array();
+ protected static $fetcheddiscussions = [];
/**
* Returns whether a user is subscribed to this moodleoverflow or a specific discussion within the moodleoverflow.
@@ -194,14 +197,14 @@ public static function fill_subscription_cache($moodleoverflowid, $userid = null
// Create the cache for the user.
if (!isset(self::$moodleoverflowcache[$userid])) {
- self::$moodleoverflowcache[$userid] = array();
+ self::$moodleoverflowcache[$userid] = [];
}
// Check if the user is subscribed to the moodleoverflow.
if (!isset(self::$moodleoverflowcache[$userid][$moodleoverflowid])) {
// Request to the database.
- $params = array('userid' => $userid, 'moodleoverflow' => $moodleoverflowid);
+ $params = ['userid' => $userid, 'moodleoverflow' => $moodleoverflowid];
if ($DB->record_exists('moodleoverflow_subscriptions', $params)) {
self::$moodleoverflowcache[$userid][$moodleoverflowid] = true;
} else {
@@ -212,7 +215,7 @@ public static function fill_subscription_cache($moodleoverflowid, $userid = null
} else { // The request is not connected to a specific user.
// Request all records.
- $params = array('moodleoverflow' => $moodleoverflowid);
+ $params = ['moodleoverflow' => $moodleoverflowid];
$subscriptions = $DB->get_recordset('moodleoverflow_subscriptions', $params, '', 'id, userid');
// Loop through the records.
@@ -220,7 +223,7 @@ public static function fill_subscription_cache($moodleoverflowid, $userid = null
// Create a new record if necessary.
if (!isset(self::$moodleoverflowcache[$data->userid])) {
- self::$moodleoverflowcache[$data->userid] = array();
+ self::$moodleoverflowcache[$data->userid] = [];
}
// Mark the subscription state.
@@ -250,7 +253,7 @@ public static function fetch_discussion_subscription($moodleoverflowid, $userid
// Create an array, if there is no record.
if (!isset(self::$discussioncache[$userid]) || !isset(self::$discussioncache[$userid][$moodleoverflowid])) {
- return array();
+ return [];
}
// Return the cached subscription state.
@@ -277,14 +280,14 @@ public static function fill_discussion_subscription_cache($moodleoverflowid, $us
// Create a new record if necessary.
if (!isset(self::$discussioncache[$userid])) {
- self::$discussioncache[$userid] = array();
+ self::$discussioncache[$userid] = [];
}
// Check if the moodleoverflow instance is already cached.
if (!isset(self::$discussioncache[$userid][$moodleoverflowid])) {
// Get all records.
- $params = array('userid' => $userid, 'moodleoverflow' => $moodleoverflowid);
+ $params = ['userid' => $userid, 'moodleoverflow' => $moodleoverflowid];
$subscriptions = $DB->get_recordset('moodleoverflow_discuss_subs', $params,
null, 'id, discussion, preference');
@@ -301,7 +304,7 @@ public static function fill_discussion_subscription_cache($moodleoverflowid, $us
// No user ID is submitted.
// Get all records.
- $params = array('moodleoverflow' => $moodleoverflowid);
+ $params = ['moodleoverflow' => $moodleoverflowid];
$subscriptions = $DB->get_recordset('moodleoverflow_discuss_subs', $params,
null, 'id, userid, discussion, preference');
@@ -329,12 +332,12 @@ private static function add_to_discussion_cache($moodleoverflowid, $userid, $dis
// Create a new array for the user if necessary.
if (!isset(self::$discussioncache[$userid])) {
- self::$discussioncache[$userid] = array();
+ self::$discussioncache[$userid] = [];
}
// Create a new array for the moodleoverflow if necessary.
if (!isset(self::$discussioncache[$userid][$moodleoverflowid])) {
- self::$discussioncache[$userid][$moodleoverflowid] = array();
+ self::$discussioncache[$userid][$moodleoverflowid] = [];
}
// Save the users preference for that discussion in this array.
@@ -356,7 +359,7 @@ public static function subscription_disabled($moodleoverflow) {
* Checks wheter the specified moodleoverflow can be subscribed to.
*
* @param object $moodleoverflow The moodleoverflow ID
- * @param \context_module $context The module context.
+ * @param context_module $context The module context.
*
* @return boolean
*/
@@ -390,7 +393,7 @@ public static function set_subscription_mode($moodleoverflowid, $status = 1) {
global $DB;
// Change the value in the database.
- return $DB->set_field('moodleoverflow', 'forcesubscribe', $status, array('id' => $moodleoverflowid));
+ return $DB->set_field('moodleoverflow', 'forcesubscribe', $status, ['id' => $moodleoverflowid]);
}
/**
@@ -415,11 +418,11 @@ public static function get_unsubscribable_moodleoverflows() {
// Get courses that the current user is enrolled to.
$courses = enrol_get_my_courses();
if (empty($courses)) {
- return array();
+ return [];
}
// Get the IDs of all that courses.
- $courseids = array();
+ $courseids = [];
foreach ($courses as $course) {
$courseids[] = $course->id;
}
@@ -436,14 +439,15 @@ public static function get_unsubscribable_moodleoverflows() {
JOIN {modules} mo ON mo.name = :modulename AND mo.id = cm.module
LEFT JOIN {moodleoverflow_subscriptions} ms ON (ms.moodleoverflow = m.id AND ms.userid = :userid)
WHERE m.forcesubscribe <> :forcesubscribe AND ms.id IS NOT NULL AND cm.course $coursesql";
- $params = array('modulename' => 'moodleoverflow',
- 'userid' => $USER->id,
- 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE);
+ $params = ['modulename' => 'moodleoverflow',
+ 'userid' => $USER->id,
+ 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE,
+ ];
$mergedparams = array_merge($courseparams, $params);
$moodleoverflows = $DB->get_recordset_sql($sql, $mergedparams);
// Loop through all of the results and add them to an array.
- $unsubscribablemoodleoverflows = array();
+ $unsubscribablemoodleoverflows = [];
foreach ($moodleoverflows as $moodleoverflow) {
$unsubscribablemoodleoverflows[] = $moodleoverflow;
}
@@ -456,7 +460,7 @@ public static function get_unsubscribable_moodleoverflows() {
/**
* Get the list of potential subscribers to a moodleoverflow.
*
- * @param \context_module $context The moodleoverflow context.
+ * @param context_module $context The moodleoverflow context.
* @param string $fields The list of fields to return for each user.
* @param string $sort Sort order.
*
@@ -494,7 +498,7 @@ public static function fill_subscription_cache_for_course($courseid, $userid) {
// Create an array for the user if necessary.
if (!isset(self::$moodleoverflowcache[$userid])) {
- self::$moodleoverflowcache[$userid] = array();
+ self::$moodleoverflowcache[$userid] = [];
}
// Fetch a record set for all moodleoverflowids and their subscription id.
@@ -502,11 +506,11 @@ public static function fill_subscription_cache_for_course($courseid, $userid) {
FROM {moodleoverflow} m
LEFT JOIN {moodleoverflow_subscriptions} s ON (s.moodleoverflow = m.id AND s.userid = :userid)
WHERE m.course = :course AND m.forcesubscribe <> :subscriptionforced";
- $params = array(
+ $params = [
'userid' => $userid,
'course' => $courseid,
'subscriptionforced' => MOODLEOVERFLOW_FORCESUBSCRIBE,
- );
+ ];
$subscriptions = $DB->get_recordset_sql($sql, $params);
// Loop through all records.
@@ -522,7 +526,7 @@ public static function fill_subscription_cache_for_course($courseid, $userid) {
* Returns a list of user object who are subscribed to this moodleoverflow.
*
* @param stdClass $moodleoverflow The moodleoverflow record
- * @param \context_module $context The moodleoverflow context
+ * @param context_module $context The moodleoverflow context
* @param string $fields Requested user fields
* @param boolean $includediscussions Whether to take discussion subscriptions into consideration
*
@@ -616,10 +620,10 @@ public static function get_subscribed_users($moodleoverflow, $context, $fields =
public static function reset_discussion_cache() {
// Reset the discussion cache.
- self::$discussioncache = array();
+ self::$discussioncache = [];
// Reset the fetched discussions.
- self::$fetcheddiscussions = array();
+ self::$fetcheddiscussions = [];
}
/**
@@ -631,18 +635,18 @@ public static function reset_discussion_cache() {
public static function reset_moodleoverflow_cache() {
// Reset the cache.
- self::$moodleoverflowcache = array();
+ self::$moodleoverflowcache = [];
// Reset the fetched moodleoverflows.
- self::$fetchedmoodleoverflows = array();
+ self::$fetchedmoodleoverflows = [];
}
/**
* Adds user to the subscriber list.
*
* @param int $userid The user ID
- * @param \stdClass $moodleoverflow The moodleoverflow record
- * @param \context_module $context The module context
+ * @param stdClass $moodleoverflow The moodleoverflow record
+ * @param context_module $context The module context
* @param bool $userrequest Whether the user requested this change themselves.
*
* @return bool|int Returns true if the user is already subscribed or the subscription id if successfully subscribed.
@@ -656,7 +660,7 @@ public static function subscribe_user($userid, $moodleoverflow, $context, $userr
}
// Create a new subscription object.
- $sub = new \stdClass();
+ $sub = new stdClass();
$sub->userid = $userid;
$sub->moodleoverflow = $moodleoverflow->id;
@@ -667,10 +671,10 @@ public static function subscribe_user($userid, $moodleoverflow, $context, $userr
if ($userrequest) {
// Delete all those discussion subscriptions.
- $params = array(
- 'userid' => $userid,
- 'moodleoverflowid' => $moodleoverflow->id,
- 'preference' => self::MOODLEOVERFLOW_DISCUSSION_UNSUBSCRIBED);
+ $params = ['userid' => $userid,
+ 'moodleoverflowid' => $moodleoverflow->id,
+ 'preference' => self::MOODLEOVERFLOW_DISCUSSION_UNSUBSCRIBED,
+ ];
$where = 'userid = :userid AND moodleoverflow = :moodleoverflowid AND preference <> :preference';
$DB->delete_records_select('moodleoverflow_discuss_subs', $where, $params);
@@ -689,12 +693,12 @@ public static function subscribe_user($userid, $moodleoverflow, $context, $userr
self::$moodleoverflowcache[$userid][$moodleoverflow->id] = true;
// Trigger an subscription created event.
- $params = array(
+ $params = [
'context' => $context,
'objectid' => $result,
'relateduserid' => $userid,
- 'other' => array('moodleoverflowid' => $moodleoverflow->id),
- );
+ 'other' => ['moodleoverflowid' => $moodleoverflow->id],
+ ];
$event = event\subscription_created::create($params);
$event->trigger();
@@ -706,8 +710,8 @@ public static function subscribe_user($userid, $moodleoverflow, $context, $userr
* Removes user from the subscriber list.
*
* @param int $userid The user ID.
- * @param \stdClass $moodleoverflow The moodleoverflow record
- * @param \context_module $context The module context
+ * @param stdClass $moodleoverflow The moodleoverflow record
+ * @param context_module $context The module context
* @param boolean $userrequest Whether the user requested this change themselves.
*
* @return bool Always returns true
@@ -716,26 +720,26 @@ public static function unsubscribe_user($userid, $moodleoverflow, $context, $use
global $DB;
// Check if there is a subscription record.
- $params = array('userid' => $userid, 'moodleoverflow' => $moodleoverflow->id);
+ $params = ['userid' => $userid, 'moodleoverflow' => $moodleoverflow->id];
if ($subscription = $DB->get_record('moodleoverflow_subscriptions', $params)) {
// Delete this record.
- $DB->delete_records('moodleoverflow_subscriptions', array('id' => $subscription->id));
+ $DB->delete_records('moodleoverflow_subscriptions', ['id' => $subscription->id]);
// Was the unsubscription requested by the user?
if ($userrequest) {
// Delete the discussion subscriptions as well.
- $params = array(
+ $params = [
'userid' => $userid,
'moodleoverflow' => $moodleoverflow->id,
'preference' => self::MOODLEOVERFLOW_DISCUSSION_UNSUBSCRIBED,
- );
+ ];
$DB->delete_records('moodleoverflow_discuss_subs', $params);
// Update the discussion cache.
if (isset(self::$discussioncache[$userid]) && isset(self::$discussioncache[$userid][$moodleoverflow->id])) {
- self::$discussioncache[$userid][$moodleoverflow->id] = array();
+ self::$discussioncache[$userid][$moodleoverflow->id] = [];
}
}
@@ -743,12 +747,12 @@ public static function unsubscribe_user($userid, $moodleoverflow, $context, $use
self::$moodleoverflowcache[$userid][$moodleoverflow->id] = false;
// Trigger an subscription deletion event.
- $params = array(
+ $params = [
'context' => $context,
'objectid' => $subscription->id,
'relateduserid' => $userid,
- 'other' => array('moodleoverflowid' => $moodleoverflow->id),
- );
+ 'other' => ['moodleoverflowid' => $moodleoverflow->id],
+ ];
$event = event\subscription_deleted::create($params);
$event->add_record_snapshot('moodleoverflow_subscriptions', $subscription);
$event->trigger();
@@ -763,8 +767,8 @@ public static function unsubscribe_user($userid, $moodleoverflow, $context, $use
*
* TODO: Refactor this function to the new way of working with discussion and posts.
* @param int $userid The user ID
- * @param \stdClass $discussion The discussion record
- * @param \context_module $context The module context
+ * @param stdClass $discussion The discussion record
+ * @param context_module $context The module context
*
* @return bool Whether a change was made
*/
@@ -772,7 +776,7 @@ public static function subscribe_user_to_discussion($userid, $discussion, $conte
global $DB;
// Check if the user is already subscribed to the discussion.
- $params = array('userid' => $userid, 'discussion' => $discussion->id);
+ $params = ['userid' => $userid, 'discussion' => $discussion->id];
$subscription = $DB->get_record('moodleoverflow_discuss_subs', $params);
// Dont continue if the user is already subscribed.
@@ -781,14 +785,14 @@ public static function subscribe_user_to_discussion($userid, $discussion, $conte
}
// Check if the user is already subscribed to the moodleoverflow.
- $params = array('userid' => $userid, 'moodleoverflow' => $discussion->moodleoverflow);
+ $params = ['userid' => $userid, 'moodleoverflow' => $discussion->moodleoverflow];
if ($DB->record_exists('moodleoverflow_subscriptions', $params)) {
// Check if the user is unsubscribed from the discussion.
if ($subscription && $subscription->preference == self::MOODLEOVERFLOW_DISCUSSION_UNSUBSCRIBED) {
// Delete the discussion preference.
- $DB->delete_records('moodleoverflow_discuss_subs', array('id' => $subscription->id));
+ $DB->delete_records('moodleoverflow_discuss_subs', ['id' => $subscription->id]);
unset(self::$discussioncache[$userid][$discussion->moodleoverflow][$discussion->id]);
} else {
@@ -808,7 +812,7 @@ public static function subscribe_user_to_discussion($userid, $discussion, $conte
} else {
// Else a new record needs to be created.
- $subscription = new \stdClass();
+ $subscription = new stdClass();
$subscription->userid = $userid;
$subscription->moodleoverflow = $discussion->moodleoverflow;
$subscription->discussion = $discussion->id;
@@ -821,12 +825,12 @@ public static function subscribe_user_to_discussion($userid, $discussion, $conte
}
// Create a discussion subscription created event.
- $params = array(
+ $params = [
'context' => $context,
'objectid' => $subscription->id,
'relateduserid' => $userid,
- 'other' => array('moodleoverflowid' => $discussion->moodleoverflow, 'discussion' => $discussion->id),
- );
+ 'other' => ['moodleoverflowid' => $discussion->moodleoverflow, 'discussion' => $discussion->id],
+ ];
$event = event\discussion_subscription_created::create($params);
$event->trigger();
@@ -837,9 +841,9 @@ public static function subscribe_user_to_discussion($userid, $discussion, $conte
/**
* Unsubscribes the user from the specified discussion.
*
- * @param int $userid The user ID
- * @param \stdClass $discussion The discussion record
- * @param \context_module $context The context module
+ * @param int $userid The user ID
+ * @param stdClass $discussion The discussion record
+ * @param context_module $context The context module
*
* @return bool Whether a change was made
*/
@@ -847,7 +851,7 @@ public static function unsubscribe_user_from_discussion($userid, $discussion, $c
global $DB;
// Check the users subscription preference for this discussion.
- $params = array('userid' => $userid, 'discussion' => $discussion->id);
+ $params = ['userid' => $userid, 'discussion' => $discussion->id];
$subscription = $DB->get_record('moodleoverflow_discuss_subs', $params);
// If the user not already subscribed to the discussion, do not continue.
@@ -856,14 +860,14 @@ public static function unsubscribe_user_from_discussion($userid, $discussion, $c
}
// Check if the user is subscribed to the moodleoverflow.
- $params = array('userid' => $userid, 'moodleoverflow' => $discussion->moodleoverflow);
+ $params = ['userid' => $userid, 'moodleoverflow' => $discussion->moodleoverflow];
if (!$DB->record_exists('moodleoverflow_subscriptions', $params)) {
// Check if the user isn't subscribed to the moodleoverflow.
if ($subscription && $subscription->preference != self::MOODLEOVERFLOW_DISCUSSION_UNSUBSCRIBED) {
// Delete the discussion subscription.
- $DB->delete_records('moodleoverflow_discuss_subs', array('id' => $subscription->id));
+ $DB->delete_records('moodleoverflow_discuss_subs', ['id' => $subscription->id]);
unset(self::$discussioncache[$userid][$discussion->moodleoverflow][$discussion->id]);
} else {
@@ -887,7 +891,7 @@ public static function unsubscribe_user_from_discussion($userid, $discussion, $c
// There is no record.
// Create a new discussion subscription record.
- $subscription = new \stdClass();
+ $subscription = new stdClass();
$subscription->userid = $userid;
$subscription->moodleoverflow = $discussion->moodleoverflow;
$subscription->discussion = $discussion->id;
@@ -902,12 +906,12 @@ public static function unsubscribe_user_from_discussion($userid, $discussion, $c
}
// Trigger an discussion subscription deletetion event.
- $params = array(
+ $params = [
'context' => $context,
'objectid' => $subscription->id,
'relateduserid' => $userid,
- 'other' => array('moodleoverflowid' => $discussion->moodleoverflow, 'discussion' => $discussion->id),
- );
+ 'other' => ['moodleoverflowid' => $discussion->moodleoverflow, 'discussion' => $discussion->id],
+ ];
$event = event\discussion_subscription_deleted::create($params);
$event->trigger();
@@ -927,16 +931,16 @@ public static function unsubscribe_user_from_discussion($userid, $discussion, $c
*
* @return string
*/
- public static function moodleoverflow_get_subscribe_link($moodleoverflow, $context, $messages = array()) {
+ public static function moodleoverflow_get_subscribe_link($moodleoverflow, $context, $messages = []) {
global $USER, $OUTPUT;
// Define strings.
- $defaultmessages = array(
+ $defaultmessages = [
'subscribed' => get_string('unsubscribe', 'moodleoverflow'),
'unsubscribed' => get_string('subscribe', 'moodleoverflow'),
'forcesubscribed' => get_string('everyoneissubscribed', 'moodleoverflow'),
'cantsubscribe' => get_string('disallowsubscribe', 'moodleoverflow'),
- );
+ ];
// Combine strings the submitted messages.
$messages = $messages + $defaultmessages;
@@ -970,7 +974,7 @@ public static function moodleoverflow_get_subscribe_link($moodleoverflow, $conte
}
// Create an options array.
- $options = array();
+ $options = [];
$options['id'] = $moodleoverflow->id;
$options['sesskey'] = sesskey();
$options['returnurl'] = 0;
@@ -979,7 +983,7 @@ public static function moodleoverflow_get_subscribe_link($moodleoverflow, $conte
// Return the link to subscribe the user.
$url = new \moodle_url('/mod/moodleoverflow/subscribe.php', $options);
- return $OUTPUT->single_button($url, $linktext, 'get', array('title' => $linktitle));
+ return $OUTPUT->single_button($url, $linktext, 'get', ['title' => $linktitle]);
}
}
@@ -988,9 +992,9 @@ public static function moodleoverflow_get_subscribe_link($moodleoverflow, $conte
*
* TODO: Refactor this function to the new way of working with discussion and posts.
* @param object $fromform The submitted form
- * @param \stdClass $moodleoverflow The moodleoverflow record
- * @param \stdClass $discussion The discussion record
- * @param \context_module $modulecontext The context of the module
+ * @param stdClass $moodleoverflow The moodleoverflow record
+ * @param stdClass $discussion The discussion record
+ * @param context_module $modulecontext The context of the module
*
* @return bool
*/
@@ -1046,12 +1050,12 @@ public static function get_discussion_subscription_icon($moodleoverflow, $contex
$status = self::is_subscribed($USER->id, $moodleoverflow, $context, $discussionid);
// Create a link to subscribe or unsubscribe to the discussion.
- $array = array(
+ $array = [
'sesskey' => sesskey(),
'id' => $moodleoverflow->id,
'd' => $discussionid,
'returnurl' => $returnurl,
- );
+ ];
$subscriptionlink = new \moodle_url('/mod/moodleoverflow/subscribe.php', $array);
// Create an icon to unsubscribe.
@@ -1062,13 +1066,13 @@ public static function get_discussion_subscription_icon($moodleoverflow, $contex
$output = $OUTPUT->pix_icon('i/subscribed', $string, 'mod_moodleoverflow');
// Return the link.
- $array = array(
+ $array = [
'title' => get_string('clicktounsubscribe', 'moodleoverflow'),
'class' => 'discussiontoggle text-muted',
'data-moodleoverflowid' => $moodleoverflow->id,
'data-discussionid' => $discussionid,
'data-includetext' => false,
- );
+ ];
return \html_writer::link($subscriptionlink, $output, $array);
}
@@ -1078,13 +1082,13 @@ public static function get_discussion_subscription_icon($moodleoverflow, $contex
$output = $OUTPUT->pix_icon('i/unsubscribed', $string, 'mod_moodleoverflow');
// Return the link.
- $array = array(
+ $array = [
'title' => get_string('clicktosubscribe', 'moodleoverflow'),
'class' => 'discussiontoggle text-muted',
'data-moodleoverflowid' => $moodleoverflow->id,
'data-discussionid' => $discussionid,
'data-includetext' => false,
- );
+ ];
return \html_writer::link($subscriptionlink, $output, $array);
}
diff --git a/classes/tables/userstats_table.php b/classes/tables/userstats_table.php
index 1c1e9a24a4..5b439420d4 100644
--- a/classes/tables/userstats_table.php
+++ b/classes/tables/userstats_table.php
@@ -45,7 +45,7 @@ class userstats_table extends \flexible_table {
private $moodleoverflowid;
/** @var array table that will have objects with every user and his statistics. */
- private $userstatsdata = array();
+ private $userstatsdata = [];
/** @var \stdClass Help icon for amountofactivity-column.*/
private $helpactivity;
@@ -75,7 +75,7 @@ public function __construct($uniqueid, $courseid, $moodleoverflow, $url) {
'forumactivity',
'courseactivity',
'forumreputation',
- 'coursereputation']);
+ 'coursereputation', ]);
$this->define_baseurl($url);
$this->define_headers([get_string('fullnameuser'),
get_string('userstatsupvotes', 'moodleoverflow'),
@@ -83,7 +83,7 @@ public function __construct($uniqueid, $courseid, $moodleoverflow, $url) {
(get_string('userstatsforumactivity', 'moodleoverflow') . $this->helpactivity->object),
(get_string('userstatscourseactivity', 'moodleoverflow') . $this->helpactivity->object),
get_string('userstatsforumreputation', 'moodleoverflow'),
- get_string('userstatscoursereputation', 'moodleoverflow')]);
+ get_string('userstatscoursereputation', 'moodleoverflow'), ]);
$this->get_table_data();
$this->sortable(true, 'coursereputation', SORT_DESC);
$this->no_sorting('username');
@@ -267,17 +267,17 @@ public function set_helpactivity() {
$this->helpactivity->icon = \html_writer::img($this->helpactivity->iconurl,
get_string('helpamountofactivity', 'moodleoverflow'));
$this->helpactivity->class = 'helpactivityclass btn btn-link';
- $this->helpactivity->iconattributes = array('role' => 'button',
- 'data-container' => 'body',
- 'data-toggle' => 'popover',
- 'data-placement' => 'right',
- 'data-action' => 'showhelpicon',
- 'data-html' => 'true',
- 'data-trigger' => 'focus',
- 'tabindex' => '0',
- 'data-content' => '' .
- get_string('helpamountofactivity', 'moodleoverflow') .
- '
');
+ $this->helpactivity->iconattributes = ['role' => 'button',
+ 'data-container' => 'body',
+ 'data-toggle' => 'popover',
+ 'data-placement' => 'right',
+ 'data-action' => 'showhelpicon',
+ 'data-html' => 'true',
+ 'data-trigger' => 'focus',
+ 'tabindex' => '0',
+ 'data-content' => '' .
+ get_string('helpamountofactivity', 'moodleoverflow') .
+ '
', ];
$this->helpactivity->object = \html_writer::span($this->helpactivity->icon,
$this->helpactivity->class,
@@ -381,10 +381,10 @@ private function createstudent($user) {
$student = new \stdClass();
$student->id = $user->id;
$student->name = $user->firstname . ' ' . $user->lastname;
- $linktostudent = new \moodle_url('/user/view.php', array('id' => $student->id, 'course' => $this->courseid));
+ $linktostudent = new \moodle_url('/user/view.php', ['id' => $student->id, 'course' => $this->courseid]);
$student->link = \html_writer::link($linktostudent->out(), $student->name);
- $student->submittedposts = array(); // Posts written by the student. Key = postid, Value = postid.
- $student->ratedposts = array(); // Posts that the student rated. Key = rateid, Value = rateid.
+ $student->submittedposts = []; // Posts written by the student. Key = postid, Value = postid.
+ $student->ratedposts = []; // Posts that the student rated. Key = rateid, Value = rateid.
$student->receivedupvotes = 0;
$student->receiveddownvotes = 0;
$student->forumactivity = 0; // Number of written posts and submitted ratings in the current moodleoverflow.
diff --git a/classes/task/send_daily_mail.php b/classes/task/send_daily_mail.php
index 7c2fa1cda9..48ac7a67b2 100644
--- a/classes/task/send_daily_mail.php
+++ b/classes/task/send_daily_mail.php
@@ -52,20 +52,20 @@ public function execute() {
// Go through each user that has unread posts.
foreach ($users as $user) {
// Sorts the records with "Order by courseid".
- $userdata = $DB->get_records('moodleoverflow_mail_info', array('userid' => $user->userid), 'courseid, forumid');
- $mail = array();
+ $userdata = $DB->get_records('moodleoverflow_mail_info', ['userid' => $user->userid], 'courseid, forumid');
+ $mail = [];
// Fill the $mail array.
foreach ($userdata as $row) {
- $currentcourse = $DB->get_record('course', array('id' => $row->courseid), 'fullname, id');
- $currentforum = $DB->get_record('moodleoverflow', array('id' => $row->forumid), 'name, id');
+ $currentcourse = $DB->get_record('course', ['id' => $row->courseid], 'fullname, id');
+ $currentforum = $DB->get_record('moodleoverflow', ['id' => $row->forumid], 'name, id');
$coursemoduleid = get_coursemodule_from_instance('moodleoverflow', $row->forumid);
- $discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $row->forumdiscussionid), 'name, id');
+ $discussion = $DB->get_record('moodleoverflow_discussions', ['id' => $row->forumdiscussionid], 'name, id');
$unreadposts = $row->numberofposts;
// Build url to the course, forum, and discussion.
- $linktocourse = new \moodle_url('/course/view.php', array('id' => $currentcourse->id));
- $linktoforum = new \moodle_url('/mod/moodleoverflow/view.php', array('id' => $coursemoduleid->id));
- $linktodiscussion = new \moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $discussion->id));
+ $linktocourse = new \moodle_url('/course/view.php', ['id' => $currentcourse->id]);
+ $linktoforum = new \moodle_url('/mod/moodleoverflow/view.php', ['id' => $coursemoduleid->id]);
+ $linktodiscussion = new \moodle_url('/mod/moodleoverflow/discussion.php', ['d' => $discussion->id]);
// Now change the url to a clickable html link.
$linktocourse = \html_writer::link($linktocourse->out(), $currentcourse->fullname);
@@ -73,19 +73,19 @@ public function execute() {
$linktodiscussion = \html_writer::link($linktodiscussion->out(), $discussion->name);
// Build a single line string with the digest information and add it to the mailarray.
- $string = get_string('digestunreadpost', 'mod_moodleoverflow', array('linktocourse' => $linktocourse,
+ $string = get_string('digestunreadpost', 'mod_moodleoverflow', ['linktocourse' => $linktocourse,
'linktoforum' => $linktoforum,
'linktodiscussion' => $linktodiscussion,
- 'unreadposts' => $unreadposts));
+ 'unreadposts' => $unreadposts, ]);
array_push($mail, $string);
}
// Build the final message and send it to user. Then remove the sent records.
$message = implode('
', $mail);
- $userto = $DB->get_record('user', array('id' => $user->userid));
+ $userto = $DB->get_record('user', ['id' => $user->userid]);
$from = \core_user::get_noreply_user();
$subject = get_string('tasksenddailymail', 'mod_moodleoverflow');
email_to_user($userto, $from, $subject, $message);
- $DB->delete_records('moodleoverflow_mail_info', array('userid' => $user->userid));
+ $DB->delete_records('moodleoverflow_mail_info', ['userid' => $user->userid]);
}
}
}
diff --git a/classes/task/send_mails.php b/classes/task/send_mails.php
index 268774bc29..310bbc5f88 100644
--- a/classes/task/send_mails.php
+++ b/classes/task/send_mails.php
@@ -79,7 +79,7 @@ public function send_review_notifications() {
"ORDER BY d.course, d.moodleoverflow, d.id",
[
'mailpending' => MOODLEOVERFLOW_MAILED_PENDING,
- 'timecutoff' => time() - get_config('moodleoverflow', 'reviewpossibleaftertime')
+ 'timecutoff' => time() - get_config('moodleoverflow', 'reviewpossibleaftertime'),
]
);
@@ -109,7 +109,7 @@ public function send_review_notifications() {
$userswithcapability = get_users_by_capability($modulecontext, 'mod/moodleoverflow:reviewpost');
$coursecontext = \context_course::instance($course->id);
$usersenrolled = get_enrolled_users($coursecontext);
- $usersto = array();
+ $usersto = [];
foreach ($userswithcapability as $user) {
if (in_array($user, $usersenrolled)) {
array_push($usersto, $user);
diff --git a/db/access.php b/db/access.php
index bf56c9400f..1ea6074738 100644
--- a/db/access.php
+++ b/db/access.php
@@ -22,7 +22,7 @@
* the module version number should be bumped up.
*
* The system has four possible values for a capability:
- * CAP_ALLOW, CAP_PREVENT, CAP_PROHIBIT, and inherit (not set).
+ * CAP_ALLOW, CAP_PREVENT, CAP_PROHIBIT, and inherit (not set].
*
* It is important that capability names are unique. The naming convention
* for capabilities that are specific to modules and blocks is as follows:
@@ -47,181 +47,181 @@
defined('MOODLE_INTERNAL') || die();
// Modify capabilities as needed and remove this comment.
-$capabilities = array(
- 'mod/moodleoverflow:addinstance' => array(
+$capabilities = [
+ 'mod/moodleoverflow:addinstance' => [
'riskbitmask' => RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_COURSE,
- 'archetypes' => array(
+ 'archetypes' => [
'editingteacher' => CAP_ALLOW,
- 'manager' => CAP_ALLOW
- ),
- 'clonepermissionsfrom' => 'moodle/course:manageactivities'
- ),
- 'mod/moodleoverflow:viewdiscussion' => array(
+ 'manager' => CAP_ALLOW,
+ ],
+ 'clonepermissionsfrom' => 'moodle/course:manageactivities',
+ ],
+ 'mod/moodleoverflow:viewdiscussion' => [
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
- 'archetypes' => array(
+ 'archetypes' => [
'frontpage' => CAP_ALLOW,
'guest' => CAP_ALLOW,
'student' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
- 'manager' => CAP_ALLOW
- ),
- 'clonepermissionsfrom' => 'mod/forum:viewdiscussion'
- ),
+ 'manager' => CAP_ALLOW,
+ ],
+ 'clonepermissionsfrom' => 'mod/forum:viewdiscussion',
+ ],
- 'mod/moodleoverflow:replypost' => array(
+ 'mod/moodleoverflow:replypost' => [
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
- 'archetypes' => array(
+ 'archetypes' => [
'student' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
- 'manager' => CAP_ALLOW
- ),
- 'clonepermissionsfrom' => 'mod/forum:replypost'
- ),
+ 'manager' => CAP_ALLOW,
+ ],
+ 'clonepermissionsfrom' => 'mod/forum:replypost',
+ ],
- 'mod/moodleoverflow:startdiscussion' => array(
+ 'mod/moodleoverflow:startdiscussion' => [
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
- 'archetypes' => array(
+ 'archetypes' => [
'student' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
- 'manager' => CAP_ALLOW
- ),
- 'clonepermissionsfrom' => 'mod/forum:startdiscussion'
- ),
+ 'manager' => CAP_ALLOW,
+ ],
+ 'clonepermissionsfrom' => 'mod/forum:startdiscussion',
+ ],
- 'mod/moodleoverflow:editanypost' => array(
+ 'mod/moodleoverflow:editanypost' => [
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
- 'archetypes' => array(
+ 'archetypes' => [
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
- 'manager' => CAP_ALLOW
- ),
- 'clonepermissionsfrom' => 'mod/forum:editanypost'
- ),
+ 'manager' => CAP_ALLOW,
+ ],
+ 'clonepermissionsfrom' => 'mod/forum:editanypost',
+ ],
- 'mod/moodleoverflow:deleteownpost' => array(
+ 'mod/moodleoverflow:deleteownpost' => [
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
- 'archetypes' => array(
+ 'archetypes' => [
'student' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
- 'manager' => CAP_ALLOW
- ),
- 'clonepermissionsfrom' => 'mod/forum:deleteownpost'
- ),
+ 'manager' => CAP_ALLOW,
+ ],
+ 'clonepermissionsfrom' => 'mod/forum:deleteownpost',
+ ],
- 'mod/moodleoverflow:deleteanypost' => array(
+ 'mod/moodleoverflow:deleteanypost' => [
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
- 'archetypes' => array(
+ 'archetypes' => [
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
- 'manager' => CAP_ALLOW
- ),
- 'clonepermissionsfrom' => 'mod/forum:deleteanypost'
- ),
- 'mod/moodleoverflow:ratepost' => array(
+ 'manager' => CAP_ALLOW,
+ ],
+ 'clonepermissionsfrom' => 'mod/forum:deleteanypost',
+ ],
+ 'mod/moodleoverflow:ratepost' => [
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
- 'archetypes' => array(
+ 'archetypes' => [
'student' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
- 'manager' => CAP_ALLOW
- )
- ),
+ 'manager' => CAP_ALLOW,
+ ],
+ ],
- 'mod/moodleoverflow:marksolved' => array(
+ 'mod/moodleoverflow:marksolved' => [
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
- 'archetypes' => array(
+ 'archetypes' => [
'student' => CAP_PROHIBIT,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
- 'manager' => CAP_ALLOW
- )
- ),
+ 'manager' => CAP_ALLOW,
+ ],
+ ],
- 'mod/moodleoverflow:managesubscriptions' => array(
+ 'mod/moodleoverflow:managesubscriptions' => [
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
- 'archetypes' => array(
+ 'archetypes' => [
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
- 'manager' => CAP_ALLOW
- ),
- 'clonepermissionsfrom' => 'mod/forum:managesubscriptions'
- ),
+ 'manager' => CAP_ALLOW,
+ ],
+ 'clonepermissionsfrom' => 'mod/forum:managesubscriptions',
+ ],
- 'mod/moodleoverflow:allowforcesubscribe' => array(
+ 'mod/moodleoverflow:allowforcesubscribe' => [
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
- 'archetypes' => array(
+ 'archetypes' => [
'student' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
- 'frontpage' => CAP_ALLOW
- ),
- 'clonepermissionsfrom' => 'mod/forum:allowforcesubscribe'
- ),
+ 'frontpage' => CAP_ALLOW,
+ ],
+ 'clonepermissionsfrom' => 'mod/forum:allowforcesubscribe',
+ ],
- 'mod/moodleoverflow:createattachment' => array(
+ 'mod/moodleoverflow:createattachment' => [
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
- 'archetypes' => array(
+ 'archetypes' => [
'student' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
- 'manager' => CAP_ALLOW
- ),
- 'clonepermissionsfrom' => 'mod/forum:createattachment'
- ),
+ 'manager' => CAP_ALLOW,
+ ],
+ 'clonepermissionsfrom' => 'mod/forum:createattachment',
+ ],
- 'mod/moodleoverflow:reviewpost' => array(
+ 'mod/moodleoverflow:reviewpost' => [
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
- 'archetypes' => array(
+ 'archetypes' => [
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
- ),
- ),
+ ],
+ ],
- 'mod/moodleoverflow:movetopic' => array(
+ 'mod/moodleoverflow:movetopic' => [
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
- 'archetypes' => array(
+ 'archetypes' => [
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
- 'manager' => CAP_ALLOW
- ),
- ),
+ 'manager' => CAP_ALLOW,
+ ],
+ ],
- 'mod/moodleoverflow:viewanyrating' => array(
+ 'mod/moodleoverflow:viewanyrating' => [
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
- 'archetypes' => array(
+ 'archetypes' => [
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
- 'manager' => CAP_ALLOW
- ),
- 'clonepermissionsfrom' => 'mod/forum:viewanyrating'
- ),
+ 'manager' => CAP_ALLOW,
+ ],
+ 'clonepermissionsfrom' => 'mod/forum:viewanyrating',
+ ],
-);
+];
diff --git a/db/events.php b/db/events.php
index 77c3f0c3ec..73679479db 100644
--- a/db/events.php
+++ b/db/events.php
@@ -24,24 +24,24 @@
defined('MOODLE_INTERNAL') || die();
-$observers = array(
+$observers = [
// Delete read records and subscriptions if the user is not anymore enrolled.
- array(
+ [
'eventname' => '\core\event\user_enrolment_deleted',
'callback' => 'mod_moodleoverflow_observer::user_enrolment_deleted',
- ),
+ ],
// Subscribe the user to moodleoverflows which force him to when enroling a user.
- array(
+ [
'eventname' => '\core\event\role_assigned',
'callback' => 'mod_moodleoverflow_observer::role_assigned',
- ),
+ ],
// Subscribe the user to moodleoverflows which force him to when creating an instance.
- array(
+ [
'eventname' => '\core\event\course_module_created',
'callback' => 'mod_moodleoverflow_observer::course_module_created',
- ),
+ ],
-);
+];
diff --git a/db/messages.php b/db/messages.php
index c03df6a673..ee2af9a367 100644
--- a/db/messages.php
+++ b/db/messages.php
@@ -24,8 +24,7 @@
defined('MOODLE_INTERNAL') || die();
-$messageproviders = array(
-
+$messageproviders = [
// Ordinary single moodleoverflow posts.
- 'posts' => array(),
-);
+ 'posts' => [],
+];
diff --git a/db/services.php b/db/services.php
index 1069519912..d2737001d5 100644
--- a/db/services.php
+++ b/db/services.php
@@ -24,30 +24,30 @@
*/
defined('MOODLE_INTERNAL') || die;
-$functions = array(
- 'mod_moodleoverflow_record_vote' => array(
+$functions = [
+ 'mod_moodleoverflow_record_vote' => [
'classname' => 'mod_moodleoverflow_external',
'methodname' => 'record_vote',
'classpath' => 'mod/moodleoverflow/externallib.php',
'description' => 'Records a vote and updates the reputation of a user',
'type' => 'write',
'ajax' => true,
- 'capabilities' => 'mod/moodleoverflow:ratepost'
- ),
- 'mod_moodleoverflow_review_approve_post' => array(
+ 'capabilities' => 'mod/moodleoverflow:ratepost',
+ ],
+ 'mod_moodleoverflow_review_approve_post' => [
'classname' => 'mod_moodleoverflow_external',
'methodname' => 'review_approve_post',
'classpath' => 'mod/moodleoverflow/externallib.php',
'description' => 'Approves a post',
'type' => 'write',
'ajax' => true,
- ),
- 'mod_moodleoverflow_review_reject_post' => array(
+ ],
+ 'mod_moodleoverflow_review_reject_post' => [
'classname' => 'mod_moodleoverflow_external',
'methodname' => 'review_reject_post',
'classpath' => 'mod/moodleoverflow/externallib.php',
'description' => 'Rejects a post',
'type' => 'write',
'ajax' => true,
- ),
-);
+ ],
+];
diff --git a/db/tasks.php b/db/tasks.php
index d7ecba65b4..0a688b84f5 100644
--- a/db/tasks.php
+++ b/db/tasks.php
@@ -24,38 +24,38 @@
defined('MOODLE_INTERNAL') || die();
-$tasks = array(
+$tasks = [
// Deliver mail notification about new posts.
- array(
+ [
'classname' => 'mod_moodleoverflow\task\send_mails',
'blocking' => 0,
'minute' => '*',
'hour' => '*',
'day' => '*',
'month' => '*',
- 'dayofweek' => '*'
- ),
+ 'dayofweek' => '*',
+ ],
// Clean old read records.
- array(
+ [
'classname' => 'mod_moodleoverflow\task\clean_readrecords',
'blocking' => 0,
'minute' => '*',
'hour' => '*',
'day' => '*',
'month' => '*',
- 'dayofweek' => '*'
- ),
+ 'dayofweek' => '*',
+ ],
// Clean old read records.
- array(
+ [
'classname' => 'mod_moodleoverflow\task\send_daily_mail',
'blocking' => 0,
'minute' => '0',
'hour' => '17',
'day' => '*',
'month' => '*',
- 'dayofweek' => '*'
- )
-);
+ 'dayofweek' => '*',
+ ],
+];
diff --git a/db/upgrade.php b/db/upgrade.php
index eb31018162..71c9471433 100644
--- a/db/upgrade.php
+++ b/db/upgrade.php
@@ -94,8 +94,8 @@ function xmldb_moodleoverflow_upgrade($oldversion) {
$table->add_field('grade', XMLDB_TYPE_FLOAT, '10', null, XMLDB_NOTNULL, null, '0');
// Adding keys to table moodleoverflow_grades.
- $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
- $table->add_key('moodleoverflowid', XMLDB_KEY_FOREIGN, array('moodleoverflowid'), 'moodleoverflow', array('id'));
+ $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
+ $table->add_key('moodleoverflowid', XMLDB_KEY_FOREIGN, ['moodleoverflowid'], 'moodleoverflow', ['id']);
// Conditionally launch create table for moodleoverflow_grades.
if (!$dbman->table_exists($table)) {
@@ -260,12 +260,11 @@ function xmldb_moodleoverflow_upgrade($oldversion) {
$table->add_field('forumdiscussionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('numberofposts', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
- $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
- $table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
- $table->add_key('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
- $table->add_key('forumid', XMLDB_KEY_FOREIGN, array('forumid'), 'moodleoverflow', array('id'));
- $table->add_key('forumdiscussionid', XMLDB_KEY_FOREIGN,
- array('forumdiscussionid'), 'moodleoverflow_discussions', array('id'));
+ $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
+ $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
+ $table->add_key('courseid', XMLDB_KEY_FOREIGN, ['courseid'], 'course', ['id']);
+ $table->add_key('forumid', XMLDB_KEY_FOREIGN, ['forumid'], 'moodleoverflow', ['id']);
+ $table->add_key('forumdiscussionid', XMLDB_KEY_FOREIGN, ['forumdiscussionid'], 'moodleoverflow_discussions', ['id']);
// Conditionally launch create table for moodleoverflow_mail_info.
if (!$dbman->table_exists($table)) {
diff --git a/discussion.php b/discussion.php
index ed07cff8b5..135504a390 100644
--- a/discussion.php
+++ b/discussion.php
@@ -33,28 +33,28 @@
$ratedpost = optional_param('rp', 0, PARAM_INT);
// Set the URL that should be used to return to this page.
-$PAGE->set_url('/mod/moodleoverflow/discussion.php', array('d' => $d));
+$PAGE->set_url('/mod/moodleoverflow/discussion.php', ['d' => $d]);
// The page should not be large, only pages containing broad tables are usually.
$PAGE->add_body_class('limitedwidth');
// Check if the discussion is valid.
-if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $d))) {
+if (!$discussion = $DB->get_record('moodleoverflow_discussions', ['id' => $d])) {
throw new moodle_exception('invaliddiscussionid', 'moodleoverflow');
}
// Check if the related moodleoverflow instance is valid.
-if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
+if (!$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $discussion->moodleoverflow])) {
throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
}
// Check if the related moodleoverflow instance is valid.
-if (!$course = $DB->get_record('course', array('id' => $discussion->course))) {
+if (!$course = $DB->get_record('course', ['id' => $discussion->course])) {
throw new moodle_exception('invalidcourseid');
}
// Save the allowmultiplemarks setting.
-$marksetting = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow->id), 'allowmultiplemarks');
+$marksetting = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow->id], 'allowmultiplemarks');
$multiplemarks = false;
if ($marksetting->allowmultiplemarks == 1) {
$multiplemarks = true;
@@ -81,7 +81,7 @@
if ($ratingid) {
require_sesskey();
- if (in_array($ratingid, array(RATING_SOLVED, RATING_REMOVE_SOLVED, RATING_HELPFUL, RATING_REMOVE_HELPFUL))) {
+ if (in_array($ratingid, [RATING_SOLVED, RATING_REMOVE_SOLVED, RATING_HELPFUL, RATING_REMOVE_HELPFUL])) {
// Rate the post.
if (!\mod_moodleoverflow\ratings::moodleoverflow_add_rating($moodleoverflow, $ratedpost, $ratingid, $cm)) {
throw new moodle_exception('ratingfailed', 'moodleoverflow');
@@ -94,10 +94,10 @@
}
// Trigger the discussion viewed event.
-$params = array(
+$params = [
'context' => $modulecontext,
'objectid' => $discussion->id,
-);
+];
$event = \mod_moodleoverflow\event\discussion_viewed::create($params);
$event->trigger();
@@ -130,7 +130,7 @@
}
$node = $forumnode->add(format_string($discussion->name),
- new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $discussion->id)));
+ new moodle_url('/mod/moodleoverflow/discussion.php', ['d' => $discussion->id]));
$node->display = false;
if ($node && ($post->id != $discussion->firstpost)) {
$node->add(format_string($post->subject), $PAGE->url);
diff --git a/externallib.php b/externallib.php
index 22255637cd..c56375b6ed 100644
--- a/externallib.php
+++ b/externallib.php
@@ -46,25 +46,25 @@ class mod_moodleoverflow_external extends external_api {
*/
public static function record_vote_parameters() {
return new external_function_parameters(
- array(
+ [
'postid' => new external_value(PARAM_INT, 'id of post'),
- 'ratingid' => new external_value(PARAM_INT, 'rating')
- )
+ 'ratingid' => new external_value(PARAM_INT, 'rating'),
+ ]
);
}
/**
* Returns the result of the vote (new rating and reputations).
- * @return external_multiple_structure
+ * @return external_single_structure
*/
public static function record_vote_returns() {
return new external_single_structure(
- array(
+ [
'postrating' => new external_value(PARAM_INT, 'new post rating'),
'ownerreputation' => new external_value(PARAM_INT, 'new reputation of post owner'),
'raterreputation' => new external_value(PARAM_INT, 'new reputation of rater'),
'ownerid' => new external_value(PARAM_INT, 'user id of post owner'),
- )
+ ]
);
}
@@ -79,27 +79,27 @@ public static function record_vote($postid, $ratingid) {
global $DB, $USER;
// Parameter validation.
- $params = self::validate_parameters(self::record_vote_parameters(), array(
+ $params = self::validate_parameters(self::record_vote_parameters(), [
'postid' => $postid,
'ratingid' => $ratingid,
- ));
+ ]);
$transaction = $DB->start_delegated_transaction();
- $post = $DB->get_record('moodleoverflow_posts', array('id' => $params['postid']), '*', MUST_EXIST);
+ $post = $DB->get_record('moodleoverflow_posts', ['id' => $params['postid']], '*', MUST_EXIST);
// Check if the discussion is valid.
- if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $post->discussion))) {
+ if (!$discussion = $DB->get_record('moodleoverflow_discussions', ['id' => $post->discussion])) {
throw new moodle_exception('invaliddiscussionid', 'moodleoverflow');
}
// Check if the related moodleoverflow instance is valid.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $discussion->moodleoverflow])) {
throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
}
// Check if the related moodleoverflow instance is valid.
- if (!$course = $DB->get_record('course', array('id' => $discussion->course))) {
+ if (!$course = $DB->get_record('course', ['id' => $discussion->course])) {
throw new moodle_exception('invalidcourseid');
}
@@ -148,7 +148,7 @@ public static function record_vote($postid, $ratingid) {
*/
public static function review_approve_post_parameters() {
return new external_function_parameters([
- 'postid' => new external_value(PARAM_INT, 'id of post')
+ 'postid' => new external_value(PARAM_INT, 'id of post'),
]);
}
@@ -210,7 +210,7 @@ public static function review_approve_post($postid) {
public static function review_reject_post_parameters() {
return new external_function_parameters([
'postid' => new external_value(PARAM_INT, 'id of post'),
- 'reason' => new external_value(PARAM_RAW, 'reason of rejection')
+ 'reason' => new external_value(PARAM_RAW, 'reason of rejection'),
]);
}
diff --git a/index.php b/index.php
index 49e454e495..7f5bc9ff7e 100644
--- a/index.php
+++ b/index.php
@@ -25,6 +25,8 @@
// Require needed files.
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
require_once(dirname(__FILE__) . '/locallib.php');
+
+global $CFG, $USER, $DB, $PAGE, $SESSION, $OUTPUT;
require_once($CFG->dirroot . '/course/lib.php');
// Fetch submitted parameters.
@@ -32,7 +34,7 @@
$subscribe = optional_param('subscribe', null, PARAM_INT);
// Set an url to go back to the page.
-$url = new moodle_url('/mod/moodleoverflow/index.php', array('id' => $id));
+$url = new moodle_url('/mod/moodleoverflow/index.php', ['id' => $id]);
// Check whether the subscription parameter was set.
if ($subscribe !== null) {
@@ -44,7 +46,7 @@
$PAGE->set_url($url);
// Check if the id is related to a valid course.
-if (!$course = $DB->get_record('course', array('id' => $id))) {
+if (!$course = $DB->get_record('course', ['id' => $id])) {
throw new moodle_exception('invalidcourseid');
}
@@ -55,15 +57,13 @@
unset($SESSION->fromdiscussion);
// Trigger the course module instace lise viewed evewnt.
-$params = array(
- 'context' => context_course::instance($course->id)
-);
+$params = ['context' => context_course::instance($course->id)];
$event = \mod_moodleoverflow\event\course_module_instance_list_viewed::create($params);
$event->add_record_snapshot('course', $course);
$event->trigger();
// Cache some strings.
-$string = array();
+$string = [];
$string['moodleoverflow'] = get_string('moodleoverflow', 'moodleoverflow');
$string['moodleoverflows'] = get_string('moodleoverflows', 'moodleoverflow');
$string['modulenameplural'] = get_string('modulenameplural', 'moodleoverflow');
@@ -86,8 +86,8 @@
// Begin to print a table for the general area.
$generaltable = new html_table();
-$generaltable->head = array($string['moodleoverflow'], $string['description'], $string['discussions']);
-$generaltable->align = array('left', 'left', 'center');
+$generaltable->head = [$string['moodleoverflow'], $string['description'], $string['discussions']];
+$generaltable->align = ['left', 'left', 'center'];
// Check whether moodleoverflows can be tracked.
$cantrack = \mod_moodleoverflow\readtracking::moodleoverflow_can_track_moodleoverflows();
@@ -111,7 +111,7 @@
// Initiate tables and variables.
$table = new html_table();
-$generalmoodleoverflows = array();
+$generalmoodleoverflows = [];
$modinfo = get_fast_modinfo($course);
$showsubscriptioncolumns = false;
@@ -119,7 +119,7 @@
$sql = "SELECT m.*
FROM {moodleoverflow} m
WHERE m.course = ?";
-$moodleoverflows = $DB->get_records_sql($sql, array($course->id));
+$moodleoverflows = $DB->get_records_sql($sql, [$course->id]);
// Loop through allmoodleoverflows.
foreach ($modinfo->get_instances_of('moodleoverflow') as $moodleoverflowid => $cm) {
@@ -163,7 +163,7 @@
if (isguestuser() || !$showsubscriptioncolumns) {
// Redirect the user back.
- $url = new moodle_url('/mod/moodleoverflow/index.php', array('id' => $id));
+ $url = new moodle_url('/mod/moodleoverflow/index.php', ['id' => $id]);
$notification = \core\output\notification::NOTIFY_ERROR;
redirect($url, $string['subscribeenrolledonly'], null, $notification);
}
@@ -210,11 +210,11 @@
}
// Create an url to return the user back to.
- $url = new moodle_url('/mod/moodleoverflow/index.php', array('id' => $id));
+ $url = new moodle_url('/mod/moodleoverflow/index.php', ['id' => $id]);
$returnto = moodleoverflow_go_back_to($url);
// Prepare the message to be displayed.
- $shortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
+ $shortname = format_string($course->shortname, true, ['context' => context_course::instance($course->id)]);
$notification = \core\output\notification::NOTIFY_SUCCESS;
// Redirect the user depending on the subscription state.
@@ -291,15 +291,15 @@
// Tracking is optional.
// Define the url the button is linked to.
- $trackingurlparams = array('id' => $moodleoverflow->id, 'sesskey' => sesskey());
+ $trackingurlparams = ['id' => $moodleoverflow->id, 'sesskey' => sesskey()];
$trackingurl = new moodle_url('/mod/moodleoverflow/tracking.php', $trackingurlparams);
// Check whether the moodleoverflow instance is tracked.
if (!isset($untracked[$moodleoverflow->id])) {
- $trackingparam = array('title' => $string['notrackmoodleoverflow']);
+ $trackingparam = ['title' => $string['notrackmoodleoverflow']];
$trackedlink = $OUTPUT->single_button($trackingurl, $string['yes'], 'post', $trackingparam);
} else {
- $trackingparam = array('title' => $string['trackmoodleoverflow']);
+ $trackingparam = ['title' => $string['trackmoodleoverflow']];
$trackedlink = $OUTPUT->single_button($trackingurl, $string['no'], 'post', $trackingparam);
}
}
@@ -323,7 +323,7 @@
$discussionlink = "id\" $style>" . $count . "";
// Create rows.
- $row = array($moodleoverflowlink, $moodleoverflow->intro, $discussionlink);
+ $row = [$moodleoverflowlink, $moodleoverflow->intro, $discussionlink];
// Add the tracking information to the rows.
if ($cantrack) {
@@ -335,12 +335,12 @@
if ($showsubscriptioncolumns) {
// Set options to create the subscription link.
- $suboptions = array(
+ $suboptions = [
'subscribed' => $string['yes'],
'unsubscribed' => $string['no'],
'forcesubscribed' => $string['yes'],
'cantsubscribe' => '-',
- );
+ ];
// Add the subscription link to the row.
$row[] = \mod_moodleoverflow\subscriptions::moodleoverflow_get_subscribe_link($moodleoverflow,
@@ -369,7 +369,7 @@
echo $OUTPUT->box_start('subscription');
// Create the subscription link.
- $urlparams = array('id' => $course->id, 'sesskey' => sesskey());
+ $urlparams = ['id' => $course->id, 'sesskey' => sesskey()];
$subscriptionlink = new moodle_url('/mod/moodleoverflow/index.php', $urlparams);
// Give the option to subscribe to all.
diff --git a/lib.php b/lib.php
index 28eb3fa794..790ee26170 100644
--- a/lib.php
+++ b/lib.php
@@ -184,7 +184,7 @@ function moodleoverflow_update_instance(stdClass $moodleoverflow, mod_moodleover
$moodleoverflow->id = $moodleoverflow->instance;
// Get the old record.
- $oldmoodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow->id));
+ $oldmoodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow->id]);
// Find the context of the module.
$modulecontext = context_module::instance($moodleoverflow->coursemodule);
@@ -235,7 +235,7 @@ function moodleoverflow_refresh_events($courseid = 0) {
return true;
}
} else {
- if (!$moodleoverflows = $DB->get_records('moodleoverflow', array('course' => $courseid))) {
+ if (!$moodleoverflows = $DB->get_records('moodleoverflow', ['course' => $courseid])) {
return true;
}
}
@@ -261,13 +261,13 @@ function moodleoverflow_delete_instance($id) {
$result = true;
// Get the needed objects.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $id))) {
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $id])) {
return false;
}
if (!$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id)) {
return false;
}
- if (!$course = $DB->get_record('course', array('id' => $cm->course))) {
+ if (!$course = $DB->get_record('course', ['id' => $cm->course])) {
return false;
}
@@ -279,12 +279,12 @@ function moodleoverflow_delete_instance($id) {
$fs->delete_area_files($context->id);
// Delete the subscription elements.
- $DB->delete_records('moodleoverflow_subscriptions', array('moodleoverflow' => $moodleoverflow->id));
- $DB->delete_records('moodleoverflow_discuss_subs', array('moodleoverflow' => $moodleoverflow->id));
- $DB->delete_records('moodleoverflow_grades', array('moodleoverflowid' => $moodleoverflow->id));
+ $DB->delete_records('moodleoverflow_subscriptions', ['moodleoverflow' => $moodleoverflow->id]);
+ $DB->delete_records('moodleoverflow_discuss_subs', ['moodleoverflow' => $moodleoverflow->id]);
+ $DB->delete_records('moodleoverflow_grades', ['moodleoverflowid' => $moodleoverflow->id]);
// Delete the discussion recursivly.
- if ($discussions = $DB->get_records('moodleoverflow_discussions', array('moodleoverflow' => $moodleoverflow->id))) {
+ if ($discussions = $DB->get_records('moodleoverflow_discussions', ['moodleoverflow' => $moodleoverflow->id])) {
require_once('locallib.php');
foreach ($discussions as $discussion) {
if (!moodleoverflow_delete_discussion($discussion, $course, $cm, $moodleoverflow)) {
@@ -297,7 +297,7 @@ function moodleoverflow_delete_instance($id) {
\mod_moodleoverflow\readtracking::moodleoverflow_delete_read_records(-1, -1, -1, $moodleoverflow->id);
// Delete the moodleoverflow instance.
- if (!$DB->delete_records('moodleoverflow', array('id' => $moodleoverflow->id))) {
+ if (!$DB->delete_records('moodleoverflow', ['id' => $moodleoverflow->id])) {
$result = false;
}
@@ -345,13 +345,13 @@ function moodleoverflow_print_recent_activity($course, $viewfullnames, $timestar
/**
* Returns all other caps used in the module.
*
- * For example, this could be array('moodle/site:accessallgroups') if the
+ * For example, this could be ['moodle/site:accessallgroups'] if the
* module uses that capability.
*
* @return array
*/
function moodleoverflow_get_extra_capabilities() {
- return array();
+ return [];
}
/* File API */
@@ -369,10 +369,10 @@ function moodleoverflow_get_extra_capabilities() {
* @return array of [(string)filearea] => (string)description
*/
function moodleoverflow_get_file_areas($course, $cm, $context) {
- return array(
+ return [
'attachment' => get_string('areaattachment', 'mod_moodleoverflow'),
'post' => get_string('areapost', 'mod_moodleoverflow'),
- );
+ ];
}
/**
@@ -411,7 +411,7 @@ function moodleoverflow_get_file_info($browser, $areas, $course, $cm, $context,
* @param bool $forcedownload whether or not force download
* @param array $options additional options affecting the file serving
*/
-function moodleoverflow_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) {
+function moodleoverflow_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = []) {
global $DB, $CFG;
if ($context->contextlevel != CONTEXT_MODULE) {
return false;
@@ -428,13 +428,13 @@ function moodleoverflow_pluginfile($course, $cm, $context, $filearea, $args, $fo
$itemid = array_pop($args);
// Check if post, discussion or moodleoverflow still exists.
- if (!$post = $DB->get_record('moodleoverflow_posts', array('id' => $itemid))) {
+ if (!$post = $DB->get_record('moodleoverflow_posts', ['id' => $itemid])) {
return false;
}
- if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $post->discussion))) {
+ if (!$discussion = $DB->get_record('moodleoverflow_discussions', ['id' => $post->discussion])) {
return false;
}
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $cm->instance))) {
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $cm->instance])) {
return false;
}
@@ -484,7 +484,7 @@ function moodleoverflow_extend_settings_navigation(settings_navigation $settings
global $CFG, $DB, $PAGE, $USER;
// Retrieve the current moodle record.
- $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $PAGE->cm->instance));
+ $moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $PAGE->cm->instance]);
// Check if the user can subscribe to the instance.
$enrolled = is_enrolled($PAGE->cm->context, $USER, '', false);
@@ -504,7 +504,7 @@ function moodleoverflow_extend_settings_navigation(settings_navigation $settings
// Generate the link.
$url = '/mod/moodleoverflow/index.php';
- $params = array('id' => $moodleoverflow->course);
+ $params = ['id' => $moodleoverflow->course];
$link = new moodle_url($url, $params);
// Add the link to the menu.
@@ -523,7 +523,7 @@ function moodleoverflow_extend_settings_navigation(settings_navigation $settings
}
// Add the link to the menu.
- $url = new moodle_url('/mod/moodleoverflow/subscribe.php', array('id' => $moodleoverflow->id, 'sesskey' => sesskey()));
+ $url = new moodle_url('/mod/moodleoverflow/subscribe.php', ['id' => $moodleoverflow->id, 'sesskey' => sesskey()]);
$moodleoverflownode->add($linktext, $url, navigation_node::TYPE_SETTING);
}
@@ -548,7 +548,7 @@ function moodleoverflow_extend_settings_navigation(settings_navigation $settings
// Generate the link.
$url = '/mod/moodleoverflow/tracking.php';
- $params = array('id' => $moodleoverflow->id, 'sesskey' => sesskey());
+ $params = ['id' => $moodleoverflow->id, 'sesskey' => sesskey()];
$link = new moodle_url($url, $params);
// Add the link to the menu.
@@ -607,19 +607,19 @@ function moodleoverflow_send_mails() {
$textout = $PAGE->get_renderer('mod_moodleoverflow', 'email', 'textemail');
// Initiate the arrays that are saving the users that are subscribed to posts that needs sending.
- $users = array();
+ $users = [];
$userscount = 0; // Count($users) is slow. This avoids using this.
// Status arrays.
- $mailcount = array();
- $errorcount = array();
+ $mailcount = [];
+ $errorcount = [];
// Cache arrays.
- $discussions = array();
- $moodleoverflows = array();
- $courses = array();
- $coursemodules = array();
- $subscribedusers = array();
+ $discussions = [];
+ $moodleoverflows = [];
+ $courses = [];
+ $coursemodules = [];
+ $subscribedusers = [];
// Posts older than x days will not be mailed.
// This will avoid problems with the cron not beeing ran for a long time.
@@ -646,7 +646,7 @@ function moodleoverflow_send_mails() {
if (!isset($discussions[$discussionid])) {
// Retrieve the discussion from the database.
- $discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $post->discussion));
+ $discussion = $DB->get_record('moodleoverflow_discussions', ['id' => $post->discussion]);
// If there is a record, update the cache. Else ignore the post.
if ($discussion) {
@@ -665,7 +665,7 @@ function moodleoverflow_send_mails() {
if (!isset($moodleoverflows[$moodleoverflowid])) {
// Retrieve the record from the database and update the cache.
- $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflowid));
+ $moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflowid]);
if ($moodleoverflow) {
$moodleoverflows[$moodleoverflowid] = $moodleoverflow;
} else {
@@ -680,7 +680,7 @@ function moodleoverflow_send_mails() {
if (!isset($courses[$courseid])) {
// Retrieve the record from the database and update the cache.
- $course = $DB->get_record('course', array('id' => $courseid));
+ $course = $DB->get_record('course', ['id' => $courseid]);
if ($course) {
$courses[$courseid] = $course;
} else {
@@ -748,9 +748,9 @@ function moodleoverflow_send_mails() {
mtrace('Processing user ' . $userto->id);
// Initiate the user caches to save memory.
$userto = clone($userto);
- $userto->ciewfullnames = array();
- $userto->canpost = array();
- $userto->markposts = array();
+ $userto->ciewfullnames = [];
+ $userto->canpost = [];
+ $userto->markposts = [];
// Cache the capabilities of the user.
// Check for moodle version. Version 401 supported until 8 December 2025.
@@ -763,7 +763,7 @@ function moodleoverflow_send_mails() {
// Reset the caches.
foreach ($coursemodules as $moodleoverflowid => $unused) {
$coursemodules[$moodleoverflowid]->cache = new stdClass();
- $coursemodules[$moodleoverflowid]->cache->caps = array();
+ $coursemodules[$moodleoverflowid]->cache->caps = [];
unset($coursemodules[$moodleoverflowid]->uservisible);
}
@@ -787,10 +787,10 @@ function moodleoverflow_send_mails() {
$dataobject->forumid = $moodleoverflow->id;
$dataobject->forumdiscussionid = $discussion->id;
$record = $DB->get_record('moodleoverflow_mail_info',
- array('userid' => $dataobject->userid,
+ ['userid' => $dataobject->userid,
'courseid' => $dataobject->courseid,
'forumid' => $dataobject->forumid,
- 'forumdiscussionid' => $dataobject->forumdiscussionid),
+ 'forumdiscussionid' => $dataobject->forumdiscussionid, ],
'numberofposts, id');
if (is_object($record)) {
$dataset = $record;
@@ -834,7 +834,7 @@ function moodleoverflow_send_mails() {
// We dont know the the user yet.
// Retrieve the user from the database.
- $userfrom = $DB->get_record('user', array('id' => $post->userid));
+ $userfrom = $DB->get_record('user', ['id' => $post->userid]);
if ($userfrom) {
moodleoverflow_minimise_user_record($userfrom);
} else {
@@ -886,11 +886,11 @@ function moodleoverflow_send_mails() {
// Preapare to actually send the post now. Build up the content.
$cleanname = str_replace('"', "'", strip_tags(format_string($moodleoverflow->name)));
$coursecontext = context_course::instance($course->id);
- $shortname = format_string($course->shortname, true, array('context' => $coursecontext));
+ $shortname = format_string($course->shortname, true, ['context' => $coursecontext]);
// Define a header to make mails easier to track.
$emailmessageid = generate_email_messageid('moodlemoodleoverflow' . $moodleoverflow->id);
- $userfrom->customheaders = array(
+ $userfrom->customheaders = [
'List-Id: "' . $cleanname . '" ' . $emailmessageid,
'List-Help: ' . $CFG->wwwroot . '/mod/moodleoverflow/view.php?m=' . $moodleoverflow->id,
'Message-ID: ' . generate_email_messageid(hash('sha256', $post->id . 'to' . $userto->id)),
@@ -901,7 +901,7 @@ function moodleoverflow_send_mails() {
'Precedence: Bulk',
'X-Auto-Response-Suppress: All',
'Auto-Submitted: auto-generated',
- );
+ ];
// Cache the users capabilities.
if (!isset($userto->canpost[$discussion->id])) {
@@ -988,7 +988,7 @@ function moodleoverflow_send_mails() {
// Generate the url to view the post.
$url = '/mod/moodleoverflow/discussion.php';
- $params = array('d' => $discussion->id);
+ $params = ['d' => $discussion->id];
$contexturl = new moodle_url($url, $params, 'p' . $post->id);
$eventdata->contexturl = $contexturl->out();
$eventdata->contexturlname = $discussion->name;
@@ -1025,7 +1025,7 @@ function moodleoverflow_send_mails() {
// Mark the posts with errors in the database.
if ($errorcount[$post->id]) {
- $DB->set_field('moodleoverflow_posts', 'mailed', MOODLEOVERFLOW_MAILED_ERROR, array('id' => $post->id));
+ $DB->set_field('moodleoverflow_posts', 'mailed', MOODLEOVERFLOW_MAILED_ERROR, ['id' => $post->id]);
}
}
}
@@ -1046,7 +1046,7 @@ function moodleoverflow_get_unmailed_posts($starttime, $endtime) {
global $DB;
// Set params for the sql query.
- $params = array();
+ $params = [];
$params['ptimestart'] = $starttime;
$params['ptimeend'] = $endtime;
@@ -1078,7 +1078,7 @@ function moodleoverflow_mark_old_posts_as_mailed($endtime) {
$now = time();
// Define variables for the sql query.
- $params = array();
+ $params = [];
$params['mailedsuccess'] = MOODLEOVERFLOW_MAILED_SUCCESS;
$params['mailedreviewsent'] = MOODLEOVERFLOW_MAILED_REVIEW_SUCCESS;
$params['now'] = $now;
@@ -1178,7 +1178,7 @@ function moodleoverflow_can_create_attachment($moodleoverflow, $context) {
function moodleoverflow_get_user_grades($moodleoverflow, $userid=0) {
global $CFG, $DB;
- $params = array("moodleoverflowid" => $moodleoverflow->id);
+ $params = ["moodleoverflowid" => $moodleoverflow->id];
$sql = "SELECT u.id AS userid, g.grade AS rawgrade
FROM {user} u, {moodleoverflow_grades} g
@@ -1238,7 +1238,7 @@ function moodleoverflow_grade_item_update($moodleoverflow, $grades=null) {
require_once($CFG->libdir.'/gradelib.php');
}
- $params = array('itemname' => $moodleoverflow->name, 'idnumber' => $moodleoverflow->id);
+ $params = ['itemname' => $moodleoverflow->name, 'idnumber' => $moodleoverflow->id];
if ($moodleoverflow->grademaxgrade <= 0) {
$params['gradetype'] = GRADE_TYPE_NONE;
@@ -1280,6 +1280,6 @@ function moodleoverflow_get_fontawesome_icon_map() {
'mod_moodleoverflow:i/subscribed' => 'fa-bell moodleoverflow-icon-1_5x',
'mod_moodleoverflow:i/unsubscribed' => 'fa-bell-slash-o moodleoverflow-icon-1_5x',
'mod_moodleoverflow:i/vote-up' => 'fa-chevron-up moodleoverflow-icon-2x moodleoverflow-icon-no-margin',
- 'mod_moodleoverflow:i/vote-down' => 'fa-chevron-down moodleoverflow-icon-2x moodleoverflow-icon-no-margin'
+ 'mod_moodleoverflow:i/vote-down' => 'fa-chevron-down moodleoverflow-icon-2x moodleoverflow-icon-no-margin',
];
}
diff --git a/locallib.php b/locallib.php
index 98b4451ba9..d6eb0d64d1 100644
--- a/locallib.php
+++ b/locallib.php
@@ -52,7 +52,7 @@ function moodleoverflow_get_discussions($cm, $page = -1, $perpage = 0) {
// User must have the permission to view the discussions.
$modcontext = context_module::instance($cm->id);
if (!capabilities::has(capabilities::VIEW_DISCUSSION, $modcontext)) {
- return array();
+ return [];
}
// Filter some defaults.
@@ -157,7 +157,7 @@ function moodleoverflow_print_latest_discussions($moodleoverflow, $cm, $page = -
$userstatsbuttontext = get_string('seeuserstats', 'moodleoverflow');
$userstatsbuttonurl = new moodle_url('/mod/moodleoverflow/userstats.php', ['id' => $cm->id,
'courseid' => $moodleoverflow->course,
- 'mid' => $moodleoverflow->id]);
+ 'mid' => $moodleoverflow->id, ]);
$userstatsbutton = new single_button($userstatsbuttonurl, $userstatsbuttontext, 'get');
$userstatsbutton->class = 'singlebutton align-middle m-2';
echo $OUTPUT->render($userstatsbutton);
@@ -191,7 +191,7 @@ function moodleoverflow_print_latest_discussions($moodleoverflow, $cm, $page = -
$unreads = moodleoverflow_get_discussions_unread($cm);
$markallread = $CFG->wwwroot . '/mod/moodleoverflow/markposts.php?m=' . $moodleoverflow->id;
} else {
- $unreads = array();
+ $unreads = [];
$markallread = null;
}
@@ -233,9 +233,9 @@ function moodleoverflow_print_latest_discussions($moodleoverflow, $cm, $page = -
// Iterate through every visible discussion.
$i = 0;
- $preparedarray = array();
+ $preparedarray = [];
foreach ($discussions as $discussion) {
- $preparedarray[$i] = array();
+ $preparedarray[$i] = [];
// Handle anonymized discussions.
if ($discussion->userid == 0) {
@@ -334,8 +334,8 @@ function moodleoverflow_print_latest_discussions($moodleoverflow, $cm, $page = -
}
} else {
// Get his picture, his name and the link to his profile.
- $preparedarray[$i]['picture'] = $OUTPUT->user_picture($startuser, array('courseid' => $moodleoverflow->course,
- 'link' => false));
+ $preparedarray[$i]['picture'] = $OUTPUT->user_picture($startuser, ['courseid' => $moodleoverflow->course,
+ 'link' => false, ]);
$preparedarray[$i]['username'] = fullname($startuser, has_capability('moodle/site:viewfullnames', $context));
$preparedarray[$i]['userlink'] = $CFG->wwwroot . '/user/view.php?id=' .
$discussion->userid . '&course=' . $moodleoverflow->course;
@@ -394,7 +394,7 @@ function moodleoverflow_print_latest_discussions($moodleoverflow, $cm, $page = -
$reviewinfo = review::get_short_review_info_for_discussion($discussion->discussion);
$preparedarray[$i]['needreview'] = $reviewinfo->count;
$preparedarray[$i]['reviewlink'] = (new moodle_url('/mod/moodleoverflow/discussion.php', [
- 'd' => $discussion->discussion
+ 'd' => $discussion->discussion,
], 'p' . $reviewinfo->first))->out(false);
}
@@ -457,10 +457,10 @@ function moodleoverflow_print_latest_discussions($moodleoverflow, $cm, $page = -
*/
function moodleoverflow_print_forum_list($course, $cm, $movetopopup) {
global $CFG, $DB, $PAGE;
- $forumarray = array(array());
- $currentforum = $DB->get_record('moodleoverflow_discussions', array('id' => $movetopopup), 'moodleoverflow');
- $currentdiscussion = $DB->get_record('moodleoverflow_discussions', array('id' => $movetopopup), 'name');
- $forums = $DB->get_records('moodleoverflow', array('course' => $course->id));
+ $forumarray = [[]];
+ $currentforum = $DB->get_record('moodleoverflow_discussions', ['id' => $movetopopup], 'moodleoverflow');
+ $currentdiscussion = $DB->get_record('moodleoverflow_discussions', ['id' => $movetopopup], 'name');
+ $forums = $DB->get_records('moodleoverflow', ['course' => $course->id]);
$amountforums = count($forums);
if ($amountforums > 1) {
@@ -609,7 +609,7 @@ function moodleoverflow_get_discussions_unread($cm) {
$params = [
'userid' => $USER->id,
'instance' => $cm->instance,
- 'cutoffdate' => $cutoffdate
+ 'cutoffdate' => $cutoffdate,
];
if (!has_capability('mod/moodleoverflow:reviewpost', $modcontext)) {
@@ -637,7 +637,7 @@ function moodleoverflow_get_discussions_unread($cm) {
} else {
// If there are no unread messages, return an empty array.
- return array();
+ return [];
}
}
@@ -666,7 +666,7 @@ function moodleoverflow_get_post_full($postid) {
JOIN {moodleoverflow_discussions} d ON p.discussion = d.id
LEFT JOIN {user} u ON p.userid = u.id
WHERE p.id = :postid";
- $params = array();
+ $params = [];
$params['postid'] = $postid;
$post = $DB->get_record_sql($sql, $params);
@@ -696,7 +696,7 @@ function moodleoverflow_user_can_see_post($moodleoverflow, $discussion, $post, $
// Fetch the moodleoverflow instance object.
if (is_numeric($moodleoverflow)) {
debugging('missing full moodleoverflow', DEBUG_DEVELOPER);
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow))) {
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow])) {
return false;
}
}
@@ -704,7 +704,7 @@ function moodleoverflow_user_can_see_post($moodleoverflow, $discussion, $post, $
// Fetch the discussion object.
if (is_numeric($discussion)) {
debugging('missing full discussion', DEBUG_DEVELOPER);
- if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $discussion))) {
+ if (!$discussion = $DB->get_record('moodleoverflow_discussions', ['id' => $discussion])) {
return false;
}
}
@@ -712,7 +712,7 @@ function moodleoverflow_user_can_see_post($moodleoverflow, $discussion, $post, $
// Fetch the post object.
if (is_numeric($post)) {
debugging('missing full post', DEBUG_DEVELOPER);
- if (!$post = $DB->get_record('moodleoverflow_posts', array('id' => $post))) {
+ if (!$post = $DB->get_record('moodleoverflow_posts', ['id' => $post])) {
return false;
}
}
@@ -760,7 +760,7 @@ function moodleoverflow_user_can_see_discussion($moodleoverflow, $discussion, $c
// Retrieve the moodleoverflow object.
if (is_numeric($moodleoverflow)) {
debugging('missing full moodleoverflow', DEBUG_DEVELOPER);
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow))) {
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow])) {
return false;
}
}
@@ -768,7 +768,7 @@ function moodleoverflow_user_can_see_discussion($moodleoverflow, $discussion, $c
// Retrieve the discussion object.
if (is_numeric($discussion)) {
debugging('missing full discussion', DEBUG_DEVELOPER);
- if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $discussion))) {
+ if (!$discussion = $DB->get_record('moodleoverflow_discussions', ['id' => $discussion])) {
return false;
}
}
@@ -805,7 +805,7 @@ function moodleoverflow_add_discussion($discussion, $modulecontext, $userid = nu
// as a real post. The discussion links to it.
// Retrieve the module instance.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow))) {
+ if (!$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $discussion->moodleoverflow])) {
return false;
}
@@ -850,7 +850,7 @@ function moodleoverflow_add_discussion($discussion, $modulecontext, $userid = nu
$post->discussion = $DB->insert_record('moodleoverflow_discussions', $discussionobject);
// Link the post to the discussion.
- $DB->set_field('moodleoverflow_posts', 'discussion', $post->discussion, array('id' => $post->id));
+ $DB->set_field('moodleoverflow_posts', 'discussion', $post->discussion, ['id' => $post->id]);
moodleoverflow_add_attachment($post, $moodleoverflow, $cm);
@@ -862,10 +862,10 @@ function moodleoverflow_add_discussion($discussion, $modulecontext, $userid = nu
}
// Trigger event.
- $params = array(
+ $params = [
'context' => $modulecontext,
'objectid' => $post->discussion,
- );
+ ];
$event = \mod_moodleoverflow\event\discussion_viewed::create($params);
$event->trigger();
@@ -1017,10 +1017,10 @@ function moodleoverflow_get_all_discussion_posts($discussionid, $tracking, $modc
global $DB, $USER, $CFG;
// Initiate tracking settings.
- $params = array();
+ $params = [];
$trackingselector = "";
$trackingjoin = "";
- $params = array();
+ $params = [];
// If tracking is enabled, another join is needed.
if ($tracking) {
@@ -1056,7 +1056,7 @@ function moodleoverflow_get_all_discussion_posts($discussionid, $tracking, $modc
// Return an empty array, if there are no posts.
if (!$posts = $DB->get_records_sql($sql, $params)) {
- return array();
+ return [];
}
// Load all ratings.
@@ -1099,7 +1099,7 @@ function moodleoverflow_get_all_discussion_posts($discussionid, $tracking, $modc
// Create the children array.
if (!isset($posts[$post->parent]->children)) {
- $posts[$post->parent]->children = array();
+ $posts[$post->parent]->children = [];
}
// Increase the level of the current post.
@@ -1205,7 +1205,7 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co
}
// Get the current link without unnecessary parameters.
- $discussionlink = new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $post->discussion));
+ $discussionlink = new moodle_url('/mod/moodleoverflow/discussion.php', ['d' => $post->discussion]);
// Build the object that represents the posting user.
$postinguser = new stdClass();
@@ -1221,19 +1221,19 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co
$postinguser->id = null;
if ($post->userid == $USER->id) {
$postinguser->fullname = get_string('anonym_you', 'mod_moodleoverflow');
- $postinguser->profilelink = new moodle_url('/user/view.php', array('id' => $post->userid, 'course' => $course->id));
+ $postinguser->profilelink = new moodle_url('/user/view.php', ['id' => $post->userid, 'course' => $course->id]);
} else {
$postinguser->fullname = $usermapping[(int) $post->userid];
$postinguser->profilelink = null;
}
} else {
$postinguser->fullname = fullname($postinguser, capabilities::has('moodle/site:viewfullnames', $modulecontext));
- $postinguser->profilelink = new moodle_url('/user/view.php', array('id' => $post->userid, 'course' => $course->id));
+ $postinguser->profilelink = new moodle_url('/user/view.php', ['id' => $post->userid, 'course' => $course->id]);
$postinguser->id = $post->userid;
}
// Prepare an array of commands.
- $commands = array();
+ $commands = [];
// Create a permalink.
$permalink = new moodle_url($discussionlink);
@@ -1255,15 +1255,15 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co
$link = '/mod/moodleoverflow/discussion.php';
if ($post->markedhelpful) {
$commands[] = html_writer::tag('a', $str->marknothelpful,
- array('class' => 'markhelpful onlyifreviewed', 'role' => 'button', 'data-moodleoverflow-action' => 'helpful'));
+ ['class' => 'markhelpful onlyifreviewed', 'role' => 'button', 'data-moodleoverflow-action' => 'helpful']);
} else {
// If there are already marked posts, change the string of the button.
if ($helpfulposts) {
$commands[] = html_writer::tag('a', $str->alsomarkhelpful,
- array('class' => 'markhelpful onlyifreviewed', 'role' => 'button', 'data-moodleoverflow-action' => 'helpful'));
+ ['class' => 'markhelpful onlyifreviewed', 'role' => 'button', 'data-moodleoverflow-action' => 'helpful']);
} else {
$commands[] = html_writer::tag('a', $str->markhelpful,
- array('class' => 'markhelpful onlyifreviewed', 'role' => 'button', 'data-moodleoverflow-action' => 'helpful'));
+ ['class' => 'markhelpful onlyifreviewed', 'role' => 'button', 'data-moodleoverflow-action' => 'helpful']);
}
}
}
@@ -1277,15 +1277,15 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co
$link = '/mod/moodleoverflow/discussion.php';
if ($post->markedsolution) {
$commands[] = html_writer::tag('a', $str->marknotsolved,
- array('class' => 'marksolved onlyifreviewed', 'role' => 'button', 'data-moodleoverflow-action' => 'solved'));
+ ['class' => 'marksolved onlyifreviewed', 'role' => 'button', 'data-moodleoverflow-action' => 'solved']);
} else {
// If there are already marked posts, change the string of the button.
if ($solvedposts) {
$commands[] = html_writer::tag('a', $str->alsomarksolved,
- array('class' => 'marksolved onlyifreviewed', 'role' => 'button', 'data-moodleoverflow-action' => 'solved'));
+ ['class' => 'marksolved onlyifreviewed', 'role' => 'button', 'data-moodleoverflow-action' => 'solved']);
} else {
$commands[] = html_writer::tag('a', $str->marksolved,
- array('class' => 'marksolved onlyifreviewed', 'role' => 'button', 'data-moodleoverflow-action' => 'solved'));
+ ['class' => 'marksolved onlyifreviewed', 'role' => 'button', 'data-moodleoverflow-action' => 'solved']);
}
}
}
@@ -1298,8 +1298,8 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co
(!review::should_post_be_reviewed($post, $moodleoverflow) || !$post->reviewed))
|| capabilities::has(capabilities::EDIT_ANY_POST, $modulecontext)
) {
- $editurl = new moodle_url('/mod/moodleoverflow/post.php', array('edit' => $post->id));
- $commands[] = array('url' => $editurl, 'text' => $str->edit);
+ $editurl = new moodle_url('/mod/moodleoverflow/post.php', ['edit' => $post->id]);
+ $commands[] = ['url' => $editurl, 'text' => $str->edit];
}
// Give the option to delete a post.
@@ -1308,30 +1308,30 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co
capabilities::has(capabilities::DELETE_ANY_POST, $modulecontext)) {
$link = '/mod/moodleoverflow/post.php';
- $commands[] = array('url' => new moodle_url($link, array('delete' => $post->id)), 'text' => $str->delete);
+ $commands[] = ['url' => new moodle_url($link, ['delete' => $post->id]), 'text' => $str->delete];
}
// Give the option to reply to a post.
if (moodleoverflow_user_can_post($modulecontext, $post, false)) {
$attributes = [
- 'class' => 'onlyifreviewed'
+ 'class' => 'onlyifreviewed',
];
// Answer to the parent post.
if (empty($post->parent)) {
- $replyurl = new moodle_url('/mod/moodleoverflow/post.php#mformmoodleoverflow', array('reply' => $post->id));
- $commands[] = array('url' => $replyurl, 'text' => $str->replyfirst, 'attributes' => $attributes);
+ $replyurl = new moodle_url('/mod/moodleoverflow/post.php#mformmoodleoverflow', ['reply' => $post->id]);
+ $commands[] = ['url' => $replyurl, 'text' => $str->replyfirst, 'attributes' => $attributes];
// If the post is a comment, answer to the parent post.
} else if (!$iscomment) {
- $replyurl = new moodle_url('/mod/moodleoverflow/post.php#mformmoodleoverflow', array('reply' => $post->id));
- $commands[] = array('url' => $replyurl, 'text' => $str->reply, 'attributes' => $attributes);
+ $replyurl = new moodle_url('/mod/moodleoverflow/post.php#mformmoodleoverflow', ['reply' => $post->id]);
+ $commands[] = ['url' => $replyurl, 'text' => $str->reply, 'attributes' => $attributes];
// Else simple respond to the answer.
} else {
- $replyurl = new moodle_url('/mod/moodleoverflow/post.php#mformmoodleoverflow', array('reply' => $iscomment));
- $commands[] = array('url' => $replyurl, 'text' => $str->reply, 'attributes' => $attributes);
+ $replyurl = new moodle_url('/mod/moodleoverflow/post.php#mformmoodleoverflow', ['reply' => $iscomment]);
+ $commands[] = ['url' => $replyurl, 'text' => $str->reply, 'attributes' => $attributes];
}
}
@@ -1467,7 +1467,7 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co
$mustachedata->attachments = get_attachments($post, $cm);
// Output the commands.
- $commandhtml = array();
+ $commandhtml = [];
foreach ($commands as $command) {
if (is_array($command)) {
$commandhtml[] = html_writer::link($command['url'], $command['text'], $command['attributes'] ?? null);
@@ -1582,14 +1582,14 @@ function moodleoverflow_print_posts_nested($course, &$cm, $moodleoverflow, $disc
*/
function get_attachments($post, $cm) {
global $CFG, $OUTPUT;
- $attachments = array();
+ $attachments = [];
if (empty($post->attachment)) {
- return array();
+ return [];
}
if (!$context = context_module::instance($cm->id)) {
- return array();
+ return [];
}
$fs = get_file_storage();
@@ -1600,20 +1600,20 @@ function get_attachments($post, $cm) {
if ($files) {
$i = 0;
foreach ($files as $file) {
- $attachments[$i] = array();
+ $attachments[$i] = [];
$attachments[$i]['filename'] = $file->get_filename();
$mimetype = $file->get_mimetype();
$iconimage = $OUTPUT->pix_icon(file_file_icon($file),
get_mimetype_description($file), 'moodle',
- array('class' => 'icon'));
+ ['class' => 'icon']);
$path = moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(), $file->get_filearea(),
$file->get_itemid(), $file->get_filepath(), $file->get_filename());
$attachments[$i]['icon'] = $iconimage;
$attachments[$i]['filepath'] = $path;
- if (in_array($mimetype, array('image/gif', 'image/jpeg', 'image/png'))) {
+ if (in_array($mimetype, ['image/gif', 'image/jpeg', 'image/png'])) {
// Image attachments don't get printed as links.
$attachments[$i]['image'] = true;
} else {
@@ -1648,7 +1648,7 @@ function moodleoverflow_add_attachment($post, $forum, $cm) {
file_save_draft_area_files($post->attachments, $context->id, 'mod_moodleoverflow', 'attachment', $post->id,
mod_moodleoverflow_post_form::attachment_options($forum));
- $DB->set_field('moodleoverflow_posts', 'attachment', $present, array('id' => $post->id));
+ $DB->set_field('moodleoverflow_posts', 'attachment', $present, ['id' => $post->id]);
return true;
}
@@ -1666,8 +1666,8 @@ function moodleoverflow_add_new_post($post) {
// We do not check if these variables exist because this function
// is just called from one function which checks all these variables.
- $discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $post->discussion));
- $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $discussion->moodleoverflow));
+ $discussion = $DB->get_record('moodleoverflow_discussions', ['id' => $post->discussion]);
+ $moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $discussion->moodleoverflow]);
$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id);
// Add some variables to the post.
@@ -1687,13 +1687,13 @@ function moodleoverflow_add_new_post($post) {
// Add the post to the database.
$post->id = $DB->insert_record('moodleoverflow_posts', $post);
- $DB->set_field('moodleoverflow_posts', 'message', $post->message, array('id' => $post->id));
+ $DB->set_field('moodleoverflow_posts', 'message', $post->message, ['id' => $post->id]);
moodleoverflow_add_attachment($post, $moodleoverflow, $cm);
if ($post->reviewed) {
// Update the discussion.
- $DB->set_field('moodleoverflow_discussions', 'timemodified', $post->modified, array('id' => $post->discussion));
- $DB->set_field('moodleoverflow_discussions', 'usermodified', $post->userid, array('id' => $post->discussion));
+ $DB->set_field('moodleoverflow_discussions', 'timemodified', $post->modified, ['id' => $post->discussion]);
+ $DB->set_field('moodleoverflow_discussions', 'usermodified', $post->userid, ['id' => $post->discussion]);
}
// Mark the created post as read if the user is tracking the discussion.
@@ -1724,7 +1724,7 @@ function moodleoverflow_delete_discussion($discussion, $course, $cm, $moodleover
$result = true;
// Get all posts related to the discussion.
- if ($posts = $DB->get_records('moodleoverflow_posts', array('discussion' => $discussion->id))) {
+ if ($posts = $DB->get_records('moodleoverflow_posts', ['discussion' => $discussion->id])) {
// Iterate through them and delete each one.
foreach ($posts as $post) {
@@ -1742,8 +1742,8 @@ function moodleoverflow_delete_discussion($discussion, $course, $cm, $moodleover
readtracking::moodleoverflow_delete_read_records(-1, -1, $discussion->id);
// Remove the subscriptions for this discussion.
- $DB->delete_records('moodleoverflow_discuss_subs', array('discussion' => $discussion->id));
- if (!$DB->delete_records('moodleoverflow_discussions', array('id' => $discussion->id))) {
+ $DB->delete_records('moodleoverflow_discuss_subs', ['discussion' => $discussion->id]);
+ if (!$DB->delete_records('moodleoverflow_discussions', ['id' => $discussion->id])) {
$result = false;
}
@@ -1770,7 +1770,7 @@ function moodleoverflow_delete_post($post, $deletechildren, $cm, $moodleoverflow
try {
$transaction = $DB->start_delegated_transaction();
- $childposts = $DB->get_records('moodleoverflow_posts', array('parent' => $post->id));
+ $childposts = $DB->get_records('moodleoverflow_posts', ['parent' => $post->id]);
if ($deletechildren && $childposts) {
foreach ($childposts as $childpost) {
moodleoverflow_delete_post($childpost, true, $cm, $moodleoverflow);
@@ -1778,10 +1778,10 @@ function moodleoverflow_delete_post($post, $deletechildren, $cm, $moodleoverflow
}
// Delete the ratings.
- $DB->delete_records('moodleoverflow_ratings', array('postid' => $post->id));
+ $DB->delete_records('moodleoverflow_ratings', ['postid' => $post->id]);
// Delete the post.
- if ($DB->delete_records('moodleoverflow_posts', array('id' => $post->id))) {
+ if ($DB->delete_records('moodleoverflow_posts', ['id' => $post->id])) {
// Delete the read records.
readtracking::moodleoverflow_delete_read_records(-1, $post->id);
@@ -1808,14 +1808,14 @@ function moodleoverflow_delete_post($post, $deletechildren, $cm, $moodleoverflow
$modulecontext = context_module::instance($cm->id);
// Trigger the post deletion event.
- $params = array(
+ $params = [
'context' => $modulecontext,
'objectid' => $post->id,
- 'other' => array(
+ 'other' => [
'discussionid' => $post->discussion,
- 'moodleoverflowid' => $moodleoverflow->id
- )
- );
+ 'moodleoverflowid' => $moodleoverflow->id,
+ ],
+ ];
if ($post->userid !== $USER->id) {
$params['relateduserid'] = $post->userid;
}
@@ -1846,7 +1846,7 @@ function moodleoverflow_discussion_update_last_post($discussionid) {
global $DB;
// Check if the given discussion exists.
- if (!$DB->record_exists('moodleoverflow_discussions', array('id' => $discussionid))) {
+ if (!$DB->record_exists('moodleoverflow_discussions', ['id' => $discussionid])) {
return false;
}
@@ -1858,7 +1858,7 @@ function moodleoverflow_discussion_update_last_post($discussionid) {
ORDER BY modified DESC";
// Find the new last post of the discussion.
- if (($lastposts = $DB->get_records_sql($sql, array($discussionid), 0, 1))) {
+ if (($lastposts = $DB->get_records_sql($sql, [$discussionid], 0, 1))) {
$lastpost = reset($lastposts);
// Create an discussion object.
@@ -1906,10 +1906,10 @@ function moodleoverflow_count_discussions($moodleoverflow, $course) {
global $CFG, $DB;
// Create a cache.
- static $cache = array();
+ static $cache = [];
// Initiate variables.
- $params = array($course->id);
+ $params = [$course->id];
// Check whether the cache for the moodleoverflow is set.
if (!isset($cache[$course->id])) {
@@ -1937,7 +1937,7 @@ function moodleoverflow_count_discussions($moodleoverflow, $course) {
// There are no records.
// Save the result into the cache.
- $cache[$course->id] = array();
+ $cache[$course->id] = [];
}
}
@@ -1953,7 +1953,7 @@ function moodleoverflow_count_discussions($moodleoverflow, $course) {
$sql = "SELECT COUNT(d.id)
FROM {moodleoverflow_discussions} d
WHERE d.moodleoverflow = ?";
- $amount = $DB->get_field_sql($sql, array($moodleoverflow->id));
+ $amount = $DB->get_field_sql($sql, [$moodleoverflow->id]);
// Return the amount.
return $amount;
@@ -1995,10 +1995,10 @@ function moodleoverflow_update_user_grade_on_db($moodleoverflow, $postuserrating
}
// Save updated grade on local table.
- if ($DB->record_exists('moodleoverflow_grades', array('userid' => $userid, 'moodleoverflowid' => $moodleoverflow->id))) {
+ if ($DB->record_exists('moodleoverflow_grades', ['userid' => $userid, 'moodleoverflowid' => $moodleoverflow->id])) {
- $DB->set_field('moodleoverflow_grades', 'grade', $grade, array('userid' => $userid,
- 'moodleoverflowid' => $moodleoverflow->id));
+ $DB->set_field('moodleoverflow_grades', 'grade', $grade, ['userid' => $userid,
+ 'moodleoverflowid' => $moodleoverflow->id, ]);
} else {
@@ -2022,7 +2022,7 @@ function moodleoverflow_update_user_grade_on_db($moodleoverflow, $postuserrating
function moodleoverflow_update_all_grades_for_cm($moodleoverflowid) {
global $DB;
- $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflowid));
+ $moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflowid]);
// Check whether moodleoverflow object has the added params.
if ($moodleoverflow->grademaxgrade > 0 && $moodleoverflow->gradescalefactor > 0) {
diff --git a/markposts.php b/markposts.php
index abae184223..9354f62912 100644
--- a/markposts.php
+++ b/markposts.php
@@ -32,7 +32,7 @@
$returndiscussion = optional_param('return', 0, PARAM_INT); // The page to return to.
// Prepare the array that should be used to return to this page.
-$url = new moodle_url('/mod/moodleoverflow/markposts.php', array('m' => $moodleoverflowid));
+$url = new moodle_url('/mod/moodleoverflow/markposts.php', ['m' => $moodleoverflowid]);
// Check the optional params.
if ($discussionid !== 0) {
@@ -46,12 +46,12 @@
$PAGE->set_url($url);
// Retrieve the connected moodleoverflow instance.
-if (!$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflowid))) {
+if (!$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflowid])) {
throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
}
// Retrieve the connected course.
-if (!$course = $DB->get_record('course', array('id' => $moodleoverflow->course))) {
+if (!$course = $DB->get_record('course', ['id' => $moodleoverflow->course])) {
throw new moodle_exception('invalidcourseid');
}
@@ -70,12 +70,12 @@
if ($returndiscussion === 0) {
// If no parameter is set, relink to the view.
- $returnto = new moodle_url("/mod/moodleoverflow/view.php", array('m' => $moodleoverflow->id));
+ $returnto = new moodle_url("/mod/moodleoverflow/view.php", ['m' => $moodleoverflow->id]);
} else {
// Else relink back to the discussion we are coming from.
- $returnto = new moodle_url("/mod/moodleoverflow/discussion.php", array('d' => $returndiscussion));
+ $returnto = new moodle_url("/mod/moodleoverflow/discussion.php", ['d' => $returndiscussion]);
}
// Guests can't mark posts as read.
@@ -99,7 +99,7 @@
if (!empty($discussionid)) {
// Check if the discussion exists.
- $options = array('id' => $discussionid, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['id' => $discussionid, 'moodleoverflow' => $moodleoverflow->id];
$discussion = $DB->get_record('moodleoverflow_discussions', $options);
if (!$discussion) {
throw new moodle_exception('invaliddiscussionid', 'moodleoverflow');
diff --git a/mod_form.php b/mod_form.php
index 4df07d8537..30cdef4367 100644
--- a/mod_form.php
+++ b/mod_form.php
@@ -59,7 +59,7 @@ public function definition() {
$mform->addElement('header', 'general', get_string('general', 'form'));
// Adding the standard "name" field.
- $mform->addElement('text', 'name', get_string('moodleoverflowname', 'moodleoverflow'), array('size' => '64'));
+ $mform->addElement('text', 'name', get_string('moodleoverflowname', 'moodleoverflow'), ['size' => '64']);
if (!empty(get_config('moodleoverflow', 'formatstringstriptags'))) {
$mform->setType('name', PARAM_TEXT);
} else {
@@ -77,7 +77,7 @@ public function definition() {
$currentsetting = $this->current && property_exists($this->current, 'anonymous') ? $this->current->anonymous : 0;
$possiblesettings = [
- anonymous::EVERYTHING_ANONYMOUS => get_string('anonymous:everything', 'moodleoverflow')
+ anonymous::EVERYTHING_ANONYMOUS => get_string('anonymous:everything', 'moodleoverflow'),
];
if ($currentsetting <= anonymous::QUESTION_ANONYMOUS) {
@@ -98,7 +98,7 @@ public function definition() {
$possiblesettings = [
review::NOTHING => get_string('nothing', 'moodleoverflow'),
review::QUESTIONS => get_string('questions', 'moodleoverflow'),
- review::EVERYTHING => get_string('questions_and_posts', 'moodleoverflow')
+ review::EVERYTHING => get_string('questions_and_posts', 'moodleoverflow'),
];
$mform->addElement('select', 'needsreview', get_string('review', 'moodleoverflow'), $possiblesettings);
@@ -115,7 +115,7 @@ public function definition() {
$mform->addHelpButton('maxbytes', 'maxattachmentsize', 'moodleoverflow');
$mform->setDefault('maxbytes', get_config('moodleoverflow', 'maxbytes'));
- $choices = array(
+ $choices = [
0 => 0,
1 => 1,
2 => 2,
@@ -129,8 +129,8 @@ public function definition() {
10 => 10,
20 => 20,
50 => 50,
- 100 => 100
- );
+ 100 => 100,
+ ];
$mform->addElement('select', 'maxattachments', get_string('maxattachments', 'moodleoverflow'), $choices);
$mform->addHelpButton('maxattachments', 'maxattachments', 'moodleoverflow');
$mform->setDefault('maxattachments', get_config('moodleoverflow', 'maxattachments'));
@@ -139,7 +139,7 @@ public function definition() {
$mform->addElement('header', 'subscriptiontrackingheader', get_string('subscriptiontrackingheader', 'moodleoverflow'));
// Prepare the array with options for the subscription state.
- $options = array();
+ $options = [];
$options[MOODLEOVERFLOW_CHOOSESUBSCRIBE] = get_string('subscriptionoptional', 'moodleoverflow');
$options[MOODLEOVERFLOW_FORCESUBSCRIBE] = get_string('subscriptionforced', 'moodleoverflow');
$options[MOODLEOVERFLOW_INITIALSUBSCRIBE] = get_string('subscriptionauto', 'moodleoverflow');
@@ -150,7 +150,7 @@ public function definition() {
$mform->addHelpButton('forcesubscribe', 'subscriptionmode', 'moodleoverflow');
// Set the options for the default readtracking.
- $options = array();
+ $options = [];
$options[MOODLEOVERFLOW_TRACKING_OPTIONAL] = get_string('trackingoptional', 'moodleoverflow');
$options[MOODLEOVERFLOW_TRACKING_OFF] = get_string('trackingoff', 'moodleoverflow');
if (get_config('moodleoverflow', 'allowforcedreadtracking')) {
@@ -194,7 +194,7 @@ public function definition() {
$mform->addElement('header', 'ratingheading', get_string('ratingheading', 'moodleoverflow'));
// Which rating is more important?
- $options = array();
+ $options = [];
$options[MOODLEOVERFLOW_PREFERENCE_STARTER] = get_string('starterrating', 'moodleoverflow');
$options[MOODLEOVERFLOW_PREFERENCE_TEACHER] = get_string('teacherrating', 'moodleoverflow');
$mform->addElement('select', 'ratingpreference', get_string('ratingpreference', 'moodleoverflow'), $options);
diff --git a/post.php b/post.php
index e204e5ee17..57757b7560 100644
--- a/post.php
+++ b/post.php
@@ -39,16 +39,11 @@
$confirm = optional_param('confirm', 0, PARAM_INT);
// Set the URL that should be used to return to this page.
-$PAGE->set_url('/mod/moodleoverflow/post.php', array(
- 'moodleoverflow' => $moodleoverflow,
- 'reply' => $reply,
- 'edit' => $edit,
- 'delete' => $delete,
- 'confirm' => $confirm,
-));
+$PAGE->set_url('/mod/moodleoverflow/post.php', ['moodleoverflow' => $moodleoverflow, 'reply' => $reply, 'edit' => $edit,
+ 'delete' => $delete, 'confirm' => $confirm, ]);
// These params will be passed as hidden variables later in the form.
-$pageparams = array('moodleoverflow' => $moodleoverflow, 'reply' => $reply, 'edit' => $edit);
+$pageparams = ['moodleoverflow' => $moodleoverflow, 'reply' => $reply, 'edit' => $edit];
// Get the system context instance.
$systemcontext = context_system::instance();
@@ -124,9 +119,9 @@
// If the interaction was cancelled, the user needs to be redirected.
if ($mformpost->is_cancelled()) {
if (!isset($prepost->discussionid)) {
- redirect(new moodle_url('/mod/moodleoverflow/view.php', array('m' => $prepost->moodleoverflowid)));
+ redirect(new moodle_url('/mod/moodleoverflow/view.php', ['m' => $prepost->moodleoverflowid]));
} else {
- redirect(new moodle_url('/mod/moodleoverflow/discussion.php', array('d' => $prepost->discussionid)));
+ redirect(new moodle_url('/mod/moodleoverflow/discussion.php', ['d' => $prepost->discussionid]));
}
exit;
}
diff --git a/settings.php b/settings.php
index 6c1a244fb5..bb2e60dd27 100644
--- a/settings.php
+++ b/settings.php
@@ -50,7 +50,7 @@
// Default read tracking settings.
- $options = array();
+ $options = [];
$options[MOODLEOVERFLOW_TRACKING_OPTIONAL] = get_string('trackingoptional', 'moodleoverflow');
$options[MOODLEOVERFLOW_TRACKING_OFF] = get_string('trackingoff', 'moodleoverflow');
$options[MOODLEOVERFLOW_TRACKING_FORCED] = get_string('trackingon', 'moodleoverflow');
@@ -70,7 +70,7 @@
get_string('configoldpostdays', 'moodleoverflow'), 14, PARAM_INT));
// Default time (hour) to execute 'clean_read_records' cron.
- $options = array();
+ $options = [];
for ($i = 0; $i < 24; $i++) {
$options[$i] = sprintf("%02d", $i);
}
diff --git a/subscribe.php b/subscribe.php
index 71487cec6d..0ea5367b30 100644
--- a/subscribe.php
+++ b/subscribe.php
@@ -38,7 +38,7 @@
$returnurl = optional_param('returnurl', null, PARAM_RAW);
// Set the url to return to the same action.
-$url = new moodle_url('/mod/moodleoverflow/subscribe.php', array('id' => $id));
+$url = new moodle_url('/mod/moodleoverflow/subscribe.php', ['id' => $id]);
if (!is_null($mode)) {
$url->param('mode', $mode);
}
@@ -50,7 +50,7 @@
}
if (!is_null($discussionid)) {
$url->param('d', $discussionid);
- if (!$discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $discussionid, 'moodleoverflow' => $id))) {
+ if (!$discussion = $DB->get_record('moodleoverflow_discussions', ['id' => $discussionid, 'moodleoverflow' => $id])) {
throw new moodle_exception('invaliddiscussionid', 'moodleoverflow');
}
}
@@ -59,16 +59,16 @@
$PAGE->set_url($url);
// Get all necessary objects.
-$moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $id), '*', MUST_EXIST);
-$course = $DB->get_record('course', array('id' => $moodleoverflow->course), '*', MUST_EXIST);
+$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $id], '*', MUST_EXIST);
+$course = $DB->get_record('course', ['id' => $moodleoverflow->course], '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $course->id, false, MUST_EXIST);
$context = context_module::instance($cm->id);
// Define variables.
-$notify = array();
+$notify = [];
$notify['success'] = \core\output\notification::NOTIFY_SUCCESS;
$notify['error'] = \core\output\notification::NOTIFY_ERROR;
-$strings = array();
+$strings = [];
$strings['subscribeenrolledonly'] = get_string('subscribeenrolledonly', 'moodleoverflow');
$strings['everyonecannowchoose'] = get_string('everyonecannowchoose', 'moodleoverflow');
$strings['everyoneisnowsubscribed'] = get_string('everyoneisnowsubscribed', 'moodleoverflow');
@@ -88,7 +88,7 @@
}
// Retrieve the user from the database.
- $user = $DB->get_record('user', array('id' => $user), '*', MUST_EXIST);
+ $user = $DB->get_record('user', ['id' => $user], '*', MUST_EXIST);
} else {
@@ -114,13 +114,13 @@
if (isguestuser()) {
echo $OUTPUT->header();
$message = $strings['subscribeenrolledonly'] . '
br>' . get_string('liketologin');
- $url = new moodle_url('/mod/moodleoverflow/view.php', array('m' => $id));
+ $url = new moodle_url('/mod/moodleoverflow/view.php', ['m' => $id]);
echo $OUTPUT->confirm($message, get_login_url(), $url);
echo $OUTPUT->footer;
exit;
} else {
// There should not be any links leading to this place. Just redirect.
- $url = new moodle_url('/mod/moodleoverflow/view.php', array('m' => $id));
+ $url = new moodle_url('/mod/moodleoverflow/view.php', ['m' => $id]);
redirect($url, $strings['subscribeenrolledonly'], null, $notify['error']);
}
}
@@ -207,7 +207,7 @@
echo $OUTPUT->header();
// Create an url to get back to the view.
- $viewurl = new moodle_url('/mod/moodleoverflow/view.php', array('m' => $id));
+ $viewurl = new moodle_url('/mod/moodleoverflow/view.php', ['m' => $id]);
// Was a discussion id submitted?
if ($discussionid) {
@@ -262,7 +262,7 @@
// The user needs to be subscribed.
// Check the capabilities.
- $capabilities = array();
+ $capabilities = [];
$capabilities['managesubscriptions'] = has_capability('mod/moodleoverflow:managesubscriptions', $context);
$capabilities['viewdiscussion'] = has_capability('mod/moodleoverflow:viewdiscussion', $context);
require_sesskey();
@@ -287,7 +287,7 @@
echo $OUTPUT->header();
// Create the url to redirect the user back to.
- $viewurl = new moodle_url('/mod/moodleoverflow/view.php', array('m' => $id));
+ $viewurl = new moodle_url('/mod/moodleoverflow/view.php', ['m' => $id]);
// Check whether a discussion is referenced.
if ($discussionid) {
diff --git a/tests/behat/behat_mod_moodleoverflow.php b/tests/behat/behat_mod_moodleoverflow.php
index 709dae2ef6..4569c1c2ca 100644
--- a/tests/behat/behat_mod_moodleoverflow.php
+++ b/tests/behat/behat_mod_moodleoverflow.php
@@ -103,7 +103,7 @@ protected function add_new_discussion($moodleoverflowname, TableNode $table, $bu
// Navigate to moodleoverflow.
$this->execute('behat_navigation::i_am_on_page_instance', [$this->escape($moodleoverflowname),
- 'moodleoverflow activity']);
+ 'moodleoverflow activity', ]);
$this->execute('behat_forms::press_button', $buttonstr);
// Fill form and post.
diff --git a/tests/dailymail_test.php b/tests/dailymail_test.php
index 26447424b1..922050e033 100644
--- a/tests/dailymail_test.php
+++ b/tests/dailymail_test.php
@@ -72,7 +72,7 @@ public function setUp(): void {
$this->redirectMessages();
// Create a new course with a moodleoverflow forum.
$this->course = $this->getDataGenerator()->create_course();
- $location = array('course' => $this->course->id, 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE);
+ $location = ['course' => $this->course->id, 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE];
$this->moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $location);
$this->coursemodule = get_coursemodule_from_instance('moodleoverflow', $this->moodleoverflow->id);
}
@@ -94,7 +94,7 @@ public function tearDown(): void {
*/
public function helper_create_user_and_discussion($maildigest) {
// Create a user enrolled in the course as student.
- $this->user = $this->getDataGenerator()->create_user(array('firstname' => 'Tamaro', 'maildigest' => $maildigest));
+ $this->user = $this->getDataGenerator()->create_user(['firstname' => 'Tamaro', 'maildigest' => $maildigest]);
$this->getDataGenerator()->enrol_user($this->user->id, $this->course->id, 'student');
// Create a new discussion and post within the moodleoverflow.
@@ -215,7 +215,7 @@ public function test_records_removed() {
$this->helper_run_send_daily_mail();
// Now check the database if the records of the users are deleted.
- $records = $DB->get_records('moodleoverflow_mail_info', array('userid' => $this->user->id));
+ $records = $DB->get_records('moodleoverflow_mail_info', ['userid' => $this->user->id]);
$this->assertEmpty($records);
}
}
diff --git a/tests/discussion_test.php b/tests/discussion_test.php
index a23af66642..9f1110713e 100644
--- a/tests/discussion_test.php
+++ b/tests/discussion_test.php
@@ -97,11 +97,11 @@ public function test_create_discussion() {
$post = $posts[$discussion->get_firstpostid()];
// The discussion and the firstpost should be in the DB.
- $dbdiscussion = $DB->get_record('moodleoverflow_discussions', array('id' => $discussion->get_id()));
+ $dbdiscussion = $DB->get_record('moodleoverflow_discussions', ['id' => $discussion->get_id()]);
$this->assertEquals($dbdiscussion->id, $discussionid);
$this->assertEquals('Discussion Topic', $dbdiscussion->name);
- $dbpost = $DB->get_record('moodleoverflow_posts', array('id' => $discussion->get_firstpostid()));
+ $dbpost = $DB->get_record('moodleoverflow_posts', ['id' => $discussion->get_firstpostid()]);
$this->assertEquals($dbpost->id, $post->get_id());
$this->assertEquals($dbpost->discussion, $post->get_discussionid());
$this->assertEquals($prepost->message, $dbpost->message);
@@ -123,10 +123,10 @@ public function test_delete_discussion() {
$this->discussion->moodleoverflow_delete_discussion($prepost);
// The discussion and the post should not be in the DB anymore.
- $discussion = count($DB->get_records('moodleoverflow_discussions', array('id' => $discussionid)));
+ $discussion = count($DB->get_records('moodleoverflow_discussions', ['id' => $discussionid]));
$this->assertEquals(0, $discussion);
- $post = count($DB->get_records('moodleoverflow_posts', array('id' => $postid)));
+ $post = count($DB->get_records('moodleoverflow_posts', ['id' => $postid]));
$this->assertEquals(0, $post);
}
@@ -139,13 +139,13 @@ private function helper_course_set_up() {
global $DB;
// Create a new course with a moodleoverflow forum.
$this->course = $this->getDataGenerator()->create_course();
- $location = array('course' => $this->course->id);
+ $location = ['course' => $this->course->id];
$this->moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $location);
$this->coursemodule = get_coursemodule_from_instance('moodleoverflow', $this->moodleoverflow->id);
$this->modulecontext = \context_module::instance($this->coursemodule->id);
// Create a teacher.
- $this->teacher = $this->getDataGenerator()->create_user(array('firstname' => 'Tamaro', 'lastname' => 'Walter'));
+ $this->teacher = $this->getDataGenerator()->create_user(['firstname' => 'Tamaro', 'lastname' => 'Walter']);
$this->getDataGenerator()->enrol_user($this->teacher->id, $this->course->id, 'student');
// Create a discussion started from the teacher.
@@ -153,8 +153,8 @@ private function helper_course_set_up() {
$discussion = $this->generator->post_to_forum($this->moodleoverflow, $this->teacher);
// Get the discussion and post object.
- $discussionrecord = $DB->get_record('moodleoverflow_discussions', array('id' => $discussion[0]->id));
- $postrecord = $DB->get_record('moodleoverflow_posts', array('id' => $discussion[1]->id));
+ $discussionrecord = $DB->get_record('moodleoverflow_discussions', ['id' => $discussion[0]->id]);
+ $postrecord = $DB->get_record('moodleoverflow_posts', ['id' => $discussion[1]->id]);
$this->discussion = discussion::from_record($discussionrecord);
$this->post = post::from_record($postrecord);
diff --git a/tests/generator/lib.php b/tests/generator/lib.php
index ace760b258..a089878295 100644
--- a/tests/generator/lib.php
+++ b/tests/generator/lib.php
@@ -165,7 +165,7 @@ public function create_discussion($record = null, $forum = null) {
$record->id = moodleoverflow_add_discussion($record, $modulecontext, $record->userid);
if (isset($timemodified) || isset($mailed)) {
- $post = $DB->get_record('moodleoverflow_posts', array('discussion' => $record->id));
+ $post = $DB->get_record('moodleoverflow_posts', ['discussion' => $record->id]);
if (isset($mailed)) {
$post->mailed = $mailed;
@@ -180,7 +180,7 @@ public function create_discussion($record = null, $forum = null) {
$DB->update_record('moodleoverflow_discussions', $record);
}
- $discussion = $DB->get_record('moodleoverflow_discussions', array('id' => $record->id));
+ $discussion = $DB->get_record('moodleoverflow_discussions', ['id' => $record->id]);
// Return the discussion object.
return $discussion;
@@ -313,9 +313,9 @@ public function post_to_forum($forum, $author, $record = null) {
$record->moodleoverflow = $forum->id;
$discussion = $this->create_discussion($record, $forum, $record);
// Retrieve the post which was created by create_discussion.
- $post = $DB->get_record('moodleoverflow_posts', array('discussion' => $discussion->id));
+ $post = $DB->get_record('moodleoverflow_posts', ['discussion' => $discussion->id]);
- return array($discussion, $post);
+ return [$discussion, $post];
}
/**
@@ -327,7 +327,7 @@ public function post_to_forum($forum, $author, $record = null) {
public function update_post_time($post, $factor) {
global $DB;
// Update the post to have a created in the past.
- $DB->set_field('moodleoverflow_posts', 'created', $post->created + $factor, array('id' => $post->id));
+ $DB->set_field('moodleoverflow_posts', 'created', $post->created + $factor, ['id' => $post->id]);
}
/**
@@ -339,9 +339,9 @@ public function update_post_time($post, $factor) {
*/
public function update_subscription_time($user, $discussion, $factor) {
global $DB;
- $sub = $DB->get_record('moodleoverflow_discuss_subs', array('userid' => $user->id, 'discussion' => $discussion->id));
+ $sub = $DB->get_record('moodleoverflow_discuss_subs', ['userid' => $user->id, 'discussion' => $discussion->id]);
// Update the subscription to have a preference in the past.
- $DB->set_field('moodleoverflow_discuss_subs', 'preference', $sub->preference + $factor, array('id' => $sub->id));
+ $DB->set_field('moodleoverflow_discuss_subs', 'preference', $sub->preference + $factor, ['id' => $sub->id]);
}
/**
@@ -379,7 +379,7 @@ public function reply_to_post($parent, $author, $straighttodb = true) {
$record = (object) [
'discussion' => $parent->discussion,
'parent' => $parent->id,
- 'userid' => $author->id
+ 'userid' => $author->id,
];
return $this->create_post($record, $straighttodb);
}
diff --git a/tests/locallib_test.php b/tests/locallib_test.php
index 6d03e704c2..cc3fb54265 100644
--- a/tests/locallib_test.php
+++ b/tests/locallib_test.php
@@ -57,7 +57,7 @@ public function test_moodleoverflow_auto_subscribe_on_create() {
$usercount = 5;
$course = $this->getDataGenerator()->create_course();
- $users = array();
+ $users = [];
for ($i = 0; $i < $usercount; $i++) {
$user = $this->getDataGenerator()->create_user();
@@ -65,11 +65,11 @@ public function test_moodleoverflow_auto_subscribe_on_create() {
$this->getDataGenerator()->enrol_user($user->id, $course->id);
}
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE); // Automatic Subscription.
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE]; // Automatic Subscription.
$mo = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Get the module context.
- $cm = $DB->get_record('course_modules', array('id' => $mo->cmid));
+ $cm = $DB->get_record('course_modules', ['id' => $mo->cmid]);
$context = \context_module::instance($cm->id);
$result = \mod_moodleoverflow\subscriptions::get_subscribed_users($mo, $context);
@@ -90,7 +90,7 @@ public function test_moodleoverflow_forced_subscribe_on_create() {
$usercount = 5;
$course = $this->getDataGenerator()->create_course();
- $users = array();
+ $users = [];
for ($i = 0; $i < $usercount; $i++) {
$user = $this->getDataGenerator()->create_user();
@@ -98,10 +98,10 @@ public function test_moodleoverflow_forced_subscribe_on_create() {
$this->getDataGenerator()->enrol_user($user->id, $course->id);
}
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE];
$mo = $this->getDataGenerator()->create_module('moodleoverflow', $options);
- $cm = $DB->get_record('course_modules', array('id' => $mo->cmid));
+ $cm = $DB->get_record('course_modules', ['id' => $mo->cmid]);
$context = \context_module::instance($cm->id);
$result = \mod_moodleoverflow\subscriptions::get_subscribed_users($mo, $context);
@@ -122,7 +122,7 @@ public function test_moodleoverflow_optional_subscribe_on_create() {
$usercount = 5;
$course = $this->getDataGenerator()->create_course();
- $users = array();
+ $users = [];
for ($i = 0; $i < $usercount; $i++) {
$user = $this->getDataGenerator()->create_user();
@@ -130,9 +130,9 @@ public function test_moodleoverflow_optional_subscribe_on_create() {
$this->getDataGenerator()->enrol_user($user->id, $course->id);
}
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE); // Subscription optional.
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE]; // Subscription optional.
$mo = $this->getDataGenerator()->create_module('moodleoverflow', $options);
- $cm = $DB->get_record('course_modules', array('id' => $mo->cmid));
+ $cm = $DB->get_record('course_modules', ['id' => $mo->cmid]);
$context = \context_module::instance($cm->id);
$result = \mod_moodleoverflow\subscriptions::get_subscribed_users($mo, $context);
@@ -153,7 +153,7 @@ public function test_moodleoverflow_disallow_subscribe_on_create() {
$usercount = 5;
$course = $this->getDataGenerator()->create_course();
- $users = array();
+ $users = [];
for ($i = 0; $i < $usercount; $i++) {
$user = $this->getDataGenerator()->create_user();
@@ -161,9 +161,9 @@ public function test_moodleoverflow_disallow_subscribe_on_create() {
$this->getDataGenerator()->enrol_user($user->id, $course->id);
}
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_DISALLOWSUBSCRIBE); // Subscription prevented.
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_DISALLOWSUBSCRIBE]; // Subscription prevented.
$mo = $this->getDataGenerator()->create_module('moodleoverflow', $options);
- $cm = $DB->get_record('course_modules', array('id' => $mo->cmid));
+ $cm = $DB->get_record('course_modules', ['id' => $mo->cmid]);
$context = \context_module::instance($cm->id);
$result = \mod_moodleoverflow\subscriptions::get_subscribed_users($mo, $context);
diff --git a/tests/post_test.php b/tests/post_test.php
index 9d7d7fc597..0f9c754f13 100644
--- a/tests/post_test.php
+++ b/tests/post_test.php
@@ -89,7 +89,7 @@ public function test_create_post() {
$post->moodleoverflow_add_new_post();
// The post should be in the database.
- $postscount = count($DB->get_records('moodleoverflow_posts', array('id' => $post->get_id())));
+ $postscount = count($DB->get_records('moodleoverflow_posts', ['id' => $post->get_id()]));
$this->assertEquals(1, $postscount);
}
@@ -100,9 +100,9 @@ public function test_edit_post() {
global $DB;
// The post and the attachment should exist.
- $numberofattachments = count($DB->get_records('files', array('itemid' => $this->post->get_id())));
+ $numberofattachments = count($DB->get_records('files', ['itemid' => $this->post->get_id()]));
$this->assertEquals(2, $numberofattachments); // One Attachment is saved twice in 'files'.
- $post = count($DB->get_records('moodleoverflow_posts', array('id' => $this->post->get_id())));
+ $post = count($DB->get_records('moodleoverflow_posts', ['id' => $this->post->get_id()]));
$this->assertEquals(1, $post);
// Gather important parameters.
@@ -113,7 +113,7 @@ public function test_edit_post() {
$this->post->moodleoverflow_edit_post($time, $message, $this->post->messageformat, $this->post->formattachments);
// The message and modified time should be changed.
- $post = $DB->get_record('moodleoverflow_posts', array('id' => $this->post->get_id()));
+ $post = $DB->get_record('moodleoverflow_posts', ['id' => $this->post->get_id()]);
$this->assertEquals($message, $post->message);
$this->assertEquals($time, $post->modified);
}
@@ -126,9 +126,9 @@ public function test_delete_post() {
global $DB;
// The post and the attachment should exist.
- $numberofattachments = count($DB->get_records('files', array('itemid' => $this->post->get_id())));
+ $numberofattachments = count($DB->get_records('files', ['itemid' => $this->post->get_id()]));
$this->assertEquals(2, $numberofattachments); // One Attachment is saved twice in 'files'.
- $post = count($DB->get_records('moodleoverflow_posts', array('id' => $this->post->get_id())));
+ $post = count($DB->get_records('moodleoverflow_posts', ['id' => $this->post->get_id()]));
$this->assertEquals(1, $post);
// Delete the post with its attachment.
@@ -137,11 +137,11 @@ public function test_delete_post() {
$this->post->moodleoverflow_delete_post(true);
// Now try to get the attachment, it should be deleted from the database.
- $numberofattachments = count($DB->get_records('files', array('itemid' => $postid)));
+ $numberofattachments = count($DB->get_records('files', ['itemid' => $postid]));
$this->assertEquals(0, $numberofattachments);
// Try to find the post, it should be deleted.
- $post = count($DB->get_records('moodleoverflow_posts', array('id' => $postid)));
+ $post = count($DB->get_records('moodleoverflow_posts', ['id' => $postid]));
$this->assertEquals(0, $post);
}
@@ -154,29 +154,29 @@ private function helper_course_set_up() {
global $DB;
// Create a new course with a moodleoverflow forum.
$this->course = $this->getDataGenerator()->create_course();
- $location = array('course' => $this->course->id);
+ $location = ['course' => $this->course->id];
$this->moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $location);
$this->coursemodule = get_coursemodule_from_instance('moodleoverflow', $this->moodleoverflow->id);
$this->modulecontext = \context_module::instance($this->coursemodule->id);
// Create a teacher.
- $this->teacher = $this->getDataGenerator()->create_user(array('firstname' => 'Tamaro', 'lastname' => 'Walter'));
+ $this->teacher = $this->getDataGenerator()->create_user(['firstname' => 'Tamaro', 'lastname' => 'Walter']);
$this->getDataGenerator()->enrol_user($this->teacher->id, $this->course->id, 'student');
// Create a discussion started from the teacher.
$this->generator = $this->getDataGenerator()->get_plugin_generator('mod_moodleoverflow');
$discussion = $this->generator->post_to_forum($this->moodleoverflow, $this->teacher);
- $discussionrecord = $DB->get_record('moodleoverflow_discussions', array('id' => $discussion[0]->id));
+ $discussionrecord = $DB->get_record('moodleoverflow_discussions', ['id' => $discussion[0]->id]);
$this->discussion = discussion::from_record($discussionrecord);
// Get a temporary post from the DB to add the attachment.
- $temppost = $DB->get_record('moodleoverflow_posts', array('id' => $this->discussion->get_firstpostid()));
+ $temppost = $DB->get_record('moodleoverflow_posts', ['id' => $this->discussion->get_firstpostid()]);
// Create an attachment by inserting it directly in the database and update the post record.
$this->add_new_attachment($temppost, $this->modulecontext, 'world.txt', 'hello world');
// Build the real post object now. That is the object that will be tested.
- $postrecord = $DB->get_record('moodleoverflow_posts', array('id' => $this->discussion->get_firstpostid()));
+ $postrecord = $DB->get_record('moodleoverflow_posts', ['id' => $this->discussion->get_firstpostid()]);
$this->post = post::from_record($postrecord);
}
diff --git a/tests/privacy_provider_test.php b/tests/privacy_provider_test.php
index c4d10fc712..d8b3c489a2 100644
--- a/tests/privacy_provider_test.php
+++ b/tests/privacy_provider_test.php
@@ -27,8 +27,8 @@
global $CFG;
use core_privacy\local\request\approved_contextlist;
-use \core_privacy\local\request\userlist;
-use \mod_moodleoverflow\privacy\provider;
+use core_privacy\local\request\userlist;
+use mod_moodleoverflow\privacy\provider;
use mod_moodleoverflow\privacy\data_export_helper;
/**
@@ -307,7 +307,7 @@ public function test_user_has_rated_others() {
$cm = get_coursemodule_from_instance('moodleoverflow', $forum->id);
$context = \context_module::instance($cm->id);
// Rate the other users content.
- $rating = array();
+ $rating = [];
$rating['moodleoverflowid'] = $forum->id;
$rating['discussionid'] = $discussion->id;
$rating['userid'] = $user->id;
@@ -351,7 +351,7 @@ public function test_user_has_been_rated() {
$context = \context_module::instance($cm->id);
// Other users rate my content.
// Rate the other users content.
- $rating = array();
+ $rating = [];
$rating['moodleoverflowid'] = $forum->id;
$rating['discussionid'] = $discussion->id;
$rating['userid'] = $otheruser->id;
@@ -645,7 +645,7 @@ public function test_all_users_deleted_from_context() {
if ($post->userid != $user->id) {
$ratedposts[$post->id] = $post;
- $rating = array();
+ $rating = [];
$rating['moodleoverflowid'] = $forum->id;
$rating['discussionid'] = $discussion->id;
$rating['userid'] = $user->id;
@@ -687,7 +687,7 @@ public function test_all_users_deleted_from_context() {
}
// All ratings should have been deleted.
foreach ($postsinforum as $post) {
- $ratings = $DB->get_records('moodleoverflow_ratings', array('postid' => $post->id));
+ $ratings = $DB->get_records('moodleoverflow_ratings', ['postid' => $post->id]);
$this->assertEmpty($ratings);
}
@@ -716,7 +716,7 @@ public function test_all_users_deleted_from_context() {
if (!isset($ratedposts[$post->id])) {
continue;
}
- $ratings = $DB->get_records('moodleoverflow_ratings', array('postid' => $post->id));
+ $ratings = $DB->get_records('moodleoverflow_ratings', ['postid' => $post->id]);
$this->assertNotEmpty($ratings);
}
}
@@ -797,7 +797,7 @@ public function test_delete_data_for_user() {
if ($post->userid != $user->id) {
$ratedposts[$post->id] = $post;
- $rating = array();
+ $rating = [];
$rating['moodleoverflowid'] = $forum->id;
$rating['discussionid'] = $discussion->id;
$rating['userid'] = $user->id;
@@ -868,7 +868,7 @@ public function test_delete_data_for_user() {
));
// Ratings should have been anonymized.
- $this->assertCount(16, $DB->get_records('moodleoverflow_ratings', array('userid' => 0)));
+ $this->assertCount(16, $DB->get_records('moodleoverflow_ratings', ['userid' => 0]));
// File count: (5 users * 2 forums * 1 file) = 10.
// Files for the affected posts should be removed.
@@ -892,7 +892,7 @@ protected function create_courses_and_modules($count) {
$forum = $this->getDataGenerator()->create_module('moodleoverflow', ['course' => $course->id]);
}
- return array($course, $forum);
+ return [$course, $forum];
}
/**
@@ -906,7 +906,7 @@ protected function create_courses_and_modules($count) {
* @return array The users created
*/
protected function create_users($course, $count) {
- $users = array();
+ $users = [];
for ($i = 0; $i < $count; $i++) {
$user = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($user->id, $course->id);
@@ -925,7 +925,7 @@ protected function create_users($course, $count) {
* @return array The users created
*/
protected function create_and_enrol_users($course, $count) {
- $users = array();
+ $users = [];
for ($i = 0; $i < $count; $i++) {
$users[$i] = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($users[$i]->id, $course->id);
@@ -1039,7 +1039,7 @@ public function test_delete_data_for_users() {
'moodleoverflowid' => $moodleoverflow->id,
'rating' => 1,
'firstrated' => $time,
- 'lastchanged' => $time
+ 'lastchanged' => $time,
];
// Inserts a rating into the table.
$DB->insert_record('moodleoverflow_ratings', $rating);
@@ -1213,7 +1213,7 @@ public function test_get_users_in_context_post_ratings() {
'moodleoverflowid' => $moodleoverflow->id,
'rating' => 1,
'firstrated' => $time,
- 'lastchanged' => $time
+ 'lastchanged' => $time,
];
// Inserts a rating into the table.
$DB->insert_record('moodleoverflow_ratings', $rating);
@@ -1429,7 +1429,7 @@ public function test_grades() {
'course' => $course->id,
'scale' => 100,
'grademaxgrade' => 50,
- 'gradescalefactor' => 2
+ 'gradescalefactor' => 2,
]);
$cm = get_coursemodule_from_instance('moodleoverflow', $forum->id);
$context = \context_module::instance($cm->id);
@@ -1439,7 +1439,7 @@ public function test_grades() {
\mod_moodleoverflow\ratings::moodleoverflow_add_rating($forum, $post->id, RATING_UPVOTE, $cm, $user2->id);
moodleoverflow_update_all_grades_for_cm($forum->id);
$grades = grade_get_grades($course->id, 'mod', 'moodleoverflow', $forum->id,
- array($user->id, $user2->id));
+ [$user->id, $user2->id]);
self::assertEquals("2.50", $grades->items[0]->grades[$user->id]->str_grade);
self::assertEquals("0.50", $grades->items[0]->grades[$user2->id]->str_grade);
@@ -1456,16 +1456,14 @@ public function test_grades() {
self::assertContains("$context->id", $contextlist->get_contextids());
provider::delete_data_for_user($contextlist);
moodleoverflow_update_all_grades_for_cm($forum->id);
- $grades = $DB->get_records('moodleoverflow_grades', array('moodleoverflowid' => $forum->id), null,
- 'userid, grade');
+ $grades = $DB->get_records('moodleoverflow_grades', ['moodleoverflowid' => $forum->id], null, 'userid, grade');
self::assertEquals(2.5, $grades[$user->id]->grade);
self::assertArrayNotHasKey($user2->id, $grades);
// Test delete context.
provider::delete_data_for_all_users_in_context($context);
moodleoverflow_update_all_grades_for_cm($forum->id);
- $grades = $DB->get_records('moodleoverflow_grades', array('moodleoverflowid' => $forum->id), null,
- 'userid, grade');
+ $grades = $DB->get_records('moodleoverflow_grades', ['moodleoverflowid' => $forum->id], null, 'userid, grade');
self::assertEmpty($grades);
}
}
diff --git a/tests/ratings_test.php b/tests/ratings_test.php
index a74de7e581..0110710dc9 100644
--- a/tests/ratings_test.php
+++ b/tests/ratings_test.php
@@ -23,6 +23,7 @@
*/
namespace mod_moodleoverflow;
use mod_moodleoverflow\ratings;
+use stdClass;
defined('MOODLE_INTERNAL') || die();
@@ -38,46 +39,46 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class ratings_test extends \advanced_testcase {
- /** @var \stdClass test course */
+ /** @var stdClass test course */
private $course;
- /** @var \stdClass coursemodule */
+ /** @var stdClass coursemodule */
private $coursemodule;
- /** @var \stdClass test moodleoverflow */
+ /** @var stdClass test moodleoverflow */
private $moodleoverflow;
- /** @var \stdClass test teacher */
+ /** @var stdClass test teacher */
private $teacher;
- /** @var \stdClass test user */
+ /** @var stdClass test user */
private $user1;
- /** @var \stdClass another test user */
+ /** @var stdClass another test user */
private $user2;
- /** @var \stdClass a discussion */
+ /** @var stdClass a discussion */
private $discussion;
- /** @var \stdClass a post from the teacher*/
+ /** @var stdClass a post from the teacher*/
private $post;
- /** @var \stdClass answer from user 1 */
+ /** @var stdClass answer from user 1 */
private $answer1;
- /** @var \stdClass answer from user 1 */
+ /** @var stdClass answer from user 1 */
private $answer2;
- /** @var \stdClass answer from user 1 */
+ /** @var stdClass answer from user 1 */
private $answer3;
- /** @var \stdClass answer from user 2 */
+ /** @var stdClass answer from user 2 */
private $answer4;
- /** @var \stdClass answer from user 2 */
+ /** @var stdClass answer from user 2 */
private $answer5;
- /** @var \stdClass answer from user 2 */
+ /** @var stdClass answer from user 2 */
private $answer6;
/** @var \mod_moodleoverflow_generator $generator */
@@ -114,19 +115,19 @@ public function test_answersorting_everygroup() {
// Test with every group of rating.
// Create a array of the posts, save the sorted post and compare them to the order that they should have.
- $posts = array($this->post, $this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6);
+ $posts = [$this->post, $this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6];
$this->set_ratingpreferences(0);
$sortedposts = ratings::moodleoverflow_sort_answers_by_ratings($posts);
- $rightorderposts = array($this->post, $this->answer1, $this->answer3, $this->answer2,
- $this->answer4, $this->answer6, $this->answer5);
+ $rightorderposts = [$this->post, $this->answer1, $this->answer3, $this->answer2,
+ $this->answer4, $this->answer6, $this->answer5, ];
$result = $this->postsorderequal($sortedposts, $rightorderposts);
$this->assertEquals(1, $result);
// Change the rating preference of the teacher and sort again.
$this->set_ratingpreferences(1);
$sortedposts = ratings::moodleoverflow_sort_answers_by_ratings($posts);
- $rightorderposts = array($this->post, $this->answer1, $this->answer2, $this->answer3,
- $this->answer4, $this->answer6, $this->answer5);
+ $rightorderposts = [$this->post, $this->answer1, $this->answer2, $this->answer3,
+ $this->answer4, $this->answer6, $this->answer5, ];
$result = $this->postsorderequal($sortedposts, $rightorderposts);
$this->assertEquals(1, $result);
}
@@ -141,44 +142,44 @@ public function test_answersorting_threegroups() {
$this->create_everygroup();
// Test without posts that are only marked as solved.
- $posts = array($this->post, $this->answer1, $this->answer3, $this->answer4, $this->answer5, $this->answer6);
+ $posts = [$this->post, $this->answer1, $this->answer3, $this->answer4, $this->answer5, $this->answer6];
$this->set_ratingpreferences(0);
$sortedposts = ratings::moodleoverflow_sort_answers_by_ratings($posts);
- $rightorderposts = array($this->post, $this->answer1, $this->answer3, $this->answer4, $this->answer6, $this->answer5);
+ $rightorderposts = [$this->post, $this->answer1, $this->answer3, $this->answer4, $this->answer6, $this->answer5];
$result = $this->postsorderequal($sortedposts, $rightorderposts);
$this->assertEquals(1, $result);
$this->set_ratingpreferences(1);
$sortedposts = ratings::moodleoverflow_sort_answers_by_ratings($posts);
- $rightorderposts = array($this->post, $this->answer1, $this->answer3, $this->answer4, $this->answer6, $this->answer5);
+ $rightorderposts = [$this->post, $this->answer1, $this->answer3, $this->answer4, $this->answer6, $this->answer5];
$result = $this->postsorderequal($sortedposts, $rightorderposts);
$this->assertEquals(1, $result);
// Test without posts that are only marked as helpful.
- $posts = array($this->post, $this->answer1, $this->answer2, $this->answer4, $this->answer5, $this->answer6);
+ $posts = [$this->post, $this->answer1, $this->answer2, $this->answer4, $this->answer5, $this->answer6];
$this->set_ratingpreferences(0);
$sortedposts = ratings::moodleoverflow_sort_answers_by_ratings($posts);
- $rightorderposts = array($this->post, $this->answer1, $this->answer2, $this->answer4, $this->answer6, $this->answer5);
+ $rightorderposts = [$this->post, $this->answer1, $this->answer2, $this->answer4, $this->answer6, $this->answer5];
$result = $this->postsorderequal($sortedposts, $rightorderposts);
$this->assertEquals(1, $result);
$this->set_ratingpreferences(1);
$sortedposts = ratings::moodleoverflow_sort_answers_by_ratings($posts);
- $rightorderposts = array($this->post, $this->answer1, $this->answer2, $this->answer4, $this->answer6, $this->answer5);
+ $rightorderposts = [$this->post, $this->answer1, $this->answer2, $this->answer4, $this->answer6, $this->answer5];
$result = $this->postsorderequal($sortedposts, $rightorderposts);
$this->assertEquals(1, $result);
// Test without posts that are marked as both helpful and solved.
- $posts = array($this->post, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6);
+ $posts = [$this->post, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6];
$this->set_ratingpreferences(0);
$sortedposts = ratings::moodleoverflow_sort_answers_by_ratings($posts);
- $rightorderposts = array($this->post, $this->answer3, $this->answer2, $this->answer4, $this->answer6, $this->answer5);
+ $rightorderposts = [$this->post, $this->answer3, $this->answer2, $this->answer4, $this->answer6, $this->answer5];
$result = $this->postsorderequal($sortedposts, $rightorderposts);
$this->assertEquals(1, $result);
$this->set_ratingpreferences(1);
$sortedposts = ratings::moodleoverflow_sort_answers_by_ratings($posts);
- $rightorderposts = array($this->post, $this->answer2, $this->answer3, $this->answer4, $this->answer6, $this->answer5);
+ $rightorderposts = [$this->post, $this->answer2, $this->answer3, $this->answer4, $this->answer6, $this->answer5];
$result = $this->postsorderequal($sortedposts, $rightorderposts);
$this->assertEquals(1, $result);
}
@@ -208,8 +209,8 @@ public function test_answersorting_twogroups() {
$group1 = 's';
$group2 = 'h';
$this->set_ratingpreferences(0);
- $rightorderposts = array($this->post, $this->answer6, $this->answer5, $this->answer4,
- $this->answer2, $this->answer1, $this->answer3);
+ $rightorderposts = [$this->post, $this->answer6, $this->answer5, $this->answer4,
+ $this->answer2, $this->answer1, $this->answer3, ];
$this->process_groups($group1, $group2, $rightorderposts);
// Test case 5: only solved posts and only helpful posts with ratingpreferences = 1.
@@ -219,10 +220,10 @@ public function test_answersorting_twogroups() {
// Test case 6: only solved posts and not-marked posts.
$group2 = 'o';
$this->create_twogroups($group1, $group2);
- $posts = array($this->post, $this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6);
+ $posts = [$this->post, $this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6];
$sortedposts = ratings::moodleoverflow_sort_answers_by_ratings($posts);
- $rightorderposts = array($this->post, $this->answer2, $this->answer1, $this->answer3,
- $this->answer6, $this->answer5, $this->answer4);
+ $rightorderposts = [$this->post, $this->answer2, $this->answer1, $this->answer3,
+ $this->answer6, $this->answer5, $this->answer4, ];
$result = $this->postsorderequal($sortedposts, $rightorderposts);
$this->assertEquals(1, $result);
@@ -246,40 +247,40 @@ public function test_answersorting_onegroup() {
// Test case 1: only solved and helpful posts.
$group = 'sh';
$this->create_onegroup($group);
- $posts = array($this->post, $this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6);
+ $posts = [$this->post, $this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6];
$sortedposts = ratings::moodleoverflow_sort_answers_by_ratings($posts);
- $rightorderposts = array($this->post, $this->answer4, $this->answer6, $this->answer3,
- $this->answer1, $this->answer2, $this->answer5);
+ $rightorderposts = [$this->post, $this->answer4, $this->answer6, $this->answer3,
+ $this->answer1, $this->answer2, $this->answer5, ];
$result = $this->postsorderequal($sortedposts, $rightorderposts);
$this->assertEquals(1, $result);
// Test case 1: only solvedposts.
$group = 's';
$this->create_onegroup($group);
- $posts = array($this->post, $this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6);
+ $posts = [$this->post, $this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6];
$sortedposts = ratings::moodleoverflow_sort_answers_by_ratings($posts);
- $rightorderposts = array($this->post, $this->answer4, $this->answer6, $this->answer3,
- $this->answer1, $this->answer2, $this->answer5);
+ $rightorderposts = [$this->post, $this->answer4, $this->answer6, $this->answer3,
+ $this->answer1, $this->answer2, $this->answer5, ];
$result = $this->postsorderequal($sortedposts, $rightorderposts);
$this->assertEquals(1, $result);
// Test case 1: only helpful posts.
$group = 'h';
$this->create_onegroup($group);
- $posts = array($this->post, $this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6);
+ $posts = [$this->post, $this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6];
$sortedposts = ratings::moodleoverflow_sort_answers_by_ratings($posts);
- $rightorderposts = array($this->post, $this->answer4, $this->answer6, $this->answer3,
- $this->answer1, $this->answer2, $this->answer5);
+ $rightorderposts = [$this->post, $this->answer4, $this->answer6, $this->answer3,
+ $this->answer1, $this->answer2, $this->answer5, ];
$result = $this->postsorderequal($sortedposts, $rightorderposts);
$this->assertEquals(1, $result);
// Test case 1: only not marked posts.
$group = 'o';
$this->create_onegroup($group);
- $posts = array($this->post, $this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6);
+ $posts = [$this->post, $this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6];
$sortedposts = ratings::moodleoverflow_sort_answers_by_ratings($posts);
- $rightorderposts = array($this->post, $this->answer4, $this->answer6, $this->answer3,
- $this->answer1, $this->answer2, $this->answer5);
+ $rightorderposts = [$this->post, $this->answer4, $this->answer6, $this->answer3,
+ $this->answer1, $this->answer2, $this->answer5, ];
$result = $this->postsorderequal($sortedposts, $rightorderposts);
$this->assertEquals(1, $result);
}
@@ -296,24 +297,24 @@ private function helper_course_set_up() {
global $DB;
// Create a new course with a moodleoverflow forum.
$this->course = $this->getDataGenerator()->create_course();
- $location = array('course' => $this->course->id);
+ $location = ['course' => $this->course->id];
$this->moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $location);
$this->coursemodule = get_coursemodule_from_instance('moodleoverflow', $this->moodleoverflow->id);
// Create a teacher.
- $this->teacher = $this->getDataGenerator()->create_user(array('firstname' => 'Tamaro', 'lastname' => 'Walter'));
+ $this->teacher = $this->getDataGenerator()->create_user(['firstname' => 'Tamaro', 'lastname' => 'Walter']);
$this->getDataGenerator()->enrol_user($this->teacher->id, $this->course->id, 'student');
// Create 2 users.
- $this->user1 = $this->getDataGenerator()->create_user(array('firstname' => 'Ava', 'lastname' => 'Davis'));
+ $this->user1 = $this->getDataGenerator()->create_user(['firstname' => 'Ava', 'lastname' => 'Davis']);
$this->getDataGenerator()->enrol_user($this->user1->id, $this->course->id, 'student');
- $this->user2 = $this->getDataGenerator()->create_user(array('firstname' => 'Ethan', 'lastname' => 'Brown'));
+ $this->user2 = $this->getDataGenerator()->create_user(['firstname' => 'Ethan', 'lastname' => 'Brown']);
$this->getDataGenerator()->enrol_user($this->user2->id, $this->course->id, 'student');
// Create a discussion, a parent post and six answers.
$this->generator = $this->getDataGenerator()->get_plugin_generator('mod_moodleoverflow');
$this->discussion = $this->generator->post_to_forum($this->moodleoverflow, $this->teacher);
- $this->post = $DB->get_record('moodleoverflow_posts', array('id' => $this->discussion[0]->firstpost), '*');
+ $this->post = $DB->get_record('moodleoverflow_posts', ['id' => $this->discussion[0]->firstpost], '*');
$this->answer1 = $this->generator->reply_to_post($this->discussion[1], $this->user1, true);
$this->answer2 = $this->generator->reply_to_post($this->discussion[1], $this->user1, true);
$this->answer3 = $this->generator->reply_to_post($this->discussion[1], $this->user1, true);
@@ -431,7 +432,7 @@ private function create_everygroup() {
* - no mark (o)
*/
private function create_onegroup($group) {
- $answers = array($this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6);
+ $answers = [$this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6];
foreach ($answers as $answer) {
switch ($group) {
case 'sh':
@@ -621,10 +622,10 @@ private function create_twogroups($group1, $group2) {
*/
private function process_groups(String $group1, string $group2, array $orderposts = null) {
$this->create_twogroups($group1, $group2);
- $posts = array($this->post, $this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6);
+ $posts = [$this->post, $this->answer1, $this->answer2, $this->answer3, $this->answer4, $this->answer5, $this->answer6];
$sortedposts = ratings::moodleoverflow_sort_answers_by_ratings($posts);
- $rightorderposts = array($this->post, $this->answer2, $this->answer1, $this->answer3,
- $this->answer6, $this->answer5, $this->answer4);
+ $rightorderposts = [$this->post, $this->answer2, $this->answer1, $this->answer3,
+ $this->answer6, $this->answer5, $this->answer4, ];
if ($orderposts) {
$rightorderposts = $orderposts;
}
diff --git a/tests/readtracking_test.php b/tests/readtracking_test.php
index bb74a59553..a4bfa108d3 100644
--- a/tests/readtracking_test.php
+++ b/tests/readtracking_test.php
@@ -49,13 +49,13 @@ public function test_moodleoverflow_can_track_moodleoverflows() {
$this->resetAfterTest();
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'trackingtype' => MOODLEOVERFLOW_TRACKING_OFF); // Off.
+ $options = ['course' => $course->id, 'trackingtype' => MOODLEOVERFLOW_TRACKING_OFF]; // Off.
$mooff = $this->getDataGenerator()->create_module('moodleoverflow', $options);
- $options = array('course' => $course->id, 'trackingtype' => MOODLEOVERFLOW_TRACKING_FORCED); // On.
+ $options = ['course' => $course->id, 'trackingtype' => MOODLEOVERFLOW_TRACKING_FORCED]; // On.
$moforce = $this->getDataGenerator()->create_module('moodleoverflow', $options);
- $options = array('course' => $course->id, 'trackingtype' => MOODLEOVERFLOW_TRACKING_OPTIONAL); // Optional.
+ $options = ['course' => $course->id, 'trackingtype' => MOODLEOVERFLOW_TRACKING_OPTIONAL]; // Optional.
$mooptional = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Allow force.
@@ -98,13 +98,13 @@ public function test_moodleoverflow_is_tracked() {
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'trackingtype' => MOODLEOVERFLOW_TRACKING_OPTIONAL);
+ $options = ['course' => $course->id, 'trackingtype' => MOODLEOVERFLOW_TRACKING_OPTIONAL];
$mooptional = $this->getDataGenerator()->create_module('moodleoverflow', $options);
- $options = array('course' => $course->id, 'trackingtype' => MOODLEOVERFLOW_TRACKING_FORCED);
+ $options = ['course' => $course->id, 'trackingtype' => MOODLEOVERFLOW_TRACKING_FORCED];
$moforce = $this->getDataGenerator()->create_module('moodleoverflow', $options);
- $options = array('course' => $course->id, 'trackingtype' => MOODLEOVERFLOW_TRACKING_OFF);
+ $options = ['course' => $course->id, 'trackingtype' => MOODLEOVERFLOW_TRACKING_OFF];
$mooff = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Allow force.
diff --git a/tests/review_test.php b/tests/review_test.php
index 52f176c8f7..019f276086 100644
--- a/tests/review_test.php
+++ b/tests/review_test.php
@@ -112,8 +112,9 @@ public function test_forum_review_everything() {
global $DB, $CFG;
require_once($CFG->dirroot . '/mod/moodleoverflow/externallib.php');
- $options = array('course' => $this->course->id, 'needsreview' => review::EVERYTHING,
- 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE);
+ $options = ['course' => $this->course->id,
+ 'needsreview' => review::EVERYTHING,
+ 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE, ];
$posts = $this->create_post($options);
$this->check_mail_records($posts['teacherpost'], $posts['studentpost'], 1, 0, MOODLEOVERFLOW_MAILED_REVIEW_SUCCESS);
@@ -177,8 +178,9 @@ public function test_forum_review_only_questions() {
global $DB, $CFG;
require_once($CFG->dirroot . '/mod/moodleoverflow/externallib.php');
- $options = array('course' => $this->course->id, 'needsreview' => review::QUESTIONS,
- 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE);
+ $options = ['course' => $this->course->id,
+ 'needsreview' => review::QUESTIONS,
+ 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE, ];
$posts = $this->create_post($options);
$this->check_mail_records($posts['teacherpost'], $posts['studentpost'], 1, 0, MOODLEOVERFLOW_MAILED_REVIEW_SUCCESS);
@@ -215,8 +217,9 @@ public function test_forum_review_only_questions() {
* Test reviews functionality when reviewing is allowed in admin settings.
*/
public function test_forum_review_disallowed() {
- $options = array('course' => $this->course->id, 'needsreview' => review::EVERYTHING,
- 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE);
+ $options = ['course' => $this->course->id,
+ 'needsreview' => review::EVERYTHING,
+ 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE, ];
set_config('allowreview', 0, 'moodleoverflow');
@@ -276,7 +279,7 @@ private function create_post($options) {
list(, $teacherpost) = $this->generator->post_to_forum($moodleoverflow, $this->teacher);
list(, $studentpost) = $this->generator->post_to_forum($moodleoverflow, $this->student);
- return array('teacherpost' => $teacherpost, 'studentpost' => $studentpost);
+ return ['teacherpost' => $teacherpost, 'studentpost' => $studentpost];
}
/**
@@ -293,17 +296,17 @@ private function check_mail_records($teacherpost, $studentpost, $review1, $revie
global $DB;
$this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_PENDING, 'reviewed' => $review1,
- 'timereviewed' => null],
+ 'timereviewed' => null, ],
$DB->get_record('moodleoverflow_posts', ['id' => $teacherpost->id]));
$this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_PENDING, 'reviewed' => $review2,
- 'timereviewed' => null],
+ 'timereviewed' => null, ],
$DB->get_record('moodleoverflow_posts', ['id' => $studentpost->id]));
$this->run_send_mails();
$this->run_send_mails(); // Execute twice to ensure no duplicate mails.
$this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_SUCCESS, 'reviewed' => $review1,
- 'timereviewed' => null],
+ 'timereviewed' => null, ],
$DB->get_record('moodleoverflow_posts', ['id' => $teacherpost->id]));
$this->assert_matches_properties(['mailed' => $mailed, 'reviewed' => $review2, 'timereviewed' => null],
$DB->get_record('moodleoverflow_posts', ['id' => $studentpost->id]));
diff --git a/tests/subscriptions_test.php b/tests/subscriptions_test.php
index 110a4f5a63..28f5776a9d 100644
--- a/tests/subscriptions_test.php
+++ b/tests/subscriptions_test.php
@@ -68,7 +68,7 @@ public function tearDown(): void {
* @return array The users created
*/
protected function helper_create_users($course, $count) {
- $users = array();
+ $users = [];
for ($i = 0; $i < $count; $i++) {
$user = $this->getDataGenerator()->create_user();
@@ -101,10 +101,10 @@ protected function helper_post_to_moodleoverflow($moodleoverflow, $author) {
$discussion = $generator->create_discussion($record, $moodleoverflow);
// Retrieve the post which was created.
- $post = $DB->get_record('moodleoverflow_posts', array('discussion' => $discussion->id));
+ $post = $DB->get_record('moodleoverflow_posts', ['discussion' => $discussion->id]);
// Return the discussion and the post.
- return array($discussion->id, $post);
+ return [$discussion->id, $post];
}
/**
@@ -118,7 +118,7 @@ public function test_subscription_modes() {
// Create a course with a moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id);
+ $options = ['course' => $course->id];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
$modulecontext = \context_module::instance($moodleoverflow->cmid);
@@ -130,7 +130,7 @@ public function test_subscription_modes() {
// Test the forced subscription.
\mod_moodleoverflow\subscriptions::set_subscription_mode($moodleoverflow->id, MOODLEOVERFLOW_FORCESUBSCRIBE);
- $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow->id));
+ $moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow->id]);
$this->assertEquals(MOODLEOVERFLOW_FORCESUBSCRIBE,
\mod_moodleoverflow\subscriptions::get_subscription_mode($moodleoverflow));
$this->assertTrue(\mod_moodleoverflow\subscriptions::is_forcesubscribed($moodleoverflow));
@@ -139,21 +139,21 @@ public function test_subscription_modes() {
// Test the disallowed subscription.
\mod_moodleoverflow\subscriptions::set_subscription_mode($moodleoverflow->id, MOODLEOVERFLOW_DISALLOWSUBSCRIBE);
- $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow->id));
+ $moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow->id]);
$this->assertTrue(\mod_moodleoverflow\subscriptions::subscription_disabled($moodleoverflow));
$this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribable($moodleoverflow, $modulecontext));
$this->assertFalse(\mod_moodleoverflow\subscriptions::is_forcesubscribed($moodleoverflow));
// Test the initial subscription.
\mod_moodleoverflow\subscriptions::set_subscription_mode($moodleoverflow->id, MOODLEOVERFLOW_INITIALSUBSCRIBE);
- $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow->id));
+ $moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow->id]);
$this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribable($moodleoverflow, $modulecontext));
$this->assertFalse(\mod_moodleoverflow\subscriptions::subscription_disabled($moodleoverflow));
$this->assertFalse(\mod_moodleoverflow\subscriptions::is_forcesubscribed($moodleoverflow));
// Test the choose subscription.
\mod_moodleoverflow\subscriptions::set_subscription_mode($moodleoverflow->id, MOODLEOVERFLOW_CHOOSESUBSCRIBE);
- $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow->id));
+ $moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow->id]);
$this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribable($moodleoverflow, $modulecontext));
$this->assertFalse(\mod_moodleoverflow\subscriptions::subscription_disabled($moodleoverflow));
$this->assertFalse(\mod_moodleoverflow\subscriptions::is_forcesubscribed($moodleoverflow));
@@ -168,7 +168,7 @@ public function test_unsubscribable_moodleoverflows() {
// Create a course with a moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id);
+ $options = ['course' => $course->id];
$mof = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Get the module context.
@@ -186,13 +186,13 @@ public function test_unsubscribable_moodleoverflows() {
$this->assertEquals(0, count($result));
// Create the moodleoverflows.
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE];
$this->getDataGenerator()->create_module('moodleoverflow', $options);
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_DISALLOWSUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_DISALLOWSUBSCRIBE];
$disallow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE];
$choose = $this->getDataGenerator()->create_module('moodleoverflow', $options);
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE];
$this->getDataGenerator()->create_module('moodleoverflow', $options);
// At present the user is only subscribed to the initial moodleoverflow.
@@ -219,7 +219,7 @@ public function test_moodleoverflow_toggle_as_other() {
// Create a course with a moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id);
+ $options = ['course' => $course->id];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Get the module context.
@@ -244,139 +244,139 @@ public function test_moodleoverflow_toggle_as_other() {
$modulecontext, $discussion->id));
// Check thast we have no records in either on the subscription tables.
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(0, $count);
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(0, $count);
// Subscribing to the moodleoverflow should create a record in the subscription table,
// but the moodleoverflow discussion subscriptions table.
\mod_moodleoverflow\subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(0, $count);
// Unsubscribing should remove the record from the moodleoverflow subscription table.
// Do not modify the moodleoverflow discussion subscriptions table.
\mod_moodleoverflow\subscriptions::unsubscribe_user($author->id, $moodleoverflow, $modulecontext);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(0, $count);
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(0, $count);
// Enroling the user in the discussion should add one record to the
// moodleoverflow discussion table without modifying the form subscription.
\mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(0, $count);
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(1, $count);
// Unsubscribing should remove the record from the moodleoverflow subscriptions
// table and not modify the moodleoverflow discussion subscription table.
\mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(0, $count);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(0, $count);
// Resubscribe to the discussion so that we can check the effect of moodleoverflow-level subscriptions.
\mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(1, $count);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(0, $count);
// Subscribing to the moodleoverflow should have no effect on the moodleoverflow discussion
// subscription table if the user did not request the change himself.
\mod_moodleoverflow\subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(1, $count);
// Unsubbing from the moodleoverflow should have no effect on the moodleoverflow
// discussion subscription table if the user did not request the change themself.
\mod_moodleoverflow\subscriptions::unsubscribe_user($author->id, $moodleoverflow, $modulecontext);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(0, $count);
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(1, $count);
// Subscribing to the moodleoverflow should remove the per-discussion
// subscription preference if the user requested the change themself.
\mod_moodleoverflow\subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext, true);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(0, $count);
// Now unsubscribe from the current discussion whilst being subscribed to the moodleoverflow as a whole.
\mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(1, $count);
// Unsubscribing from the moodleoverflow should remove the per-discussion
// subscription preference if the user requested the change himself.
\mod_moodleoverflow\subscriptions::unsubscribe_user($author->id, $moodleoverflow, $modulecontext, true);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(0, $count);
- $count = $DB->count_records('moodleoverflow_discuss_subs', array(
+ $count = $DB->count_records('moodleoverflow_discuss_subs', [
'userid' => $author->id,
'discussion' => $discussion->id,
- ));
+ ]);
$this->assertEquals(0, $count);
// Subscribe to the discussion.
\mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(0, $count);
- $count = $DB->count_records('moodleoverflow_discuss_subs', array(
+ $count = $DB->count_records('moodleoverflow_discuss_subs', [
'userid' => $author->id,
'discussion' => $discussion->id,
- ));
+ ]);
$this->assertEquals(1, $count);
// Subscribe to the moodleoverflow without removing the discussion preferences.
\mod_moodleoverflow\subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(1, $count);
// Unsubscribe from the discussion should result in a change.
\mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(1, $count);
}
@@ -390,7 +390,7 @@ public function test_moodleoverflow_discussion_subscription_moodleoverflow_unsub
// Create a course with a moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Create users enrolled in the course as students.
@@ -417,7 +417,7 @@ public function test_moodleoverflow_discussion_subscription_moodleoverflow_subsc
// Create a course with a moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Get the module context.
@@ -456,7 +456,7 @@ public function test_moodleoverflow_discussion_subscription_moodleoverflow_unsub
// Create a course and a new moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Get the module context.
@@ -500,7 +500,7 @@ public function test_moodleoverflow_discussion_subscription_moodleoverflow_subsc
// Create a course, with a moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Get the module context.
@@ -544,7 +544,7 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
// Create a course with a moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id);
@@ -574,10 +574,10 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$discussion, $modulecontext));
// And there should be no discussion subscriptions (and one moodleoverflow subscription).
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(0, $count);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
@@ -592,10 +592,10 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$discussion, $modulecontext));
// And there should be a discussion subscriptions (and one moodleoverflow subscription).
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(1, $count);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
@@ -604,12 +604,12 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$discussion->id));
// There should be a record in the discussion subscription tracking table.
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(1, $count);
// And one in the moodleoverflow subscription tracking table.
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
@@ -624,12 +624,12 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$discussion->id));
// And one in the moodleoverflow subscription tracking table.
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
// There should be no record in the discussion subscription tracking table.
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(0, $count);
@@ -644,12 +644,12 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$discussion->id));
// And one in the moodleoverflow subscription tracking table.
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
// There should be a record in the discussion subscription tracking table.
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(1, $count);
@@ -665,12 +665,12 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$discussion->id));
// There should be no record in the discussion subscription tracking table.
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(0, $count);
// And one in the forum subscription tracking table.
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
@@ -685,12 +685,12 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// There should be a record in the discussion subscription tracking table.
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(1, $count);
// And one in the moodleoverflow subscription tracking table.
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
@@ -699,10 +699,10 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
true));
// This removes both the moodleoverflow, and the moodleoverflow records.
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(0, $count);
- $options = array('userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id);
+ $options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(0, $count);
@@ -723,7 +723,7 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_unsubscribe
// Create a course, with a moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Get the module context.
@@ -762,7 +762,7 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_unsubscribe
$discussion->id));
// There should be a record in the discussion subscription tracking table.
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(1, $count);
@@ -777,7 +777,7 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_unsubscribe
$discussion->id));
// There should be no record in the discussion subscription tracking table.
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(0, $count);
@@ -792,7 +792,7 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_unsubscribe
$this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// There should be a record in the discussion subscription tracking table.
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(1, $count);
@@ -807,7 +807,7 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_unsubscribe
$this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// There should be no record in the discussion subscription tracking table.
- $options = array('userid' => $author->id, 'discussion' => $discussion->id);
+ $options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(0, $count);
}
@@ -824,7 +824,7 @@ public function test_fetch_subscribed_users_subscriptions() {
// Create a course, with a moodleoverflow. where users are initially subscribed.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Get the module context.
@@ -865,7 +865,7 @@ public function test_fetch_subscribed_users_forced() {
// Create a course, with a moodleoverflow. where users are initially subscribed.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Get the module context.
@@ -892,7 +892,7 @@ public function test_fetch_subscribed_users_discussion_subscriptions() {
// Create a course, with a moodleoverflow. where users are initially subscribed.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Get the module context.
@@ -979,7 +979,7 @@ public function test_force_subscribed_to_moodleoverflow() {
// Create a course, with a moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Remove the allowforcesubscribe capability from the user.
@@ -1011,7 +1011,7 @@ public function test_subscription_cache_prefill() {
// Create a course, with a moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Create some users.
@@ -1046,7 +1046,7 @@ public function test_subscription_cache_fill() {
// Create a course, with a moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Create some users.
@@ -1079,11 +1079,11 @@ public function test_discussion_subscription_cache_fill_for_course() {
$course = $this->getDataGenerator()->create_course();
// Create the moodleoverflows.
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_DISALLOWSUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_DISALLOWSUBSCRIBE];
$disallowmoodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE];
$choosemoodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE];
$initialmoodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Create some users and keep a reference to the first user.
@@ -1130,7 +1130,7 @@ public function test_discussion_subscription_cache_prefill() {
// Create a course, with a moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Get the module context.
@@ -1141,7 +1141,7 @@ public function test_discussion_subscription_cache_prefill() {
$users = $this->helper_create_users($course, 20);
// Post some discussions to the moodleoverflow.
- $discussions = array();
+ $discussions = [];
$author = $users[0];
for ($i = 0; $i < 20; $i++) {
$discussion = new \stdClass();
@@ -1197,14 +1197,14 @@ public function test_discussion_subscription_cache_fill() {
// Create a course, with a moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_INITIALSUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Create some users.
$users = $this->helper_create_users($course, 20);
// Post some discussions to the moodleoverflow.
- $discussions = array();
+ $discussions = [];
$author = $users[0];
for ($i = 0; $i < 20; $i++) {
$discussion = new \stdClass();
@@ -1270,7 +1270,7 @@ public function test_moodleoverflow_subscribe_toggle_as_other_repeat_subscriptio
// Create a course, with a moodleoverflow.
$course = $this->getDataGenerator()->create_course();
- $options = array('course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE);
+ $options = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_CHOOSESUBSCRIBE];
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
// Get the module context.
@@ -1294,26 +1294,26 @@ public function test_moodleoverflow_subscribe_toggle_as_other_repeat_subscriptio
$discussion->id));
// Confirm that we have no records in either of the subscription tables.
- $this->assertEquals(0, $DB->count_records('moodleoverflow_subscriptions', array(
+ $this->assertEquals(0, $DB->count_records('moodleoverflow_subscriptions', [
'userid' => $user->id,
'moodleoverflow' => $moodleoverflow->id,
- )));
- $this->assertEquals(0, $DB->count_records('moodleoverflow_discuss_subs', array(
+ ]));
+ $this->assertEquals(0, $DB->count_records('moodleoverflow_discuss_subs', [
'userid' => $user->id,
'discussion' => $discussion->id,
- )));
+ ]));
// Subscribing to the moodleoverflow should create a record in the subscriptions table,
// but not the moodleoverflow discussion subscriptions table.
\mod_moodleoverflow\subscriptions::subscribe_user($user->id, $moodleoverflow, $modulecontext);
- $this->assertEquals(1, $DB->count_records('moodleoverflow_subscriptions', array(
+ $this->assertEquals(1, $DB->count_records('moodleoverflow_subscriptions', [
'userid' => $user->id,
'moodleoverflow' => $moodleoverflow->id,
- )));
- $this->assertEquals(0, $DB->count_records('moodleoverflow_discuss_subs', array(
+ ]));
+ $this->assertEquals(0, $DB->count_records('moodleoverflow_discuss_subs', [
'userid' => $user->id,
'discussion' => $discussion->id,
- )));
+ ]));
// Now unsubscribe from the discussion. This should return true.
$uid = $user->id;
@@ -1334,25 +1334,25 @@ public function test_moodleoverflow_subscribe_toggle_as_other_repeat_subscriptio
// And unsubscribing from the moodleoverflow but not as a request from the user should maintain their preference.
\mod_moodleoverflow\subscriptions::unsubscribe_user($user->id, $moodleoverflow, $modulecontext);
- $this->assertEquals(0, $DB->count_records('moodleoverflow_subscriptions', array(
+ $this->assertEquals(0, $DB->count_records('moodleoverflow_subscriptions', [
'userid' => $user->id,
'moodleoverflow' => $moodleoverflow->id,
- )));
- $this->assertEquals(1, $DB->count_records('moodleoverflow_discuss_subs', array(
+ ]));
+ $this->assertEquals(1, $DB->count_records('moodleoverflow_discuss_subs', [
'userid' => $user->id,
'discussion' => $discussion->id,
- )));
+ ]));
// Subscribing to the discussion should return truthfully because a change was made.
$this->assertTrue(\mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($user->id, $discussion, $modulecontext));
- $this->assertEquals(0, $DB->count_records('moodleoverflow_subscriptions', array(
+ $this->assertEquals(0, $DB->count_records('moodleoverflow_subscriptions', [
'userid' => $user->id,
'moodleoverflow' => $moodleoverflow->id,
- )));
- $this->assertEquals(1, $DB->count_records('moodleoverflow_discuss_subs', array(
+ ]));
+ $this->assertEquals(1, $DB->count_records('moodleoverflow_discuss_subs', [
'userid' => $user->id,
'discussion' => $discussion->id,
- )));
+ ]));
}
/**
@@ -1422,7 +1422,7 @@ public function test_is_subscribable_is_guest($options) {
$this->resetAfterTest(true);
// Create a guest user.
- $guest = $DB->get_record('user', array('username' => 'guest'));
+ $guest = $DB->get_record('user', ['username' => 'guest']);
$this->setUser($guest);
// Create a course, with a moodleoverflow.
diff --git a/tests/userstats_test.php b/tests/userstats_test.php
index 044dd1f8b7..741712320f 100644
--- a/tests/userstats_test.php
+++ b/tests/userstats_test.php
@@ -183,7 +183,7 @@ public function test_partial_anonymous() {
// User1 starts a new discussion, the forum activity shouldn't change.
$discussion = $this->generator->post_to_forum($this->moodleoverflow, $this->user1);
- $starterpost = $DB->get_record('moodleoverflow_posts', array('id' => $discussion[0]->firstpost), '*');
+ $starterpost = $DB->get_record('moodleoverflow_posts', ['id' => $discussion[0]->firstpost], '*');
$newuserstats = $this->create_statstable();
$newactivityuser1 = $this->get_specific_userstats($newuserstats, $this->user1, 'forumactivity');
$this->assertEquals($oldactivityuser1, $newactivityuser1);
@@ -276,25 +276,25 @@ private function helper_course_set_up() {
global $DB;
// Create a new course with a moodleoverflow forum.
$this->course = $this->getDataGenerator()->create_course();
- $location = array('course' => $this->course->id);
+ $location = ['course' => $this->course->id];
$this->moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $location);
$this->coursemodule = get_coursemodule_from_instance('moodleoverflow', $this->moodleoverflow->id);
// Create a teacher.
- $this->teacher = $this->getDataGenerator()->create_user(array('firstname' => 'Tamaro', 'lastname' => 'Walter'));
+ $this->teacher = $this->getDataGenerator()->create_user(['firstname' => 'Tamaro', 'lastname' => 'Walter']);
$this->getDataGenerator()->enrol_user($this->teacher->id, $this->course->id, 'student');
// Create 2 users and their discussions and posts.
- $this->user1 = $this->getDataGenerator()->create_user(array('firstname' => 'Ava', 'lastname' => 'Davis'));
+ $this->user1 = $this->getDataGenerator()->create_user(['firstname' => 'Ava', 'lastname' => 'Davis']);
$this->getDataGenerator()->enrol_user($this->user1->id, $this->course->id, 'student');
- $this->user2 = $this->getDataGenerator()->create_user(array('firstname' => 'Ethan', 'lastname' => 'Brown'));
+ $this->user2 = $this->getDataGenerator()->create_user(['firstname' => 'Ethan', 'lastname' => 'Brown']);
$this->getDataGenerator()->enrol_user($this->user2->id, $this->course->id, 'student');
$this->generator = $this->getDataGenerator()->get_plugin_generator('mod_moodleoverflow');
$this->discussion1 = $this->generator->post_to_forum($this->moodleoverflow, $this->user1);
$this->discussion2 = $this->generator->post_to_forum($this->moodleoverflow, $this->user2);
- $this->post1 = $DB->get_record('moodleoverflow_posts', array('id' => $this->discussion1[0]->firstpost), '*');
- $this->post2 = $DB->get_record('moodleoverflow_posts', array('id' => $this->discussion1[0]->firstpost), '*');
+ $this->post1 = $DB->get_record('moodleoverflow_posts', ['id' => $this->discussion1[0]->firstpost], '*');
+ $this->post2 = $DB->get_record('moodleoverflow_posts', ['id' => $this->discussion1[0]->firstpost], '*');
$this->answer1 = $this->generator->reply_to_post($this->discussion1[1], $this->user2, true);
$this->answer2 = $this->generator->reply_to_post($this->discussion2[1], $this->user1, true);
}
@@ -323,7 +323,7 @@ private function make_anonymous($anonymoussetting) {
private function create_statstable() {
$url = new \moodle_url('/mod/moodleoverflow/userstats.php', ['id' => $this->coursemodule->id,
'courseid' => $this->course->id,
- 'mid' => $this->moodleoverflow->id]);
+ 'mid' => $this->moodleoverflow->id, ]);
$userstatstable = new userstats_table('testtable', $this->course->id, $this->moodleoverflow->id, $url);
$userstatstable->get_table_data();
return $userstatstable->get_usertable();
@@ -346,7 +346,7 @@ private function create_upvote($author, $discussion, $post) {
'postid' => $post->id,
'rating' => 2,
'firstrated' => time(),
- 'lastchanged' => time()
+ 'lastchanged' => time(),
];
return $this->generator->create_rating($record);
}
@@ -368,7 +368,7 @@ private function create_downvote($author, $discussion, $post) {
'postid' => $post->id,
'rating' => 1,
'firstrated' => time(),
- 'lastchanged' => time()
+ 'lastchanged' => time(),
];
return $this->generator->create_rating($record);
}
@@ -390,7 +390,7 @@ private function create_helpful($author, $discussion, $post) {
'postid' => $post->id,
'rating' => 4,
'firstrated' => time(),
- 'lastchanged' => time()
+ 'lastchanged' => time(),
];
return $this->generator->create_rating($record);
}
@@ -412,7 +412,7 @@ private function create_solution($author, $discussion, $post) {
'postid' => $post->id,
'rating' => 3,
'firstrated' => time(),
- 'lastchanged' => time()
+ 'lastchanged' => time(),
];
return $this->generator->create_rating($record);
}
diff --git a/tracking.php b/tracking.php
index 9011bbe3df..b152d5d439 100644
--- a/tracking.php
+++ b/tracking.php
@@ -34,12 +34,12 @@
require_sesskey();
// Retrieve the moodleoverflow instance to track or untrack.
-if (!$moodleoverflow = $DB->get_record("moodleoverflow", array("id" => $id))) {
+if (!$moodleoverflow = $DB->get_record("moodleoverflow", ["id" => $id])) {
throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
}
// Retrieve the course of the instance.
-if (!$course = $DB->get_record("course", array("id" => $moodleoverflow->course))) {
+if (!$course = $DB->get_record("course", ["id" => $moodleoverflow->course])) {
throw new moodle_exception('invalidcoursemodule');
}
@@ -53,7 +53,7 @@
// Set the page to return to.
$url = '/mod/moodleoverflow/' . $returnpage;
-$params = array('id' => $course->id, 'm' => $moodleoverflow->id);
+$params = ['id' => $course->id, 'm' => $moodleoverflow->id];
$returnpageurl = new moodle_url($url, $params);
$returnto = moodleoverflow_go_back_to($returnpageurl);
@@ -72,11 +72,11 @@
$info->moodleoverflow = format_string($moodleoverflow->name);
// Set parameters for an event.
-$eventparams = array(
+$eventparams = [
'context' => context_module::instance($cm->id),
'relateduserid' => $USER->id,
- 'other' => array('moodleoverflowid' => $moodleoverflow->id),
-);
+ 'other' => ['moodleoverflowid' => $moodleoverflow->id],
+];
// Check whether the moodleoverflow is tracked.
$istracked = \mod_moodleoverflow\readtracking::moodleoverflow_is_tracked($moodleoverflow);
diff --git a/userstats.php b/userstats.php
index cab12d15d1..6d61eaec89 100644
--- a/userstats.php
+++ b/userstats.php
@@ -38,13 +38,13 @@
// Define important variables.
if ($courseid) {
- $course = $DB->get_record('course', array('id' => $courseid), '*');
+ $course = $DB->get_record('course', ['id' => $courseid], '*');
}
if ($cmid) {
$cm = get_coursemodule_from_id('moodleoverflow', $cmid, $course->id, false, MUST_EXIST);
}
if ($mid) {
- $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $mid), '*');
+ $moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $mid], '*');
}
// Require a login.
require_login($course, true, $cm);
@@ -56,8 +56,8 @@
// Do a capability check, in case a user iserts the userstats-url manually.
if (has_capability('mod/moodleoverflow:viewanyrating', $context) && get_config('moodleoverflow', 'showuserstats')) {
// Print the page header.
- $PAGE->set_url('/mod/moodleoverflow/userstats.php', array('id' => $cm->id,
- 'courseid' => $course->id, 'mid' => $moodleoverflow->id));
+ $PAGE->set_url('/mod/moodleoverflow/userstats.php', ['id' => $cm->id, 'courseid' => $course->id,
+ 'mid' => $moodleoverflow->id, ]);
$PAGE->set_title(format_string('User statistics'));
$PAGE->set_heading(format_string('User statistics of course: ' . $course->fullname));
diff --git a/version.php b/version.php
index c5e7541f80..ab72068a1b 100644
--- a/version.php
+++ b/version.php
@@ -29,7 +29,8 @@
$plugin->component = 'mod_moodleoverflow';
$plugin->version = 2023070300;
+$plugin->version = 2023082500;
$plugin->release = 'v4.2-r2';
$plugin->requires = 2020061500; // Requires Moodle 3.9+.
$plugin->maturity = MATURITY_STABLE;
-$plugin->dependencies = array();
+$plugin->dependencies = [];
diff --git a/view.php b/view.php
index 552292d209..d30c6e6544 100644
--- a/view.php
+++ b/view.php
@@ -38,7 +38,7 @@
$linktoforum = optional_param('movetoforum', 0, PARAM_INT); // Forum to which it is moved.
// Set the parameters.
-$params = array();
+$params = [];
if ($id) {
$params['id'] = $id;
} else {
@@ -52,18 +52,18 @@
// Check for the course and module.
if ($id) {
$cm = get_coursemodule_from_id('moodleoverflow', $id, 0, false, MUST_EXIST);
- $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
- $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $cm->instance), '*', MUST_EXIST);
+ $course = $DB->get_record('course', ['id' => $cm->course], '*', MUST_EXIST);
+ $moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $cm->instance], '*', MUST_EXIST);
} else if ($m) {
- $moodleoverflow = $DB->get_record('moodleoverflow', array('id' => $m), '*', MUST_EXIST);
- $course = $DB->get_record('course', array('id' => $moodleoverflow->course), '*', MUST_EXIST);
+ $moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $m], '*', MUST_EXIST);
+ $course = $DB->get_record('course', ['id' => $moodleoverflow->course], '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('moodleoverflow', $moodleoverflow->id, $course->id, false, MUST_EXIST);
} else {
throw new moodle_exception('missingparameter');
}
// Save the allowmultiplemarks setting.
-$marksetting = $DB->get_record('moodleoverflow', array('id' => $moodleoverflow->id), 'allowmultiplemarks');
+$marksetting = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow->id], 'allowmultiplemarks');
// Require a login.
require_login($course, true, $cm);
@@ -78,14 +78,14 @@
}
// Mark the activity completed (if required) and trigger the course_module_viewed event.
-$event = \mod_moodleoverflow\event\course_module_viewed::create(array(
+$event = \mod_moodleoverflow\event\course_module_viewed::create([
'objectid' => $PAGE->cm->instance,
'context' => $PAGE->context,
-));
+]);
$event->trigger();
// Print the page header.
-$PAGE->set_url('/mod/moodleoverflow/view.php', array('id' => $cm->id));
+$PAGE->set_url('/mod/moodleoverflow/view.php', ['id' => $cm->id]);
$PAGE->set_title(format_string($moodleoverflow->name));
$PAGE->set_heading(format_string($course->fullname));
@@ -100,7 +100,7 @@
if ($moodleoverflow->anonymous > 0) {
$strkeys = [
\mod_moodleoverflow\anonymous::QUESTION_ANONYMOUS => 'desc:only_questions',
- \mod_moodleoverflow\anonymous::EVERYTHING_ANONYMOUS => 'desc:anonymous'
+ \mod_moodleoverflow\anonymous::EVERYTHING_ANONYMOUS => 'desc:anonymous',
];
echo html_writer::tag('p', get_string($strkeys[$moodleoverflow->anonymous], 'moodleoverflow'));
}
@@ -109,7 +109,7 @@
if ($reviewlevel > 0) {
$strkeys = [
\mod_moodleoverflow\review::QUESTIONS => 'desc:review_questions',
- \mod_moodleoverflow\review::EVERYTHING => 'desc:review_everything'
+ \mod_moodleoverflow\review::EVERYTHING => 'desc:review_everything',
];
echo html_writer::tag('p', get_string($strkeys[$reviewlevel], 'moodleoverflow'));
}
@@ -131,7 +131,7 @@
if ($linktoforum && $movetopopup && has_capability('mod/moodleoverflow:movetopic', $context)) {
// Take the $movetopopup-id and the $linktoforum-id and move the discussion to the forum.
- $topic = $DB->get_record('moodleoverflow_discussions', array('id' => $movetopopup));
+ $topic = $DB->get_record('moodleoverflow_discussions', ['id' => $movetopopup]);
$topic->moodleoverflow = $linktoforum;
$DB->update_record('moodleoverflow_discussions', $topic);
redirect($CFG->wwwroot . '/mod/moodleoverflow/view.php?id=' . $cm->id);
From a6917ad7660fca108d853a210dc684ad79aeb7e7 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 2 Nov 2023 09:31:44 +0100
Subject: [PATCH 35/56] codechecker fix in subscriptions_test
---
tests/subscriptions_test.php | 306 +++++++++++++++++------------------
1 file changed, 153 insertions(+), 153 deletions(-)
diff --git a/tests/subscriptions_test.php b/tests/subscriptions_test.php
index 28f5776a9d..e7a70c06b5 100644
--- a/tests/subscriptions_test.php
+++ b/tests/subscriptions_test.php
@@ -45,8 +45,8 @@ class subscriptions_test extends advanced_testcase {
*/
public function setUp(): void {
// Clear all caches.
- \mod_moodleoverflow\subscriptions::reset_moodleoverflow_cache();
- \mod_moodleoverflow\subscriptions::reset_discussion_cache();
+ subscriptions::reset_moodleoverflow_cache();
+ subscriptions::reset_discussion_cache();
}
/**
@@ -54,8 +54,8 @@ public function setUp(): void {
*/
public function tearDown(): void {
// Clear all caches.
- \mod_moodleoverflow\subscriptions::reset_moodleoverflow_cache();
- \mod_moodleoverflow\subscriptions::reset_discussion_cache();
+ subscriptions::reset_moodleoverflow_cache();
+ subscriptions::reset_discussion_cache();
}
/**
@@ -129,34 +129,34 @@ public function test_subscription_modes() {
$this->setUser($user);
// Test the forced subscription.
- \mod_moodleoverflow\subscriptions::set_subscription_mode($moodleoverflow->id, MOODLEOVERFLOW_FORCESUBSCRIBE);
+ subscriptions::set_subscription_mode($moodleoverflow->id, MOODLEOVERFLOW_FORCESUBSCRIBE);
$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow->id]);
$this->assertEquals(MOODLEOVERFLOW_FORCESUBSCRIBE,
- \mod_moodleoverflow\subscriptions::get_subscription_mode($moodleoverflow));
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_forcesubscribed($moodleoverflow));
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribable($moodleoverflow, $modulecontext));
- $this->assertFalse(\mod_moodleoverflow\subscriptions::subscription_disabled($moodleoverflow));
+ subscriptions::get_subscription_mode($moodleoverflow));
+ $this->assertTrue(subscriptions::is_forcesubscribed($moodleoverflow));
+ $this->assertFalse(subscriptions::is_subscribable($moodleoverflow, $modulecontext));
+ $this->assertFalse(subscriptions::subscription_disabled($moodleoverflow));
// Test the disallowed subscription.
- \mod_moodleoverflow\subscriptions::set_subscription_mode($moodleoverflow->id, MOODLEOVERFLOW_DISALLOWSUBSCRIBE);
+ subscriptions::set_subscription_mode($moodleoverflow->id, MOODLEOVERFLOW_DISALLOWSUBSCRIBE);
$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow->id]);
- $this->assertTrue(\mod_moodleoverflow\subscriptions::subscription_disabled($moodleoverflow));
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribable($moodleoverflow, $modulecontext));
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_forcesubscribed($moodleoverflow));
+ $this->assertTrue(subscriptions::subscription_disabled($moodleoverflow));
+ $this->assertFalse(subscriptions::is_subscribable($moodleoverflow, $modulecontext));
+ $this->assertFalse(subscriptions::is_forcesubscribed($moodleoverflow));
// Test the initial subscription.
- \mod_moodleoverflow\subscriptions::set_subscription_mode($moodleoverflow->id, MOODLEOVERFLOW_INITIALSUBSCRIBE);
+ subscriptions::set_subscription_mode($moodleoverflow->id, MOODLEOVERFLOW_INITIALSUBSCRIBE);
$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow->id]);
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribable($moodleoverflow, $modulecontext));
- $this->assertFalse(\mod_moodleoverflow\subscriptions::subscription_disabled($moodleoverflow));
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_forcesubscribed($moodleoverflow));
+ $this->assertTrue(subscriptions::is_subscribable($moodleoverflow, $modulecontext));
+ $this->assertFalse(subscriptions::subscription_disabled($moodleoverflow));
+ $this->assertFalse(subscriptions::is_forcesubscribed($moodleoverflow));
// Test the choose subscription.
- \mod_moodleoverflow\subscriptions::set_subscription_mode($moodleoverflow->id, MOODLEOVERFLOW_CHOOSESUBSCRIBE);
+ subscriptions::set_subscription_mode($moodleoverflow->id, MOODLEOVERFLOW_CHOOSESUBSCRIBE);
$moodleoverflow = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow->id]);
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribable($moodleoverflow, $modulecontext));
- $this->assertFalse(\mod_moodleoverflow\subscriptions::subscription_disabled($moodleoverflow));
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_forcesubscribed($moodleoverflow));
+ $this->assertTrue(subscriptions::is_subscribable($moodleoverflow, $modulecontext));
+ $this->assertFalse(subscriptions::subscription_disabled($moodleoverflow));
+ $this->assertFalse(subscriptions::is_forcesubscribed($moodleoverflow));
}
/**
@@ -182,7 +182,7 @@ public function test_unsubscribable_moodleoverflows() {
$this->setUser($user);
// Without any subscriptions, there should be nothing returned.
- $result = \mod_moodleoverflow\subscriptions::get_unsubscribable_moodleoverflows();
+ $result = subscriptions::get_unsubscribable_moodleoverflows();
$this->assertEquals(0, count($result));
// Create the moodleoverflows.
@@ -196,15 +196,15 @@ public function test_unsubscribable_moodleoverflows() {
$this->getDataGenerator()->create_module('moodleoverflow', $options);
// At present the user is only subscribed to the initial moodleoverflow.
- $result = \mod_moodleoverflow\subscriptions::get_unsubscribable_moodleoverflows();
+ $result = subscriptions::get_unsubscribable_moodleoverflows();
$this->assertEquals(1, count($result));
// Ensure that the user is enrolled in all of the moodleoverflows execpt force subscribe.
- \mod_moodleoverflow\subscriptions::subscribe_user($user->id, $disallow, $modulecontext);
- \mod_moodleoverflow\subscriptions::subscribe_user($user->id, $choose, $modulecontext);
+ subscriptions::subscribe_user($user->id, $disallow, $modulecontext);
+ subscriptions::subscribe_user($user->id, $choose, $modulecontext);
// At present the user is subscribed to all three moodleoverflows.
- $result = \mod_moodleoverflow\subscriptions::get_unsubscribable_moodleoverflows();
+ $result = subscriptions::get_unsubscribable_moodleoverflows();
$this->assertEquals(3, count($result));
}
@@ -236,11 +236,11 @@ public function test_moodleoverflow_toggle_as_other() {
$discussion->moodleoverflow = $moodleoverflow->id;
// Check that the user is currently not subscribed to the moodleoverflow.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow,
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow,
$modulecontext));
// Check that the user is unsubscribed from the discussion too.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow,
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow,
$modulecontext, $discussion->id));
// Check thast we have no records in either on the subscription tables.
@@ -253,7 +253,7 @@ public function test_moodleoverflow_toggle_as_other() {
// Subscribing to the moodleoverflow should create a record in the subscription table,
// but the moodleoverflow discussion subscriptions table.
- \mod_moodleoverflow\subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext);
+ subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext);
$options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
@@ -263,7 +263,7 @@ public function test_moodleoverflow_toggle_as_other() {
// Unsubscribing should remove the record from the moodleoverflow subscription table.
// Do not modify the moodleoverflow discussion subscriptions table.
- \mod_moodleoverflow\subscriptions::unsubscribe_user($author->id, $moodleoverflow, $modulecontext);
+ subscriptions::unsubscribe_user($author->id, $moodleoverflow, $modulecontext);
$options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(0, $count);
@@ -273,7 +273,7 @@ public function test_moodleoverflow_toggle_as_other() {
// Enroling the user in the discussion should add one record to the
// moodleoverflow discussion table without modifying the form subscription.
- \mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
$options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(0, $count);
@@ -283,7 +283,7 @@ public function test_moodleoverflow_toggle_as_other() {
// Unsubscribing should remove the record from the moodleoverflow subscriptions
// table and not modify the moodleoverflow discussion subscription table.
- \mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
$options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(0, $count);
@@ -292,7 +292,7 @@ public function test_moodleoverflow_toggle_as_other() {
$this->assertEquals(0, $count);
// Resubscribe to the discussion so that we can check the effect of moodleoverflow-level subscriptions.
- \mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
$options = ['userid' => $author->id, 'discussion' => $discussion->id];
$count = $DB->count_records('moodleoverflow_discuss_subs', $options);
$this->assertEquals(1, $count);
@@ -302,7 +302,7 @@ public function test_moodleoverflow_toggle_as_other() {
// Subscribing to the moodleoverflow should have no effect on the moodleoverflow discussion
// subscription table if the user did not request the change himself.
- \mod_moodleoverflow\subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext);
+ subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext);
$options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
@@ -312,7 +312,7 @@ public function test_moodleoverflow_toggle_as_other() {
// Unsubbing from the moodleoverflow should have no effect on the moodleoverflow
// discussion subscription table if the user did not request the change themself.
- \mod_moodleoverflow\subscriptions::unsubscribe_user($author->id, $moodleoverflow, $modulecontext);
+ subscriptions::unsubscribe_user($author->id, $moodleoverflow, $modulecontext);
$options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(0, $count);
@@ -322,7 +322,7 @@ public function test_moodleoverflow_toggle_as_other() {
// Subscribing to the moodleoverflow should remove the per-discussion
// subscription preference if the user requested the change themself.
- \mod_moodleoverflow\subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext, true);
+ subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext, true);
$options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
@@ -331,7 +331,7 @@ public function test_moodleoverflow_toggle_as_other() {
$this->assertEquals(0, $count);
// Now unsubscribe from the current discussion whilst being subscribed to the moodleoverflow as a whole.
- \mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
$options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
@@ -341,7 +341,7 @@ public function test_moodleoverflow_toggle_as_other() {
// Unsubscribing from the moodleoverflow should remove the per-discussion
// subscription preference if the user requested the change himself.
- \mod_moodleoverflow\subscriptions::unsubscribe_user($author->id, $moodleoverflow, $modulecontext, true);
+ subscriptions::unsubscribe_user($author->id, $moodleoverflow, $modulecontext, true);
$options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(0, $count);
@@ -352,7 +352,7 @@ public function test_moodleoverflow_toggle_as_other() {
$this->assertEquals(0, $count);
// Subscribe to the discussion.
- \mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
$options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(0, $count);
@@ -363,7 +363,7 @@ public function test_moodleoverflow_toggle_as_other() {
$this->assertEquals(1, $count);
// Subscribe to the moodleoverflow without removing the discussion preferences.
- \mod_moodleoverflow\subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext);
+ subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext);
$options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
@@ -372,7 +372,7 @@ public function test_moodleoverflow_toggle_as_other() {
$this->assertEquals(1, $count);
// Unsubscribe from the discussion should result in a change.
- \mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
$options = ['userid' => $author->id, 'moodleoverflow' => $moodleoverflow->id];
$count = $DB->count_records('moodleoverflow_subscriptions', $options);
$this->assertEquals(1, $count);
@@ -397,14 +397,14 @@ public function test_moodleoverflow_discussion_subscription_moodleoverflow_unsub
list($author) = $this->helper_create_users($course, 1);
// Check that the user is currently not subscribed to the moodleoverflow.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $moodleoverflow));
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $moodleoverflow));
// Post a discussion to the moodleoverflow.
list($discussion, $post) = $this->helper_post_to_moodleoverflow($moodleoverflow, $author);
unset($post);
// Check that the user is unsubscribed from the discussion too.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow,
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow,
$moodleoverflow, $discussion));
}
@@ -429,21 +429,21 @@ public function test_moodleoverflow_discussion_subscription_moodleoverflow_subsc
// Enrol the user in the moodleoverflow.
// If a subscription was added, we get the record ID.
- $this->assertIsInt(\mod_moodleoverflow\subscriptions::subscribe_user($author->id,
+ $this->assertIsInt(subscriptions::subscribe_user($author->id,
$moodleoverflow, $modulecontext));
// If we already have a subscription when subscribing the user, we get a boolean (true).
- $this->assertTrue(\mod_moodleoverflow\subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext));
+ $this->assertTrue(subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext));
// Check that the user is currently subscribed to the moodleoverflow.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// Post a discussion to the moodleoverflow.
list($discussion, $post) = $this->helper_post_to_moodleoverflow($moodleoverflow, $author);
unset($post);
// Check that the user is subscribed to the discussion too.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
$discussion));
}
@@ -467,7 +467,7 @@ public function test_moodleoverflow_discussion_subscription_moodleoverflow_unsub
list($author) = $this->helper_create_users($course, 1);
// Check that the user is currently not subscribed to the moodleoverflow.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $moodleoverflow));
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $moodleoverflow));
// Post a discussion to the moodleoverflow.
$discussion = new \stdClass();
@@ -476,18 +476,18 @@ public function test_moodleoverflow_discussion_subscription_moodleoverflow_unsub
$discussion->moodleoverflow = $moodleoverflow->id;
// Attempting to unsubscribe from the discussion should not make a change.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($author->id,
+ $this->assertFalse(subscriptions::unsubscribe_user_from_discussion($author->id,
$discussion, $modulecontext));
// Then subscribe them to the discussion.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($author->id,
+ $this->assertTrue(subscriptions::subscribe_user_to_discussion($author->id,
$discussion, $modulecontext));
// Check that the user is still unsubscribed from the moodleoverflow.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $moodleoverflow));
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $moodleoverflow));
// But subscribed to the discussion.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
$discussion->id));
}
@@ -511,10 +511,10 @@ public function test_moodleoverflow_discussion_subscription_moodleoverflow_subsc
list($author) = $this->helper_create_users($course, 2);
// Enrol the student in the moodleoverflow.
- \mod_moodleoverflow\subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext);
+ subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext);
// Check that the user is currently subscribed to the moodleoverflow.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// Post a discussion to the moodleoverflow.
$discussion = new \stdClass();
@@ -523,13 +523,13 @@ public function test_moodleoverflow_discussion_subscription_moodleoverflow_subsc
$discussion->moodleoverflow = $moodleoverflow->id;
// Then unsubscribe them from the discussion.
- \mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
// Check that the user is still subscribed to the moodleoverflow.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// But unsubscribed from the discussion.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
$discussion->id));
}
@@ -554,7 +554,7 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
list($author) = $this->helper_create_users($course, 2);
// Enrol the student in the moodleoverflow.
- \mod_moodleoverflow\subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext);
+ subscriptions::subscribe_user($author->id, $moodleoverflow, $modulecontext);
// Post a discussion to the moodleoverflow.
$discussion = new \stdClass();
@@ -563,14 +563,14 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$discussion->moodleoverflow = $moodleoverflow->id;
// Check that the user is currently subscribed to the moodleoverflow.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// Check that the user is initially subscribed to that discussion.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
$discussion->id));
// An attempt to subscribe again should result in a falsey return to indicate that no change was made.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($author->id,
+ $this->assertFalse(subscriptions::subscribe_user_to_discussion($author->id,
$discussion, $modulecontext));
// And there should be no discussion subscriptions (and one moodleoverflow subscription).
@@ -582,13 +582,13 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$this->assertEquals(1, $count);
// Then unsubscribe them from the discussion.
- \mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
// Check that the user is still subscribed to the moodleoverflow.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// An attempt to unsubscribe again should result in a falsey return to indicate that no change was made.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($author->id,
+ $this->assertFalse(subscriptions::unsubscribe_user_from_discussion($author->id,
$discussion, $modulecontext));
// And there should be a discussion subscriptions (and one moodleoverflow subscription).
@@ -600,7 +600,7 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$this->assertEquals(1, $count);
// But unsubscribed from the discussion.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
$discussion->id));
// There should be a record in the discussion subscription tracking table.
@@ -614,13 +614,13 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$this->assertEquals(1, $count);
// Now subscribe the user again to the discussion.
- \mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
// Check that the user is still subscribed to the moodleoverflow.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// And is subscribed to the discussion again.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
$discussion->id));
// And one in the moodleoverflow subscription tracking table.
@@ -634,13 +634,13 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$this->assertEquals(0, $count);
// And unsubscribe again.
- \mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
// Check that the user is still subscribed to the moodleoverflow.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// But unsubscribed from the discussion.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
$discussion->id));
// And one in the moodleoverflow subscription tracking table.
@@ -654,14 +654,14 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$this->assertEquals(1, $count);
// And subscribe the user again to the discussion.
- \mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
// Check that the user is still subscribed to the moodleoverflow.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// And is subscribed to the discussion again.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
$discussion->id));
// There should be no record in the discussion subscription tracking table.
@@ -675,14 +675,14 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$this->assertEquals(1, $count);
// And unsubscribe again.
- \mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
// But unsubscribed from the discussion.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
$discussion->id));
// Check that the user is still subscribed to the moodleoverflow.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// There should be a record in the discussion subscription tracking table.
$options = ['userid' => $author->id, 'discussion' => $discussion->id];
@@ -695,7 +695,7 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$this->assertEquals(1, $count);
// Now unsubscribe the user from the moodleoverflow.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::unsubscribe_user($author->id, $moodleoverflow, $modulecontext,
+ $this->assertTrue(subscriptions::unsubscribe_user($author->id, $moodleoverflow, $modulecontext,
true));
// This removes both the moodleoverflow, and the moodleoverflow records.
@@ -707,7 +707,7 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(
$this->assertEquals(0, $count);
// And should have reset the discussion cache value.
- $result = \mod_moodleoverflow\subscriptions::fetch_discussion_subscription($moodleoverflow->id, $author->id);
+ $result = subscriptions::fetch_discussion_subscription($moodleoverflow->id, $author->id);
$this->assertIsArray($result);
$this->assertFalse(isset($result[$discussion->id]));
}
@@ -734,7 +734,7 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_unsubscribe
list($author) = $this->helper_create_users($course, 2);
// Check that the user is currently unsubscribed to the moodleoverflow.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// Post a discussion to the moodleoverflow.
$discussion = new \stdClass();
@@ -743,22 +743,22 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_unsubscribe
$discussion->moodleoverflow = $moodleoverflow->id;
// Check that the user is initially unsubscribed to that discussion.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
$discussion->id));
// Then subscribe them to the discussion.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($author->id,
+ $this->assertTrue(subscriptions::subscribe_user_to_discussion($author->id,
$discussion, $modulecontext));
// An attempt to subscribe again should result in a falsey return to indicate that no change was made.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($author->id,
+ $this->assertFalse(subscriptions::subscribe_user_to_discussion($author->id,
$discussion, $modulecontext));
// Check that the user is still unsubscribed from the moodleoverflow.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// But subscribed to the discussion.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
$discussion->id));
// There should be a record in the discussion subscription tracking table.
@@ -767,13 +767,13 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_unsubscribe
$this->assertEquals(1, $count);
// Now unsubscribe the user again from the discussion.
- \mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
// Check that the user is still unsubscribed from the moodleoverflow.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// And is unsubscribed from the discussion again.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
$discussion->id));
// There should be no record in the discussion subscription tracking table.
@@ -782,14 +782,14 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_unsubscribe
$this->assertEquals(0, $count);
// And subscribe the user again to the discussion.
- \mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::subscribe_user_to_discussion($author->id, $discussion, $modulecontext);
// And is subscribed to the discussion again.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
+ $this->assertTrue(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
$discussion->id));
// Check that the user is still unsubscribed from the moodleoverflow.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// There should be a record in the discussion subscription tracking table.
$options = ['userid' => $author->id, 'discussion' => $discussion->id];
@@ -797,14 +797,14 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_unsubscribe
$this->assertEquals(1, $count);
// And unsubscribe again.
- \mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
+ subscriptions::unsubscribe_user_from_discussion($author->id, $discussion, $modulecontext);
// But unsubscribed from the discussion.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext,
$discussion->id));
// Check that the user is still unsubscribed from the moodleoverflow.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
+ $this->assertFalse(subscriptions::is_subscribed($author->id, $moodleoverflow, $modulecontext));
// There should be no record in the discussion subscription tracking table.
$options = ['userid' => $author->id, 'discussion' => $discussion->id];
@@ -836,22 +836,22 @@ public function test_fetch_subscribed_users_subscriptions() {
$users = $this->helper_create_users($course, $usercount);
// All users should be subscribed.
- $subscribers = \mod_moodleoverflow\subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
+ $subscribers = subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
$this->assertEquals($usercount, count($subscribers));
// Subscribe the guest user too to the moodleoverflow - they should never be returned by this function.
$this->getDataGenerator()->enrol_user($CFG->siteguest, $course->id);
- $subscribers = \mod_moodleoverflow\subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
+ $subscribers = subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
$this->assertEquals($usercount, count($subscribers));
// Unsubscribe 2 users.
$unsubscribedcount = 2;
for ($i = 0; $i < $unsubscribedcount; $i++) {
- \mod_moodleoverflow\subscriptions::unsubscribe_user($users[$i]->id, $moodleoverflow, $modulecontext);
+ subscriptions::unsubscribe_user($users[$i]->id, $moodleoverflow, $modulecontext);
}
// The subscription count should now take into account those users who have been unsubscribed.
- $subscribers = \mod_moodleoverflow\subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
+ $subscribers = subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
$this->assertEquals($usercount - $unsubscribedcount, count($subscribers));
}
@@ -877,7 +877,7 @@ public function test_fetch_subscribed_users_forced() {
$this->helper_create_users($course, $usercount);
// All users should be subscribed.
- $subscribers = \mod_moodleoverflow\subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
+ $subscribers = subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
$this->assertEquals($usercount, count($subscribers));
}
@@ -910,20 +910,20 @@ public function test_fetch_subscribed_users_discussion_subscriptions() {
$discussion->moodleoverflow = $moodleoverflow->id;
// All users should be subscribed.
- $subscribers = \mod_moodleoverflow\subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
+ $subscribers = subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
$this->assertEquals($usercount, count($subscribers));
- $subscribers = \mod_moodleoverflow\subscriptions::get_subscribed_users($moodleoverflow, $modulecontext, null,
+ $subscribers = subscriptions::get_subscribed_users($moodleoverflow, $modulecontext, null,
true);
$this->assertEquals($usercount, count($subscribers));
- \mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($users[0]->id, $discussion, $modulecontext);
+ subscriptions::unsubscribe_user_from_discussion($users[0]->id, $discussion, $modulecontext);
// All users should be subscribed.
- $subscribers = \mod_moodleoverflow\subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
+ $subscribers = subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
$this->assertEquals($usercount, count($subscribers));
// All users should be subscribed.
- $subscribers = \mod_moodleoverflow\subscriptions::get_subscribed_users($moodleoverflow, $modulecontext, null,
+ $subscribers = subscriptions::get_subscribed_users($moodleoverflow, $modulecontext, null,
true);
$this->assertEquals($usercount, count($subscribers));
@@ -936,33 +936,33 @@ public function test_fetch_subscribed_users_discussion_subscriptions() {
$DB->insert_record('moodleoverflow_discuss_subs', $record);
// The discussion count should not have changed.
- $subscribers = \mod_moodleoverflow\subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
+ $subscribers = subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
$this->assertEquals($usercount, count($subscribers));
- $subscribers = \mod_moodleoverflow\subscriptions::get_subscribed_users($moodleoverflow, $modulecontext, null,
+ $subscribers = subscriptions::get_subscribed_users($moodleoverflow, $modulecontext, null,
true);
$this->assertEquals($usercount, count($subscribers));
// Unsubscribe 2 users.
$unsubscribedcount = 2;
for ($i = 0; $i < $unsubscribedcount; $i++) {
- \mod_moodleoverflow\subscriptions::unsubscribe_user($users[$i]->id, $moodleoverflow, $modulecontext);
+ subscriptions::unsubscribe_user($users[$i]->id, $moodleoverflow, $modulecontext);
}
// The subscription count should now take into account those users who have been unsubscribed.
- $subscribers = \mod_moodleoverflow\subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
+ $subscribers = subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
$this->assertEquals($usercount - $unsubscribedcount, count($subscribers));
- $subscribers = \mod_moodleoverflow\subscriptions::get_subscribed_users($moodleoverflow, $modulecontext, null,
+ $subscribers = subscriptions::get_subscribed_users($moodleoverflow, $modulecontext, null,
true);
$this->assertEquals($usercount - $unsubscribedcount, count($subscribers));
// Now subscribe one of those users back to the discussion.
$subedusers = 1;
for ($i = 0; $i < $subedusers; $i++) {
- \mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($users[$i]->id, $discussion, $modulecontext);
+ subscriptions::subscribe_user_to_discussion($users[$i]->id, $discussion, $modulecontext);
}
- $subscribers = \mod_moodleoverflow\subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
+ $subscribers = subscriptions::get_subscribed_users($moodleoverflow, $modulecontext);
$this->assertEquals($usercount - $unsubscribedcount, count($subscribers));
- $subscribers = \mod_moodleoverflow\subscriptions::get_subscribed_users($moodleoverflow, $modulecontext, null,
+ $subscribers = subscriptions::get_subscribed_users($moodleoverflow, $modulecontext, null,
true);
$this->assertEquals($usercount - $unsubscribedcount + $subedusers, count($subscribers));
}
@@ -992,7 +992,7 @@ public function test_force_subscribed_to_moodleoverflow() {
$this->getDataGenerator()->enrol_user($user->id, $course->id, $roleids['student']);
// Check that the user is currently subscribed to the moodleoverflow.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::is_subscribed($user->id, $moodleoverflow, $context));
+ $this->assertTrue(subscriptions::is_subscribed($user->id, $moodleoverflow, $context));
assign_capability('mod/moodleoverflow:allowforcesubscribe', CAP_PROHIBIT, $roleids['student'],
$context);
@@ -1018,17 +1018,17 @@ public function test_subscription_cache_prefill() {
$users = $this->helper_create_users($course, 20);
// Reset the subscription cache.
- \mod_moodleoverflow\subscriptions::reset_moodleoverflow_cache();
+ subscriptions::reset_moodleoverflow_cache();
// Filling the subscription cache should only use a single query, except for Postgres, which delegates actual reading
// to Cursors, thus tripling the amount of queries. We intend to test the cache, though, so no worries.
- $this->assertNull(\mod_moodleoverflow\subscriptions::fill_subscription_cache($moodleoverflow->id));
+ $this->assertNull(subscriptions::fill_subscription_cache($moodleoverflow->id));
$postfillcount = $DB->perf_get_reads();
// Now fetch some subscriptions from that moodleoverflow - these should use
// the cache and not perform additional queries.
foreach ($users as $user) {
- $this->assertTrue(\mod_moodleoverflow\subscriptions::fetch_subscription_cache($moodleoverflow->id, $user->id));
+ $this->assertTrue(subscriptions::fetch_subscription_cache($moodleoverflow->id, $user->id));
}
$finalcount = $DB->perf_get_reads();
$this->assertEquals($finalcount, $postfillcount);
@@ -1053,14 +1053,14 @@ public function test_subscription_cache_fill() {
$users = $this->helper_create_users($course, 20);
// Reset the subscription cache.
- \mod_moodleoverflow\subscriptions::reset_moodleoverflow_cache();
+ subscriptions::reset_moodleoverflow_cache();
// Filling the subscription cache should only use a single query.
$startcount = $DB->perf_get_reads();
// Fetch some subscriptions from that moodleoverflow - these should not use the cache and will perform additional queries.
foreach ($users as $user) {
- $this->assertTrue(\mod_moodleoverflow\subscriptions::fetch_subscription_cache($moodleoverflow->id, $user->id));
+ $this->assertTrue(subscriptions::fetch_subscription_cache($moodleoverflow->id, $user->id));
}
$finalcount = $DB->perf_get_reads();
$this->assertEquals(20, $finalcount - $startcount);
@@ -1091,23 +1091,23 @@ public function test_discussion_subscription_cache_fill_for_course() {
$user = reset($users);
// Reset the subscription caches.
- \mod_moodleoverflow\subscriptions::reset_moodleoverflow_cache();
+ subscriptions::reset_moodleoverflow_cache();
- $result = \mod_moodleoverflow\subscriptions::fill_subscription_cache_for_course($course->id, $user->id);
+ $result = subscriptions::fill_subscription_cache_for_course($course->id, $user->id);
$this->assertNull($result);
$postfillcount = $DB->perf_get_reads();
- $this->assertFalse(\mod_moodleoverflow\subscriptions::fetch_subscription_cache($disallowmoodleoverflow->id, $user->id));
- $this->assertFalse(\mod_moodleoverflow\subscriptions::fetch_subscription_cache($choosemoodleoverflow->id, $user->id));
- $this->assertTrue(\mod_moodleoverflow\subscriptions::fetch_subscription_cache($initialmoodleoverflow->id, $user->id));
+ $this->assertFalse(subscriptions::fetch_subscription_cache($disallowmoodleoverflow->id, $user->id));
+ $this->assertFalse(subscriptions::fetch_subscription_cache($choosemoodleoverflow->id, $user->id));
+ $this->assertTrue(subscriptions::fetch_subscription_cache($initialmoodleoverflow->id, $user->id));
$finalcount = $DB->perf_get_reads();
$this->assertEquals(0, $finalcount - $postfillcount);
// Test for all users.
foreach ($users as $user) {
- $result = \mod_moodleoverflow\subscriptions::fill_subscription_cache_for_course($course->id, $user->id);
- $this->assertFalse(\mod_moodleoverflow\subscriptions::fetch_subscription_cache($disallowmoodleoverflow->id, $user->id));
- $this->assertFalse(\mod_moodleoverflow\subscriptions::fetch_subscription_cache($choosemoodleoverflow->id, $user->id));
- $this->assertTrue(\mod_moodleoverflow\subscriptions::fetch_subscription_cache($initialmoodleoverflow->id, $user->id));
+ $result = subscriptions::fill_subscription_cache_for_course($course->id, $user->id);
+ $this->assertFalse(subscriptions::fetch_subscription_cache($disallowmoodleoverflow->id, $user->id));
+ $this->assertFalse(subscriptions::fetch_subscription_cache($choosemoodleoverflow->id, $user->id));
+ $this->assertTrue(subscriptions::fetch_subscription_cache($initialmoodleoverflow->id, $user->id));
}
$finalcount = $DB->perf_get_reads();
$reads = $finalcount - $postfillcount;
@@ -1162,24 +1162,24 @@ public function test_discussion_subscription_cache_prefill() {
if ($usercount % 2) {
continue;
}
- \mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion, $modulecontext);
+ subscriptions::unsubscribe_user_from_discussion($user->id, $discussion, $modulecontext);
$usercount++;
}
$moodleoverflowcount++;
}
// Reset the subscription caches.
- \mod_moodleoverflow\subscriptions::reset_moodleoverflow_cache();
- \mod_moodleoverflow\subscriptions::reset_discussion_cache();
+ subscriptions::reset_moodleoverflow_cache();
+ subscriptions::reset_discussion_cache();
// Filling the discussion subscription cache should only use a single query.
- $this->assertNull(\mod_moodleoverflow\subscriptions::fill_discussion_subscription_cache($moodleoverflow->id));
+ $this->assertNull(subscriptions::fill_discussion_subscription_cache($moodleoverflow->id));
$postfillcount = $DB->perf_get_reads();
// Now fetch some subscriptions from that moodleoverflow - these should use
// the cache and not perform additional queries.
foreach ($users as $user) {
- $result = \mod_moodleoverflow\subscriptions::fetch_discussion_subscription($moodleoverflow->id, $user->id);
+ $result = subscriptions::fetch_discussion_subscription($moodleoverflow->id, $user->id);
$this->assertIsArray($result);
}
$finalcount = $DB->perf_get_reads();
@@ -1229,22 +1229,22 @@ public function test_discussion_subscription_cache_fill() {
if ($usercount % 2) {
continue;
}
- \mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion, $modulecontext);
+ subscriptions::unsubscribe_user_from_discussion($user->id, $discussion, $modulecontext);
$usercount++;
}
$moodleoverflowcount++;
}
// Reset the subscription caches.
- \mod_moodleoverflow\subscriptions::reset_moodleoverflow_cache();
- \mod_moodleoverflow\subscriptions::reset_discussion_cache();
+ subscriptions::reset_moodleoverflow_cache();
+ subscriptions::reset_discussion_cache();
$startcount = $DB->perf_get_reads();
// Now fetch some subscriptions from that moodleoverflow - these should use
// the cache and not perform additional queries.
foreach ($users as $user) {
- $result = \mod_moodleoverflow\subscriptions::fetch_discussion_subscription($moodleoverflow->id, $user->id);
+ $result = subscriptions::fetch_discussion_subscription($moodleoverflow->id, $user->id);
$this->assertIsArray($result);
}
$finalcount = $DB->perf_get_reads();
@@ -1287,10 +1287,10 @@ public function test_moodleoverflow_subscribe_toggle_as_other_repeat_subscriptio
$discussion->moodleoverflow = $moodleoverflow->id;
// Confirm that the user is currently not subscribed to the moodleoverflow.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($user->id, $moodleoverflow, $modulecontext));
+ $this->assertFalse(subscriptions::is_subscribed($user->id, $moodleoverflow, $modulecontext));
// Confirm that the user is unsubscribed from the discussion too.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribed($user->id, $moodleoverflow, $modulecontext,
+ $this->assertFalse(subscriptions::is_subscribed($user->id, $moodleoverflow, $modulecontext,
$discussion->id));
// Confirm that we have no records in either of the subscription tables.
@@ -1305,7 +1305,7 @@ public function test_moodleoverflow_subscribe_toggle_as_other_repeat_subscriptio
// Subscribing to the moodleoverflow should create a record in the subscriptions table,
// but not the moodleoverflow discussion subscriptions table.
- \mod_moodleoverflow\subscriptions::subscribe_user($user->id, $moodleoverflow, $modulecontext);
+ subscriptions::subscribe_user($user->id, $moodleoverflow, $modulecontext);
$this->assertEquals(1, $DB->count_records('moodleoverflow_subscriptions', [
'userid' => $user->id,
'moodleoverflow' => $moodleoverflow->id,
@@ -1317,22 +1317,22 @@ public function test_moodleoverflow_subscribe_toggle_as_other_repeat_subscriptio
// Now unsubscribe from the discussion. This should return true.
$uid = $user->id;
- $this->assertTrue(\mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($uid, $discussion, $modulecontext));
+ $this->assertTrue(subscriptions::unsubscribe_user_from_discussion($uid, $discussion, $modulecontext));
// Attempting to unsubscribe again should return false because no change was made.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($uid, $discussion, $modulecontext));
+ $this->assertFalse(subscriptions::unsubscribe_user_from_discussion($uid, $discussion, $modulecontext));
// Subscribing to the discussion again should return truthfully as the subscription preference was removed.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($user->id, $discussion, $modulecontext));
+ $this->assertTrue(subscriptions::subscribe_user_to_discussion($user->id, $discussion, $modulecontext));
// Attempting to subscribe again should return false because no change was made.
- $this->assertFalse(\mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($user->id, $discussion, $modulecontext));
+ $this->assertFalse(subscriptions::subscribe_user_to_discussion($user->id, $discussion, $modulecontext));
// Now unsubscribe from the discussion. This should return true once more.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::unsubscribe_user_from_discussion($uid, $discussion, $modulecontext));
+ $this->assertTrue(subscriptions::unsubscribe_user_from_discussion($uid, $discussion, $modulecontext));
// And unsubscribing from the moodleoverflow but not as a request from the user should maintain their preference.
- \mod_moodleoverflow\subscriptions::unsubscribe_user($user->id, $moodleoverflow, $modulecontext);
+ subscriptions::unsubscribe_user($user->id, $moodleoverflow, $modulecontext);
$this->assertEquals(0, $DB->count_records('moodleoverflow_subscriptions', [
'userid' => $user->id,
@@ -1344,7 +1344,7 @@ public function test_moodleoverflow_subscribe_toggle_as_other_repeat_subscriptio
]));
// Subscribing to the discussion should return truthfully because a change was made.
- $this->assertTrue(\mod_moodleoverflow\subscriptions::subscribe_user_to_discussion($user->id, $discussion, $modulecontext));
+ $this->assertTrue(subscriptions::subscribe_user_to_discussion($user->id, $discussion, $modulecontext));
$this->assertEquals(0, $DB->count_records('moodleoverflow_subscriptions', [
'userid' => $user->id,
'moodleoverflow' => $moodleoverflow->id,
@@ -1382,7 +1382,7 @@ public function is_subscribable_moodleoverflows() {
*
* @return array
*/
- public function is_subscribable_provider() {
+ public function is_subscribable_provider() : array {
$data = [];
foreach ($this->is_subscribable_moodleoverflows() as $moodleoverflow) {
$data[] = [$moodleoverflow];
@@ -1406,7 +1406,7 @@ public function test_is_subscribable_logged_out($options) {
$options['course'] = $course->id;
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribable($moodleoverflow,
+ $this->assertFalse(subscriptions::is_subscribable($moodleoverflow,
\context_module::instance($moodleoverflow->cmid)));
}
@@ -1430,15 +1430,15 @@ public function test_is_subscribable_is_guest($options) {
$options['course'] = $course->id;
$moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $options);
- $this->assertFalse(\mod_moodleoverflow\subscriptions::is_subscribable($moodleoverflow,
+ $this->assertFalse(subscriptions::is_subscribable($moodleoverflow,
\context_module::instance($moodleoverflow->cmid)));
}
/**
- * Returns subscription obtions.
+ * Returns subscription options.
* @return array
*/
- public function is_subscribable_loggedin_provider() {
+ public function is_subscribable_loggedin_provider() : array {
return [
[
['forcesubscribe' => MOODLEOVERFLOW_DISALLOWSUBSCRIBE],
@@ -1481,7 +1481,7 @@ public function test_is_subscribable_loggedin($options, $expect) {
$this->getDataGenerator()->enrol_user($user->id, $course->id);
$this->setUser($user);
- $this->assertEquals($expect, \mod_moodleoverflow\subscriptions::is_subscribable($moodleoverflow,
+ $this->assertEquals($expect, subscriptions::is_subscribable($moodleoverflow,
\context_module::instance($moodleoverflow->cmid)));
}
}
From ef6bef851f2720d6c00a70448af6f90cc2827d4a Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 30 Nov 2023 09:10:26 +0100
Subject: [PATCH 36/56] grammar fix in comments
---
tests/userstats_test.php | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/tests/userstats_test.php b/tests/userstats_test.php
index 741712320f..9e43a9a174 100644
--- a/tests/userstats_test.php
+++ b/tests/userstats_test.php
@@ -93,8 +93,8 @@ public function setUp(): void {
*/
public function tearDown(): void {
// Clear all caches.
- \mod_moodleoverflow\subscriptions::reset_moodleoverflow_cache();
- \mod_moodleoverflow\subscriptions::reset_discussion_cache();
+ subscriptions::reset_moodleoverflow_cache();
+ subscriptions::reset_discussion_cache();
}
// Begin of test functions.
@@ -221,11 +221,11 @@ public function test_partial_anonymous() {
}
/**
- * Test, if userstats are calculated correctly if the moodleoverflow is partially anonymous.
+ * Test, if userstats are calculated correctly if the moodleoverflow is totally anonymous.
* @covers \userstats_table
*/
public function test_total_anonymous() {
- // Test case: Only topic startes are anonymous.
+ // Test case: All posts are anonymous.
$this->make_anonymous(2);
// Get the current userstats to compare later.
@@ -303,7 +303,7 @@ private function helper_course_set_up() {
* Makes the existing moodleoverflow anonymous.
* There are 2 types of anonymous moodleoverflows:
* anonymous = 1, the topic starter is anonymous
- * anonymous = 2, all users are anonym
+ * anonymous = 2, all users are anonymous
*
* @param int $anonymoussetting
*/
From c03c799f82d903afff2dff08db28252212358d97 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Tue, 23 Apr 2024 18:18:40 +0200
Subject: [PATCH 37/56] Change anonymous name from Anonymous to Questioner in
attachment
---
tests/behat/anonymous.feature | 2 +-
version.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/behat/anonymous.feature b/tests/behat/anonymous.feature
index 7e27e4bf28..875ab4cf0a 100644
--- a/tests/behat/anonymous.feature
+++ b/tests/behat/anonymous.feature
@@ -35,4 +35,4 @@ Feature: Use moodleoverflow anonymously
And I should see "Questioner"
Given I follow "Edit"
And I click on "NH.jpg" "link"
- Then the field "Author" matches value "Anonymous"
+ Then the field "Author" matches value "Questioner"
diff --git a/version.php b/version.php
index fe90ba0727..b8fffbb5e6 100644
--- a/version.php
+++ b/version.php
@@ -28,8 +28,8 @@
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'mod_moodleoverflow';
-$plugin->version = 2023082500;
$plugin->release = 'v4.2-r4';
+$plugin->version = 2024031200;
$plugin->requires = 2020061500; // Requires Moodle 3.9+.
$plugin->maturity = MATURITY_STABLE;
$plugin->dependencies = [];
From 0a6d18125df858dd2a713aff38f3d798199e2c7d Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Fri, 26 Apr 2024 16:27:39 +0200
Subject: [PATCH 38/56] fix for behat test
---
classes/post/post_control.php | 14 ++++++++++++--
tests/behat/anonymous.feature | 2 +-
tests/post_test.php | 1 +
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index 91da39cff8..2b77efad11 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -26,6 +26,7 @@
namespace mod_moodleoverflow\post;
// Import namespace from the locallib, needs a check later which namespaces are really needed.
+use mod_moodleoverflow\anonymous;
use mod_moodleoverflow\capabilities;
use mod_moodleoverflow\review;
@@ -479,8 +480,7 @@ private function execute_edit($form, $errordestination) {
if ($this->prepost->userid == $USER->id) {
$redirectmessage = get_string('postupdated', 'moodleoverflow');
} else {
- if (\mod_moodleoverflow\anonymous::is_post_anonymous($this->info->discussion, $this->info->moodleoverflow,
- $this->prepost->userid)) {
+ if (anonymous::is_post_anonymous($this->info->discussion, $this->info->moodleoverflow, $this->prepost->userid)) {
$name = get_string('anonymous', 'moodleoverflow');
} else {
$realuser = $DB->get_record('user', ['id' => $this->prepost->userid]);
@@ -567,6 +567,16 @@ public function build_postform($pageparams) {
empty($this->prepost->postid) ? null : $this->prepost->postid,
\mod_moodleoverflow_post_form::attachment_options($this->info->moodleoverflow));
+ // If the post is anonymous, attachments should have an anonymous author when editing the attachment.
+ if ($draftitemid && $this->interaction == 'edit' && anonymous::is_post_anonymous($this->info->discussion,
+ $this->info->moodleoverflow, $this->prepost->userid)) {
+ $usercontext = \context_user::instance($USER->id);
+ $anonymousstr = get_string('anonymous', 'moodleoverflow');
+ foreach (get_file_storage()->get_area_files($usercontext->id, 'user', 'draft', $draftitemid) as $file) {
+ $file->set_author($anonymousstr);
+ }
+ }
+
// Prepare the form.
$edit = $this->interaction == 'edit';
$formarray = ['course' => $this->info->course, 'cm' => $this->info->cm, 'coursecontext' => $this->info->coursecontext,
diff --git a/tests/behat/anonymous.feature b/tests/behat/anonymous.feature
index 875ab4cf0a..7e27e4bf28 100644
--- a/tests/behat/anonymous.feature
+++ b/tests/behat/anonymous.feature
@@ -35,4 +35,4 @@ Feature: Use moodleoverflow anonymously
And I should see "Questioner"
Given I follow "Edit"
And I click on "NH.jpg" "link"
- Then the field "Author" matches value "Questioner"
+ Then the field "Author" matches value "Anonymous"
diff --git a/tests/post_test.php b/tests/post_test.php
index 0f9c754f13..b80e5ad86f 100644
--- a/tests/post_test.php
+++ b/tests/post_test.php
@@ -109,6 +109,7 @@ public function test_edit_post() {
$message = 'a new message';
$time = time();
+
// Update the post.
$this->post->moodleoverflow_edit_post($time, $message, $this->post->messageformat, $this->post->formattachments);
From 0eb61303d289b377932703c0dea24d15c8a64a31 Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 30 May 2024 12:20:36 +0200
Subject: [PATCH 39/56] check for php version
---
classes/post/post_control.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index 2b77efad11..01876c1d21 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -279,12 +279,12 @@ private function build_prepost_reply($replypostid) {
// Append 'RE: ' to the discussions subject.
$strre = get_string('re', 'moodleoverflow');
- if ($CFG->branch > 309) {
+ if (floor(phpversion()) >= 8) {
if (!(str_starts_with($this->prepost->subject, $strre))) {
$this->prepost->subject = $strre . ' ' . $this->prepost->subject;
}
} else {
- // TODO: remove this else branch when support for version 3.9 ends and delete the branch check.
+ // TODO: remove this else branch when support for php version 7.4 ends.
if (!(substr($this->prepost->subject, 0, strlen($strre)) == $strre)) {
$this->prepost->subject = $strre . ' ' . $this->prepost->subject;
}
From 121957eabc1df3dc2c37563419cc69b41df6670d Mon Sep 17 00:00:00 2001
From: TamaroWalter
Date: Thu, 30 May 2024 12:34:22 +0200
Subject: [PATCH 40/56] use moodle function to check php version
---
classes/post/post_control.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index 01876c1d21..60f1558966 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -279,7 +279,7 @@ private function build_prepost_reply($replypostid) {
// Append 'RE: ' to the discussions subject.
$strre = get_string('re', 'moodleoverflow');
- if (floor(phpversion()) >= 8) {
+ if (check_php_version('8.0.0')) {
if (!(str_starts_with($this->prepost->subject, $strre))) {
$this->prepost->subject = $strre . ' ' . $this->prepost->subject;
}
From c7dedfa7feaba2c41688caa0a2f79977bf652274 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Mon, 7 Jul 2025 17:24:08 +0000
Subject: [PATCH 41/56] Sync with Learnweb's centralized pull request template
---
.github/PULL_REQUEST_TEMPLATE.md | 53 ++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
create mode 100644 .github/PULL_REQUEST_TEMPLATE.md
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000000..81ba4368dd
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,53 @@
+> **Note:** Please fill out all required sections and remove irrelevant ones.
+### 🔀 Purpose of this PR:
+
+- [ ] Fixes a bug
+- [ ] Updates for a new Moodle version
+- [ ] Adds a new feature of functionality
+- [ ] Improves or enhances existing features
+- [ ] Refactoring: restructures code for better performance or maintainability
+- [ ] Testing: add missing or improve existing tests
+- [ ] Miscellaneous: code cleaning (without functional changes), documentation, configuration, ...
+
+---
+
+### 📝 Description:
+
+Please describe the purpose of this PR in a few sentences.
+
+- What feature or bug does it address?
+- Why is this change or addition necessary?
+- What is the expected behavior after the change?
+
+---
+
+### 📋 Checklist
+
+Please confirm the following (check all that apply):
+
+- [ ] I have `phpunit` and/or `behat` tests that cover my changes or additions.
+- [ ] Code passes the code checker without errors and warnings.
+- [ ] Code passes the moodle-ci/cd pipeline on all supported Moodle versions or the ones the plugin supports.
+- [ ] Code does not have `var_dump()` or `var_export` or any other debugging statements (or commented out code) that
+ should not appear on the productive branch.
+- [ ] Code only uses language strings instead of hard-coded strings.
+- [ ] If there are changes in the database: I updated/created the necessary upgrade steps in `db/upgrade.php` and
+ updated the `version.php`.
+- [ ] If there are changes in javascript: I build new `.min` files with the `grunt amd` command.
+- [ ] If it is a Moodle update PR: I read the release notes, updated the `version.php` and the `CHANGES.md`.
+ I ran all tests thoroughly checking for errors. I checked if bootstrap had any changes/deprecations that require
+ changes in the plugins UI.
+
+---
+
+### 🔍 Related Issues
+
+- Related to #[IssueNumber]
+
+---
+
+### 🧾📸🌐 Additional Information (like screenshots, documentation, links, etc.)
+
+Any other relevant information.
+
+---
\ No newline at end of file
From 7fe2ba9d4811fdeb0e76f6a891ac45d64a6643e4 Mon Sep 17 00:00:00 2001
From: Tamaro Walter
Date: Mon, 7 Jul 2025 19:33:30 +0200
Subject: [PATCH 42/56] code cleaning
---
classes/discussion/discussion.php | 2 +-
classes/post/post.php | 5 +-
classes/post/post_control.php | 42 +++++++--
classes/subscriptions.php | 4 +-
externallib.php | 2 +-
lang/en/moodleoverflow.php | 143 +-----------------------------
lib.php | 2 +-
locallib.php | 10 +--
post.php | 2 +-
tests/discussion_test.php | 4 +-
tests/post_test.php | 2 +
11 files changed, 56 insertions(+), 162 deletions(-)
diff --git a/classes/discussion/discussion.php b/classes/discussion/discussion.php
index bdc887eeac..68b2d7a03d 100644
--- a/classes/discussion/discussion.php
+++ b/classes/discussion/discussion.php
@@ -233,7 +233,7 @@ public function moodleoverflow_add_discussion($prepost) {
'context' => $prepost->modulecontext,
'objectid' => $this->id,
];
- // TODO: check if the event functions.
+ // LEARNWEB-TODO: check if the event functions.
$event = \mod_moodleoverflow\event\discussion_viewed::create($params);
$event->trigger();
diff --git a/classes/post/post.php b/classes/post/post.php
index b054a55595..b5b022e1be 100644
--- a/classes/post/post.php
+++ b/classes/post/post.php
@@ -31,6 +31,7 @@
use mod_moodleoverflow\review;
use mod_moodleoverflow\readtracking;
use mod_moodleoverflow\discussion\discussion;
+use moodle_exception;
defined('MOODLE_INTERNAL') || die();
@@ -680,7 +681,7 @@ private function build_db_object() {
return $dbobject;
}
- /*
+ /**
* Count all replies of a post.
*
* @param bool $onlyreviewed Whether to count only reviewed posts.
@@ -710,7 +711,7 @@ public function moodleoverflow_count_replies($onlyreviewed) {
*/
private function existence_check() {
if (empty($this->id) || $this->id == false || $this->id == null) {
- throw new \moodle_exception('noexistingpost', 'moodleoverflow');
+ throw new moodle_exception('noexistingpost', 'moodleoverflow');
}
return true;
}
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index 60f1558966..2f8aea7318 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -28,10 +28,14 @@
// Import namespace from the locallib, needs a check later which namespaces are really needed.
use mod_moodleoverflow\anonymous;
use mod_moodleoverflow\capabilities;
+use mod_moodleoverflow\event\discussion_created;
+use mod_moodleoverflow\event\post_created;
+use mod_moodleoverflow\event\post_updated;
use mod_moodleoverflow\review;
use mod_moodleoverflow\post\post;
use mod_moodleoverflow\discussion\discussion;
+use mod_moodleoverflow\subscriptions;
use moodle_exception;
defined('MOODLE_INTERNAL') || die();
@@ -284,7 +288,7 @@ private function build_prepost_reply($replypostid) {
$this->prepost->subject = $strre . ' ' . $this->prepost->subject;
}
} else {
- // TODO: remove this else branch when support for php version 7.4 ends.
+ // LEARNWEB-TODO: remove this else branch when support for php version 7.4 ends.
if (!(substr($this->prepost->subject, 0, strlen($strre)) == $strre)) {
$this->prepost->subject = $strre . ' ' . $this->prepost->subject;
}
@@ -371,6 +375,13 @@ private function build_prepost_delete($deletepostid) {
// Execute Functions.
+ /**
+ * Executes the creation of a new discussion.
+ *
+ * @param object $form The results from the post_form.
+ * @param string $errordestination The URL to redirect to in case of an error.
+ * @throws moodle_exception if the discussion could not be added.
+ */
private function execute_create($form, $errordestination) {
global $USER;
// Check if the user is allowed to post.
@@ -400,13 +411,13 @@ private function execute_create($form, $errordestination) {
// Trigger the discussion created event.
$params = ['context' => $this->info->modulecontext, 'objectid' => $discussion->get_id()];
- $event = \mod_moodleoverflow\event\discussion_created::create($params);
+ $event = discussion_created::create($params);
$event->trigger();
// Subscribe to this thread.
// Please be aware that in future the use of get_db_object() should be replaced with only $this->info->discussion,
// as the subscription class should be refactored with the new way of working with posts.
- \mod_moodleoverflow\subscriptions::moodleoverflow_post_subscription($form, $this->info->moodleoverflow,
+ subscriptions::moodleoverflow_post_subscription($form, $this->info->moodleoverflow,
$discussion->get_db_object(),
$this->info->modulecontext);
@@ -415,6 +426,13 @@ private function execute_create($form, $errordestination) {
redirect(moodleoverflow_go_back_to($redirectto->out()), $redirectmessage, null, \core\output\notification::NOTIFY_SUCCESS);
}
+ /**
+ * Executes the reply to an existing post.
+ *
+ * @param object $form The results from the post_form.
+ * @param string $errordestination The URL to redirect to in case of an error.
+ * @throws moodle_exception if the reply could not be added.
+ */
private function execute_reply($form, $errordestination) {
// Check if the user has the capability to write a reply.
$this->check_user_can_create_reply();
@@ -443,13 +461,13 @@ private function execute_reply($form, $errordestination) {
'moodleoverflowid' => $this->prepost->moodleoverflowid,
],
];
- $event = \mod_moodleoverflow\event\post_created::create($params);
+ $event = post_created::create($params);
$event->trigger();
// Subscribe to this thread.
// Please be aware that in future the use of build_db_object() should be replaced with only $this->info->discussion,
// as the subscription class should be refactored with the new way of working with posts.
- \mod_moodleoverflow\subscriptions::moodleoverflow_post_subscription($form, $this->info->moodleoverflow,
+ subscriptions::moodleoverflow_post_subscription($form, $this->info->moodleoverflow,
$this->info->discussion->get_db_object(),
$this->info->modulecontext);
@@ -460,6 +478,13 @@ private function execute_reply($form, $errordestination) {
}
+ /**
+ * Executes the edit of an existing post.
+ *
+ * @param object $form The results from the post_form.
+ * @param string $errordestination The URL to redirect to in case of an error.
+ * @throws moodle_exception if the post could not be updated.
+ */
private function execute_edit($form, $errordestination) {
global $USER, $DB;
// Check if the user has the capability to edit his post.
@@ -496,7 +521,7 @@ private function execute_edit($form, $errordestination) {
],
'relateduserid' => $this->prepost->userid == $USER->id ? $this->prepost->userid : null,
];
- $event = \mod_moodleoverflow\event\post_updated::create($params);
+ $event = post_updated::create($params);
$event->trigger();
// Define the location to redirect the user after successfully editing.
@@ -505,6 +530,11 @@ private function execute_edit($form, $errordestination) {
redirect(moodleoverflow_go_back_to($redirectto->out()), $redirectmessage, null, \core\output\notification::NOTIFY_SUCCESS);
}
+ /**
+ * Executes the deletion of a post.
+ *
+ * @throws moodle_exception if the post could not be deleted.
+ */
public function execute_delete() {
$this->check_interaction('delete');
diff --git a/classes/subscriptions.php b/classes/subscriptions.php
index f0bee2fdbe..14fe64ceb7 100644
--- a/classes/subscriptions.php
+++ b/classes/subscriptions.php
@@ -764,7 +764,7 @@ public static function unsubscribe_user($userid, $moodleoverflow, $context, $use
/**
* Subscribes the user to the specified discussion.
*
- * TODO: Refactor this function to the new way of working with discussion and posts.
+ * LEARNWEB-TODO: Refactor this function to the new way of working with discussion and posts.
* @param int $userid The user ID
* @param stdClass $discussion The discussion record
* @param context_module $context The module context
@@ -989,7 +989,7 @@ public static function moodleoverflow_get_subscribe_link($moodleoverflow, $conte
/**
* Given a new post, subscribes the user to the thread the post was posted in.
*
- * TODO: Refactor this function to the new way of working with discussion and posts.
+ * LEARNWEB-TODO: Refactor this function to the new way of working with discussion and posts.
* @param object $fromform The submitted form
* @param stdClass $moodleoverflow The moodleoverflow record
* @param stdClass $discussion The discussion record
diff --git a/externallib.php b/externallib.php
index 120f2b3d8d..98d8739e3b 100644
--- a/externallib.php
+++ b/externallib.php
@@ -40,7 +40,7 @@
*/
class mod_moodleoverflow_external extends external_api {
- // TODO: Adapt the functions to the new way of working with posts.
+ // LEARNWEB-TODO: Adapt the functions to the new way of working with posts.
/**
* Returns description of method parameters
* @return external_function_parameters
diff --git a/lang/en/moodleoverflow.php b/lang/en/moodleoverflow.php
index 11e12f6a27..169b594b81 100644
--- a/lang/en/moodleoverflow.php
+++ b/lang/en/moodleoverflow.php
@@ -227,146 +227,7 @@
$string['moodleoverflow:reviewpost'] = 'Review (approve or reject) posts';
$string['moodleoverflow:startdiscussion'] = 'Start a discussion';
$string['moodleoverflow:viewanyrating'] = 'View total ratings that anyone received';
-<<<<<<< HEAD
-
-// Strings for the view.php.
-$string['noviewdiscussionspermission'] = 'You do not have the permission to view discussions in this forum';
-$string['lastpost'] = 'Last post';
-
-// Strings for the locallib.php.
-$string['addanewdiscussion'] = 'Add a new discussion topic';
-$string['seeuserstats'] = 'View user statistics';
-$string['nodiscussions'] = 'There are no discussion topics yet in this forum.';
-$string['markallread_forum'] = 'Mark all posts as read';
-$string['markallread'] = 'Mark all posts in this discussion as read';
-$string['delete'] = 'Delete';
-$string['parent'] = 'Show parent';
-$string['markread'] = 'Mark read';
-$string['markunread'] = 'Mark unread';
-$string['permalink'] = 'Permalink';
-$string['postbyuser'] = '{$a->post} by {$a->user}';
-$string['bynameondate'] = 'by {$a->name} ({$a->rating}) - {$a->date}';
-$string['bynameondatenorating'] = 'by {$a->name} - {$a->date}';
-$string['deletesure'] = 'Are you sure you want to delete this post?';
-$string['deletesureplural'] = 'Are you sure you want to delete this post and all replies? ({$a} posts)';
-$string['amount_unread_posts_in_discussion'] = 'There are {$a} unread posts in this discussion.';
-
-// Strings for the settings.php.
-$string['configmanydiscussions'] = 'Maximum number of discussions shown in a Moodleoverflow instance per page';
-$string['manydiscussions'] = 'Discussions per page';
-$string['maxattachmentsize'] = 'Maximum attachment size';
-$string['maxattachmentsize_help'] = 'This setting specifies the largest size of file that can be attached to a forum post.';
-$string['configmaxbytes'] = 'Default maximum size for all forum attachments on the site (subject to course limits and other local settings)';
-$string['maxattachments'] = 'Maximum number of attachments';
-$string['maxattachments_help'] = 'This setting specifies the maximum number of files that can be attached to a forum post.';
-$string['configmaxattachments'] = 'Default maximum number of attachments allowed per post.';
-$string['maxeditingtime'] = 'Maximum amount of time during which a post can be edited by its owner (sec)';
-$string['configmaxeditingtime'] = 'Default maximum seconds are 3600 (= one hour). Regarding editing posts, please also consider the "Review possible after" setting for moderated forums.';
-$string['configoldpostdays'] = 'Number of days old any post is considered read.';
-$string['oldpostdays'] = 'Read after days';
-$string['trackingoff'] = 'Off';
-$string['trackingon'] = 'Forced';
-$string['trackingoptional'] = 'Optional';
-$string['trackingtype'] = 'Read tracking';
-$string['configtrackingtype'] = 'Default setting for read tracking.';
-$string['trackmoodleoverflow'] = 'Track unread posts';
-$string['configtrackmoodleoverflow'] = 'Set to \'yes\' if you want to track read/unread for each user.';
-$string['forcedreadtracking'] = 'Allow forced read tracking';
-$string['configforcedreadtracking'] = 'Allows Moodleoverflows to be set to forced read tracking. Will result in decreased performance for some users, particularly on courses with many moodleoverflows and posts. When off, any moodleoverflows previously set to Forced are treated as optional.';
-$string['cleanreadtime'] = 'Mark old posts as read hour';
-$string['configcleanreadtime'] = 'The hour of the day to clean old posts from the \'read\' table.';
-$string['allowdisablerating'] = 'Allow teachers to disable rating and reputation';
-$string['configallowdisablerating'] = 'Set to \'yes\' if you want to give teachers the ability to disable rating and reputation.';
-
-$string['votescalevote'] = 'Reputation: Vote.';
-$string['configvotescalevote'] = 'The amount of reputation voting gives.';
-$string['votescaledownvote'] = 'Reputation: Downvote';
-$string['configvotescaledownvote'] = 'The amount of reputation a downvote for your post gives.';
-$string['votescaleupvote'] = 'Reputation: Upvote';
-$string['configvotescaleupvote'] = 'The amount of reputation an upvote for your post gives.';
-$string['votescalesolved'] = 'Reputation: Solution';
-$string['configvotescalesolved'] = 'The amount of reputation a mark as solution on your post gives.';
-$string['votescalehelpful'] = 'Reputation: Helpful';
-$string['configvotescalehelpful'] = 'The amount of reputation a mark as helpful on your post gives.';
-$string['reputationnotnegative'] = 'Reputation just positive?';
-$string['configreputationnotnegative'] = 'Prohibits the users reputation being negative.';
-$string['allowcoursereputation'] = 'Sum reputation within a course.';
-$string['configallowcoursereputation'] = 'Allow to sum the reputation of all instances of the current course?';
-$string['maxmailingtime'] = 'Maximal mailing time';
-$string['configmaxmailingtime'] = 'Posts older than this number of hours will not be mailed to the users. This will help to avoid problems where the cron has not been running for a long time.';
-
-// Strings for the post.php environment.
-$string['invalidmoodleoverflowid'] = 'Forum ID was incorrect';
-$string['invalidparentpostid'] = 'Parent post ID was incorrect';
-$string['notpartofdiscussion'] = 'This post is not part of a discussion!';
-$string['noguestpost'] = 'Sorry, guests are not allowed to post.';
-$string['nopostmoodleoverflow'] = 'Sorry, you are not allowed to post to this forum.';
-$string['yourreply'] = 'Your reply';
-$string['re'] = 'Re:';
-$string['invalidpostid'] = 'Invalid post ID - {$a}';
-$string['cannotfindparentpost'] = 'Could not find top parent of post {$a}';
-$string['edit'] = 'Edit';
-$string['cannotreply'] = 'You cannot reply to this post';
-$string['cannotcreatediscussion'] = 'Could not create new discussion';
-$string['couldnotadd'] = 'Could not add your post due to an unknown error';
-$string['postaddedsuccess'] = 'Your post was successfully added.';
-$string['postaddedtimeleft'] = 'You have {$a} to edit it if you want to make any changes.';
-$string['cannotupdatepost'] = 'You can not update this post';
-$string['couldnotupdate'] = 'Could not update your post due to an unknown error';
-$string['editedpostupdated'] = '{$a}\'s post was updated';
-$string['postupdated'] = 'Your post was updated';
-$string['editedby'] = 'Edited by {$a->name} on {$a->date}';
-$string['cannotdeletepost'] = 'You can\'t delete this post!';
-$string['couldnotdeletereplies'] = 'Sorry, that cannot be deleted as people have already responded to it';
-$string['errorwhiledelete'] = 'An error occurred while deleting record.';
-$string['couldnotdeletereplies'] = 'Sorry, that cannot be deleted as people have already responded to it';
-$string['noexistingpost'] = 'Post does not exists, needs to be created first';
-$string['noexistingdiscussion'] = 'Discussion does not exists, needs to be created first';
-$string['notallpostsavailable'] = 'This Discussion does not have all of its posts, this could lead to errors!';
-$string['missingformattachments'] = 'This functions requires data that was not submitted.';
-$string['unexpectedinteractionerror'] = 'An unexpected error occured, please try again';
-
-// String for the classes/post/post_control.php.
-$string['wronginteraction'] = 'Wrong interaction detected, please choose the right function';
-
-// Strings for the classes/mod_form.php.
-$string['subject'] = 'Subject';
-$string['reply'] = 'Comment';
-$string['replyfirst'] = 'Answer';
-$string['message'] = 'Message';
-$string['discussionsubscription'] = 'Discussion subscription';
-$string['discussionsubscription_help'] = 'Subscribing to a discussion means you will receive notifications of new posts to that discussion.';
-$string['posttomoodleoverflow'] = 'Post to forum';
-$string['posts'] = 'Posts';
-$string['erroremptysubject'] = 'Post subject cannot be empty.';
-$string['erroremptymessage'] = 'Post message cannot be empty';
-$string['yournewtopic'] = 'Your new discussion topic';
-
-// Strings for the classes/ratings.php.
-$string['postnotexist'] = 'Requested post does not exist';
-$string['noratemoodleoverflow'] = 'Sorry, you are not allowed to vote in this forum.';
-$string['configallowratingchange'] = 'Can a user change its ratings?';
-$string['allowratingchange'] = 'Allow rating changes';
-$string['configpreferteachersmark'] = 'The answer marked as solution by a course owner are prioritized over the answer marked as helpful by the starter of the discussion.';
-$string['preferteachersmark'] = 'Prefer course owners\' marks?';
-$string['noratingchangeallowed'] = 'You are not allowed to change your ratings.';
-$string['invalidratingid'] = 'The submitted rating is neither an upvote nor a downvote.';
-$string['notstartuser'] = 'Only the user who started the discussion can mark an answer as helpful.';
-$string['notteacher'] = 'Only course owners can do this.';
-$string['ratingtoold'] = 'Ratings can only be changed within 30 minutes after the first vote. ';
-$string['postnotpartofdiscussion'] = 'Post does not exist in this discussion, please check the parameter';
-
-// Strings for the discussion.php.
-$string['invaliddiscussionid'] = 'Discussion ID was incorrect';
-$string['notexists'] = 'Discussion no longer exists';
-$string['discussionname'] = 'Discussion name';
-$string['discussionlocked'] = 'This discussion has been locked so you can no longer reply to it.';
-$string['hiddenmoodleoverflowpost'] = 'Hidden forum post';
-$string['moodleoverflowsubjecthidden'] = 'Subject (hidden)';
-
-=======
$string['moodleoverflow:viewdiscussion'] = 'View discussion';
->>>>>>> 0702bd3437f0d25ebe364a04cb0149f0ca79f0e2
$string['moodleoverflowauthorhidden'] = 'Author (hidden)';
$string['moodleoverflowbodyhidden'] = 'This post cannot be viewed by you, probably because you have not posted in the discussion, the maximum editing time hasn\'t passed yet, the discussion has not started or the discussion has expired.';
$string['moodleoverflowfieldset'] = 'Custom example fieldset';
@@ -410,9 +271,7 @@
$string['postaddedtimeleft'] = 'You have {$a} to edit it if you want to make any changes.';
$string['postbyuser'] = '{$a->post} by {$a->user}';
$string['postincontext'] = 'See this post in context';
-$string['postmailinfolink'] = 'This is a copy of a message posted in {$a->coursename}.
-
-To reply click on this link: {$a->replylink}';
+$string['postmailinfolink'] = 'This is a copy of a message posted in {$a->coursename}. To reply click on this link: {$a->replylink}';
$string['postmailsubject'] = '{$a->courseshortname}: {$a->subject}';
$string['postnotexist'] = 'Requested post does not exist';
$string['posts'] = 'Posts';
diff --git a/lib.php b/lib.php
index 4685931df7..d8c512e6be 100644
--- a/lib.php
+++ b/lib.php
@@ -29,7 +29,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-// TODO: Adapt functions to the new way of working with posts and discussions (Replace the post/discussion functions).
+// LEARNWEB-TODO: Adapt functions to the new way of working with posts and discussions (Replace the post/discussion functions).
use core\context\course;
defined('MOODLE_INTERNAL') || die();
diff --git a/locallib.php b/locallib.php
index bd9b7935b0..607e9eb943 100644
--- a/locallib.php
+++ b/locallib.php
@@ -49,7 +49,7 @@
function moodleoverflow_get_discussions($cm, $page = -1, $perpage = 0) {
global $DB, $CFG, $USER;
- // TODO Refactor variable naming. $discussion->id is first post and $discussion->discussion is discussion id?
+ // LEARNWEB-TODO Refactor variable naming. $discussion->id is first post and $discussion->discussion is discussion id?
// User must have the permission to view the discussions.
$modcontext = context_module::instance($cm->id);
@@ -531,7 +531,7 @@ function moodleoverflow_count_discussion_replies($cm) {
}
/**
- * TODO: Delete this function when adapting the print-functions to the new post and discussion structure.
+ * LEARNWEB-TODO: Delete this function when adapting the print-functions to the new post and discussion structure.
* Check if the user is capable of starting a new discussion.
*
* @param object $moodleoverflow
@@ -925,7 +925,7 @@ function moodleoverflow_user_can_post($modulecontext, $posttoreplyto, $considerr
/**
* Prints a moodleoverflow discussion.
- * TODO: REFACTOR WITH NEW POST AND DISCUSSION STRUCTURE.
+ * LEARNWEB-TODO: REFACTOR WITH NEW POST AND DISCUSSION STRUCTURE.
*
* @param stdClass $course The course object
* @param object $cm
@@ -1117,7 +1117,7 @@ function moodleoverflow_get_all_discussion_posts($discussionid, $tracking, $modc
/**
*
- * TODO: REFACTOR THIS FUNCTION FOR THE NEW POST STRUCTURE.
+ * LEARNWEB-TODO: REFACTOR THIS FUNCTION FOR THE NEW POST STRUCTURE.
* Prints a moodleoverflow post.
* @param object $post
* @param object $discussion
@@ -1642,7 +1642,7 @@ function moodleoverflow_print_posts_nested($course, &$cm, $moodleoverflow, $disc
}
/**
- * TODO: Delete this function after adapting the print_post function to the new post structure
+ * LEARNWEB-TODO: Delete this function after adapting the print_post function to the new post structure
* Returns attachments with information for the template
*
* @param object $post
diff --git a/post.php b/post.php
index f4b613b197..853710a645 100644
--- a/post.php
+++ b/post.php
@@ -74,7 +74,7 @@
}
// Require a general login to post something.
-// TODO: should course or id really be zero?.
+// LEARNWEB-TODO: should course or id really be zero?.
require_login(0, false);
// Now the post_control checks which interaction is wanted and builds a prepost.
diff --git a/tests/discussion_test.php b/tests/discussion_test.php
index 0a536ebfcb..e5ee1c6c31 100644
--- a/tests/discussion_test.php
+++ b/tests/discussion_test.php
@@ -35,7 +35,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \mod_moodleoverflow\discussion\discussion
*/
-class discussion_test extends \advanced_testcase {
+final class discussion_test extends \advanced_testcase {
/** @var \stdClass test course */
private $course;
@@ -62,6 +62,7 @@ class discussion_test extends \advanced_testcase {
private $generator;
public function setUp(): void {
+ parent::setUp();
$this->resetAfterTest();
$this->helper_course_set_up();
}
@@ -70,6 +71,7 @@ public function tearDown(): void {
// Clear all caches.
subscriptions::reset_moodleoverflow_cache();
subscriptions::reset_discussion_cache();
+ parent::tearDown();
}
/**
diff --git a/tests/post_test.php b/tests/post_test.php
index 501e0460ed..fa7e39b078 100644
--- a/tests/post_test.php
+++ b/tests/post_test.php
@@ -184,6 +184,8 @@ private function helper_course_set_up() {
}
/**
+ * Helper function to add a new attachment to a post.
+ *
* @param object $object // The object that will have the attachment
* @param $modulecontext
* @param string $filename
From e072457eda28025b54ca686ea1f4f155c1bb6706 Mon Sep 17 00:00:00 2001
From: Tamaro Walter
Date: Mon, 7 Jul 2025 19:44:43 +0200
Subject: [PATCH 43/56] fix merge problems
---
classes/post/post_control.php | 10 ++++++----
locallib.php | 1 +
post.php | 4 ++--
tests/post_test.php | 23 ++++++++++++-----------
version.php | 2 +-
5 files changed, 22 insertions(+), 18 deletions(-)
diff --git a/classes/post/post_control.php b/classes/post/post_control.php
index 2f8aea7318..2e692c3060 100644
--- a/classes/post/post_control.php
+++ b/classes/post/post_control.php
@@ -37,6 +37,7 @@
use mod_moodleoverflow\discussion\discussion;
use mod_moodleoverflow\subscriptions;
use moodle_exception;
+use stdClass;
defined('MOODLE_INTERNAL') || die();
global $CFG;
@@ -89,12 +90,13 @@ class post_control {
* Constructor
*/
public function __construct() {
- $this->info = new \stdClass();
+ $this->info = new stdClass();
}
/**
* Detects the interaction and builds the prepost.
- * @param object $urlparamter parameter from the post.php
+ * @param stdClass $urlparameter parameter from the post.php
+ * @throws \coding_exception
* @throws moodle_exception if the interaction is not correct.
*/
public function detect_interaction($urlparameter) {
@@ -620,7 +622,7 @@ public function build_postform($pageparams) {
// If the user is not the original author append an extra message to the message. (Happens when interaction = 'edit').
if ($USER->id != $this->prepost->userid) {
// Create a temporary object.
- $data = new \stdClass();
+ $data = new stdClass();
$data->date = userdate(time());
$this->prepost->messageformat = editors_get_preferred_format();
if ($this->prepost->messageformat == FORMAT_HTML) {
@@ -721,7 +723,7 @@ private function collect_information($postid = false, $moodleoverflowid = false)
* Some prepost parameters will be assigned individually by the build_prepost functions.
*/
private function assemble_prepost() {
- $this->prepost = new \stdClass();
+ $this->prepost = new stdClass();
$this->prepost->courseid = $this->info->course->id;
$this->prepost->moodleoverflowid = $this->info->moodleoverflow->id;
$this->prepost->modulecontext = $this->info->modulecontext;
diff --git a/locallib.php b/locallib.php
index 607e9eb943..44b3a381d5 100644
--- a/locallib.php
+++ b/locallib.php
@@ -1135,6 +1135,7 @@ function moodleoverflow_get_all_discussion_posts($discussionid, $tracking, $modc
* @param array $usermapping
* @param int $level
* @param bool $multiplemarks setting of multiplemarks
+ * @param stdClass|null $limitedanswersetting
* @return void|null
* @throws coding_exception
* @throws dml_exception
diff --git a/post.php b/post.php
index 853710a645..43caa1e6db 100644
--- a/post.php
+++ b/post.php
@@ -53,7 +53,7 @@
$postcontrol = new post_control();
// Put all interaction parameters in one object for the post_control.
-$urlparameter = new \stdClass();
+$urlparameter = new stdClass();
$urlparameter->create = $moodleoverflow;
$urlparameter->reply = $reply;
$urlparameter->edit = $edit;
@@ -137,7 +137,7 @@
// The post_form will be displayed.
// Define the message to be displayed above the form.
-$toppost = new \stdClass();
+$toppost = new stdClass();
$toppost->subject = get_string('addanewdiscussion', 'moodleoverflow');
// Initiate the page.
diff --git a/tests/post_test.php b/tests/post_test.php
index fa7e39b078..8b16739bbd 100644
--- a/tests/post_test.php
+++ b/tests/post_test.php
@@ -24,8 +24,10 @@
namespace mod_moodleoverflow;
// Use the post class.
+use context;
use mod_moodleoverflow\post\post;
use mod_moodleoverflow\discussion\discussion;
+use stdClass;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__ . '/../locallib.php');
@@ -41,19 +43,19 @@
*/
final class post_test extends \advanced_testcase {
- /** @var \stdClass test course */
+ /** @var stdClass test course */
private $course;
- /** @var \stdClass coursemodule */
+ /** @var stdClass coursemodule */
private $coursemodule;
- /** @var \stdClass modulecontext */
+ /** @var stdClass modulecontext */
private $modulecontext;
- /** @var \stdClass test moodleoverflow */
+ /** @var stdClass test moodleoverflow */
private $moodleoverflow;
- /** @var \stdClass test teacher */
+ /** @var stdClass test teacher */
private $teacher;
/** @var discussion a discussion */
@@ -184,13 +186,12 @@ private function helper_course_set_up() {
}
/**
- * Helper function to add a new attachment to a post.
+ * Adds a new attachment to a post.
*
- * @param object $object // The object that will have the attachment
- * @param $modulecontext
- * @param string $filename
- * @param $filecontent
- * @return void
+ * @param stdClass $object The post object to which the attachment should be added.
+ * @param context $modulecontext The context of the module.
+ * @param string $filename The name of the file to be added.
+ * @param string $filecontent The content of the file to be added.
*/
private function add_new_attachment($object, $modulecontext, $filename, $filecontent) {
global $DB;
diff --git a/version.php b/version.php
index e290cb3873..6f099b71c6 100644
--- a/version.php
+++ b/version.php
@@ -26,7 +26,7 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2024070700;
+$plugin->version = 2025070700;
$plugin->requires = 2022112819; // Require Moodle 4.1.
$plugin->supported = [401, 500];
$plugin->component = 'mod_moodleoverflow';
From d19fe7f5fc19e15b2b369c132be4c0cdd4b2ab55 Mon Sep 17 00:00:00 2001
From: Tamaro Walter
Date: Mon, 7 Jul 2025 19:55:19 +0200
Subject: [PATCH 44/56] delete build files
---
amd/build/activityhelp.min.js | 11 -----------
amd/build/activityhelp.min.js.map | 1 -
amd/build/rating.min.js | 10 ----------
amd/build/rating.min.js.map | 1 -
amd/build/reviewing.min.js | 10 ----------
amd/build/reviewing.min.js.map | 1 -
amd/build/warnmodechange.min.js | 10 ----------
amd/build/warnmodechange.min.js.map | 1 -
8 files changed, 45 deletions(-)
delete mode 100644 amd/build/activityhelp.min.js
delete mode 100644 amd/build/activityhelp.min.js.map
delete mode 100644 amd/build/rating.min.js
delete mode 100644 amd/build/rating.min.js.map
delete mode 100644 amd/build/reviewing.min.js
delete mode 100644 amd/build/reviewing.min.js.map
delete mode 100644 amd/build/warnmodechange.min.js
delete mode 100644 amd/build/warnmodechange.min.js.map
diff --git a/amd/build/activityhelp.min.js b/amd/build/activityhelp.min.js
deleted file mode 100644
index a875b70b82..0000000000
--- a/amd/build/activityhelp.min.js
+++ /dev/null
@@ -1,11 +0,0 @@
-define("mod_moodleoverflow/activityhelp",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;
-/**
- * Show a help string for the amount of activity column in userstats_table.php
- *
- * @module mod_moodleoverflow/activityhelp
- * @copyright 2023 Tamaro Walter
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-const Selectors_actions={showHelpIcon:'[data-action="showhelpicon"]'};_exports.init=()=>{document.addEventListener("click",(event=>{event.target.closest(Selectors_actions.showHelpIcon)&&event.preventDefault()}))}}));
-
-//# sourceMappingURL=activityhelp.min.js.map
\ No newline at end of file
diff --git a/amd/build/activityhelp.min.js.map b/amd/build/activityhelp.min.js.map
deleted file mode 100644
index 2cdca4d1e4..0000000000
--- a/amd/build/activityhelp.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;MAyBMA,kBACO,CACLC,aAAc,8CAOF,KAChBC,SAASC,iBAAiB,SAASC,QAC3BA,MAAMC,OAAOC,QAAQN,kBAAkBC,eACvCG,MAAMG"}
\ No newline at end of file
diff --git a/amd/build/rating.min.js b/amd/build/rating.min.js
deleted file mode 100644
index b70923c901..0000000000
--- a/amd/build/rating.min.js
+++ /dev/null
@@ -1,10 +0,0 @@
-define("mod_moodleoverflow/rating",["exports","core/ajax","core/prefetch","core/str"],(function(_exports,_ajax,_prefetch,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
-/**
- * Implements rating functionality
- *
- * @module mod_moodleoverflow/rating
- * @copyright 2022 Justus Dieckmann WWU
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(userid,allowmultiplemarks){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","marknotsolved","markhelpful","marknothelpful","action_remove_upvote","action_upvote","action_remove_downvote","action_downvote"]),root.onclick=async event=>{const actionElement=event.target.closest("[data-moodleoverflow-action]");if(!actionElement)return;const action=actionElement.getAttribute("data-moodleoverflow-action"),postElement=actionElement.closest("[data-moodleoverflow-postid]"),postid=null==postElement?void 0:postElement.getAttribute("data-moodleoverflow-postid");switch(action){case"upvote":case"downvote":{const isupvote="upvote"===action;if("clicked"===actionElement.getAttribute("data-moodleoverflow-state"))await sendVote(postid,isupvote?20:10,userid),actionElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_"+action,"mod_moodleoverflow");else{const otherAction=isupvote?"downvote":"upvote";await sendVote(postid,isupvote?2:1,userid),actionElement.setAttribute("data-moodleoverflow-state","clicked");const otherElement=postElement.querySelector(`[data-moodleoverflow-action="${otherAction}"]`);otherElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_remove_"+action,"mod_moodleoverflow"),otherElement.title=await(0,_str.get_string)("action_"+otherAction,"mod_moodleoverflow")}}break;case"helpful":case"solved":{const isHelpful="helpful"===action,htmlclass=isHelpful?"markedhelpful":"markedsolution",shouldRemove=postElement.classList.contains(htmlclass),baseRating=isHelpful?4:3,rating=shouldRemove?10*baseRating:baseRating;if(await sendVote(postid,rating,userid),allowmultiplemarks)shouldRemove&&(postElement.classList.remove(htmlclass),actionElement.textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"),changeStrings(htmlclass,action));else for(const el of root.querySelectorAll(".moodleoverflowpost."+htmlclass))el.classList.remove(htmlclass),el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow");shouldRemove||(postElement.classList.add(htmlclass),actionElement.textContent=await(0,_str.get_string)(`marknot${action}`,"mod_moodleoverflow"),allowmultiplemarks&&changeStrings(htmlclass,action))}}}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch);const root=document.getElementById("moodleoverflow-root");async function sendVote(postid,rating,userid){const response=await _ajax.default.call([{methodname:"mod_moodleoverflow_record_vote",args:{postid:postid,ratingid:rating}}])[0];return root.querySelectorAll(`[data-moodleoverflow-userreputation="${userid}"]`).forEach((i=>{i.textContent=response.raterreputation})),root.querySelectorAll(`[data-moodleoverflow-userreputation="${response.ownerid}"]`).forEach((i=>{i.textContent=response.ownerreputation})),root.querySelectorAll(`[data-moodleoverflow-postreputation="${postid}"]`).forEach((i=>{i.textContent=response.postrating})),response}async function changeStrings(htmlclass,action){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","alsomarksolved","markhelpful","alsomarkhelpful"]);var othermarkedposts=!1;for(const el of root.querySelectorAll(".moodleoverflowpost"))if(el.classList.contains(htmlclass)){othermarkedposts=!0;break}for(const el of root.querySelectorAll(".moodleoverflowpost"))!el.classList.contains(htmlclass)&&el.querySelector(`[data-moodleoverflow-action="${action}"]`)&&(el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=othermarkedposts?await(0,_str.get_string)(`alsomark${action}`,"mod_moodleoverflow"):await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"))}}));
-
-//# sourceMappingURL=rating.min.js.map
\ No newline at end of file
diff --git a/amd/build/rating.min.js.map b/amd/build/rating.min.js.map
deleted file mode 100644
index 0c1d368bbd..0000000000
--- a/amd/build/rating.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"rating.min.js","sources":["../src/rating.js"],"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 * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if multiplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["userid","allowmultiplemarks","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","setAttribute","title","otherAction","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","rating","remove","textContent","changeStrings","el","querySelectorAll","add","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":";;;;;;;oFAsEqBA,OAAQC,sCAChBC,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,MAAAA,cACLC,cAAgBC,MAAMC,OAAOC,QAAQ,oCACtCH,2BAICI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,MAAAA,mBAAAA,YAAaD,aAAa,qCAEjCD,YACC,aACA,kBACKI,SAAsB,WAAXJ,UAC+C,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SA7Dd,GADE,GA8DsEd,QACjFM,cAAcU,aAAa,4BAA6B,cACxDV,cAAcW,YAAc,mBAAU,UAAYP,OAAQ,0BACvD,OACGQ,YAAcJ,SAAW,WAAa,eACtCC,SAASF,OAAQC,SApErB,EADE,EAqE+Dd,QACnEM,cAAcU,aAAa,4BAA6B,iBAClDG,aAAeP,YAAYQ,cAC5B,gCAA+BF,iBACpCC,aAAaH,aAAa,4BAA6B,cACvDV,cAAcW,YAAc,mBAAU,iBAAmBP,OAAQ,sBACjES,aAAaF,YAAc,mBAAU,UAAYC,YAAa,iCAIjE,cACA,gBACKG,UAAuB,YAAXX,OACZY,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAeX,YAAYY,UAAUC,SAASH,WAC9CI,WAAaL,UA/EZ,EADD,EAiFAM,OAASJ,aAA4B,GAAbG,WAAkBA,oBAC1CX,SAASF,OAAQc,OAAQ3B,QAO1BC,mBASGsB,eACAX,YAAYY,UAAUI,OAAON,WAC7BhB,cAAcuB,kBAAoB,mBAAW,OAAMnB,SAAU,sBAC7DoB,cAAcR,UAAWZ,kBAVxB,MAAMqB,MAAM5B,KAAK6B,iBAAiB,uBAAyBV,WAC5DS,GAAGP,UAAUI,OAAON,WACpBS,GAAGX,cAAe,gCAA+BV,YAAYmB,kBACnD,mBAAW,OAAMnB,SAAU,sBAWxCa,eACDX,YAAYY,UAAUS,IAAIX,WAC1BhB,cAAcuB,kBAAoB,mBAAW,UAASnB,SAAU,sBAC5DT,oBACA6B,cAAcR,UAAWZ,mGA1G3CP,KAAO+B,SAASC,eAAe,sCAStBpB,SAASF,OAAQc,OAAQ3B,cAC9BoC,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACF3B,OAAQA,OACR4B,SAAUd,WAEd,UACJxB,KAAK6B,iBAAkB,wCAAuChC,YAAY0C,SAASC,IAC/EA,EAAEd,YAAcO,SAASQ,mBAE7BzC,KAAK6B,iBAAkB,wCAAuCI,SAASS,aAAaH,SAASC,IACzFA,EAAEd,YAAcO,SAASU,mBAE7B3C,KAAK6B,iBAAkB,wCAAuCnB,YAAY6B,SAASC,IAC/EA,EAAEd,YAAcO,SAASW,cAEtBX,wBAgGIN,cAAcR,UAAWZ,0BAC3BR,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,wBAGhD8C,kBAAmB,MAClB,MAAMjB,MAAM5B,KAAK6B,iBAAiB,0BAC/BD,GAAGP,UAAUC,SAASH,WAAY,CAClC0B,kBAAmB,YAKtB,MAAMjB,MAAM5B,KAAK6B,iBAAiB,wBAC9BD,GAAGP,UAAUC,SAASH,YAAcS,GAAGX,cAAe,gCAA+BV,cAElFqB,GAAGX,cAAe,gCAA+BV,YAAYmB,YAD7DmB,uBAEU,mBAAW,WAAUtC,SAAU,4BAG/B,mBAAW,OAAMA,SAAU"}
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js b/amd/build/reviewing.min.js
deleted file mode 100644
index 59b05be5da..0000000000
--- a/amd/build/reviewing.min.js
+++ /dev/null
@@ -1,10 +0,0 @@
-define("mod_moodleoverflow/reviewing",["exports","core/ajax","core/prefetch","core/templates","core/str"],(function(_exports,_ajax,_prefetch,_templates,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
-/**
- * Implements reviewing functionality
- *
- * @module mod_moodleoverflow/reviewing
- * @copyright 2022 Justus Dieckmann WWU
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){_prefetch.default.prefetchTemplates(["mod_moodleoverflow/reject_post_form","mod_moodleoverflow/review_buttons"]),_prefetch.default.prefetchStrings("mod_moodleoverflow",["post_was_approved","jump_to_next_post_needing_review","there_are_no_posts_needing_review","post_was_rejected"]);document.getElementById("moodleoverflow-posts").onclick=async e=>{const action=e.target.getAttribute("data-moodleoverflow-action");if(!action)return;const post=e.target.closest("*[data-moodleoverflow-postid]"),reviewRow=e.target.closest(".reviewrow"),postID=post.getAttribute("data-moodleoverflow-postid");if("approve"===action){reviewRow.innerHTML=".";const nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_approve_post",args:{postid:postID}}])[0];let message=await(0,_str.get_string)("post_was_approved","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message,post.classList.remove("pendingreview")}else if("reject"===action)reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/reject_post_form",{});else if("reject-submit"===action){const rejectMessage=post.querySelector("textarea.reject-reason").value.toString().trim();reviewRow.innerHTML=".";const args={postid:postID,reason:rejectMessage||null},nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_reject_post",args:args}])[0];let message=await(0,_str.get_string)("post_was_rejected","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message}else"reject-cancel"===action&&(reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/review_buttons",{}))}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch),_templates=_interopRequireDefault(_templates)}));
-
-//# sourceMappingURL=reviewing.min.js.map
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js.map b/amd/build/reviewing.min.js.map
deleted file mode 100644
index b14cb0911d..0000000000
--- a/amd/build/reviewing.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.js"],"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 * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","e","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason"],"mappings":";;;;;;;wGA+BaA,kBAAkB,CAAC,sCAAuC,wDAC1DC,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,QAAUC,MAAAA,UACLC,OAASC,EAAEC,OAAOC,aAAa,kCAEhCH,oBAICI,KAAOH,EAAEC,OAAOG,QAAQ,iCACxBC,UAAYL,EAAEC,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,iCAElB,YAAXH,OAAsB,CACtBM,UAAUE,UAAY,UAChBC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,OAEAQ,cAAgB,mBAAU,oBAAqB,sBAAwB,IAEvEA,SADAN,YACY,YAAWA,sBACX,mBAAU,mCAAoC,sBACpD,aAEW,mBAAU,oCAAqC,sBAEpEH,UAAUE,UAAYO,QACtBX,KAAKY,UAAUC,OAAO,sBACnB,GAAe,WAAXjB,OACPM,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBU,mBAAUC,OAAO,sCAAuC,SACjF,GAAe,kBAAXnB,OAA4B,OAC7BoB,cAAgBhB,KAAKiB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFlB,UAAUE,UAAY,UAChBK,KAAO,CACTC,OAAQP,OACRkB,OAAQL,eAAgC,MAEtCX,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,OAEAE,cAAgB,mBAAU,oBAAqB,sBAAwB,IAEvEA,SADAN,YACY,YAAWA,sBACX,mBAAU,mCAAoC,sBACpD,aAEW,mBAAU,oCAAqC,sBAEpEH,UAAUE,UAAYO,YACJ,kBAAXf,SACPM,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBU,mBAAUC,OAAO,oCAAqC"}
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js b/amd/build/warnmodechange.min.js
deleted file mode 100644
index 5042ba704b..0000000000
--- a/amd/build/warnmodechange.min.js
+++ /dev/null
@@ -1,10 +0,0 @@
-define("mod_moodleoverflow/warnmodechange",["exports","core/str","core/notification","core/prefetch"],(function(_exports,_str,_notification,_prefetch){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
-/**
- * Warns on changing the subscription mode.
- *
- * @module mod_moodleoverflow/warnmodechange
- * @copyright 2022 Justus Dieckmann WWU
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(previousSetting){_prefetch.default.prefetchStrings("mod_moodleoverflow",["switchtooptional","switchtoauto"]),_prefetch.default.prefetchStrings("moodle",["confirm","cancel"]);const form=document.querySelector("form.mform"),select=document.getElementById("id_forcesubscribe");form.onsubmit=async e=>{const value=select.selectedOptions[0].value;value!=previousSetting&&1!=value&&3!=value&&(e.preventDefault(),await _notification.default.confirm(await(0,_str.get_string)("confirm"),await(0,_str.get_string)(0==value?"switchtooptional":"switchtoauto","mod_moodleoverflow"),await(0,_str.get_string)("confirm"),await(0,_str.get_string)("cancel"),(()=>{form.onsubmit=void 0,form.requestSubmit(e.submitter)}),void 0))}},_notification=_interopRequireDefault(_notification),_prefetch=_interopRequireDefault(_prefetch)}));
-
-//# sourceMappingURL=warnmodechange.min.js.map
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js.map b/amd/build/warnmodechange.min.js.map
deleted file mode 100644
index 70683e5540..0000000000
--- a/amd/build/warnmodechange.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.js"],"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 * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["previousSetting","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","e","preventDefault","Notification","confirm","undefined","requestSubmit","submitter"],"mappings":";;;;;;;oFA8BqBA,mCACRC,gBAAgB,qBAAsB,CAAC,mBAAoB,mCAC3DA,gBAAgB,SAAU,CAAC,UAAW,iBACzCC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,MAAAA,UACNC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAAST,iBAA4B,GAATS,OAAuB,GAATA,QAG9CE,EAAEC,uBACIC,sBAAaC,cACT,mBAAU,iBACV,mBAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,mBAAU,iBACV,mBAAU,WAChB,KAEIP,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcL,EAAEM,kBACtBF"}
\ No newline at end of file
From f746d8b85983ecd2dcd08803a1c042cbaa499da1 Mon Sep 17 00:00:00 2001
From: Tamaro Walter
Date: Mon, 7 Jul 2025 19:55:38 +0200
Subject: [PATCH 45/56] build new js files
---
amd/build/activityhelp.min.js | 11 +++++++++++
amd/build/activityhelp.min.js.map | 1 +
amd/build/rating.min.js | 10 ++++++++++
amd/build/rating.min.js.map | 1 +
amd/build/reviewing.min.js | 10 ++++++++++
amd/build/reviewing.min.js.map | 1 +
amd/build/warnmodechange.min.js | 10 ++++++++++
amd/build/warnmodechange.min.js.map | 1 +
8 files changed, 45 insertions(+)
create mode 100644 amd/build/activityhelp.min.js
create mode 100644 amd/build/activityhelp.min.js.map
create mode 100644 amd/build/rating.min.js
create mode 100644 amd/build/rating.min.js.map
create mode 100644 amd/build/reviewing.min.js
create mode 100644 amd/build/reviewing.min.js.map
create mode 100644 amd/build/warnmodechange.min.js
create mode 100644 amd/build/warnmodechange.min.js.map
diff --git a/amd/build/activityhelp.min.js b/amd/build/activityhelp.min.js
new file mode 100644
index 0000000000..a875b70b82
--- /dev/null
+++ b/amd/build/activityhelp.min.js
@@ -0,0 +1,11 @@
+define("mod_moodleoverflow/activityhelp",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;
+/**
+ * Show a help string for the amount of activity column in userstats_table.php
+ *
+ * @module mod_moodleoverflow/activityhelp
+ * @copyright 2023 Tamaro Walter
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+const Selectors_actions={showHelpIcon:'[data-action="showhelpicon"]'};_exports.init=()=>{document.addEventListener("click",(event=>{event.target.closest(Selectors_actions.showHelpIcon)&&event.preventDefault()}))}}));
+
+//# sourceMappingURL=activityhelp.min.js.map
\ No newline at end of file
diff --git a/amd/build/activityhelp.min.js.map b/amd/build/activityhelp.min.js.map
new file mode 100644
index 0000000000..2cdca4d1e4
--- /dev/null
+++ b/amd/build/activityhelp.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;MAyBMA,kBACO,CACLC,aAAc,8CAOF,KAChBC,SAASC,iBAAiB,SAASC,QAC3BA,MAAMC,OAAOC,QAAQN,kBAAkBC,eACvCG,MAAMG"}
\ No newline at end of file
diff --git a/amd/build/rating.min.js b/amd/build/rating.min.js
new file mode 100644
index 0000000000..b70923c901
--- /dev/null
+++ b/amd/build/rating.min.js
@@ -0,0 +1,10 @@
+define("mod_moodleoverflow/rating",["exports","core/ajax","core/prefetch","core/str"],(function(_exports,_ajax,_prefetch,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
+/**
+ * Implements rating functionality
+ *
+ * @module mod_moodleoverflow/rating
+ * @copyright 2022 Justus Dieckmann WWU
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(userid,allowmultiplemarks){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","marknotsolved","markhelpful","marknothelpful","action_remove_upvote","action_upvote","action_remove_downvote","action_downvote"]),root.onclick=async event=>{const actionElement=event.target.closest("[data-moodleoverflow-action]");if(!actionElement)return;const action=actionElement.getAttribute("data-moodleoverflow-action"),postElement=actionElement.closest("[data-moodleoverflow-postid]"),postid=null==postElement?void 0:postElement.getAttribute("data-moodleoverflow-postid");switch(action){case"upvote":case"downvote":{const isupvote="upvote"===action;if("clicked"===actionElement.getAttribute("data-moodleoverflow-state"))await sendVote(postid,isupvote?20:10,userid),actionElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_"+action,"mod_moodleoverflow");else{const otherAction=isupvote?"downvote":"upvote";await sendVote(postid,isupvote?2:1,userid),actionElement.setAttribute("data-moodleoverflow-state","clicked");const otherElement=postElement.querySelector(`[data-moodleoverflow-action="${otherAction}"]`);otherElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_remove_"+action,"mod_moodleoverflow"),otherElement.title=await(0,_str.get_string)("action_"+otherAction,"mod_moodleoverflow")}}break;case"helpful":case"solved":{const isHelpful="helpful"===action,htmlclass=isHelpful?"markedhelpful":"markedsolution",shouldRemove=postElement.classList.contains(htmlclass),baseRating=isHelpful?4:3,rating=shouldRemove?10*baseRating:baseRating;if(await sendVote(postid,rating,userid),allowmultiplemarks)shouldRemove&&(postElement.classList.remove(htmlclass),actionElement.textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"),changeStrings(htmlclass,action));else for(const el of root.querySelectorAll(".moodleoverflowpost."+htmlclass))el.classList.remove(htmlclass),el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow");shouldRemove||(postElement.classList.add(htmlclass),actionElement.textContent=await(0,_str.get_string)(`marknot${action}`,"mod_moodleoverflow"),allowmultiplemarks&&changeStrings(htmlclass,action))}}}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch);const root=document.getElementById("moodleoverflow-root");async function sendVote(postid,rating,userid){const response=await _ajax.default.call([{methodname:"mod_moodleoverflow_record_vote",args:{postid:postid,ratingid:rating}}])[0];return root.querySelectorAll(`[data-moodleoverflow-userreputation="${userid}"]`).forEach((i=>{i.textContent=response.raterreputation})),root.querySelectorAll(`[data-moodleoverflow-userreputation="${response.ownerid}"]`).forEach((i=>{i.textContent=response.ownerreputation})),root.querySelectorAll(`[data-moodleoverflow-postreputation="${postid}"]`).forEach((i=>{i.textContent=response.postrating})),response}async function changeStrings(htmlclass,action){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","alsomarksolved","markhelpful","alsomarkhelpful"]);var othermarkedposts=!1;for(const el of root.querySelectorAll(".moodleoverflowpost"))if(el.classList.contains(htmlclass)){othermarkedposts=!0;break}for(const el of root.querySelectorAll(".moodleoverflowpost"))!el.classList.contains(htmlclass)&&el.querySelector(`[data-moodleoverflow-action="${action}"]`)&&(el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=othermarkedposts?await(0,_str.get_string)(`alsomark${action}`,"mod_moodleoverflow"):await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"))}}));
+
+//# sourceMappingURL=rating.min.js.map
\ No newline at end of file
diff --git a/amd/build/rating.min.js.map b/amd/build/rating.min.js.map
new file mode 100644
index 0000000000..0c1d368bbd
--- /dev/null
+++ b/amd/build/rating.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"rating.min.js","sources":["../src/rating.js"],"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 * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if multiplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["userid","allowmultiplemarks","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","setAttribute","title","otherAction","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","rating","remove","textContent","changeStrings","el","querySelectorAll","add","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":";;;;;;;oFAsEqBA,OAAQC,sCAChBC,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,MAAAA,cACLC,cAAgBC,MAAMC,OAAOC,QAAQ,oCACtCH,2BAICI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,MAAAA,mBAAAA,YAAaD,aAAa,qCAEjCD,YACC,aACA,kBACKI,SAAsB,WAAXJ,UAC+C,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SA7Dd,GADE,GA8DsEd,QACjFM,cAAcU,aAAa,4BAA6B,cACxDV,cAAcW,YAAc,mBAAU,UAAYP,OAAQ,0BACvD,OACGQ,YAAcJ,SAAW,WAAa,eACtCC,SAASF,OAAQC,SApErB,EADE,EAqE+Dd,QACnEM,cAAcU,aAAa,4BAA6B,iBAClDG,aAAeP,YAAYQ,cAC5B,gCAA+BF,iBACpCC,aAAaH,aAAa,4BAA6B,cACvDV,cAAcW,YAAc,mBAAU,iBAAmBP,OAAQ,sBACjES,aAAaF,YAAc,mBAAU,UAAYC,YAAa,iCAIjE,cACA,gBACKG,UAAuB,YAAXX,OACZY,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAeX,YAAYY,UAAUC,SAASH,WAC9CI,WAAaL,UA/EZ,EADD,EAiFAM,OAASJ,aAA4B,GAAbG,WAAkBA,oBAC1CX,SAASF,OAAQc,OAAQ3B,QAO1BC,mBASGsB,eACAX,YAAYY,UAAUI,OAAON,WAC7BhB,cAAcuB,kBAAoB,mBAAW,OAAMnB,SAAU,sBAC7DoB,cAAcR,UAAWZ,kBAVxB,MAAMqB,MAAM5B,KAAK6B,iBAAiB,uBAAyBV,WAC5DS,GAAGP,UAAUI,OAAON,WACpBS,GAAGX,cAAe,gCAA+BV,YAAYmB,kBACnD,mBAAW,OAAMnB,SAAU,sBAWxCa,eACDX,YAAYY,UAAUS,IAAIX,WAC1BhB,cAAcuB,kBAAoB,mBAAW,UAASnB,SAAU,sBAC5DT,oBACA6B,cAAcR,UAAWZ,mGA1G3CP,KAAO+B,SAASC,eAAe,sCAStBpB,SAASF,OAAQc,OAAQ3B,cAC9BoC,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACF3B,OAAQA,OACR4B,SAAUd,WAEd,UACJxB,KAAK6B,iBAAkB,wCAAuChC,YAAY0C,SAASC,IAC/EA,EAAEd,YAAcO,SAASQ,mBAE7BzC,KAAK6B,iBAAkB,wCAAuCI,SAASS,aAAaH,SAASC,IACzFA,EAAEd,YAAcO,SAASU,mBAE7B3C,KAAK6B,iBAAkB,wCAAuCnB,YAAY6B,SAASC,IAC/EA,EAAEd,YAAcO,SAASW,cAEtBX,wBAgGIN,cAAcR,UAAWZ,0BAC3BR,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,wBAGhD8C,kBAAmB,MAClB,MAAMjB,MAAM5B,KAAK6B,iBAAiB,0BAC/BD,GAAGP,UAAUC,SAASH,WAAY,CAClC0B,kBAAmB,YAKtB,MAAMjB,MAAM5B,KAAK6B,iBAAiB,wBAC9BD,GAAGP,UAAUC,SAASH,YAAcS,GAAGX,cAAe,gCAA+BV,cAElFqB,GAAGX,cAAe,gCAA+BV,YAAYmB,YAD7DmB,uBAEU,mBAAW,WAAUtC,SAAU,4BAG/B,mBAAW,OAAMA,SAAU"}
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js b/amd/build/reviewing.min.js
new file mode 100644
index 0000000000..59b05be5da
--- /dev/null
+++ b/amd/build/reviewing.min.js
@@ -0,0 +1,10 @@
+define("mod_moodleoverflow/reviewing",["exports","core/ajax","core/prefetch","core/templates","core/str"],(function(_exports,_ajax,_prefetch,_templates,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
+/**
+ * Implements reviewing functionality
+ *
+ * @module mod_moodleoverflow/reviewing
+ * @copyright 2022 Justus Dieckmann WWU
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){_prefetch.default.prefetchTemplates(["mod_moodleoverflow/reject_post_form","mod_moodleoverflow/review_buttons"]),_prefetch.default.prefetchStrings("mod_moodleoverflow",["post_was_approved","jump_to_next_post_needing_review","there_are_no_posts_needing_review","post_was_rejected"]);document.getElementById("moodleoverflow-posts").onclick=async e=>{const action=e.target.getAttribute("data-moodleoverflow-action");if(!action)return;const post=e.target.closest("*[data-moodleoverflow-postid]"),reviewRow=e.target.closest(".reviewrow"),postID=post.getAttribute("data-moodleoverflow-postid");if("approve"===action){reviewRow.innerHTML=".";const nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_approve_post",args:{postid:postID}}])[0];let message=await(0,_str.get_string)("post_was_approved","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message,post.classList.remove("pendingreview")}else if("reject"===action)reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/reject_post_form",{});else if("reject-submit"===action){const rejectMessage=post.querySelector("textarea.reject-reason").value.toString().trim();reviewRow.innerHTML=".";const args={postid:postID,reason:rejectMessage||null},nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_reject_post",args:args}])[0];let message=await(0,_str.get_string)("post_was_rejected","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message}else"reject-cancel"===action&&(reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/review_buttons",{}))}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch),_templates=_interopRequireDefault(_templates)}));
+
+//# sourceMappingURL=reviewing.min.js.map
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js.map b/amd/build/reviewing.min.js.map
new file mode 100644
index 0000000000..b14cb0911d
--- /dev/null
+++ b/amd/build/reviewing.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.js"],"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 * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","e","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason"],"mappings":";;;;;;;wGA+BaA,kBAAkB,CAAC,sCAAuC,wDAC1DC,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,QAAUC,MAAAA,UACLC,OAASC,EAAEC,OAAOC,aAAa,kCAEhCH,oBAICI,KAAOH,EAAEC,OAAOG,QAAQ,iCACxBC,UAAYL,EAAEC,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,iCAElB,YAAXH,OAAsB,CACtBM,UAAUE,UAAY,UAChBC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,OAEAQ,cAAgB,mBAAU,oBAAqB,sBAAwB,IAEvEA,SADAN,YACY,YAAWA,sBACX,mBAAU,mCAAoC,sBACpD,aAEW,mBAAU,oCAAqC,sBAEpEH,UAAUE,UAAYO,QACtBX,KAAKY,UAAUC,OAAO,sBACnB,GAAe,WAAXjB,OACPM,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBU,mBAAUC,OAAO,sCAAuC,SACjF,GAAe,kBAAXnB,OAA4B,OAC7BoB,cAAgBhB,KAAKiB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFlB,UAAUE,UAAY,UAChBK,KAAO,CACTC,OAAQP,OACRkB,OAAQL,eAAgC,MAEtCX,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,OAEAE,cAAgB,mBAAU,oBAAqB,sBAAwB,IAEvEA,SADAN,YACY,YAAWA,sBACX,mBAAU,mCAAoC,sBACpD,aAEW,mBAAU,oCAAqC,sBAEpEH,UAAUE,UAAYO,YACJ,kBAAXf,SACPM,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBU,mBAAUC,OAAO,oCAAqC"}
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js b/amd/build/warnmodechange.min.js
new file mode 100644
index 0000000000..5042ba704b
--- /dev/null
+++ b/amd/build/warnmodechange.min.js
@@ -0,0 +1,10 @@
+define("mod_moodleoverflow/warnmodechange",["exports","core/str","core/notification","core/prefetch"],(function(_exports,_str,_notification,_prefetch){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
+/**
+ * Warns on changing the subscription mode.
+ *
+ * @module mod_moodleoverflow/warnmodechange
+ * @copyright 2022 Justus Dieckmann WWU
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(previousSetting){_prefetch.default.prefetchStrings("mod_moodleoverflow",["switchtooptional","switchtoauto"]),_prefetch.default.prefetchStrings("moodle",["confirm","cancel"]);const form=document.querySelector("form.mform"),select=document.getElementById("id_forcesubscribe");form.onsubmit=async e=>{const value=select.selectedOptions[0].value;value!=previousSetting&&1!=value&&3!=value&&(e.preventDefault(),await _notification.default.confirm(await(0,_str.get_string)("confirm"),await(0,_str.get_string)(0==value?"switchtooptional":"switchtoauto","mod_moodleoverflow"),await(0,_str.get_string)("confirm"),await(0,_str.get_string)("cancel"),(()=>{form.onsubmit=void 0,form.requestSubmit(e.submitter)}),void 0))}},_notification=_interopRequireDefault(_notification),_prefetch=_interopRequireDefault(_prefetch)}));
+
+//# sourceMappingURL=warnmodechange.min.js.map
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js.map b/amd/build/warnmodechange.min.js.map
new file mode 100644
index 0000000000..70683e5540
--- /dev/null
+++ b/amd/build/warnmodechange.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.js"],"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 * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["previousSetting","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","e","preventDefault","Notification","confirm","undefined","requestSubmit","submitter"],"mappings":";;;;;;;oFA8BqBA,mCACRC,gBAAgB,qBAAsB,CAAC,mBAAoB,mCAC3DA,gBAAgB,SAAU,CAAC,UAAW,iBACzCC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,MAAAA,UACNC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAAST,iBAA4B,GAATS,OAAuB,GAATA,QAG9CE,EAAEC,uBACIC,sBAAaC,cACT,mBAAU,iBACV,mBAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,mBAAU,iBACV,mBAAU,WAChB,KAEIP,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcL,EAAEM,kBACtBF"}
\ No newline at end of file
From 28987453ffd230290309943a4d9ac73119f7850f Mon Sep 17 00:00:00 2001
From: Tamaro Walter
Date: Mon, 7 Jul 2025 20:00:04 +0200
Subject: [PATCH 46/56] rebuild js files
---
amd/build/activityhelp.min.js | 4 ++--
amd/build/activityhelp.min.js.map | 2 +-
amd/build/rating.min.js | 4 ++--
amd/build/rating.min.js.map | 2 +-
amd/build/reviewing.min.js | 4 ++--
amd/build/reviewing.min.js.map | 2 +-
amd/build/warnmodechange.min.js | 4 ++--
amd/build/warnmodechange.min.js.map | 2 +-
8 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/amd/build/activityhelp.min.js b/amd/build/activityhelp.min.js
index a875b70b82..4e6f2f9007 100644
--- a/amd/build/activityhelp.min.js
+++ b/amd/build/activityhelp.min.js
@@ -1,4 +1,4 @@
-define("mod_moodleoverflow/activityhelp",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;
+define("mod_moodleoverflow/activityhelp",["exports"],function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;
/**
* Show a help string for the amount of activity column in userstats_table.php
*
@@ -6,6 +6,6 @@ define("mod_moodleoverflow/activityhelp",["exports"],(function(_exports){Object.
* @copyright 2023 Tamaro Walter
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-const Selectors_actions={showHelpIcon:'[data-action="showhelpicon"]'};_exports.init=()=>{document.addEventListener("click",(event=>{event.target.closest(Selectors_actions.showHelpIcon)&&event.preventDefault()}))}}));
+const Selectors_actions={showHelpIcon:'[data-action="showhelpicon"]'};_exports.init=()=>{document.addEventListener("click",event=>{event.target.closest(Selectors_actions.showHelpIcon)&&event.preventDefault()})}});
//# sourceMappingURL=activityhelp.min.js.map
\ No newline at end of file
diff --git a/amd/build/activityhelp.min.js.map b/amd/build/activityhelp.min.js.map
index 2cdca4d1e4..1934ca29c6 100644
--- a/amd/build/activityhelp.min.js.map
+++ b/amd/build/activityhelp.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;MAyBMA,kBACO,CACLC,aAAc,8CAOF,KAChBC,SAASC,iBAAiB,SAASC,QAC3BA,MAAMC,OAAOC,QAAQN,kBAAkBC,eACvCG,MAAMG"}
\ No newline at end of file
+{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","_exports","init","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;AAyBA,MAAMA,kBACO,CACLC,aAAc,gCAapBC,SAAAC,KANkBA,KAChBC,SAASC,iBAAiB,QAASC,QAC3BA,MAAMC,OAAOC,QAAQR,kBAAkBC,eACvCK,MAAMG,mBAGhB"}
\ No newline at end of file
diff --git a/amd/build/rating.min.js b/amd/build/rating.min.js
index b70923c901..93a4db92d9 100644
--- a/amd/build/rating.min.js
+++ b/amd/build/rating.min.js
@@ -1,10 +1,10 @@
-define("mod_moodleoverflow/rating",["exports","core/ajax","core/prefetch","core/str"],(function(_exports,_ajax,_prefetch,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
+define("mod_moodleoverflow/rating",["exports","core/ajax","core/prefetch","core/str"],function(_exports,_ajax,_prefetch,_str){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
/**
* Implements rating functionality
*
* @module mod_moodleoverflow/rating
* @copyright 2022 Justus Dieckmann WWU
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(userid,allowmultiplemarks){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","marknotsolved","markhelpful","marknothelpful","action_remove_upvote","action_upvote","action_remove_downvote","action_downvote"]),root.onclick=async event=>{const actionElement=event.target.closest("[data-moodleoverflow-action]");if(!actionElement)return;const action=actionElement.getAttribute("data-moodleoverflow-action"),postElement=actionElement.closest("[data-moodleoverflow-postid]"),postid=null==postElement?void 0:postElement.getAttribute("data-moodleoverflow-postid");switch(action){case"upvote":case"downvote":{const isupvote="upvote"===action;if("clicked"===actionElement.getAttribute("data-moodleoverflow-state"))await sendVote(postid,isupvote?20:10,userid),actionElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_"+action,"mod_moodleoverflow");else{const otherAction=isupvote?"downvote":"upvote";await sendVote(postid,isupvote?2:1,userid),actionElement.setAttribute("data-moodleoverflow-state","clicked");const otherElement=postElement.querySelector(`[data-moodleoverflow-action="${otherAction}"]`);otherElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_remove_"+action,"mod_moodleoverflow"),otherElement.title=await(0,_str.get_string)("action_"+otherAction,"mod_moodleoverflow")}}break;case"helpful":case"solved":{const isHelpful="helpful"===action,htmlclass=isHelpful?"markedhelpful":"markedsolution",shouldRemove=postElement.classList.contains(htmlclass),baseRating=isHelpful?4:3,rating=shouldRemove?10*baseRating:baseRating;if(await sendVote(postid,rating,userid),allowmultiplemarks)shouldRemove&&(postElement.classList.remove(htmlclass),actionElement.textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"),changeStrings(htmlclass,action));else for(const el of root.querySelectorAll(".moodleoverflowpost."+htmlclass))el.classList.remove(htmlclass),el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow");shouldRemove||(postElement.classList.add(htmlclass),actionElement.textContent=await(0,_str.get_string)(`marknot${action}`,"mod_moodleoverflow"),allowmultiplemarks&&changeStrings(htmlclass,action))}}}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch);const root=document.getElementById("moodleoverflow-root");async function sendVote(postid,rating,userid){const response=await _ajax.default.call([{methodname:"mod_moodleoverflow_record_vote",args:{postid:postid,ratingid:rating}}])[0];return root.querySelectorAll(`[data-moodleoverflow-userreputation="${userid}"]`).forEach((i=>{i.textContent=response.raterreputation})),root.querySelectorAll(`[data-moodleoverflow-userreputation="${response.ownerid}"]`).forEach((i=>{i.textContent=response.ownerreputation})),root.querySelectorAll(`[data-moodleoverflow-postreputation="${postid}"]`).forEach((i=>{i.textContent=response.postrating})),response}async function changeStrings(htmlclass,action){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","alsomarksolved","markhelpful","alsomarkhelpful"]);var othermarkedposts=!1;for(const el of root.querySelectorAll(".moodleoverflowpost"))if(el.classList.contains(htmlclass)){othermarkedposts=!0;break}for(const el of root.querySelectorAll(".moodleoverflowpost"))!el.classList.contains(htmlclass)&&el.querySelector(`[data-moodleoverflow-action="${action}"]`)&&(el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=othermarkedposts?await(0,_str.get_string)(`alsomark${action}`,"mod_moodleoverflow"):await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"))}}));
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(userid,allowmultiplemarks){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","marknotsolved","markhelpful","marknothelpful","action_remove_upvote","action_upvote","action_remove_downvote","action_downvote"]),root.onclick=async event=>{const actionElement=event.target.closest("[data-moodleoverflow-action]");if(!actionElement)return;const action=actionElement.getAttribute("data-moodleoverflow-action"),postElement=actionElement.closest("[data-moodleoverflow-postid]"),postid=null==postElement?void 0:postElement.getAttribute("data-moodleoverflow-postid");switch(action){case"upvote":case"downvote":{const isupvote="upvote"===action;if("clicked"===actionElement.getAttribute("data-moodleoverflow-state"))await sendVote(postid,isupvote?RATING_REMOVE_UPVOTE:RATING_REMOVE_DOWNVOTE,userid),actionElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_"+action,"mod_moodleoverflow");else{const otherAction=isupvote?"downvote":"upvote";await sendVote(postid,isupvote?RATING_UPVOTE:RATING_DOWNVOTE,userid),actionElement.setAttribute("data-moodleoverflow-state","clicked");const otherElement=postElement.querySelector(`[data-moodleoverflow-action="${otherAction}"]`);otherElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_remove_"+action,"mod_moodleoverflow"),otherElement.title=await(0,_str.get_string)("action_"+otherAction,"mod_moodleoverflow")}}break;case"helpful":case"solved":{const isHelpful="helpful"===action,htmlclass=isHelpful?"markedhelpful":"markedsolution",shouldRemove=postElement.classList.contains(htmlclass),baseRating=isHelpful?RATING_HELPFUL:RATING_SOLVED,rating=shouldRemove?10*baseRating:baseRating;if(await sendVote(postid,rating,userid),allowmultiplemarks)shouldRemove&&(postElement.classList.remove(htmlclass),actionElement.textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"),changeStrings(htmlclass,action));else for(const el of root.querySelectorAll(".moodleoverflowpost."+htmlclass))el.classList.remove(htmlclass),el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow");shouldRemove||(postElement.classList.add(htmlclass),actionElement.textContent=await(0,_str.get_string)(`marknot${action}`,"mod_moodleoverflow"),allowmultiplemarks&&changeStrings(htmlclass,action))}}}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch);const RATING_DOWNVOTE=1,RATING_UPVOTE=2,RATING_REMOVE_DOWNVOTE=10,RATING_REMOVE_UPVOTE=20,RATING_SOLVED=3,RATING_HELPFUL=4,root=document.getElementById("moodleoverflow-root");async function sendVote(postid,rating,userid){const response=await _ajax.default.call([{methodname:"mod_moodleoverflow_record_vote",args:{postid:postid,ratingid:rating}}])[0];return root.querySelectorAll(`[data-moodleoverflow-userreputation="${userid}"]`).forEach(i=>{i.textContent=response.raterreputation}),root.querySelectorAll(`[data-moodleoverflow-userreputation="${response.ownerid}"]`).forEach(i=>{i.textContent=response.ownerreputation}),root.querySelectorAll(`[data-moodleoverflow-postreputation="${postid}"]`).forEach(i=>{i.textContent=response.postrating}),response}async function changeStrings(htmlclass,action){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","alsomarksolved","markhelpful","alsomarkhelpful"]);var othermarkedposts=!1;for(const el of root.querySelectorAll(".moodleoverflowpost"))if(el.classList.contains(htmlclass)){othermarkedposts=!0;break}for(const el of root.querySelectorAll(".moodleoverflowpost"))!el.classList.contains(htmlclass)&&el.querySelector(`[data-moodleoverflow-action="${action}"]`)&&(el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=othermarkedposts?await(0,_str.get_string)(`alsomark${action}`,"mod_moodleoverflow"):await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"))}});
//# sourceMappingURL=rating.min.js.map
\ No newline at end of file
diff --git a/amd/build/rating.min.js.map b/amd/build/rating.min.js.map
index 0c1d368bbd..64af28a834 100644
--- a/amd/build/rating.min.js.map
+++ b/amd/build/rating.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"rating.min.js","sources":["../src/rating.js"],"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 * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if multiplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["userid","allowmultiplemarks","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","setAttribute","title","otherAction","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","rating","remove","textContent","changeStrings","el","querySelectorAll","add","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":";;;;;;;oFAsEqBA,OAAQC,sCAChBC,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,MAAAA,cACLC,cAAgBC,MAAMC,OAAOC,QAAQ,oCACtCH,2BAICI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,MAAAA,mBAAAA,YAAaD,aAAa,qCAEjCD,YACC,aACA,kBACKI,SAAsB,WAAXJ,UAC+C,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SA7Dd,GADE,GA8DsEd,QACjFM,cAAcU,aAAa,4BAA6B,cACxDV,cAAcW,YAAc,mBAAU,UAAYP,OAAQ,0BACvD,OACGQ,YAAcJ,SAAW,WAAa,eACtCC,SAASF,OAAQC,SApErB,EADE,EAqE+Dd,QACnEM,cAAcU,aAAa,4BAA6B,iBAClDG,aAAeP,YAAYQ,cAC5B,gCAA+BF,iBACpCC,aAAaH,aAAa,4BAA6B,cACvDV,cAAcW,YAAc,mBAAU,iBAAmBP,OAAQ,sBACjES,aAAaF,YAAc,mBAAU,UAAYC,YAAa,iCAIjE,cACA,gBACKG,UAAuB,YAAXX,OACZY,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAeX,YAAYY,UAAUC,SAASH,WAC9CI,WAAaL,UA/EZ,EADD,EAiFAM,OAASJ,aAA4B,GAAbG,WAAkBA,oBAC1CX,SAASF,OAAQc,OAAQ3B,QAO1BC,mBASGsB,eACAX,YAAYY,UAAUI,OAAON,WAC7BhB,cAAcuB,kBAAoB,mBAAW,OAAMnB,SAAU,sBAC7DoB,cAAcR,UAAWZ,kBAVxB,MAAMqB,MAAM5B,KAAK6B,iBAAiB,uBAAyBV,WAC5DS,GAAGP,UAAUI,OAAON,WACpBS,GAAGX,cAAe,gCAA+BV,YAAYmB,kBACnD,mBAAW,OAAMnB,SAAU,sBAWxCa,eACDX,YAAYY,UAAUS,IAAIX,WAC1BhB,cAAcuB,kBAAoB,mBAAW,UAASnB,SAAU,sBAC5DT,oBACA6B,cAAcR,UAAWZ,mGA1G3CP,KAAO+B,SAASC,eAAe,sCAStBpB,SAASF,OAAQc,OAAQ3B,cAC9BoC,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACF3B,OAAQA,OACR4B,SAAUd,WAEd,UACJxB,KAAK6B,iBAAkB,wCAAuChC,YAAY0C,SAASC,IAC/EA,EAAEd,YAAcO,SAASQ,mBAE7BzC,KAAK6B,iBAAkB,wCAAuCI,SAASS,aAAaH,SAASC,IACzFA,EAAEd,YAAcO,SAASU,mBAE7B3C,KAAK6B,iBAAkB,wCAAuCnB,YAAY6B,SAASC,IAC/EA,EAAEd,YAAcO,SAASW,cAEtBX,wBAgGIN,cAAcR,UAAWZ,0BAC3BR,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,wBAGhD8C,kBAAmB,MAClB,MAAMjB,MAAM5B,KAAK6B,iBAAiB,0BAC/BD,GAAGP,UAAUC,SAASH,WAAY,CAClC0B,kBAAmB,YAKtB,MAAMjB,MAAM5B,KAAK6B,iBAAiB,wBAC9BD,GAAGP,UAAUC,SAASH,YAAcS,GAAGX,cAAe,gCAA+BV,cAElFqB,GAAGX,cAAe,gCAA+BV,YAAYmB,YAD7DmB,uBAEU,mBAAW,WAAUtC,SAAU,4BAG/B,mBAAW,OAAMA,SAAU"}
\ No newline at end of file
+{"version":3,"file":"rating.min.js","sources":["../src/rating.js"],"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 * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if multiplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["_interopRequireDefault","e","__esModule","default","userid","allowmultiplemarks","Prefetch","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","RATING_REMOVE_UPVOTE","RATING_REMOVE_DOWNVOTE","setAttribute","title","getString","otherAction","RATING_UPVOTE","RATING_DOWNVOTE","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","RATING_HELPFUL","RATING_SOLVED","rating","remove","textContent","changeStrings","el","querySelectorAll","add","_ajax","_prefetch","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":"8HAuBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EA+C9B,SAAcG,OAAQC,oBACzBC,UAAQH,QAACI,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,cACX,MAAMC,cAAgBC,MAAMC,OAAOC,QAAQ,gCAC3C,IAAKH,cACD,OAGJ,MAAMI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,uBAAAA,EAAAA,YAAaD,aAAa,8BAEzC,OAAQD,QACJ,IAAK,SACL,IAAK,WAAY,CACb,MAAMI,SAAsB,WAAXJ,OACjB,GAAgE,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SAAWE,qBAAuBC,uBAAwBlB,QACjFO,cAAcY,aAAa,4BAA6B,cACxDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,UAAYV,OAAQ,0BACvD,CACH,MAAMW,YAAcP,SAAW,WAAa,eACtCC,SAASF,OAAQC,SAAWQ,cAAgBC,gBAAiBxB,QACnEO,cAAcY,aAAa,4BAA6B,WACxD,MAAMM,aAAeZ,YAAYa,cAC7B,gCAAgCJ,iBACpCG,aAAaN,aAAa,4BAA6B,cACvDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,iBAAmBV,OAAQ,sBACjEc,aAAaL,YAAc,EAAAC,KAAAA,YAAU,UAAYC,YAAa,qBAClE,CACJ,CACA,MACA,IAAK,UACL,IAAK,SAAU,CACX,MAAMK,UAAuB,YAAXhB,OACZiB,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAehB,YAAYiB,UAAUC,SAASH,WAC9CI,WAAaL,UAAYM,eAAiBC,cAC1CC,OAASN,aAA4B,GAAbG,WAAkBA,WAQhD,SAPMhB,SAASF,OAAQqB,OAAQnC,QAO1BC,mBASG4B,eACAhB,YAAYiB,UAAUM,OAAOR,WAC7BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,OAAOV,SAAU,sBAC7D2B,cAAcV,UAAWjB,cAV7B,IAAK,MAAM4B,MAAMnC,KAAKoC,iBAAiB,uBAAyBZ,WAC5DW,GAAGT,UAAUM,OAAOR,WACpBW,GAAGb,cAAc,gCAAgCf,YAAY0B,kBACnD,EAAAhB,iBAAU,OAAOV,SAAU,sBAWxCkB,eACDhB,YAAYiB,UAAUW,IAAIb,WAC1BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,UAAUV,SAAU,sBAC5DV,oBACAqC,cAAcV,UAAWjB,QAIrC,GAIZ,EA7HA+B,MAAA9C,uBAAA8C,OACAC,UAAA/C,uBAAA+C,WAGA,MAAMnB,gBAAkB,EAClBD,cAAgB,EAChBL,uBAAyB,GACzBD,qBAAuB,GACvBiB,cAAgB,EAChBD,eAAiB,EAEjB7B,KAAOwC,SAASC,eAAe,uBASrCvC,eAAeU,SAASF,OAAQqB,OAAQnC,QACpC,MAAM8C,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACFpC,OAAQA,OACRqC,SAAUhB,WAEd,GAUJ,OATA/B,KAAKoC,iBAAiB,wCAAwCxC,YAAYoD,QAASC,IAC/EA,EAAEhB,YAAcS,SAASQ,kBAE7BlD,KAAKoC,iBAAiB,wCAAwCM,SAASS,aAAaH,QAASC,IACzFA,EAAEhB,YAAcS,SAASU,kBAE7BpD,KAAKoC,iBAAiB,wCAAwC1B,YAAYsC,QAASC,IAC/EA,EAAEhB,YAAcS,SAASW,aAEtBX,QACX,CA+FAxC,eAAegC,cAAcV,UAAWjB,QACpCT,UAAAA,QAASC,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,oBAGpD,IAAIuD,kBAAmB,EACvB,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,uBACnC,GAAID,GAAGT,UAAUC,SAASH,WAAY,CAClC8B,kBAAmB,EACnB,KACJ,CAGJ,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,wBAC9BD,GAAGT,UAAUC,SAASH,YAAcW,GAAGb,cAAc,gCAAgCf,cAElF4B,GAAGb,cAAc,gCAAgCf,YAAY0B,YAD7DqB,uBAEU,EAAArC,iBAAU,WAAWV,SAAU,4BAG/B,EAAAU,iBAAU,OAAOV,SAAU,sBAIrD,CAAC"}
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js b/amd/build/reviewing.min.js
index 59b05be5da..d027cc1635 100644
--- a/amd/build/reviewing.min.js
+++ b/amd/build/reviewing.min.js
@@ -1,10 +1,10 @@
-define("mod_moodleoverflow/reviewing",["exports","core/ajax","core/prefetch","core/templates","core/str"],(function(_exports,_ajax,_prefetch,_templates,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
+define("mod_moodleoverflow/reviewing",["exports","core/ajax","core/prefetch","core/templates","core/str"],function(_exports,_ajax,_prefetch,_templates,_str){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
/**
* Implements reviewing functionality
*
* @module mod_moodleoverflow/reviewing
* @copyright 2022 Justus Dieckmann WWU
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){_prefetch.default.prefetchTemplates(["mod_moodleoverflow/reject_post_form","mod_moodleoverflow/review_buttons"]),_prefetch.default.prefetchStrings("mod_moodleoverflow",["post_was_approved","jump_to_next_post_needing_review","there_are_no_posts_needing_review","post_was_rejected"]);document.getElementById("moodleoverflow-posts").onclick=async e=>{const action=e.target.getAttribute("data-moodleoverflow-action");if(!action)return;const post=e.target.closest("*[data-moodleoverflow-postid]"),reviewRow=e.target.closest(".reviewrow"),postID=post.getAttribute("data-moodleoverflow-postid");if("approve"===action){reviewRow.innerHTML=".";const nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_approve_post",args:{postid:postID}}])[0];let message=await(0,_str.get_string)("post_was_approved","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message,post.classList.remove("pendingreview")}else if("reject"===action)reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/reject_post_form",{});else if("reject-submit"===action){const rejectMessage=post.querySelector("textarea.reject-reason").value.toString().trim();reviewRow.innerHTML=".";const args={postid:postID,reason:rejectMessage||null},nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_reject_post",args:args}])[0];let message=await(0,_str.get_string)("post_was_rejected","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message}else"reject-cancel"===action&&(reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/review_buttons",{}))}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch),_templates=_interopRequireDefault(_templates)}));
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){_prefetch.default.prefetchTemplates(["mod_moodleoverflow/reject_post_form","mod_moodleoverflow/review_buttons"]),_prefetch.default.prefetchStrings("mod_moodleoverflow",["post_was_approved","jump_to_next_post_needing_review","there_are_no_posts_needing_review","post_was_rejected"]);document.getElementById("moodleoverflow-posts").onclick=async e=>{const action=e.target.getAttribute("data-moodleoverflow-action");if(!action)return;const post=e.target.closest("*[data-moodleoverflow-postid]"),reviewRow=e.target.closest(".reviewrow"),postID=post.getAttribute("data-moodleoverflow-postid");if("approve"===action){reviewRow.innerHTML=".";const nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_approve_post",args:{postid:postID}}])[0];let message=await(0,_str.get_string)("post_was_approved","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message,post.classList.remove("pendingreview")}else if("reject"===action)reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/reject_post_form",{});else if("reject-submit"===action){const rejectMessage=post.querySelector("textarea.reject-reason").value.toString().trim();reviewRow.innerHTML=".";const args={postid:postID,reason:rejectMessage||null},nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_reject_post",args:args}])[0];let message=await(0,_str.get_string)("post_was_rejected","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message}else"reject-cancel"===action&&(reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/review_buttons",{}))}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch),_templates=_interopRequireDefault(_templates)});
//# sourceMappingURL=reviewing.min.js.map
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js.map b/amd/build/reviewing.min.js.map
index b14cb0911d..9695518cff 100644
--- a/amd/build/reviewing.min.js.map
+++ b/amd/build/reviewing.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.js"],"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 * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","e","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason"],"mappings":";;;;;;;wGA+BaA,kBAAkB,CAAC,sCAAuC,wDAC1DC,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,QAAUC,MAAAA,UACLC,OAASC,EAAEC,OAAOC,aAAa,kCAEhCH,oBAICI,KAAOH,EAAEC,OAAOG,QAAQ,iCACxBC,UAAYL,EAAEC,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,iCAElB,YAAXH,OAAsB,CACtBM,UAAUE,UAAY,UAChBC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,OAEAQ,cAAgB,mBAAU,oBAAqB,sBAAwB,IAEvEA,SADAN,YACY,YAAWA,sBACX,mBAAU,mCAAoC,sBACpD,aAEW,mBAAU,oCAAqC,sBAEpEH,UAAUE,UAAYO,QACtBX,KAAKY,UAAUC,OAAO,sBACnB,GAAe,WAAXjB,OACPM,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBU,mBAAUC,OAAO,sCAAuC,SACjF,GAAe,kBAAXnB,OAA4B,OAC7BoB,cAAgBhB,KAAKiB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFlB,UAAUE,UAAY,UAChBK,KAAO,CACTC,OAAQP,OACRkB,OAAQL,eAAgC,MAEtCX,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,OAEAE,cAAgB,mBAAU,oBAAqB,sBAAwB,IAEvEA,SADAN,YACY,YAAWA,sBACX,mBAAU,mCAAoC,sBACpD,aAEW,mBAAU,oCAAqC,sBAEpEH,UAAUE,UAAYO,YACJ,kBAAXf,SACPM,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBU,mBAAUC,OAAO,oCAAqC"}
\ No newline at end of file
+{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.js"],"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 * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","Prefetch","prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","getString","get_string","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason","_ajax","_prefetch","_templates"],"mappings":"6JAwBuC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAMhC,WACHG,UAAQD,QAACE,kBAAkB,CAAC,sCAAuC,sCACnED,UAAAA,QAASE,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,QAAUC,UACX,MAAMC,OAASV,EAAEW,OAAOC,aAAa,8BAErC,IAAKF,OACD,OAGJ,MAAMG,KAAOb,EAAEW,OAAOG,QAAQ,iCACxBC,UAAYf,EAAEW,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,8BAEjC,GAAe,YAAXF,OAAsB,CACtBK,UAAUE,UAAY,IACtB,MAAMC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,GAEJ,IAAIQ,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,QACtBX,KAAKc,UAAUC,OAAO,gBAC1B,MAAO,GAAe,WAAXlB,OACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,sCAAuC,CAAA,QACjF,GAAe,kBAAXpB,OAA4B,CACnC,MAAMqB,cAAgBlB,KAAKmB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFpB,UAAUE,UAAY,IACtB,MAAMK,KAAO,CACTC,OAAQP,OACRoB,OAAQL,eAAgC,MAEtCb,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,GAEJ,IAAIE,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,OAC1B,KAAsB,kBAAXd,SACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,oCAAqC,CAAA,IAG9F,EAzEAO,MAAAtC,uBAAAsC,OACAC,UAAAvC,uBAAAuC,WACAC,WAAAxC,uBAAAwC,WAuEC"}
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js b/amd/build/warnmodechange.min.js
index 5042ba704b..605c6f767f 100644
--- a/amd/build/warnmodechange.min.js
+++ b/amd/build/warnmodechange.min.js
@@ -1,10 +1,10 @@
-define("mod_moodleoverflow/warnmodechange",["exports","core/str","core/notification","core/prefetch"],(function(_exports,_str,_notification,_prefetch){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
+define("mod_moodleoverflow/warnmodechange",["exports","core/str","core/notification","core/prefetch"],function(_exports,_str,_notification,_prefetch){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
/**
* Warns on changing the subscription mode.
*
* @module mod_moodleoverflow/warnmodechange
* @copyright 2022 Justus Dieckmann WWU
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(previousSetting){_prefetch.default.prefetchStrings("mod_moodleoverflow",["switchtooptional","switchtoauto"]),_prefetch.default.prefetchStrings("moodle",["confirm","cancel"]);const form=document.querySelector("form.mform"),select=document.getElementById("id_forcesubscribe");form.onsubmit=async e=>{const value=select.selectedOptions[0].value;value!=previousSetting&&1!=value&&3!=value&&(e.preventDefault(),await _notification.default.confirm(await(0,_str.get_string)("confirm"),await(0,_str.get_string)(0==value?"switchtooptional":"switchtoauto","mod_moodleoverflow"),await(0,_str.get_string)("confirm"),await(0,_str.get_string)("cancel"),(()=>{form.onsubmit=void 0,form.requestSubmit(e.submitter)}),void 0))}},_notification=_interopRequireDefault(_notification),_prefetch=_interopRequireDefault(_prefetch)}));
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(previousSetting){_prefetch.default.prefetchStrings("mod_moodleoverflow",["switchtooptional","switchtoauto"]),_prefetch.default.prefetchStrings("moodle",["confirm","cancel"]);const form=document.querySelector("form.mform"),select=document.getElementById("id_forcesubscribe");form.onsubmit=async e=>{const value=select.selectedOptions[0].value;value!=previousSetting&&1!=value&&3!=value&&(e.preventDefault(),await _notification.default.confirm(await(0,_str.get_string)("confirm"),await(0,_str.get_string)(0==value?"switchtooptional":"switchtoauto","mod_moodleoverflow"),await(0,_str.get_string)("confirm"),await(0,_str.get_string)("cancel"),()=>{form.onsubmit=void 0,form.requestSubmit(e.submitter)},void 0))}},_notification=_interopRequireDefault(_notification),_prefetch=_interopRequireDefault(_prefetch)});
//# sourceMappingURL=warnmodechange.min.js.map
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js.map b/amd/build/warnmodechange.min.js.map
index 70683e5540..b205af0c40 100644
--- a/amd/build/warnmodechange.min.js.map
+++ b/amd/build/warnmodechange.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.js"],"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 * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["previousSetting","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","e","preventDefault","Notification","confirm","undefined","requestSubmit","submitter"],"mappings":";;;;;;;oFA8BqBA,mCACRC,gBAAgB,qBAAsB,CAAC,mBAAoB,mCAC3DA,gBAAgB,SAAU,CAAC,UAAW,iBACzCC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,MAAAA,UACNC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAAST,iBAA4B,GAATS,OAAuB,GAATA,QAG9CE,EAAEC,uBACIC,sBAAaC,cACT,mBAAU,iBACV,mBAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,mBAAU,iBACV,mBAAU,WAChB,KAEIP,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcL,EAAEM,kBACtBF"}
\ No newline at end of file
+{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.js"],"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 * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","previousSetting","Prefetch","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","preventDefault","Notification","confirm","getString","undefined","requestSubmit","submitter","_notification","_prefetch"],"mappings":"sJAwBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAM9B,SAAcG,iBACjBC,UAAQF,QAACG,gBAAgB,qBAAsB,CAAC,mBAAoB,iBACpED,UAAQF,QAACG,gBAAgB,SAAU,CAAC,UAAW,WAC/C,MAAMC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,UACZ,MAAMC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAASV,iBAA4B,GAATU,OAAuB,GAATA,QAG9Cb,EAAEe,uBACIC,sBAAaC,cACT,EAAAC,iBAAU,iBACV,EAAAA,KAAAA,YAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,EAAAK,iBAAU,iBACV,EAAAA,KAAAA,YAAU,UAChB,KAEIZ,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcpB,EAAEqB,iBACtBF,IAEf,EA7BAG,cAAAvB,uBAAAuB,eACAC,UAAAxB,uBAAAwB,UA4BC"}
\ No newline at end of file
From 7e487362ee55273ef81499e2e3c68a8c233b75b8 Mon Sep 17 00:00:00 2001
From: tamaro
Date: Mon, 7 Jul 2025 20:06:47 +0200
Subject: [PATCH 47/56] rebuild min js files
---
amd/build/activityhelp.min.js | 4 ++--
amd/build/activityhelp.min.js.map | 2 +-
amd/build/rating.min.js | 4 ++--
amd/build/rating.min.js.map | 2 +-
amd/build/reviewing.min.js | 4 ++--
amd/build/reviewing.min.js.map | 2 +-
amd/build/warnmodechange.min.js | 4 ++--
amd/build/warnmodechange.min.js.map | 2 +-
8 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/amd/build/activityhelp.min.js b/amd/build/activityhelp.min.js
index 4e6f2f9007..a875b70b82 100644
--- a/amd/build/activityhelp.min.js
+++ b/amd/build/activityhelp.min.js
@@ -1,4 +1,4 @@
-define("mod_moodleoverflow/activityhelp",["exports"],function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;
+define("mod_moodleoverflow/activityhelp",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;
/**
* Show a help string for the amount of activity column in userstats_table.php
*
@@ -6,6 +6,6 @@ define("mod_moodleoverflow/activityhelp",["exports"],function(_exports){Object.d
* @copyright 2023 Tamaro Walter
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-const Selectors_actions={showHelpIcon:'[data-action="showhelpicon"]'};_exports.init=()=>{document.addEventListener("click",event=>{event.target.closest(Selectors_actions.showHelpIcon)&&event.preventDefault()})}});
+const Selectors_actions={showHelpIcon:'[data-action="showhelpicon"]'};_exports.init=()=>{document.addEventListener("click",(event=>{event.target.closest(Selectors_actions.showHelpIcon)&&event.preventDefault()}))}}));
//# sourceMappingURL=activityhelp.min.js.map
\ No newline at end of file
diff --git a/amd/build/activityhelp.min.js.map b/amd/build/activityhelp.min.js.map
index 1934ca29c6..2cdca4d1e4 100644
--- a/amd/build/activityhelp.min.js.map
+++ b/amd/build/activityhelp.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","_exports","init","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;AAyBA,MAAMA,kBACO,CACLC,aAAc,gCAapBC,SAAAC,KANkBA,KAChBC,SAASC,iBAAiB,QAASC,QAC3BA,MAAMC,OAAOC,QAAQR,kBAAkBC,eACvCK,MAAMG,mBAGhB"}
\ No newline at end of file
+{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;MAyBMA,kBACO,CACLC,aAAc,8CAOF,KAChBC,SAASC,iBAAiB,SAASC,QAC3BA,MAAMC,OAAOC,QAAQN,kBAAkBC,eACvCG,MAAMG"}
\ No newline at end of file
diff --git a/amd/build/rating.min.js b/amd/build/rating.min.js
index 93a4db92d9..b70923c901 100644
--- a/amd/build/rating.min.js
+++ b/amd/build/rating.min.js
@@ -1,10 +1,10 @@
-define("mod_moodleoverflow/rating",["exports","core/ajax","core/prefetch","core/str"],function(_exports,_ajax,_prefetch,_str){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
+define("mod_moodleoverflow/rating",["exports","core/ajax","core/prefetch","core/str"],(function(_exports,_ajax,_prefetch,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
/**
* Implements rating functionality
*
* @module mod_moodleoverflow/rating
* @copyright 2022 Justus Dieckmann WWU
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(userid,allowmultiplemarks){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","marknotsolved","markhelpful","marknothelpful","action_remove_upvote","action_upvote","action_remove_downvote","action_downvote"]),root.onclick=async event=>{const actionElement=event.target.closest("[data-moodleoverflow-action]");if(!actionElement)return;const action=actionElement.getAttribute("data-moodleoverflow-action"),postElement=actionElement.closest("[data-moodleoverflow-postid]"),postid=null==postElement?void 0:postElement.getAttribute("data-moodleoverflow-postid");switch(action){case"upvote":case"downvote":{const isupvote="upvote"===action;if("clicked"===actionElement.getAttribute("data-moodleoverflow-state"))await sendVote(postid,isupvote?RATING_REMOVE_UPVOTE:RATING_REMOVE_DOWNVOTE,userid),actionElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_"+action,"mod_moodleoverflow");else{const otherAction=isupvote?"downvote":"upvote";await sendVote(postid,isupvote?RATING_UPVOTE:RATING_DOWNVOTE,userid),actionElement.setAttribute("data-moodleoverflow-state","clicked");const otherElement=postElement.querySelector(`[data-moodleoverflow-action="${otherAction}"]`);otherElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_remove_"+action,"mod_moodleoverflow"),otherElement.title=await(0,_str.get_string)("action_"+otherAction,"mod_moodleoverflow")}}break;case"helpful":case"solved":{const isHelpful="helpful"===action,htmlclass=isHelpful?"markedhelpful":"markedsolution",shouldRemove=postElement.classList.contains(htmlclass),baseRating=isHelpful?RATING_HELPFUL:RATING_SOLVED,rating=shouldRemove?10*baseRating:baseRating;if(await sendVote(postid,rating,userid),allowmultiplemarks)shouldRemove&&(postElement.classList.remove(htmlclass),actionElement.textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"),changeStrings(htmlclass,action));else for(const el of root.querySelectorAll(".moodleoverflowpost."+htmlclass))el.classList.remove(htmlclass),el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow");shouldRemove||(postElement.classList.add(htmlclass),actionElement.textContent=await(0,_str.get_string)(`marknot${action}`,"mod_moodleoverflow"),allowmultiplemarks&&changeStrings(htmlclass,action))}}}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch);const RATING_DOWNVOTE=1,RATING_UPVOTE=2,RATING_REMOVE_DOWNVOTE=10,RATING_REMOVE_UPVOTE=20,RATING_SOLVED=3,RATING_HELPFUL=4,root=document.getElementById("moodleoverflow-root");async function sendVote(postid,rating,userid){const response=await _ajax.default.call([{methodname:"mod_moodleoverflow_record_vote",args:{postid:postid,ratingid:rating}}])[0];return root.querySelectorAll(`[data-moodleoverflow-userreputation="${userid}"]`).forEach(i=>{i.textContent=response.raterreputation}),root.querySelectorAll(`[data-moodleoverflow-userreputation="${response.ownerid}"]`).forEach(i=>{i.textContent=response.ownerreputation}),root.querySelectorAll(`[data-moodleoverflow-postreputation="${postid}"]`).forEach(i=>{i.textContent=response.postrating}),response}async function changeStrings(htmlclass,action){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","alsomarksolved","markhelpful","alsomarkhelpful"]);var othermarkedposts=!1;for(const el of root.querySelectorAll(".moodleoverflowpost"))if(el.classList.contains(htmlclass)){othermarkedposts=!0;break}for(const el of root.querySelectorAll(".moodleoverflowpost"))!el.classList.contains(htmlclass)&&el.querySelector(`[data-moodleoverflow-action="${action}"]`)&&(el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=othermarkedposts?await(0,_str.get_string)(`alsomark${action}`,"mod_moodleoverflow"):await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"))}});
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(userid,allowmultiplemarks){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","marknotsolved","markhelpful","marknothelpful","action_remove_upvote","action_upvote","action_remove_downvote","action_downvote"]),root.onclick=async event=>{const actionElement=event.target.closest("[data-moodleoverflow-action]");if(!actionElement)return;const action=actionElement.getAttribute("data-moodleoverflow-action"),postElement=actionElement.closest("[data-moodleoverflow-postid]"),postid=null==postElement?void 0:postElement.getAttribute("data-moodleoverflow-postid");switch(action){case"upvote":case"downvote":{const isupvote="upvote"===action;if("clicked"===actionElement.getAttribute("data-moodleoverflow-state"))await sendVote(postid,isupvote?20:10,userid),actionElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_"+action,"mod_moodleoverflow");else{const otherAction=isupvote?"downvote":"upvote";await sendVote(postid,isupvote?2:1,userid),actionElement.setAttribute("data-moodleoverflow-state","clicked");const otherElement=postElement.querySelector(`[data-moodleoverflow-action="${otherAction}"]`);otherElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_remove_"+action,"mod_moodleoverflow"),otherElement.title=await(0,_str.get_string)("action_"+otherAction,"mod_moodleoverflow")}}break;case"helpful":case"solved":{const isHelpful="helpful"===action,htmlclass=isHelpful?"markedhelpful":"markedsolution",shouldRemove=postElement.classList.contains(htmlclass),baseRating=isHelpful?4:3,rating=shouldRemove?10*baseRating:baseRating;if(await sendVote(postid,rating,userid),allowmultiplemarks)shouldRemove&&(postElement.classList.remove(htmlclass),actionElement.textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"),changeStrings(htmlclass,action));else for(const el of root.querySelectorAll(".moodleoverflowpost."+htmlclass))el.classList.remove(htmlclass),el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow");shouldRemove||(postElement.classList.add(htmlclass),actionElement.textContent=await(0,_str.get_string)(`marknot${action}`,"mod_moodleoverflow"),allowmultiplemarks&&changeStrings(htmlclass,action))}}}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch);const root=document.getElementById("moodleoverflow-root");async function sendVote(postid,rating,userid){const response=await _ajax.default.call([{methodname:"mod_moodleoverflow_record_vote",args:{postid:postid,ratingid:rating}}])[0];return root.querySelectorAll(`[data-moodleoverflow-userreputation="${userid}"]`).forEach((i=>{i.textContent=response.raterreputation})),root.querySelectorAll(`[data-moodleoverflow-userreputation="${response.ownerid}"]`).forEach((i=>{i.textContent=response.ownerreputation})),root.querySelectorAll(`[data-moodleoverflow-postreputation="${postid}"]`).forEach((i=>{i.textContent=response.postrating})),response}async function changeStrings(htmlclass,action){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","alsomarksolved","markhelpful","alsomarkhelpful"]);var othermarkedposts=!1;for(const el of root.querySelectorAll(".moodleoverflowpost"))if(el.classList.contains(htmlclass)){othermarkedposts=!0;break}for(const el of root.querySelectorAll(".moodleoverflowpost"))!el.classList.contains(htmlclass)&&el.querySelector(`[data-moodleoverflow-action="${action}"]`)&&(el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=othermarkedposts?await(0,_str.get_string)(`alsomark${action}`,"mod_moodleoverflow"):await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"))}}));
//# sourceMappingURL=rating.min.js.map
\ No newline at end of file
diff --git a/amd/build/rating.min.js.map b/amd/build/rating.min.js.map
index 64af28a834..0c1d368bbd 100644
--- a/amd/build/rating.min.js.map
+++ b/amd/build/rating.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"rating.min.js","sources":["../src/rating.js"],"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 * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if multiplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["_interopRequireDefault","e","__esModule","default","userid","allowmultiplemarks","Prefetch","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","RATING_REMOVE_UPVOTE","RATING_REMOVE_DOWNVOTE","setAttribute","title","getString","otherAction","RATING_UPVOTE","RATING_DOWNVOTE","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","RATING_HELPFUL","RATING_SOLVED","rating","remove","textContent","changeStrings","el","querySelectorAll","add","_ajax","_prefetch","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":"8HAuBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EA+C9B,SAAcG,OAAQC,oBACzBC,UAAQH,QAACI,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,cACX,MAAMC,cAAgBC,MAAMC,OAAOC,QAAQ,gCAC3C,IAAKH,cACD,OAGJ,MAAMI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,uBAAAA,EAAAA,YAAaD,aAAa,8BAEzC,OAAQD,QACJ,IAAK,SACL,IAAK,WAAY,CACb,MAAMI,SAAsB,WAAXJ,OACjB,GAAgE,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SAAWE,qBAAuBC,uBAAwBlB,QACjFO,cAAcY,aAAa,4BAA6B,cACxDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,UAAYV,OAAQ,0BACvD,CACH,MAAMW,YAAcP,SAAW,WAAa,eACtCC,SAASF,OAAQC,SAAWQ,cAAgBC,gBAAiBxB,QACnEO,cAAcY,aAAa,4BAA6B,WACxD,MAAMM,aAAeZ,YAAYa,cAC7B,gCAAgCJ,iBACpCG,aAAaN,aAAa,4BAA6B,cACvDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,iBAAmBV,OAAQ,sBACjEc,aAAaL,YAAc,EAAAC,KAAAA,YAAU,UAAYC,YAAa,qBAClE,CACJ,CACA,MACA,IAAK,UACL,IAAK,SAAU,CACX,MAAMK,UAAuB,YAAXhB,OACZiB,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAehB,YAAYiB,UAAUC,SAASH,WAC9CI,WAAaL,UAAYM,eAAiBC,cAC1CC,OAASN,aAA4B,GAAbG,WAAkBA,WAQhD,SAPMhB,SAASF,OAAQqB,OAAQnC,QAO1BC,mBASG4B,eACAhB,YAAYiB,UAAUM,OAAOR,WAC7BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,OAAOV,SAAU,sBAC7D2B,cAAcV,UAAWjB,cAV7B,IAAK,MAAM4B,MAAMnC,KAAKoC,iBAAiB,uBAAyBZ,WAC5DW,GAAGT,UAAUM,OAAOR,WACpBW,GAAGb,cAAc,gCAAgCf,YAAY0B,kBACnD,EAAAhB,iBAAU,OAAOV,SAAU,sBAWxCkB,eACDhB,YAAYiB,UAAUW,IAAIb,WAC1BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,UAAUV,SAAU,sBAC5DV,oBACAqC,cAAcV,UAAWjB,QAIrC,GAIZ,EA7HA+B,MAAA9C,uBAAA8C,OACAC,UAAA/C,uBAAA+C,WAGA,MAAMnB,gBAAkB,EAClBD,cAAgB,EAChBL,uBAAyB,GACzBD,qBAAuB,GACvBiB,cAAgB,EAChBD,eAAiB,EAEjB7B,KAAOwC,SAASC,eAAe,uBASrCvC,eAAeU,SAASF,OAAQqB,OAAQnC,QACpC,MAAM8C,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACFpC,OAAQA,OACRqC,SAAUhB,WAEd,GAUJ,OATA/B,KAAKoC,iBAAiB,wCAAwCxC,YAAYoD,QAASC,IAC/EA,EAAEhB,YAAcS,SAASQ,kBAE7BlD,KAAKoC,iBAAiB,wCAAwCM,SAASS,aAAaH,QAASC,IACzFA,EAAEhB,YAAcS,SAASU,kBAE7BpD,KAAKoC,iBAAiB,wCAAwC1B,YAAYsC,QAASC,IAC/EA,EAAEhB,YAAcS,SAASW,aAEtBX,QACX,CA+FAxC,eAAegC,cAAcV,UAAWjB,QACpCT,UAAAA,QAASC,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,oBAGpD,IAAIuD,kBAAmB,EACvB,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,uBACnC,GAAID,GAAGT,UAAUC,SAASH,WAAY,CAClC8B,kBAAmB,EACnB,KACJ,CAGJ,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,wBAC9BD,GAAGT,UAAUC,SAASH,YAAcW,GAAGb,cAAc,gCAAgCf,cAElF4B,GAAGb,cAAc,gCAAgCf,YAAY0B,YAD7DqB,uBAEU,EAAArC,iBAAU,WAAWV,SAAU,4BAG/B,EAAAU,iBAAU,OAAOV,SAAU,sBAIrD,CAAC"}
\ No newline at end of file
+{"version":3,"file":"rating.min.js","sources":["../src/rating.js"],"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 * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if multiplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["userid","allowmultiplemarks","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","setAttribute","title","otherAction","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","rating","remove","textContent","changeStrings","el","querySelectorAll","add","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":";;;;;;;oFAsEqBA,OAAQC,sCAChBC,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,MAAAA,cACLC,cAAgBC,MAAMC,OAAOC,QAAQ,oCACtCH,2BAICI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,MAAAA,mBAAAA,YAAaD,aAAa,qCAEjCD,YACC,aACA,kBACKI,SAAsB,WAAXJ,UAC+C,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SA7Dd,GADE,GA8DsEd,QACjFM,cAAcU,aAAa,4BAA6B,cACxDV,cAAcW,YAAc,mBAAU,UAAYP,OAAQ,0BACvD,OACGQ,YAAcJ,SAAW,WAAa,eACtCC,SAASF,OAAQC,SApErB,EADE,EAqE+Dd,QACnEM,cAAcU,aAAa,4BAA6B,iBAClDG,aAAeP,YAAYQ,cAC5B,gCAA+BF,iBACpCC,aAAaH,aAAa,4BAA6B,cACvDV,cAAcW,YAAc,mBAAU,iBAAmBP,OAAQ,sBACjES,aAAaF,YAAc,mBAAU,UAAYC,YAAa,iCAIjE,cACA,gBACKG,UAAuB,YAAXX,OACZY,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAeX,YAAYY,UAAUC,SAASH,WAC9CI,WAAaL,UA/EZ,EADD,EAiFAM,OAASJ,aAA4B,GAAbG,WAAkBA,oBAC1CX,SAASF,OAAQc,OAAQ3B,QAO1BC,mBASGsB,eACAX,YAAYY,UAAUI,OAAON,WAC7BhB,cAAcuB,kBAAoB,mBAAW,OAAMnB,SAAU,sBAC7DoB,cAAcR,UAAWZ,kBAVxB,MAAMqB,MAAM5B,KAAK6B,iBAAiB,uBAAyBV,WAC5DS,GAAGP,UAAUI,OAAON,WACpBS,GAAGX,cAAe,gCAA+BV,YAAYmB,kBACnD,mBAAW,OAAMnB,SAAU,sBAWxCa,eACDX,YAAYY,UAAUS,IAAIX,WAC1BhB,cAAcuB,kBAAoB,mBAAW,UAASnB,SAAU,sBAC5DT,oBACA6B,cAAcR,UAAWZ,mGA1G3CP,KAAO+B,SAASC,eAAe,sCAStBpB,SAASF,OAAQc,OAAQ3B,cAC9BoC,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACF3B,OAAQA,OACR4B,SAAUd,WAEd,UACJxB,KAAK6B,iBAAkB,wCAAuChC,YAAY0C,SAASC,IAC/EA,EAAEd,YAAcO,SAASQ,mBAE7BzC,KAAK6B,iBAAkB,wCAAuCI,SAASS,aAAaH,SAASC,IACzFA,EAAEd,YAAcO,SAASU,mBAE7B3C,KAAK6B,iBAAkB,wCAAuCnB,YAAY6B,SAASC,IAC/EA,EAAEd,YAAcO,SAASW,cAEtBX,wBAgGIN,cAAcR,UAAWZ,0BAC3BR,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,wBAGhD8C,kBAAmB,MAClB,MAAMjB,MAAM5B,KAAK6B,iBAAiB,0BAC/BD,GAAGP,UAAUC,SAASH,WAAY,CAClC0B,kBAAmB,YAKtB,MAAMjB,MAAM5B,KAAK6B,iBAAiB,wBAC9BD,GAAGP,UAAUC,SAASH,YAAcS,GAAGX,cAAe,gCAA+BV,cAElFqB,GAAGX,cAAe,gCAA+BV,YAAYmB,YAD7DmB,uBAEU,mBAAW,WAAUtC,SAAU,4BAG/B,mBAAW,OAAMA,SAAU"}
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js b/amd/build/reviewing.min.js
index d027cc1635..59b05be5da 100644
--- a/amd/build/reviewing.min.js
+++ b/amd/build/reviewing.min.js
@@ -1,10 +1,10 @@
-define("mod_moodleoverflow/reviewing",["exports","core/ajax","core/prefetch","core/templates","core/str"],function(_exports,_ajax,_prefetch,_templates,_str){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
+define("mod_moodleoverflow/reviewing",["exports","core/ajax","core/prefetch","core/templates","core/str"],(function(_exports,_ajax,_prefetch,_templates,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
/**
* Implements reviewing functionality
*
* @module mod_moodleoverflow/reviewing
* @copyright 2022 Justus Dieckmann WWU
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){_prefetch.default.prefetchTemplates(["mod_moodleoverflow/reject_post_form","mod_moodleoverflow/review_buttons"]),_prefetch.default.prefetchStrings("mod_moodleoverflow",["post_was_approved","jump_to_next_post_needing_review","there_are_no_posts_needing_review","post_was_rejected"]);document.getElementById("moodleoverflow-posts").onclick=async e=>{const action=e.target.getAttribute("data-moodleoverflow-action");if(!action)return;const post=e.target.closest("*[data-moodleoverflow-postid]"),reviewRow=e.target.closest(".reviewrow"),postID=post.getAttribute("data-moodleoverflow-postid");if("approve"===action){reviewRow.innerHTML=".";const nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_approve_post",args:{postid:postID}}])[0];let message=await(0,_str.get_string)("post_was_approved","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message,post.classList.remove("pendingreview")}else if("reject"===action)reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/reject_post_form",{});else if("reject-submit"===action){const rejectMessage=post.querySelector("textarea.reject-reason").value.toString().trim();reviewRow.innerHTML=".";const args={postid:postID,reason:rejectMessage||null},nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_reject_post",args:args}])[0];let message=await(0,_str.get_string)("post_was_rejected","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message}else"reject-cancel"===action&&(reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/review_buttons",{}))}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch),_templates=_interopRequireDefault(_templates)});
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){_prefetch.default.prefetchTemplates(["mod_moodleoverflow/reject_post_form","mod_moodleoverflow/review_buttons"]),_prefetch.default.prefetchStrings("mod_moodleoverflow",["post_was_approved","jump_to_next_post_needing_review","there_are_no_posts_needing_review","post_was_rejected"]);document.getElementById("moodleoverflow-posts").onclick=async e=>{const action=e.target.getAttribute("data-moodleoverflow-action");if(!action)return;const post=e.target.closest("*[data-moodleoverflow-postid]"),reviewRow=e.target.closest(".reviewrow"),postID=post.getAttribute("data-moodleoverflow-postid");if("approve"===action){reviewRow.innerHTML=".";const nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_approve_post",args:{postid:postID}}])[0];let message=await(0,_str.get_string)("post_was_approved","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message,post.classList.remove("pendingreview")}else if("reject"===action)reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/reject_post_form",{});else if("reject-submit"===action){const rejectMessage=post.querySelector("textarea.reject-reason").value.toString().trim();reviewRow.innerHTML=".";const args={postid:postID,reason:rejectMessage||null},nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_reject_post",args:args}])[0];let message=await(0,_str.get_string)("post_was_rejected","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message}else"reject-cancel"===action&&(reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/review_buttons",{}))}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch),_templates=_interopRequireDefault(_templates)}));
//# sourceMappingURL=reviewing.min.js.map
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js.map b/amd/build/reviewing.min.js.map
index 9695518cff..b14cb0911d 100644
--- a/amd/build/reviewing.min.js.map
+++ b/amd/build/reviewing.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.js"],"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 * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","Prefetch","prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","getString","get_string","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason","_ajax","_prefetch","_templates"],"mappings":"6JAwBuC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAMhC,WACHG,UAAQD,QAACE,kBAAkB,CAAC,sCAAuC,sCACnED,UAAAA,QAASE,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,QAAUC,UACX,MAAMC,OAASV,EAAEW,OAAOC,aAAa,8BAErC,IAAKF,OACD,OAGJ,MAAMG,KAAOb,EAAEW,OAAOG,QAAQ,iCACxBC,UAAYf,EAAEW,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,8BAEjC,GAAe,YAAXF,OAAsB,CACtBK,UAAUE,UAAY,IACtB,MAAMC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,GAEJ,IAAIQ,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,QACtBX,KAAKc,UAAUC,OAAO,gBAC1B,MAAO,GAAe,WAAXlB,OACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,sCAAuC,CAAA,QACjF,GAAe,kBAAXpB,OAA4B,CACnC,MAAMqB,cAAgBlB,KAAKmB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFpB,UAAUE,UAAY,IACtB,MAAMK,KAAO,CACTC,OAAQP,OACRoB,OAAQL,eAAgC,MAEtCb,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,GAEJ,IAAIE,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,OAC1B,KAAsB,kBAAXd,SACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,oCAAqC,CAAA,IAG9F,EAzEAO,MAAAtC,uBAAAsC,OACAC,UAAAvC,uBAAAuC,WACAC,WAAAxC,uBAAAwC,WAuEC"}
\ No newline at end of file
+{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.js"],"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 * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","e","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason"],"mappings":";;;;;;;wGA+BaA,kBAAkB,CAAC,sCAAuC,wDAC1DC,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,QAAUC,MAAAA,UACLC,OAASC,EAAEC,OAAOC,aAAa,kCAEhCH,oBAICI,KAAOH,EAAEC,OAAOG,QAAQ,iCACxBC,UAAYL,EAAEC,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,iCAElB,YAAXH,OAAsB,CACtBM,UAAUE,UAAY,UAChBC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,OAEAQ,cAAgB,mBAAU,oBAAqB,sBAAwB,IAEvEA,SADAN,YACY,YAAWA,sBACX,mBAAU,mCAAoC,sBACpD,aAEW,mBAAU,oCAAqC,sBAEpEH,UAAUE,UAAYO,QACtBX,KAAKY,UAAUC,OAAO,sBACnB,GAAe,WAAXjB,OACPM,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBU,mBAAUC,OAAO,sCAAuC,SACjF,GAAe,kBAAXnB,OAA4B,OAC7BoB,cAAgBhB,KAAKiB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFlB,UAAUE,UAAY,UAChBK,KAAO,CACTC,OAAQP,OACRkB,OAAQL,eAAgC,MAEtCX,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,OAEAE,cAAgB,mBAAU,oBAAqB,sBAAwB,IAEvEA,SADAN,YACY,YAAWA,sBACX,mBAAU,mCAAoC,sBACpD,aAEW,mBAAU,oCAAqC,sBAEpEH,UAAUE,UAAYO,YACJ,kBAAXf,SACPM,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBU,mBAAUC,OAAO,oCAAqC"}
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js b/amd/build/warnmodechange.min.js
index 605c6f767f..5042ba704b 100644
--- a/amd/build/warnmodechange.min.js
+++ b/amd/build/warnmodechange.min.js
@@ -1,10 +1,10 @@
-define("mod_moodleoverflow/warnmodechange",["exports","core/str","core/notification","core/prefetch"],function(_exports,_str,_notification,_prefetch){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
+define("mod_moodleoverflow/warnmodechange",["exports","core/str","core/notification","core/prefetch"],(function(_exports,_str,_notification,_prefetch){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
/**
* Warns on changing the subscription mode.
*
* @module mod_moodleoverflow/warnmodechange
* @copyright 2022 Justus Dieckmann WWU
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(previousSetting){_prefetch.default.prefetchStrings("mod_moodleoverflow",["switchtooptional","switchtoauto"]),_prefetch.default.prefetchStrings("moodle",["confirm","cancel"]);const form=document.querySelector("form.mform"),select=document.getElementById("id_forcesubscribe");form.onsubmit=async e=>{const value=select.selectedOptions[0].value;value!=previousSetting&&1!=value&&3!=value&&(e.preventDefault(),await _notification.default.confirm(await(0,_str.get_string)("confirm"),await(0,_str.get_string)(0==value?"switchtooptional":"switchtoauto","mod_moodleoverflow"),await(0,_str.get_string)("confirm"),await(0,_str.get_string)("cancel"),()=>{form.onsubmit=void 0,form.requestSubmit(e.submitter)},void 0))}},_notification=_interopRequireDefault(_notification),_prefetch=_interopRequireDefault(_prefetch)});
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(previousSetting){_prefetch.default.prefetchStrings("mod_moodleoverflow",["switchtooptional","switchtoauto"]),_prefetch.default.prefetchStrings("moodle",["confirm","cancel"]);const form=document.querySelector("form.mform"),select=document.getElementById("id_forcesubscribe");form.onsubmit=async e=>{const value=select.selectedOptions[0].value;value!=previousSetting&&1!=value&&3!=value&&(e.preventDefault(),await _notification.default.confirm(await(0,_str.get_string)("confirm"),await(0,_str.get_string)(0==value?"switchtooptional":"switchtoauto","mod_moodleoverflow"),await(0,_str.get_string)("confirm"),await(0,_str.get_string)("cancel"),(()=>{form.onsubmit=void 0,form.requestSubmit(e.submitter)}),void 0))}},_notification=_interopRequireDefault(_notification),_prefetch=_interopRequireDefault(_prefetch)}));
//# sourceMappingURL=warnmodechange.min.js.map
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js.map b/amd/build/warnmodechange.min.js.map
index b205af0c40..70683e5540 100644
--- a/amd/build/warnmodechange.min.js.map
+++ b/amd/build/warnmodechange.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.js"],"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 * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","previousSetting","Prefetch","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","preventDefault","Notification","confirm","getString","undefined","requestSubmit","submitter","_notification","_prefetch"],"mappings":"sJAwBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAM9B,SAAcG,iBACjBC,UAAQF,QAACG,gBAAgB,qBAAsB,CAAC,mBAAoB,iBACpED,UAAQF,QAACG,gBAAgB,SAAU,CAAC,UAAW,WAC/C,MAAMC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,UACZ,MAAMC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAASV,iBAA4B,GAATU,OAAuB,GAATA,QAG9Cb,EAAEe,uBACIC,sBAAaC,cACT,EAAAC,iBAAU,iBACV,EAAAA,KAAAA,YAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,EAAAK,iBAAU,iBACV,EAAAA,KAAAA,YAAU,UAChB,KAEIZ,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcpB,EAAEqB,iBACtBF,IAEf,EA7BAG,cAAAvB,uBAAAuB,eACAC,UAAAxB,uBAAAwB,UA4BC"}
\ No newline at end of file
+{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.js"],"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 * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["previousSetting","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","e","preventDefault","Notification","confirm","undefined","requestSubmit","submitter"],"mappings":";;;;;;;oFA8BqBA,mCACRC,gBAAgB,qBAAsB,CAAC,mBAAoB,mCAC3DA,gBAAgB,SAAU,CAAC,UAAW,iBACzCC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,MAAAA,UACNC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAAST,iBAA4B,GAATS,OAAuB,GAATA,QAG9CE,EAAEC,uBACIC,sBAAaC,cACT,mBAAU,iBACV,mBAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,mBAAU,iBACV,mBAAU,WAChB,KAEIP,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcL,EAAEM,kBACtBF"}
\ No newline at end of file
From f44ff1174bd25ba734d1f813911d4f91c2830f12 Mon Sep 17 00:00:00 2001
From: Tamaro Walter
Date: Mon, 7 Jul 2025 20:12:24 +0200
Subject: [PATCH 48/56] WIP: rebuild min files
---
amd/build/activityhelp.min.js | 4 ++--
amd/build/activityhelp.min.js.map | 2 +-
amd/build/rating.min.js | 4 ++--
amd/build/rating.min.js.map | 2 +-
amd/build/reviewing.min.js | 4 ++--
amd/build/reviewing.min.js.map | 2 +-
amd/build/warnmodechange.min.js | 4 ++--
amd/build/warnmodechange.min.js.map | 2 +-
8 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/amd/build/activityhelp.min.js b/amd/build/activityhelp.min.js
index a875b70b82..4e6f2f9007 100644
--- a/amd/build/activityhelp.min.js
+++ b/amd/build/activityhelp.min.js
@@ -1,4 +1,4 @@
-define("mod_moodleoverflow/activityhelp",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;
+define("mod_moodleoverflow/activityhelp",["exports"],function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;
/**
* Show a help string for the amount of activity column in userstats_table.php
*
@@ -6,6 +6,6 @@ define("mod_moodleoverflow/activityhelp",["exports"],(function(_exports){Object.
* @copyright 2023 Tamaro Walter
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-const Selectors_actions={showHelpIcon:'[data-action="showhelpicon"]'};_exports.init=()=>{document.addEventListener("click",(event=>{event.target.closest(Selectors_actions.showHelpIcon)&&event.preventDefault()}))}}));
+const Selectors_actions={showHelpIcon:'[data-action="showhelpicon"]'};_exports.init=()=>{document.addEventListener("click",event=>{event.target.closest(Selectors_actions.showHelpIcon)&&event.preventDefault()})}});
//# sourceMappingURL=activityhelp.min.js.map
\ No newline at end of file
diff --git a/amd/build/activityhelp.min.js.map b/amd/build/activityhelp.min.js.map
index 2cdca4d1e4..1934ca29c6 100644
--- a/amd/build/activityhelp.min.js.map
+++ b/amd/build/activityhelp.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;MAyBMA,kBACO,CACLC,aAAc,8CAOF,KAChBC,SAASC,iBAAiB,SAASC,QAC3BA,MAAMC,OAAOC,QAAQN,kBAAkBC,eACvCG,MAAMG"}
\ No newline at end of file
+{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","_exports","init","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;AAyBA,MAAMA,kBACO,CACLC,aAAc,gCAapBC,SAAAC,KANkBA,KAChBC,SAASC,iBAAiB,QAASC,QAC3BA,MAAMC,OAAOC,QAAQR,kBAAkBC,eACvCK,MAAMG,mBAGhB"}
\ No newline at end of file
diff --git a/amd/build/rating.min.js b/amd/build/rating.min.js
index b70923c901..93a4db92d9 100644
--- a/amd/build/rating.min.js
+++ b/amd/build/rating.min.js
@@ -1,10 +1,10 @@
-define("mod_moodleoverflow/rating",["exports","core/ajax","core/prefetch","core/str"],(function(_exports,_ajax,_prefetch,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
+define("mod_moodleoverflow/rating",["exports","core/ajax","core/prefetch","core/str"],function(_exports,_ajax,_prefetch,_str){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
/**
* Implements rating functionality
*
* @module mod_moodleoverflow/rating
* @copyright 2022 Justus Dieckmann WWU
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(userid,allowmultiplemarks){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","marknotsolved","markhelpful","marknothelpful","action_remove_upvote","action_upvote","action_remove_downvote","action_downvote"]),root.onclick=async event=>{const actionElement=event.target.closest("[data-moodleoverflow-action]");if(!actionElement)return;const action=actionElement.getAttribute("data-moodleoverflow-action"),postElement=actionElement.closest("[data-moodleoverflow-postid]"),postid=null==postElement?void 0:postElement.getAttribute("data-moodleoverflow-postid");switch(action){case"upvote":case"downvote":{const isupvote="upvote"===action;if("clicked"===actionElement.getAttribute("data-moodleoverflow-state"))await sendVote(postid,isupvote?20:10,userid),actionElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_"+action,"mod_moodleoverflow");else{const otherAction=isupvote?"downvote":"upvote";await sendVote(postid,isupvote?2:1,userid),actionElement.setAttribute("data-moodleoverflow-state","clicked");const otherElement=postElement.querySelector(`[data-moodleoverflow-action="${otherAction}"]`);otherElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_remove_"+action,"mod_moodleoverflow"),otherElement.title=await(0,_str.get_string)("action_"+otherAction,"mod_moodleoverflow")}}break;case"helpful":case"solved":{const isHelpful="helpful"===action,htmlclass=isHelpful?"markedhelpful":"markedsolution",shouldRemove=postElement.classList.contains(htmlclass),baseRating=isHelpful?4:3,rating=shouldRemove?10*baseRating:baseRating;if(await sendVote(postid,rating,userid),allowmultiplemarks)shouldRemove&&(postElement.classList.remove(htmlclass),actionElement.textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"),changeStrings(htmlclass,action));else for(const el of root.querySelectorAll(".moodleoverflowpost."+htmlclass))el.classList.remove(htmlclass),el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow");shouldRemove||(postElement.classList.add(htmlclass),actionElement.textContent=await(0,_str.get_string)(`marknot${action}`,"mod_moodleoverflow"),allowmultiplemarks&&changeStrings(htmlclass,action))}}}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch);const root=document.getElementById("moodleoverflow-root");async function sendVote(postid,rating,userid){const response=await _ajax.default.call([{methodname:"mod_moodleoverflow_record_vote",args:{postid:postid,ratingid:rating}}])[0];return root.querySelectorAll(`[data-moodleoverflow-userreputation="${userid}"]`).forEach((i=>{i.textContent=response.raterreputation})),root.querySelectorAll(`[data-moodleoverflow-userreputation="${response.ownerid}"]`).forEach((i=>{i.textContent=response.ownerreputation})),root.querySelectorAll(`[data-moodleoverflow-postreputation="${postid}"]`).forEach((i=>{i.textContent=response.postrating})),response}async function changeStrings(htmlclass,action){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","alsomarksolved","markhelpful","alsomarkhelpful"]);var othermarkedposts=!1;for(const el of root.querySelectorAll(".moodleoverflowpost"))if(el.classList.contains(htmlclass)){othermarkedposts=!0;break}for(const el of root.querySelectorAll(".moodleoverflowpost"))!el.classList.contains(htmlclass)&&el.querySelector(`[data-moodleoverflow-action="${action}"]`)&&(el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=othermarkedposts?await(0,_str.get_string)(`alsomark${action}`,"mod_moodleoverflow"):await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"))}}));
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(userid,allowmultiplemarks){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","marknotsolved","markhelpful","marknothelpful","action_remove_upvote","action_upvote","action_remove_downvote","action_downvote"]),root.onclick=async event=>{const actionElement=event.target.closest("[data-moodleoverflow-action]");if(!actionElement)return;const action=actionElement.getAttribute("data-moodleoverflow-action"),postElement=actionElement.closest("[data-moodleoverflow-postid]"),postid=null==postElement?void 0:postElement.getAttribute("data-moodleoverflow-postid");switch(action){case"upvote":case"downvote":{const isupvote="upvote"===action;if("clicked"===actionElement.getAttribute("data-moodleoverflow-state"))await sendVote(postid,isupvote?RATING_REMOVE_UPVOTE:RATING_REMOVE_DOWNVOTE,userid),actionElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_"+action,"mod_moodleoverflow");else{const otherAction=isupvote?"downvote":"upvote";await sendVote(postid,isupvote?RATING_UPVOTE:RATING_DOWNVOTE,userid),actionElement.setAttribute("data-moodleoverflow-state","clicked");const otherElement=postElement.querySelector(`[data-moodleoverflow-action="${otherAction}"]`);otherElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_remove_"+action,"mod_moodleoverflow"),otherElement.title=await(0,_str.get_string)("action_"+otherAction,"mod_moodleoverflow")}}break;case"helpful":case"solved":{const isHelpful="helpful"===action,htmlclass=isHelpful?"markedhelpful":"markedsolution",shouldRemove=postElement.classList.contains(htmlclass),baseRating=isHelpful?RATING_HELPFUL:RATING_SOLVED,rating=shouldRemove?10*baseRating:baseRating;if(await sendVote(postid,rating,userid),allowmultiplemarks)shouldRemove&&(postElement.classList.remove(htmlclass),actionElement.textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"),changeStrings(htmlclass,action));else for(const el of root.querySelectorAll(".moodleoverflowpost."+htmlclass))el.classList.remove(htmlclass),el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow");shouldRemove||(postElement.classList.add(htmlclass),actionElement.textContent=await(0,_str.get_string)(`marknot${action}`,"mod_moodleoverflow"),allowmultiplemarks&&changeStrings(htmlclass,action))}}}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch);const RATING_DOWNVOTE=1,RATING_UPVOTE=2,RATING_REMOVE_DOWNVOTE=10,RATING_REMOVE_UPVOTE=20,RATING_SOLVED=3,RATING_HELPFUL=4,root=document.getElementById("moodleoverflow-root");async function sendVote(postid,rating,userid){const response=await _ajax.default.call([{methodname:"mod_moodleoverflow_record_vote",args:{postid:postid,ratingid:rating}}])[0];return root.querySelectorAll(`[data-moodleoverflow-userreputation="${userid}"]`).forEach(i=>{i.textContent=response.raterreputation}),root.querySelectorAll(`[data-moodleoverflow-userreputation="${response.ownerid}"]`).forEach(i=>{i.textContent=response.ownerreputation}),root.querySelectorAll(`[data-moodleoverflow-postreputation="${postid}"]`).forEach(i=>{i.textContent=response.postrating}),response}async function changeStrings(htmlclass,action){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","alsomarksolved","markhelpful","alsomarkhelpful"]);var othermarkedposts=!1;for(const el of root.querySelectorAll(".moodleoverflowpost"))if(el.classList.contains(htmlclass)){othermarkedposts=!0;break}for(const el of root.querySelectorAll(".moodleoverflowpost"))!el.classList.contains(htmlclass)&&el.querySelector(`[data-moodleoverflow-action="${action}"]`)&&(el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=othermarkedposts?await(0,_str.get_string)(`alsomark${action}`,"mod_moodleoverflow"):await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"))}});
//# sourceMappingURL=rating.min.js.map
\ No newline at end of file
diff --git a/amd/build/rating.min.js.map b/amd/build/rating.min.js.map
index 0c1d368bbd..64af28a834 100644
--- a/amd/build/rating.min.js.map
+++ b/amd/build/rating.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"rating.min.js","sources":["../src/rating.js"],"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 * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if multiplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["userid","allowmultiplemarks","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","setAttribute","title","otherAction","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","rating","remove","textContent","changeStrings","el","querySelectorAll","add","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":";;;;;;;oFAsEqBA,OAAQC,sCAChBC,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,MAAAA,cACLC,cAAgBC,MAAMC,OAAOC,QAAQ,oCACtCH,2BAICI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,MAAAA,mBAAAA,YAAaD,aAAa,qCAEjCD,YACC,aACA,kBACKI,SAAsB,WAAXJ,UAC+C,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SA7Dd,GADE,GA8DsEd,QACjFM,cAAcU,aAAa,4BAA6B,cACxDV,cAAcW,YAAc,mBAAU,UAAYP,OAAQ,0BACvD,OACGQ,YAAcJ,SAAW,WAAa,eACtCC,SAASF,OAAQC,SApErB,EADE,EAqE+Dd,QACnEM,cAAcU,aAAa,4BAA6B,iBAClDG,aAAeP,YAAYQ,cAC5B,gCAA+BF,iBACpCC,aAAaH,aAAa,4BAA6B,cACvDV,cAAcW,YAAc,mBAAU,iBAAmBP,OAAQ,sBACjES,aAAaF,YAAc,mBAAU,UAAYC,YAAa,iCAIjE,cACA,gBACKG,UAAuB,YAAXX,OACZY,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAeX,YAAYY,UAAUC,SAASH,WAC9CI,WAAaL,UA/EZ,EADD,EAiFAM,OAASJ,aAA4B,GAAbG,WAAkBA,oBAC1CX,SAASF,OAAQc,OAAQ3B,QAO1BC,mBASGsB,eACAX,YAAYY,UAAUI,OAAON,WAC7BhB,cAAcuB,kBAAoB,mBAAW,OAAMnB,SAAU,sBAC7DoB,cAAcR,UAAWZ,kBAVxB,MAAMqB,MAAM5B,KAAK6B,iBAAiB,uBAAyBV,WAC5DS,GAAGP,UAAUI,OAAON,WACpBS,GAAGX,cAAe,gCAA+BV,YAAYmB,kBACnD,mBAAW,OAAMnB,SAAU,sBAWxCa,eACDX,YAAYY,UAAUS,IAAIX,WAC1BhB,cAAcuB,kBAAoB,mBAAW,UAASnB,SAAU,sBAC5DT,oBACA6B,cAAcR,UAAWZ,mGA1G3CP,KAAO+B,SAASC,eAAe,sCAStBpB,SAASF,OAAQc,OAAQ3B,cAC9BoC,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACF3B,OAAQA,OACR4B,SAAUd,WAEd,UACJxB,KAAK6B,iBAAkB,wCAAuChC,YAAY0C,SAASC,IAC/EA,EAAEd,YAAcO,SAASQ,mBAE7BzC,KAAK6B,iBAAkB,wCAAuCI,SAASS,aAAaH,SAASC,IACzFA,EAAEd,YAAcO,SAASU,mBAE7B3C,KAAK6B,iBAAkB,wCAAuCnB,YAAY6B,SAASC,IAC/EA,EAAEd,YAAcO,SAASW,cAEtBX,wBAgGIN,cAAcR,UAAWZ,0BAC3BR,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,wBAGhD8C,kBAAmB,MAClB,MAAMjB,MAAM5B,KAAK6B,iBAAiB,0BAC/BD,GAAGP,UAAUC,SAASH,WAAY,CAClC0B,kBAAmB,YAKtB,MAAMjB,MAAM5B,KAAK6B,iBAAiB,wBAC9BD,GAAGP,UAAUC,SAASH,YAAcS,GAAGX,cAAe,gCAA+BV,cAElFqB,GAAGX,cAAe,gCAA+BV,YAAYmB,YAD7DmB,uBAEU,mBAAW,WAAUtC,SAAU,4BAG/B,mBAAW,OAAMA,SAAU"}
\ No newline at end of file
+{"version":3,"file":"rating.min.js","sources":["../src/rating.js"],"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 * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if multiplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["_interopRequireDefault","e","__esModule","default","userid","allowmultiplemarks","Prefetch","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","RATING_REMOVE_UPVOTE","RATING_REMOVE_DOWNVOTE","setAttribute","title","getString","otherAction","RATING_UPVOTE","RATING_DOWNVOTE","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","RATING_HELPFUL","RATING_SOLVED","rating","remove","textContent","changeStrings","el","querySelectorAll","add","_ajax","_prefetch","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":"8HAuBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EA+C9B,SAAcG,OAAQC,oBACzBC,UAAQH,QAACI,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,cACX,MAAMC,cAAgBC,MAAMC,OAAOC,QAAQ,gCAC3C,IAAKH,cACD,OAGJ,MAAMI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,uBAAAA,EAAAA,YAAaD,aAAa,8BAEzC,OAAQD,QACJ,IAAK,SACL,IAAK,WAAY,CACb,MAAMI,SAAsB,WAAXJ,OACjB,GAAgE,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SAAWE,qBAAuBC,uBAAwBlB,QACjFO,cAAcY,aAAa,4BAA6B,cACxDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,UAAYV,OAAQ,0BACvD,CACH,MAAMW,YAAcP,SAAW,WAAa,eACtCC,SAASF,OAAQC,SAAWQ,cAAgBC,gBAAiBxB,QACnEO,cAAcY,aAAa,4BAA6B,WACxD,MAAMM,aAAeZ,YAAYa,cAC7B,gCAAgCJ,iBACpCG,aAAaN,aAAa,4BAA6B,cACvDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,iBAAmBV,OAAQ,sBACjEc,aAAaL,YAAc,EAAAC,KAAAA,YAAU,UAAYC,YAAa,qBAClE,CACJ,CACA,MACA,IAAK,UACL,IAAK,SAAU,CACX,MAAMK,UAAuB,YAAXhB,OACZiB,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAehB,YAAYiB,UAAUC,SAASH,WAC9CI,WAAaL,UAAYM,eAAiBC,cAC1CC,OAASN,aAA4B,GAAbG,WAAkBA,WAQhD,SAPMhB,SAASF,OAAQqB,OAAQnC,QAO1BC,mBASG4B,eACAhB,YAAYiB,UAAUM,OAAOR,WAC7BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,OAAOV,SAAU,sBAC7D2B,cAAcV,UAAWjB,cAV7B,IAAK,MAAM4B,MAAMnC,KAAKoC,iBAAiB,uBAAyBZ,WAC5DW,GAAGT,UAAUM,OAAOR,WACpBW,GAAGb,cAAc,gCAAgCf,YAAY0B,kBACnD,EAAAhB,iBAAU,OAAOV,SAAU,sBAWxCkB,eACDhB,YAAYiB,UAAUW,IAAIb,WAC1BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,UAAUV,SAAU,sBAC5DV,oBACAqC,cAAcV,UAAWjB,QAIrC,GAIZ,EA7HA+B,MAAA9C,uBAAA8C,OACAC,UAAA/C,uBAAA+C,WAGA,MAAMnB,gBAAkB,EAClBD,cAAgB,EAChBL,uBAAyB,GACzBD,qBAAuB,GACvBiB,cAAgB,EAChBD,eAAiB,EAEjB7B,KAAOwC,SAASC,eAAe,uBASrCvC,eAAeU,SAASF,OAAQqB,OAAQnC,QACpC,MAAM8C,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACFpC,OAAQA,OACRqC,SAAUhB,WAEd,GAUJ,OATA/B,KAAKoC,iBAAiB,wCAAwCxC,YAAYoD,QAASC,IAC/EA,EAAEhB,YAAcS,SAASQ,kBAE7BlD,KAAKoC,iBAAiB,wCAAwCM,SAASS,aAAaH,QAASC,IACzFA,EAAEhB,YAAcS,SAASU,kBAE7BpD,KAAKoC,iBAAiB,wCAAwC1B,YAAYsC,QAASC,IAC/EA,EAAEhB,YAAcS,SAASW,aAEtBX,QACX,CA+FAxC,eAAegC,cAAcV,UAAWjB,QACpCT,UAAAA,QAASC,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,oBAGpD,IAAIuD,kBAAmB,EACvB,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,uBACnC,GAAID,GAAGT,UAAUC,SAASH,WAAY,CAClC8B,kBAAmB,EACnB,KACJ,CAGJ,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,wBAC9BD,GAAGT,UAAUC,SAASH,YAAcW,GAAGb,cAAc,gCAAgCf,cAElF4B,GAAGb,cAAc,gCAAgCf,YAAY0B,YAD7DqB,uBAEU,EAAArC,iBAAU,WAAWV,SAAU,4BAG/B,EAAAU,iBAAU,OAAOV,SAAU,sBAIrD,CAAC"}
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js b/amd/build/reviewing.min.js
index 59b05be5da..d027cc1635 100644
--- a/amd/build/reviewing.min.js
+++ b/amd/build/reviewing.min.js
@@ -1,10 +1,10 @@
-define("mod_moodleoverflow/reviewing",["exports","core/ajax","core/prefetch","core/templates","core/str"],(function(_exports,_ajax,_prefetch,_templates,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
+define("mod_moodleoverflow/reviewing",["exports","core/ajax","core/prefetch","core/templates","core/str"],function(_exports,_ajax,_prefetch,_templates,_str){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
/**
* Implements reviewing functionality
*
* @module mod_moodleoverflow/reviewing
* @copyright 2022 Justus Dieckmann WWU
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){_prefetch.default.prefetchTemplates(["mod_moodleoverflow/reject_post_form","mod_moodleoverflow/review_buttons"]),_prefetch.default.prefetchStrings("mod_moodleoverflow",["post_was_approved","jump_to_next_post_needing_review","there_are_no_posts_needing_review","post_was_rejected"]);document.getElementById("moodleoverflow-posts").onclick=async e=>{const action=e.target.getAttribute("data-moodleoverflow-action");if(!action)return;const post=e.target.closest("*[data-moodleoverflow-postid]"),reviewRow=e.target.closest(".reviewrow"),postID=post.getAttribute("data-moodleoverflow-postid");if("approve"===action){reviewRow.innerHTML=".";const nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_approve_post",args:{postid:postID}}])[0];let message=await(0,_str.get_string)("post_was_approved","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message,post.classList.remove("pendingreview")}else if("reject"===action)reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/reject_post_form",{});else if("reject-submit"===action){const rejectMessage=post.querySelector("textarea.reject-reason").value.toString().trim();reviewRow.innerHTML=".";const args={postid:postID,reason:rejectMessage||null},nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_reject_post",args:args}])[0];let message=await(0,_str.get_string)("post_was_rejected","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message}else"reject-cancel"===action&&(reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/review_buttons",{}))}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch),_templates=_interopRequireDefault(_templates)}));
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){_prefetch.default.prefetchTemplates(["mod_moodleoverflow/reject_post_form","mod_moodleoverflow/review_buttons"]),_prefetch.default.prefetchStrings("mod_moodleoverflow",["post_was_approved","jump_to_next_post_needing_review","there_are_no_posts_needing_review","post_was_rejected"]);document.getElementById("moodleoverflow-posts").onclick=async e=>{const action=e.target.getAttribute("data-moodleoverflow-action");if(!action)return;const post=e.target.closest("*[data-moodleoverflow-postid]"),reviewRow=e.target.closest(".reviewrow"),postID=post.getAttribute("data-moodleoverflow-postid");if("approve"===action){reviewRow.innerHTML=".";const nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_approve_post",args:{postid:postID}}])[0];let message=await(0,_str.get_string)("post_was_approved","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message,post.classList.remove("pendingreview")}else if("reject"===action)reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/reject_post_form",{});else if("reject-submit"===action){const rejectMessage=post.querySelector("textarea.reject-reason").value.toString().trim();reviewRow.innerHTML=".";const args={postid:postID,reason:rejectMessage||null},nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_reject_post",args:args}])[0];let message=await(0,_str.get_string)("post_was_rejected","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message}else"reject-cancel"===action&&(reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/review_buttons",{}))}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch),_templates=_interopRequireDefault(_templates)});
//# sourceMappingURL=reviewing.min.js.map
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js.map b/amd/build/reviewing.min.js.map
index b14cb0911d..9695518cff 100644
--- a/amd/build/reviewing.min.js.map
+++ b/amd/build/reviewing.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.js"],"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 * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","e","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason"],"mappings":";;;;;;;wGA+BaA,kBAAkB,CAAC,sCAAuC,wDAC1DC,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,QAAUC,MAAAA,UACLC,OAASC,EAAEC,OAAOC,aAAa,kCAEhCH,oBAICI,KAAOH,EAAEC,OAAOG,QAAQ,iCACxBC,UAAYL,EAAEC,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,iCAElB,YAAXH,OAAsB,CACtBM,UAAUE,UAAY,UAChBC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,OAEAQ,cAAgB,mBAAU,oBAAqB,sBAAwB,IAEvEA,SADAN,YACY,YAAWA,sBACX,mBAAU,mCAAoC,sBACpD,aAEW,mBAAU,oCAAqC,sBAEpEH,UAAUE,UAAYO,QACtBX,KAAKY,UAAUC,OAAO,sBACnB,GAAe,WAAXjB,OACPM,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBU,mBAAUC,OAAO,sCAAuC,SACjF,GAAe,kBAAXnB,OAA4B,OAC7BoB,cAAgBhB,KAAKiB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFlB,UAAUE,UAAY,UAChBK,KAAO,CACTC,OAAQP,OACRkB,OAAQL,eAAgC,MAEtCX,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,OAEAE,cAAgB,mBAAU,oBAAqB,sBAAwB,IAEvEA,SADAN,YACY,YAAWA,sBACX,mBAAU,mCAAoC,sBACpD,aAEW,mBAAU,oCAAqC,sBAEpEH,UAAUE,UAAYO,YACJ,kBAAXf,SACPM,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBU,mBAAUC,OAAO,oCAAqC"}
\ No newline at end of file
+{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.js"],"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 * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","Prefetch","prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","getString","get_string","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason","_ajax","_prefetch","_templates"],"mappings":"6JAwBuC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAMhC,WACHG,UAAQD,QAACE,kBAAkB,CAAC,sCAAuC,sCACnED,UAAAA,QAASE,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,QAAUC,UACX,MAAMC,OAASV,EAAEW,OAAOC,aAAa,8BAErC,IAAKF,OACD,OAGJ,MAAMG,KAAOb,EAAEW,OAAOG,QAAQ,iCACxBC,UAAYf,EAAEW,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,8BAEjC,GAAe,YAAXF,OAAsB,CACtBK,UAAUE,UAAY,IACtB,MAAMC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,GAEJ,IAAIQ,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,QACtBX,KAAKc,UAAUC,OAAO,gBAC1B,MAAO,GAAe,WAAXlB,OACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,sCAAuC,CAAA,QACjF,GAAe,kBAAXpB,OAA4B,CACnC,MAAMqB,cAAgBlB,KAAKmB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFpB,UAAUE,UAAY,IACtB,MAAMK,KAAO,CACTC,OAAQP,OACRoB,OAAQL,eAAgC,MAEtCb,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,GAEJ,IAAIE,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,OAC1B,KAAsB,kBAAXd,SACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,oCAAqC,CAAA,IAG9F,EAzEAO,MAAAtC,uBAAAsC,OACAC,UAAAvC,uBAAAuC,WACAC,WAAAxC,uBAAAwC,WAuEC"}
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js b/amd/build/warnmodechange.min.js
index 5042ba704b..605c6f767f 100644
--- a/amd/build/warnmodechange.min.js
+++ b/amd/build/warnmodechange.min.js
@@ -1,10 +1,10 @@
-define("mod_moodleoverflow/warnmodechange",["exports","core/str","core/notification","core/prefetch"],(function(_exports,_str,_notification,_prefetch){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}
+define("mod_moodleoverflow/warnmodechange",["exports","core/str","core/notification","core/prefetch"],function(_exports,_str,_notification,_prefetch){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
/**
* Warns on changing the subscription mode.
*
* @module mod_moodleoverflow/warnmodechange
* @copyright 2022 Justus Dieckmann WWU
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(previousSetting){_prefetch.default.prefetchStrings("mod_moodleoverflow",["switchtooptional","switchtoauto"]),_prefetch.default.prefetchStrings("moodle",["confirm","cancel"]);const form=document.querySelector("form.mform"),select=document.getElementById("id_forcesubscribe");form.onsubmit=async e=>{const value=select.selectedOptions[0].value;value!=previousSetting&&1!=value&&3!=value&&(e.preventDefault(),await _notification.default.confirm(await(0,_str.get_string)("confirm"),await(0,_str.get_string)(0==value?"switchtooptional":"switchtoauto","mod_moodleoverflow"),await(0,_str.get_string)("confirm"),await(0,_str.get_string)("cancel"),(()=>{form.onsubmit=void 0,form.requestSubmit(e.submitter)}),void 0))}},_notification=_interopRequireDefault(_notification),_prefetch=_interopRequireDefault(_prefetch)}));
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(previousSetting){_prefetch.default.prefetchStrings("mod_moodleoverflow",["switchtooptional","switchtoauto"]),_prefetch.default.prefetchStrings("moodle",["confirm","cancel"]);const form=document.querySelector("form.mform"),select=document.getElementById("id_forcesubscribe");form.onsubmit=async e=>{const value=select.selectedOptions[0].value;value!=previousSetting&&1!=value&&3!=value&&(e.preventDefault(),await _notification.default.confirm(await(0,_str.get_string)("confirm"),await(0,_str.get_string)(0==value?"switchtooptional":"switchtoauto","mod_moodleoverflow"),await(0,_str.get_string)("confirm"),await(0,_str.get_string)("cancel"),()=>{form.onsubmit=void 0,form.requestSubmit(e.submitter)},void 0))}},_notification=_interopRequireDefault(_notification),_prefetch=_interopRequireDefault(_prefetch)});
//# sourceMappingURL=warnmodechange.min.js.map
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js.map b/amd/build/warnmodechange.min.js.map
index 70683e5540..b205af0c40 100644
--- a/amd/build/warnmodechange.min.js.map
+++ b/amd/build/warnmodechange.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.js"],"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 * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["previousSetting","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","e","preventDefault","Notification","confirm","undefined","requestSubmit","submitter"],"mappings":";;;;;;;oFA8BqBA,mCACRC,gBAAgB,qBAAsB,CAAC,mBAAoB,mCAC3DA,gBAAgB,SAAU,CAAC,UAAW,iBACzCC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,MAAAA,UACNC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAAST,iBAA4B,GAATS,OAAuB,GAATA,QAG9CE,EAAEC,uBACIC,sBAAaC,cACT,mBAAU,iBACV,mBAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,mBAAU,iBACV,mBAAU,WAChB,KAEIP,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcL,EAAEM,kBACtBF"}
\ No newline at end of file
+{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.js"],"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 * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","previousSetting","Prefetch","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","preventDefault","Notification","confirm","getString","undefined","requestSubmit","submitter","_notification","_prefetch"],"mappings":"sJAwBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAM9B,SAAcG,iBACjBC,UAAQF,QAACG,gBAAgB,qBAAsB,CAAC,mBAAoB,iBACpED,UAAQF,QAACG,gBAAgB,SAAU,CAAC,UAAW,WAC/C,MAAMC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,UACZ,MAAMC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAASV,iBAA4B,GAATU,OAAuB,GAATA,QAG9Cb,EAAEe,uBACIC,sBAAaC,cACT,EAAAC,iBAAU,iBACV,EAAAA,KAAAA,YAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,EAAAK,iBAAU,iBACV,EAAAA,KAAAA,YAAU,UAChB,KAEIZ,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcpB,EAAEqB,iBACtBF,IAEf,EA7BAG,cAAAvB,uBAAAuB,eACAC,UAAAxB,uBAAAwB,UA4BC"}
\ No newline at end of file
From c297e610c61cc5c7df6d06798a6b01596c371424 Mon Sep 17 00:00:00 2001
From: Tamaro Walter
Date: Mon, 7 Jul 2025 20:23:01 +0200
Subject: [PATCH 49/56] remove old builds
---
amd/build/activityhelp.min.js | 11 -----------
amd/build/activityhelp.min.js.map | 1 -
amd/build/rating.min.js | 10 ----------
amd/build/rating.min.js.map | 1 -
amd/build/reviewing.min.js | 10 ----------
amd/build/reviewing.min.js.map | 1 -
amd/build/warnmodechange.min.js | 10 ----------
amd/build/warnmodechange.min.js.map | 1 -
8 files changed, 45 deletions(-)
delete mode 100644 amd/build/activityhelp.min.js
delete mode 100644 amd/build/activityhelp.min.js.map
delete mode 100644 amd/build/rating.min.js
delete mode 100644 amd/build/rating.min.js.map
delete mode 100644 amd/build/reviewing.min.js
delete mode 100644 amd/build/reviewing.min.js.map
delete mode 100644 amd/build/warnmodechange.min.js
delete mode 100644 amd/build/warnmodechange.min.js.map
diff --git a/amd/build/activityhelp.min.js b/amd/build/activityhelp.min.js
deleted file mode 100644
index 4e6f2f9007..0000000000
--- a/amd/build/activityhelp.min.js
+++ /dev/null
@@ -1,11 +0,0 @@
-define("mod_moodleoverflow/activityhelp",["exports"],function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;
-/**
- * Show a help string for the amount of activity column in userstats_table.php
- *
- * @module mod_moodleoverflow/activityhelp
- * @copyright 2023 Tamaro Walter
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-const Selectors_actions={showHelpIcon:'[data-action="showhelpicon"]'};_exports.init=()=>{document.addEventListener("click",event=>{event.target.closest(Selectors_actions.showHelpIcon)&&event.preventDefault()})}});
-
-//# sourceMappingURL=activityhelp.min.js.map
\ No newline at end of file
diff --git a/amd/build/activityhelp.min.js.map b/amd/build/activityhelp.min.js.map
deleted file mode 100644
index 1934ca29c6..0000000000
--- a/amd/build/activityhelp.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","_exports","init","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;AAyBA,MAAMA,kBACO,CACLC,aAAc,gCAapBC,SAAAC,KANkBA,KAChBC,SAASC,iBAAiB,QAASC,QAC3BA,MAAMC,OAAOC,QAAQR,kBAAkBC,eACvCK,MAAMG,mBAGhB"}
\ No newline at end of file
diff --git a/amd/build/rating.min.js b/amd/build/rating.min.js
deleted file mode 100644
index 93a4db92d9..0000000000
--- a/amd/build/rating.min.js
+++ /dev/null
@@ -1,10 +0,0 @@
-define("mod_moodleoverflow/rating",["exports","core/ajax","core/prefetch","core/str"],function(_exports,_ajax,_prefetch,_str){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
-/**
- * Implements rating functionality
- *
- * @module mod_moodleoverflow/rating
- * @copyright 2022 Justus Dieckmann WWU
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(userid,allowmultiplemarks){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","marknotsolved","markhelpful","marknothelpful","action_remove_upvote","action_upvote","action_remove_downvote","action_downvote"]),root.onclick=async event=>{const actionElement=event.target.closest("[data-moodleoverflow-action]");if(!actionElement)return;const action=actionElement.getAttribute("data-moodleoverflow-action"),postElement=actionElement.closest("[data-moodleoverflow-postid]"),postid=null==postElement?void 0:postElement.getAttribute("data-moodleoverflow-postid");switch(action){case"upvote":case"downvote":{const isupvote="upvote"===action;if("clicked"===actionElement.getAttribute("data-moodleoverflow-state"))await sendVote(postid,isupvote?RATING_REMOVE_UPVOTE:RATING_REMOVE_DOWNVOTE,userid),actionElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_"+action,"mod_moodleoverflow");else{const otherAction=isupvote?"downvote":"upvote";await sendVote(postid,isupvote?RATING_UPVOTE:RATING_DOWNVOTE,userid),actionElement.setAttribute("data-moodleoverflow-state","clicked");const otherElement=postElement.querySelector(`[data-moodleoverflow-action="${otherAction}"]`);otherElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_remove_"+action,"mod_moodleoverflow"),otherElement.title=await(0,_str.get_string)("action_"+otherAction,"mod_moodleoverflow")}}break;case"helpful":case"solved":{const isHelpful="helpful"===action,htmlclass=isHelpful?"markedhelpful":"markedsolution",shouldRemove=postElement.classList.contains(htmlclass),baseRating=isHelpful?RATING_HELPFUL:RATING_SOLVED,rating=shouldRemove?10*baseRating:baseRating;if(await sendVote(postid,rating,userid),allowmultiplemarks)shouldRemove&&(postElement.classList.remove(htmlclass),actionElement.textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"),changeStrings(htmlclass,action));else for(const el of root.querySelectorAll(".moodleoverflowpost."+htmlclass))el.classList.remove(htmlclass),el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow");shouldRemove||(postElement.classList.add(htmlclass),actionElement.textContent=await(0,_str.get_string)(`marknot${action}`,"mod_moodleoverflow"),allowmultiplemarks&&changeStrings(htmlclass,action))}}}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch);const RATING_DOWNVOTE=1,RATING_UPVOTE=2,RATING_REMOVE_DOWNVOTE=10,RATING_REMOVE_UPVOTE=20,RATING_SOLVED=3,RATING_HELPFUL=4,root=document.getElementById("moodleoverflow-root");async function sendVote(postid,rating,userid){const response=await _ajax.default.call([{methodname:"mod_moodleoverflow_record_vote",args:{postid:postid,ratingid:rating}}])[0];return root.querySelectorAll(`[data-moodleoverflow-userreputation="${userid}"]`).forEach(i=>{i.textContent=response.raterreputation}),root.querySelectorAll(`[data-moodleoverflow-userreputation="${response.ownerid}"]`).forEach(i=>{i.textContent=response.ownerreputation}),root.querySelectorAll(`[data-moodleoverflow-postreputation="${postid}"]`).forEach(i=>{i.textContent=response.postrating}),response}async function changeStrings(htmlclass,action){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","alsomarksolved","markhelpful","alsomarkhelpful"]);var othermarkedposts=!1;for(const el of root.querySelectorAll(".moodleoverflowpost"))if(el.classList.contains(htmlclass)){othermarkedposts=!0;break}for(const el of root.querySelectorAll(".moodleoverflowpost"))!el.classList.contains(htmlclass)&&el.querySelector(`[data-moodleoverflow-action="${action}"]`)&&(el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=othermarkedposts?await(0,_str.get_string)(`alsomark${action}`,"mod_moodleoverflow"):await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"))}});
-
-//# sourceMappingURL=rating.min.js.map
\ No newline at end of file
diff --git a/amd/build/rating.min.js.map b/amd/build/rating.min.js.map
deleted file mode 100644
index 64af28a834..0000000000
--- a/amd/build/rating.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"rating.min.js","sources":["../src/rating.js"],"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 * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if multiplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["_interopRequireDefault","e","__esModule","default","userid","allowmultiplemarks","Prefetch","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","RATING_REMOVE_UPVOTE","RATING_REMOVE_DOWNVOTE","setAttribute","title","getString","otherAction","RATING_UPVOTE","RATING_DOWNVOTE","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","RATING_HELPFUL","RATING_SOLVED","rating","remove","textContent","changeStrings","el","querySelectorAll","add","_ajax","_prefetch","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":"8HAuBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EA+C9B,SAAcG,OAAQC,oBACzBC,UAAQH,QAACI,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,cACX,MAAMC,cAAgBC,MAAMC,OAAOC,QAAQ,gCAC3C,IAAKH,cACD,OAGJ,MAAMI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,uBAAAA,EAAAA,YAAaD,aAAa,8BAEzC,OAAQD,QACJ,IAAK,SACL,IAAK,WAAY,CACb,MAAMI,SAAsB,WAAXJ,OACjB,GAAgE,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SAAWE,qBAAuBC,uBAAwBlB,QACjFO,cAAcY,aAAa,4BAA6B,cACxDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,UAAYV,OAAQ,0BACvD,CACH,MAAMW,YAAcP,SAAW,WAAa,eACtCC,SAASF,OAAQC,SAAWQ,cAAgBC,gBAAiBxB,QACnEO,cAAcY,aAAa,4BAA6B,WACxD,MAAMM,aAAeZ,YAAYa,cAC7B,gCAAgCJ,iBACpCG,aAAaN,aAAa,4BAA6B,cACvDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,iBAAmBV,OAAQ,sBACjEc,aAAaL,YAAc,EAAAC,KAAAA,YAAU,UAAYC,YAAa,qBAClE,CACJ,CACA,MACA,IAAK,UACL,IAAK,SAAU,CACX,MAAMK,UAAuB,YAAXhB,OACZiB,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAehB,YAAYiB,UAAUC,SAASH,WAC9CI,WAAaL,UAAYM,eAAiBC,cAC1CC,OAASN,aAA4B,GAAbG,WAAkBA,WAQhD,SAPMhB,SAASF,OAAQqB,OAAQnC,QAO1BC,mBASG4B,eACAhB,YAAYiB,UAAUM,OAAOR,WAC7BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,OAAOV,SAAU,sBAC7D2B,cAAcV,UAAWjB,cAV7B,IAAK,MAAM4B,MAAMnC,KAAKoC,iBAAiB,uBAAyBZ,WAC5DW,GAAGT,UAAUM,OAAOR,WACpBW,GAAGb,cAAc,gCAAgCf,YAAY0B,kBACnD,EAAAhB,iBAAU,OAAOV,SAAU,sBAWxCkB,eACDhB,YAAYiB,UAAUW,IAAIb,WAC1BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,UAAUV,SAAU,sBAC5DV,oBACAqC,cAAcV,UAAWjB,QAIrC,GAIZ,EA7HA+B,MAAA9C,uBAAA8C,OACAC,UAAA/C,uBAAA+C,WAGA,MAAMnB,gBAAkB,EAClBD,cAAgB,EAChBL,uBAAyB,GACzBD,qBAAuB,GACvBiB,cAAgB,EAChBD,eAAiB,EAEjB7B,KAAOwC,SAASC,eAAe,uBASrCvC,eAAeU,SAASF,OAAQqB,OAAQnC,QACpC,MAAM8C,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACFpC,OAAQA,OACRqC,SAAUhB,WAEd,GAUJ,OATA/B,KAAKoC,iBAAiB,wCAAwCxC,YAAYoD,QAASC,IAC/EA,EAAEhB,YAAcS,SAASQ,kBAE7BlD,KAAKoC,iBAAiB,wCAAwCM,SAASS,aAAaH,QAASC,IACzFA,EAAEhB,YAAcS,SAASU,kBAE7BpD,KAAKoC,iBAAiB,wCAAwC1B,YAAYsC,QAASC,IAC/EA,EAAEhB,YAAcS,SAASW,aAEtBX,QACX,CA+FAxC,eAAegC,cAAcV,UAAWjB,QACpCT,UAAAA,QAASC,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,oBAGpD,IAAIuD,kBAAmB,EACvB,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,uBACnC,GAAID,GAAGT,UAAUC,SAASH,WAAY,CAClC8B,kBAAmB,EACnB,KACJ,CAGJ,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,wBAC9BD,GAAGT,UAAUC,SAASH,YAAcW,GAAGb,cAAc,gCAAgCf,cAElF4B,GAAGb,cAAc,gCAAgCf,YAAY0B,YAD7DqB,uBAEU,EAAArC,iBAAU,WAAWV,SAAU,4BAG/B,EAAAU,iBAAU,OAAOV,SAAU,sBAIrD,CAAC"}
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js b/amd/build/reviewing.min.js
deleted file mode 100644
index d027cc1635..0000000000
--- a/amd/build/reviewing.min.js
+++ /dev/null
@@ -1,10 +0,0 @@
-define("mod_moodleoverflow/reviewing",["exports","core/ajax","core/prefetch","core/templates","core/str"],function(_exports,_ajax,_prefetch,_templates,_str){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
-/**
- * Implements reviewing functionality
- *
- * @module mod_moodleoverflow/reviewing
- * @copyright 2022 Justus Dieckmann WWU
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){_prefetch.default.prefetchTemplates(["mod_moodleoverflow/reject_post_form","mod_moodleoverflow/review_buttons"]),_prefetch.default.prefetchStrings("mod_moodleoverflow",["post_was_approved","jump_to_next_post_needing_review","there_are_no_posts_needing_review","post_was_rejected"]);document.getElementById("moodleoverflow-posts").onclick=async e=>{const action=e.target.getAttribute("data-moodleoverflow-action");if(!action)return;const post=e.target.closest("*[data-moodleoverflow-postid]"),reviewRow=e.target.closest(".reviewrow"),postID=post.getAttribute("data-moodleoverflow-postid");if("approve"===action){reviewRow.innerHTML=".";const nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_approve_post",args:{postid:postID}}])[0];let message=await(0,_str.get_string)("post_was_approved","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message,post.classList.remove("pendingreview")}else if("reject"===action)reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/reject_post_form",{});else if("reject-submit"===action){const rejectMessage=post.querySelector("textarea.reject-reason").value.toString().trim();reviewRow.innerHTML=".";const args={postid:postID,reason:rejectMessage||null},nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_reject_post",args:args}])[0];let message=await(0,_str.get_string)("post_was_rejected","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message}else"reject-cancel"===action&&(reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/review_buttons",{}))}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch),_templates=_interopRequireDefault(_templates)});
-
-//# sourceMappingURL=reviewing.min.js.map
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js.map b/amd/build/reviewing.min.js.map
deleted file mode 100644
index 9695518cff..0000000000
--- a/amd/build/reviewing.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.js"],"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 * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","Prefetch","prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","getString","get_string","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason","_ajax","_prefetch","_templates"],"mappings":"6JAwBuC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAMhC,WACHG,UAAQD,QAACE,kBAAkB,CAAC,sCAAuC,sCACnED,UAAAA,QAASE,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,QAAUC,UACX,MAAMC,OAASV,EAAEW,OAAOC,aAAa,8BAErC,IAAKF,OACD,OAGJ,MAAMG,KAAOb,EAAEW,OAAOG,QAAQ,iCACxBC,UAAYf,EAAEW,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,8BAEjC,GAAe,YAAXF,OAAsB,CACtBK,UAAUE,UAAY,IACtB,MAAMC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,GAEJ,IAAIQ,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,QACtBX,KAAKc,UAAUC,OAAO,gBAC1B,MAAO,GAAe,WAAXlB,OACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,sCAAuC,CAAA,QACjF,GAAe,kBAAXpB,OAA4B,CACnC,MAAMqB,cAAgBlB,KAAKmB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFpB,UAAUE,UAAY,IACtB,MAAMK,KAAO,CACTC,OAAQP,OACRoB,OAAQL,eAAgC,MAEtCb,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,GAEJ,IAAIE,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,OAC1B,KAAsB,kBAAXd,SACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,oCAAqC,CAAA,IAG9F,EAzEAO,MAAAtC,uBAAAsC,OACAC,UAAAvC,uBAAAuC,WACAC,WAAAxC,uBAAAwC,WAuEC"}
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js b/amd/build/warnmodechange.min.js
deleted file mode 100644
index 605c6f767f..0000000000
--- a/amd/build/warnmodechange.min.js
+++ /dev/null
@@ -1,10 +0,0 @@
-define("mod_moodleoverflow/warnmodechange",["exports","core/str","core/notification","core/prefetch"],function(_exports,_str,_notification,_prefetch){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
-/**
- * Warns on changing the subscription mode.
- *
- * @module mod_moodleoverflow/warnmodechange
- * @copyright 2022 Justus Dieckmann WWU
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(previousSetting){_prefetch.default.prefetchStrings("mod_moodleoverflow",["switchtooptional","switchtoauto"]),_prefetch.default.prefetchStrings("moodle",["confirm","cancel"]);const form=document.querySelector("form.mform"),select=document.getElementById("id_forcesubscribe");form.onsubmit=async e=>{const value=select.selectedOptions[0].value;value!=previousSetting&&1!=value&&3!=value&&(e.preventDefault(),await _notification.default.confirm(await(0,_str.get_string)("confirm"),await(0,_str.get_string)(0==value?"switchtooptional":"switchtoauto","mod_moodleoverflow"),await(0,_str.get_string)("confirm"),await(0,_str.get_string)("cancel"),()=>{form.onsubmit=void 0,form.requestSubmit(e.submitter)},void 0))}},_notification=_interopRequireDefault(_notification),_prefetch=_interopRequireDefault(_prefetch)});
-
-//# sourceMappingURL=warnmodechange.min.js.map
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js.map b/amd/build/warnmodechange.min.js.map
deleted file mode 100644
index b205af0c40..0000000000
--- a/amd/build/warnmodechange.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.js"],"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 * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","previousSetting","Prefetch","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","preventDefault","Notification","confirm","getString","undefined","requestSubmit","submitter","_notification","_prefetch"],"mappings":"sJAwBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAM9B,SAAcG,iBACjBC,UAAQF,QAACG,gBAAgB,qBAAsB,CAAC,mBAAoB,iBACpED,UAAQF,QAACG,gBAAgB,SAAU,CAAC,UAAW,WAC/C,MAAMC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,UACZ,MAAMC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAASV,iBAA4B,GAATU,OAAuB,GAATA,QAG9Cb,EAAEe,uBACIC,sBAAaC,cACT,EAAAC,iBAAU,iBACV,EAAAA,KAAAA,YAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,EAAAK,iBAAU,iBACV,EAAAA,KAAAA,YAAU,UAChB,KAEIZ,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcpB,EAAEqB,iBACtBF,IAEf,EA7BAG,cAAAvB,uBAAAuB,eACAC,UAAAxB,uBAAAwB,UA4BC"}
\ No newline at end of file
From a0483059d65c008856e2f767c3b925933440b396 Mon Sep 17 00:00:00 2001
From: Tamaro Walter
Date: Mon, 7 Jul 2025 20:33:20 +0200
Subject: [PATCH 50/56] WIP: rebuild min files
---
amd/build/activityhelp.min.js | 11 +++++++++++
amd/build/activityhelp.min.js.map | 1 +
amd/build/rating.min.js | 10 ++++++++++
amd/build/rating.min.js.map | 1 +
amd/build/reviewing.min.js | 10 ++++++++++
amd/build/reviewing.min.js.map | 1 +
amd/build/warnmodechange.min.js | 10 ++++++++++
amd/build/warnmodechange.min.js.map | 1 +
8 files changed, 45 insertions(+)
create mode 100644 amd/build/activityhelp.min.js
create mode 100644 amd/build/activityhelp.min.js.map
create mode 100644 amd/build/rating.min.js
create mode 100644 amd/build/rating.min.js.map
create mode 100644 amd/build/reviewing.min.js
create mode 100644 amd/build/reviewing.min.js.map
create mode 100644 amd/build/warnmodechange.min.js
create mode 100644 amd/build/warnmodechange.min.js.map
diff --git a/amd/build/activityhelp.min.js b/amd/build/activityhelp.min.js
new file mode 100644
index 0000000000..4e6f2f9007
--- /dev/null
+++ b/amd/build/activityhelp.min.js
@@ -0,0 +1,11 @@
+define("mod_moodleoverflow/activityhelp",["exports"],function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;
+/**
+ * Show a help string for the amount of activity column in userstats_table.php
+ *
+ * @module mod_moodleoverflow/activityhelp
+ * @copyright 2023 Tamaro Walter
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+const Selectors_actions={showHelpIcon:'[data-action="showhelpicon"]'};_exports.init=()=>{document.addEventListener("click",event=>{event.target.closest(Selectors_actions.showHelpIcon)&&event.preventDefault()})}});
+
+//# sourceMappingURL=activityhelp.min.js.map
\ No newline at end of file
diff --git a/amd/build/activityhelp.min.js.map b/amd/build/activityhelp.min.js.map
new file mode 100644
index 0000000000..1934ca29c6
--- /dev/null
+++ b/amd/build/activityhelp.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","_exports","init","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;AAyBA,MAAMA,kBACO,CACLC,aAAc,gCAapBC,SAAAC,KANkBA,KAChBC,SAASC,iBAAiB,QAASC,QAC3BA,MAAMC,OAAOC,QAAQR,kBAAkBC,eACvCK,MAAMG,mBAGhB"}
\ No newline at end of file
diff --git a/amd/build/rating.min.js b/amd/build/rating.min.js
new file mode 100644
index 0000000000..93a4db92d9
--- /dev/null
+++ b/amd/build/rating.min.js
@@ -0,0 +1,10 @@
+define("mod_moodleoverflow/rating",["exports","core/ajax","core/prefetch","core/str"],function(_exports,_ajax,_prefetch,_str){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
+/**
+ * Implements rating functionality
+ *
+ * @module mod_moodleoverflow/rating
+ * @copyright 2022 Justus Dieckmann WWU
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(userid,allowmultiplemarks){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","marknotsolved","markhelpful","marknothelpful","action_remove_upvote","action_upvote","action_remove_downvote","action_downvote"]),root.onclick=async event=>{const actionElement=event.target.closest("[data-moodleoverflow-action]");if(!actionElement)return;const action=actionElement.getAttribute("data-moodleoverflow-action"),postElement=actionElement.closest("[data-moodleoverflow-postid]"),postid=null==postElement?void 0:postElement.getAttribute("data-moodleoverflow-postid");switch(action){case"upvote":case"downvote":{const isupvote="upvote"===action;if("clicked"===actionElement.getAttribute("data-moodleoverflow-state"))await sendVote(postid,isupvote?RATING_REMOVE_UPVOTE:RATING_REMOVE_DOWNVOTE,userid),actionElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_"+action,"mod_moodleoverflow");else{const otherAction=isupvote?"downvote":"upvote";await sendVote(postid,isupvote?RATING_UPVOTE:RATING_DOWNVOTE,userid),actionElement.setAttribute("data-moodleoverflow-state","clicked");const otherElement=postElement.querySelector(`[data-moodleoverflow-action="${otherAction}"]`);otherElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_remove_"+action,"mod_moodleoverflow"),otherElement.title=await(0,_str.get_string)("action_"+otherAction,"mod_moodleoverflow")}}break;case"helpful":case"solved":{const isHelpful="helpful"===action,htmlclass=isHelpful?"markedhelpful":"markedsolution",shouldRemove=postElement.classList.contains(htmlclass),baseRating=isHelpful?RATING_HELPFUL:RATING_SOLVED,rating=shouldRemove?10*baseRating:baseRating;if(await sendVote(postid,rating,userid),allowmultiplemarks)shouldRemove&&(postElement.classList.remove(htmlclass),actionElement.textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"),changeStrings(htmlclass,action));else for(const el of root.querySelectorAll(".moodleoverflowpost."+htmlclass))el.classList.remove(htmlclass),el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow");shouldRemove||(postElement.classList.add(htmlclass),actionElement.textContent=await(0,_str.get_string)(`marknot${action}`,"mod_moodleoverflow"),allowmultiplemarks&&changeStrings(htmlclass,action))}}}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch);const RATING_DOWNVOTE=1,RATING_UPVOTE=2,RATING_REMOVE_DOWNVOTE=10,RATING_REMOVE_UPVOTE=20,RATING_SOLVED=3,RATING_HELPFUL=4,root=document.getElementById("moodleoverflow-root");async function sendVote(postid,rating,userid){const response=await _ajax.default.call([{methodname:"mod_moodleoverflow_record_vote",args:{postid:postid,ratingid:rating}}])[0];return root.querySelectorAll(`[data-moodleoverflow-userreputation="${userid}"]`).forEach(i=>{i.textContent=response.raterreputation}),root.querySelectorAll(`[data-moodleoverflow-userreputation="${response.ownerid}"]`).forEach(i=>{i.textContent=response.ownerreputation}),root.querySelectorAll(`[data-moodleoverflow-postreputation="${postid}"]`).forEach(i=>{i.textContent=response.postrating}),response}async function changeStrings(htmlclass,action){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","alsomarksolved","markhelpful","alsomarkhelpful"]);var othermarkedposts=!1;for(const el of root.querySelectorAll(".moodleoverflowpost"))if(el.classList.contains(htmlclass)){othermarkedposts=!0;break}for(const el of root.querySelectorAll(".moodleoverflowpost"))!el.classList.contains(htmlclass)&&el.querySelector(`[data-moodleoverflow-action="${action}"]`)&&(el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=othermarkedposts?await(0,_str.get_string)(`alsomark${action}`,"mod_moodleoverflow"):await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"))}});
+
+//# sourceMappingURL=rating.min.js.map
\ No newline at end of file
diff --git a/amd/build/rating.min.js.map b/amd/build/rating.min.js.map
new file mode 100644
index 0000000000..64af28a834
--- /dev/null
+++ b/amd/build/rating.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"rating.min.js","sources":["../src/rating.js"],"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 * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if multiplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["_interopRequireDefault","e","__esModule","default","userid","allowmultiplemarks","Prefetch","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","RATING_REMOVE_UPVOTE","RATING_REMOVE_DOWNVOTE","setAttribute","title","getString","otherAction","RATING_UPVOTE","RATING_DOWNVOTE","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","RATING_HELPFUL","RATING_SOLVED","rating","remove","textContent","changeStrings","el","querySelectorAll","add","_ajax","_prefetch","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":"8HAuBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EA+C9B,SAAcG,OAAQC,oBACzBC,UAAQH,QAACI,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,cACX,MAAMC,cAAgBC,MAAMC,OAAOC,QAAQ,gCAC3C,IAAKH,cACD,OAGJ,MAAMI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,uBAAAA,EAAAA,YAAaD,aAAa,8BAEzC,OAAQD,QACJ,IAAK,SACL,IAAK,WAAY,CACb,MAAMI,SAAsB,WAAXJ,OACjB,GAAgE,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SAAWE,qBAAuBC,uBAAwBlB,QACjFO,cAAcY,aAAa,4BAA6B,cACxDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,UAAYV,OAAQ,0BACvD,CACH,MAAMW,YAAcP,SAAW,WAAa,eACtCC,SAASF,OAAQC,SAAWQ,cAAgBC,gBAAiBxB,QACnEO,cAAcY,aAAa,4BAA6B,WACxD,MAAMM,aAAeZ,YAAYa,cAC7B,gCAAgCJ,iBACpCG,aAAaN,aAAa,4BAA6B,cACvDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,iBAAmBV,OAAQ,sBACjEc,aAAaL,YAAc,EAAAC,KAAAA,YAAU,UAAYC,YAAa,qBAClE,CACJ,CACA,MACA,IAAK,UACL,IAAK,SAAU,CACX,MAAMK,UAAuB,YAAXhB,OACZiB,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAehB,YAAYiB,UAAUC,SAASH,WAC9CI,WAAaL,UAAYM,eAAiBC,cAC1CC,OAASN,aAA4B,GAAbG,WAAkBA,WAQhD,SAPMhB,SAASF,OAAQqB,OAAQnC,QAO1BC,mBASG4B,eACAhB,YAAYiB,UAAUM,OAAOR,WAC7BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,OAAOV,SAAU,sBAC7D2B,cAAcV,UAAWjB,cAV7B,IAAK,MAAM4B,MAAMnC,KAAKoC,iBAAiB,uBAAyBZ,WAC5DW,GAAGT,UAAUM,OAAOR,WACpBW,GAAGb,cAAc,gCAAgCf,YAAY0B,kBACnD,EAAAhB,iBAAU,OAAOV,SAAU,sBAWxCkB,eACDhB,YAAYiB,UAAUW,IAAIb,WAC1BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,UAAUV,SAAU,sBAC5DV,oBACAqC,cAAcV,UAAWjB,QAIrC,GAIZ,EA7HA+B,MAAA9C,uBAAA8C,OACAC,UAAA/C,uBAAA+C,WAGA,MAAMnB,gBAAkB,EAClBD,cAAgB,EAChBL,uBAAyB,GACzBD,qBAAuB,GACvBiB,cAAgB,EAChBD,eAAiB,EAEjB7B,KAAOwC,SAASC,eAAe,uBASrCvC,eAAeU,SAASF,OAAQqB,OAAQnC,QACpC,MAAM8C,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACFpC,OAAQA,OACRqC,SAAUhB,WAEd,GAUJ,OATA/B,KAAKoC,iBAAiB,wCAAwCxC,YAAYoD,QAASC,IAC/EA,EAAEhB,YAAcS,SAASQ,kBAE7BlD,KAAKoC,iBAAiB,wCAAwCM,SAASS,aAAaH,QAASC,IACzFA,EAAEhB,YAAcS,SAASU,kBAE7BpD,KAAKoC,iBAAiB,wCAAwC1B,YAAYsC,QAASC,IAC/EA,EAAEhB,YAAcS,SAASW,aAEtBX,QACX,CA+FAxC,eAAegC,cAAcV,UAAWjB,QACpCT,UAAAA,QAASC,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,oBAGpD,IAAIuD,kBAAmB,EACvB,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,uBACnC,GAAID,GAAGT,UAAUC,SAASH,WAAY,CAClC8B,kBAAmB,EACnB,KACJ,CAGJ,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,wBAC9BD,GAAGT,UAAUC,SAASH,YAAcW,GAAGb,cAAc,gCAAgCf,cAElF4B,GAAGb,cAAc,gCAAgCf,YAAY0B,YAD7DqB,uBAEU,EAAArC,iBAAU,WAAWV,SAAU,4BAG/B,EAAAU,iBAAU,OAAOV,SAAU,sBAIrD,CAAC"}
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js b/amd/build/reviewing.min.js
new file mode 100644
index 0000000000..d027cc1635
--- /dev/null
+++ b/amd/build/reviewing.min.js
@@ -0,0 +1,10 @@
+define("mod_moodleoverflow/reviewing",["exports","core/ajax","core/prefetch","core/templates","core/str"],function(_exports,_ajax,_prefetch,_templates,_str){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
+/**
+ * Implements reviewing functionality
+ *
+ * @module mod_moodleoverflow/reviewing
+ * @copyright 2022 Justus Dieckmann WWU
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){_prefetch.default.prefetchTemplates(["mod_moodleoverflow/reject_post_form","mod_moodleoverflow/review_buttons"]),_prefetch.default.prefetchStrings("mod_moodleoverflow",["post_was_approved","jump_to_next_post_needing_review","there_are_no_posts_needing_review","post_was_rejected"]);document.getElementById("moodleoverflow-posts").onclick=async e=>{const action=e.target.getAttribute("data-moodleoverflow-action");if(!action)return;const post=e.target.closest("*[data-moodleoverflow-postid]"),reviewRow=e.target.closest(".reviewrow"),postID=post.getAttribute("data-moodleoverflow-postid");if("approve"===action){reviewRow.innerHTML=".";const nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_approve_post",args:{postid:postID}}])[0];let message=await(0,_str.get_string)("post_was_approved","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message,post.classList.remove("pendingreview")}else if("reject"===action)reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/reject_post_form",{});else if("reject-submit"===action){const rejectMessage=post.querySelector("textarea.reject-reason").value.toString().trim();reviewRow.innerHTML=".";const args={postid:postID,reason:rejectMessage||null},nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_reject_post",args:args}])[0];let message=await(0,_str.get_string)("post_was_rejected","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message}else"reject-cancel"===action&&(reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/review_buttons",{}))}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch),_templates=_interopRequireDefault(_templates)});
+
+//# sourceMappingURL=reviewing.min.js.map
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js.map b/amd/build/reviewing.min.js.map
new file mode 100644
index 0000000000..9695518cff
--- /dev/null
+++ b/amd/build/reviewing.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.js"],"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 * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","Prefetch","prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","getString","get_string","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason","_ajax","_prefetch","_templates"],"mappings":"6JAwBuC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAMhC,WACHG,UAAQD,QAACE,kBAAkB,CAAC,sCAAuC,sCACnED,UAAAA,QAASE,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,QAAUC,UACX,MAAMC,OAASV,EAAEW,OAAOC,aAAa,8BAErC,IAAKF,OACD,OAGJ,MAAMG,KAAOb,EAAEW,OAAOG,QAAQ,iCACxBC,UAAYf,EAAEW,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,8BAEjC,GAAe,YAAXF,OAAsB,CACtBK,UAAUE,UAAY,IACtB,MAAMC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,GAEJ,IAAIQ,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,QACtBX,KAAKc,UAAUC,OAAO,gBAC1B,MAAO,GAAe,WAAXlB,OACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,sCAAuC,CAAA,QACjF,GAAe,kBAAXpB,OAA4B,CACnC,MAAMqB,cAAgBlB,KAAKmB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFpB,UAAUE,UAAY,IACtB,MAAMK,KAAO,CACTC,OAAQP,OACRoB,OAAQL,eAAgC,MAEtCb,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,GAEJ,IAAIE,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,OAC1B,KAAsB,kBAAXd,SACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,oCAAqC,CAAA,IAG9F,EAzEAO,MAAAtC,uBAAAsC,OACAC,UAAAvC,uBAAAuC,WACAC,WAAAxC,uBAAAwC,WAuEC"}
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js b/amd/build/warnmodechange.min.js
new file mode 100644
index 0000000000..605c6f767f
--- /dev/null
+++ b/amd/build/warnmodechange.min.js
@@ -0,0 +1,10 @@
+define("mod_moodleoverflow/warnmodechange",["exports","core/str","core/notification","core/prefetch"],function(_exports,_str,_notification,_prefetch){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
+/**
+ * Warns on changing the subscription mode.
+ *
+ * @module mod_moodleoverflow/warnmodechange
+ * @copyright 2022 Justus Dieckmann WWU
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(previousSetting){_prefetch.default.prefetchStrings("mod_moodleoverflow",["switchtooptional","switchtoauto"]),_prefetch.default.prefetchStrings("moodle",["confirm","cancel"]);const form=document.querySelector("form.mform"),select=document.getElementById("id_forcesubscribe");form.onsubmit=async e=>{const value=select.selectedOptions[0].value;value!=previousSetting&&1!=value&&3!=value&&(e.preventDefault(),await _notification.default.confirm(await(0,_str.get_string)("confirm"),await(0,_str.get_string)(0==value?"switchtooptional":"switchtoauto","mod_moodleoverflow"),await(0,_str.get_string)("confirm"),await(0,_str.get_string)("cancel"),()=>{form.onsubmit=void 0,form.requestSubmit(e.submitter)},void 0))}},_notification=_interopRequireDefault(_notification),_prefetch=_interopRequireDefault(_prefetch)});
+
+//# sourceMappingURL=warnmodechange.min.js.map
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js.map b/amd/build/warnmodechange.min.js.map
new file mode 100644
index 0000000000..b205af0c40
--- /dev/null
+++ b/amd/build/warnmodechange.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.js"],"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 * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","previousSetting","Prefetch","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","preventDefault","Notification","confirm","getString","undefined","requestSubmit","submitter","_notification","_prefetch"],"mappings":"sJAwBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAM9B,SAAcG,iBACjBC,UAAQF,QAACG,gBAAgB,qBAAsB,CAAC,mBAAoB,iBACpED,UAAQF,QAACG,gBAAgB,SAAU,CAAC,UAAW,WAC/C,MAAMC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,UACZ,MAAMC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAASV,iBAA4B,GAATU,OAAuB,GAATA,QAG9Cb,EAAEe,uBACIC,sBAAaC,cACT,EAAAC,iBAAU,iBACV,EAAAA,KAAAA,YAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,EAAAK,iBAAU,iBACV,EAAAA,KAAAA,YAAU,UAChB,KAEIZ,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcpB,EAAEqB,iBACtBF,IAEf,EA7BAG,cAAAvB,uBAAAuB,eACAC,UAAAxB,uBAAAwB,UA4BC"}
\ No newline at end of file
From f2d5a8f52a96817dcd50c1371b593a15880cddb0 Mon Sep 17 00:00:00 2001
From: Tamaro Walter
Date: Mon, 7 Jul 2025 20:39:32 +0200
Subject: [PATCH 51/56] delete min files
---
amd/build/activityhelp.min.js | 11 -----------
amd/build/activityhelp.min.js.map | 1 -
amd/build/rating.min.js | 10 ----------
amd/build/rating.min.js.map | 1 -
amd/build/reviewing.min.js | 10 ----------
amd/build/reviewing.min.js.map | 1 -
amd/build/warnmodechange.min.js | 10 ----------
amd/build/warnmodechange.min.js.map | 1 -
8 files changed, 45 deletions(-)
delete mode 100644 amd/build/activityhelp.min.js
delete mode 100644 amd/build/activityhelp.min.js.map
delete mode 100644 amd/build/rating.min.js
delete mode 100644 amd/build/rating.min.js.map
delete mode 100644 amd/build/reviewing.min.js
delete mode 100644 amd/build/reviewing.min.js.map
delete mode 100644 amd/build/warnmodechange.min.js
delete mode 100644 amd/build/warnmodechange.min.js.map
diff --git a/amd/build/activityhelp.min.js b/amd/build/activityhelp.min.js
deleted file mode 100644
index 4e6f2f9007..0000000000
--- a/amd/build/activityhelp.min.js
+++ /dev/null
@@ -1,11 +0,0 @@
-define("mod_moodleoverflow/activityhelp",["exports"],function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;
-/**
- * Show a help string for the amount of activity column in userstats_table.php
- *
- * @module mod_moodleoverflow/activityhelp
- * @copyright 2023 Tamaro Walter
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-const Selectors_actions={showHelpIcon:'[data-action="showhelpicon"]'};_exports.init=()=>{document.addEventListener("click",event=>{event.target.closest(Selectors_actions.showHelpIcon)&&event.preventDefault()})}});
-
-//# sourceMappingURL=activityhelp.min.js.map
\ No newline at end of file
diff --git a/amd/build/activityhelp.min.js.map b/amd/build/activityhelp.min.js.map
deleted file mode 100644
index 1934ca29c6..0000000000
--- a/amd/build/activityhelp.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","_exports","init","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;AAyBA,MAAMA,kBACO,CACLC,aAAc,gCAapBC,SAAAC,KANkBA,KAChBC,SAASC,iBAAiB,QAASC,QAC3BA,MAAMC,OAAOC,QAAQR,kBAAkBC,eACvCK,MAAMG,mBAGhB"}
\ No newline at end of file
diff --git a/amd/build/rating.min.js b/amd/build/rating.min.js
deleted file mode 100644
index 93a4db92d9..0000000000
--- a/amd/build/rating.min.js
+++ /dev/null
@@ -1,10 +0,0 @@
-define("mod_moodleoverflow/rating",["exports","core/ajax","core/prefetch","core/str"],function(_exports,_ajax,_prefetch,_str){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
-/**
- * Implements rating functionality
- *
- * @module mod_moodleoverflow/rating
- * @copyright 2022 Justus Dieckmann WWU
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(userid,allowmultiplemarks){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","marknotsolved","markhelpful","marknothelpful","action_remove_upvote","action_upvote","action_remove_downvote","action_downvote"]),root.onclick=async event=>{const actionElement=event.target.closest("[data-moodleoverflow-action]");if(!actionElement)return;const action=actionElement.getAttribute("data-moodleoverflow-action"),postElement=actionElement.closest("[data-moodleoverflow-postid]"),postid=null==postElement?void 0:postElement.getAttribute("data-moodleoverflow-postid");switch(action){case"upvote":case"downvote":{const isupvote="upvote"===action;if("clicked"===actionElement.getAttribute("data-moodleoverflow-state"))await sendVote(postid,isupvote?RATING_REMOVE_UPVOTE:RATING_REMOVE_DOWNVOTE,userid),actionElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_"+action,"mod_moodleoverflow");else{const otherAction=isupvote?"downvote":"upvote";await sendVote(postid,isupvote?RATING_UPVOTE:RATING_DOWNVOTE,userid),actionElement.setAttribute("data-moodleoverflow-state","clicked");const otherElement=postElement.querySelector(`[data-moodleoverflow-action="${otherAction}"]`);otherElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_remove_"+action,"mod_moodleoverflow"),otherElement.title=await(0,_str.get_string)("action_"+otherAction,"mod_moodleoverflow")}}break;case"helpful":case"solved":{const isHelpful="helpful"===action,htmlclass=isHelpful?"markedhelpful":"markedsolution",shouldRemove=postElement.classList.contains(htmlclass),baseRating=isHelpful?RATING_HELPFUL:RATING_SOLVED,rating=shouldRemove?10*baseRating:baseRating;if(await sendVote(postid,rating,userid),allowmultiplemarks)shouldRemove&&(postElement.classList.remove(htmlclass),actionElement.textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"),changeStrings(htmlclass,action));else for(const el of root.querySelectorAll(".moodleoverflowpost."+htmlclass))el.classList.remove(htmlclass),el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow");shouldRemove||(postElement.classList.add(htmlclass),actionElement.textContent=await(0,_str.get_string)(`marknot${action}`,"mod_moodleoverflow"),allowmultiplemarks&&changeStrings(htmlclass,action))}}}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch);const RATING_DOWNVOTE=1,RATING_UPVOTE=2,RATING_REMOVE_DOWNVOTE=10,RATING_REMOVE_UPVOTE=20,RATING_SOLVED=3,RATING_HELPFUL=4,root=document.getElementById("moodleoverflow-root");async function sendVote(postid,rating,userid){const response=await _ajax.default.call([{methodname:"mod_moodleoverflow_record_vote",args:{postid:postid,ratingid:rating}}])[0];return root.querySelectorAll(`[data-moodleoverflow-userreputation="${userid}"]`).forEach(i=>{i.textContent=response.raterreputation}),root.querySelectorAll(`[data-moodleoverflow-userreputation="${response.ownerid}"]`).forEach(i=>{i.textContent=response.ownerreputation}),root.querySelectorAll(`[data-moodleoverflow-postreputation="${postid}"]`).forEach(i=>{i.textContent=response.postrating}),response}async function changeStrings(htmlclass,action){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","alsomarksolved","markhelpful","alsomarkhelpful"]);var othermarkedposts=!1;for(const el of root.querySelectorAll(".moodleoverflowpost"))if(el.classList.contains(htmlclass)){othermarkedposts=!0;break}for(const el of root.querySelectorAll(".moodleoverflowpost"))!el.classList.contains(htmlclass)&&el.querySelector(`[data-moodleoverflow-action="${action}"]`)&&(el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=othermarkedposts?await(0,_str.get_string)(`alsomark${action}`,"mod_moodleoverflow"):await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"))}});
-
-//# sourceMappingURL=rating.min.js.map
\ No newline at end of file
diff --git a/amd/build/rating.min.js.map b/amd/build/rating.min.js.map
deleted file mode 100644
index 64af28a834..0000000000
--- a/amd/build/rating.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"rating.min.js","sources":["../src/rating.js"],"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 * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if multiplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["_interopRequireDefault","e","__esModule","default","userid","allowmultiplemarks","Prefetch","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","RATING_REMOVE_UPVOTE","RATING_REMOVE_DOWNVOTE","setAttribute","title","getString","otherAction","RATING_UPVOTE","RATING_DOWNVOTE","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","RATING_HELPFUL","RATING_SOLVED","rating","remove","textContent","changeStrings","el","querySelectorAll","add","_ajax","_prefetch","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":"8HAuBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EA+C9B,SAAcG,OAAQC,oBACzBC,UAAQH,QAACI,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,cACX,MAAMC,cAAgBC,MAAMC,OAAOC,QAAQ,gCAC3C,IAAKH,cACD,OAGJ,MAAMI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,uBAAAA,EAAAA,YAAaD,aAAa,8BAEzC,OAAQD,QACJ,IAAK,SACL,IAAK,WAAY,CACb,MAAMI,SAAsB,WAAXJ,OACjB,GAAgE,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SAAWE,qBAAuBC,uBAAwBlB,QACjFO,cAAcY,aAAa,4BAA6B,cACxDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,UAAYV,OAAQ,0BACvD,CACH,MAAMW,YAAcP,SAAW,WAAa,eACtCC,SAASF,OAAQC,SAAWQ,cAAgBC,gBAAiBxB,QACnEO,cAAcY,aAAa,4BAA6B,WACxD,MAAMM,aAAeZ,YAAYa,cAC7B,gCAAgCJ,iBACpCG,aAAaN,aAAa,4BAA6B,cACvDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,iBAAmBV,OAAQ,sBACjEc,aAAaL,YAAc,EAAAC,KAAAA,YAAU,UAAYC,YAAa,qBAClE,CACJ,CACA,MACA,IAAK,UACL,IAAK,SAAU,CACX,MAAMK,UAAuB,YAAXhB,OACZiB,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAehB,YAAYiB,UAAUC,SAASH,WAC9CI,WAAaL,UAAYM,eAAiBC,cAC1CC,OAASN,aAA4B,GAAbG,WAAkBA,WAQhD,SAPMhB,SAASF,OAAQqB,OAAQnC,QAO1BC,mBASG4B,eACAhB,YAAYiB,UAAUM,OAAOR,WAC7BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,OAAOV,SAAU,sBAC7D2B,cAAcV,UAAWjB,cAV7B,IAAK,MAAM4B,MAAMnC,KAAKoC,iBAAiB,uBAAyBZ,WAC5DW,GAAGT,UAAUM,OAAOR,WACpBW,GAAGb,cAAc,gCAAgCf,YAAY0B,kBACnD,EAAAhB,iBAAU,OAAOV,SAAU,sBAWxCkB,eACDhB,YAAYiB,UAAUW,IAAIb,WAC1BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,UAAUV,SAAU,sBAC5DV,oBACAqC,cAAcV,UAAWjB,QAIrC,GAIZ,EA7HA+B,MAAA9C,uBAAA8C,OACAC,UAAA/C,uBAAA+C,WAGA,MAAMnB,gBAAkB,EAClBD,cAAgB,EAChBL,uBAAyB,GACzBD,qBAAuB,GACvBiB,cAAgB,EAChBD,eAAiB,EAEjB7B,KAAOwC,SAASC,eAAe,uBASrCvC,eAAeU,SAASF,OAAQqB,OAAQnC,QACpC,MAAM8C,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACFpC,OAAQA,OACRqC,SAAUhB,WAEd,GAUJ,OATA/B,KAAKoC,iBAAiB,wCAAwCxC,YAAYoD,QAASC,IAC/EA,EAAEhB,YAAcS,SAASQ,kBAE7BlD,KAAKoC,iBAAiB,wCAAwCM,SAASS,aAAaH,QAASC,IACzFA,EAAEhB,YAAcS,SAASU,kBAE7BpD,KAAKoC,iBAAiB,wCAAwC1B,YAAYsC,QAASC,IAC/EA,EAAEhB,YAAcS,SAASW,aAEtBX,QACX,CA+FAxC,eAAegC,cAAcV,UAAWjB,QACpCT,UAAAA,QAASC,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,oBAGpD,IAAIuD,kBAAmB,EACvB,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,uBACnC,GAAID,GAAGT,UAAUC,SAASH,WAAY,CAClC8B,kBAAmB,EACnB,KACJ,CAGJ,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,wBAC9BD,GAAGT,UAAUC,SAASH,YAAcW,GAAGb,cAAc,gCAAgCf,cAElF4B,GAAGb,cAAc,gCAAgCf,YAAY0B,YAD7DqB,uBAEU,EAAArC,iBAAU,WAAWV,SAAU,4BAG/B,EAAAU,iBAAU,OAAOV,SAAU,sBAIrD,CAAC"}
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js b/amd/build/reviewing.min.js
deleted file mode 100644
index d027cc1635..0000000000
--- a/amd/build/reviewing.min.js
+++ /dev/null
@@ -1,10 +0,0 @@
-define("mod_moodleoverflow/reviewing",["exports","core/ajax","core/prefetch","core/templates","core/str"],function(_exports,_ajax,_prefetch,_templates,_str){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
-/**
- * Implements reviewing functionality
- *
- * @module mod_moodleoverflow/reviewing
- * @copyright 2022 Justus Dieckmann WWU
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){_prefetch.default.prefetchTemplates(["mod_moodleoverflow/reject_post_form","mod_moodleoverflow/review_buttons"]),_prefetch.default.prefetchStrings("mod_moodleoverflow",["post_was_approved","jump_to_next_post_needing_review","there_are_no_posts_needing_review","post_was_rejected"]);document.getElementById("moodleoverflow-posts").onclick=async e=>{const action=e.target.getAttribute("data-moodleoverflow-action");if(!action)return;const post=e.target.closest("*[data-moodleoverflow-postid]"),reviewRow=e.target.closest(".reviewrow"),postID=post.getAttribute("data-moodleoverflow-postid");if("approve"===action){reviewRow.innerHTML=".";const nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_approve_post",args:{postid:postID}}])[0];let message=await(0,_str.get_string)("post_was_approved","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message,post.classList.remove("pendingreview")}else if("reject"===action)reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/reject_post_form",{});else if("reject-submit"===action){const rejectMessage=post.querySelector("textarea.reject-reason").value.toString().trim();reviewRow.innerHTML=".";const args={postid:postID,reason:rejectMessage||null},nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_reject_post",args:args}])[0];let message=await(0,_str.get_string)("post_was_rejected","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message}else"reject-cancel"===action&&(reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/review_buttons",{}))}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch),_templates=_interopRequireDefault(_templates)});
-
-//# sourceMappingURL=reviewing.min.js.map
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js.map b/amd/build/reviewing.min.js.map
deleted file mode 100644
index 9695518cff..0000000000
--- a/amd/build/reviewing.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.js"],"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 * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","Prefetch","prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","getString","get_string","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason","_ajax","_prefetch","_templates"],"mappings":"6JAwBuC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAMhC,WACHG,UAAQD,QAACE,kBAAkB,CAAC,sCAAuC,sCACnED,UAAAA,QAASE,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,QAAUC,UACX,MAAMC,OAASV,EAAEW,OAAOC,aAAa,8BAErC,IAAKF,OACD,OAGJ,MAAMG,KAAOb,EAAEW,OAAOG,QAAQ,iCACxBC,UAAYf,EAAEW,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,8BAEjC,GAAe,YAAXF,OAAsB,CACtBK,UAAUE,UAAY,IACtB,MAAMC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,GAEJ,IAAIQ,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,QACtBX,KAAKc,UAAUC,OAAO,gBAC1B,MAAO,GAAe,WAAXlB,OACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,sCAAuC,CAAA,QACjF,GAAe,kBAAXpB,OAA4B,CACnC,MAAMqB,cAAgBlB,KAAKmB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFpB,UAAUE,UAAY,IACtB,MAAMK,KAAO,CACTC,OAAQP,OACRoB,OAAQL,eAAgC,MAEtCb,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,GAEJ,IAAIE,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,OAC1B,KAAsB,kBAAXd,SACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,oCAAqC,CAAA,IAG9F,EAzEAO,MAAAtC,uBAAAsC,OACAC,UAAAvC,uBAAAuC,WACAC,WAAAxC,uBAAAwC,WAuEC"}
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js b/amd/build/warnmodechange.min.js
deleted file mode 100644
index 605c6f767f..0000000000
--- a/amd/build/warnmodechange.min.js
+++ /dev/null
@@ -1,10 +0,0 @@
-define("mod_moodleoverflow/warnmodechange",["exports","core/str","core/notification","core/prefetch"],function(_exports,_str,_notification,_prefetch){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
-/**
- * Warns on changing the subscription mode.
- *
- * @module mod_moodleoverflow/warnmodechange
- * @copyright 2022 Justus Dieckmann WWU
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(previousSetting){_prefetch.default.prefetchStrings("mod_moodleoverflow",["switchtooptional","switchtoauto"]),_prefetch.default.prefetchStrings("moodle",["confirm","cancel"]);const form=document.querySelector("form.mform"),select=document.getElementById("id_forcesubscribe");form.onsubmit=async e=>{const value=select.selectedOptions[0].value;value!=previousSetting&&1!=value&&3!=value&&(e.preventDefault(),await _notification.default.confirm(await(0,_str.get_string)("confirm"),await(0,_str.get_string)(0==value?"switchtooptional":"switchtoauto","mod_moodleoverflow"),await(0,_str.get_string)("confirm"),await(0,_str.get_string)("cancel"),()=>{form.onsubmit=void 0,form.requestSubmit(e.submitter)},void 0))}},_notification=_interopRequireDefault(_notification),_prefetch=_interopRequireDefault(_prefetch)});
-
-//# sourceMappingURL=warnmodechange.min.js.map
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js.map b/amd/build/warnmodechange.min.js.map
deleted file mode 100644
index b205af0c40..0000000000
--- a/amd/build/warnmodechange.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.js"],"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 * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","previousSetting","Prefetch","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","preventDefault","Notification","confirm","getString","undefined","requestSubmit","submitter","_notification","_prefetch"],"mappings":"sJAwBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAM9B,SAAcG,iBACjBC,UAAQF,QAACG,gBAAgB,qBAAsB,CAAC,mBAAoB,iBACpED,UAAQF,QAACG,gBAAgB,SAAU,CAAC,UAAW,WAC/C,MAAMC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,UACZ,MAAMC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAASV,iBAA4B,GAATU,OAAuB,GAATA,QAG9Cb,EAAEe,uBACIC,sBAAaC,cACT,EAAAC,iBAAU,iBACV,EAAAA,KAAAA,YAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,EAAAK,iBAAU,iBACV,EAAAA,KAAAA,YAAU,UAChB,KAEIZ,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcpB,EAAEqB,iBACtBF,IAEf,EA7BAG,cAAAvB,uBAAAuB,eACAC,UAAAxB,uBAAAwB,UA4BC"}
\ No newline at end of file
From 6c8c27c83ee79569542db95379ec344a7ab52c09 Mon Sep 17 00:00:00 2001
From: Tamaro Walter
Date: Mon, 7 Jul 2025 20:40:54 +0200
Subject: [PATCH 52/56] rebuild min files
---
amd/build/activityhelp.min.js | 11 +++++++++++
amd/build/activityhelp.min.js.map | 1 +
amd/build/rating.min.js | 10 ++++++++++
amd/build/rating.min.js.map | 1 +
amd/build/reviewing.min.js | 10 ++++++++++
amd/build/reviewing.min.js.map | 1 +
amd/build/warnmodechange.min.js | 10 ++++++++++
amd/build/warnmodechange.min.js.map | 1 +
8 files changed, 45 insertions(+)
create mode 100644 amd/build/activityhelp.min.js
create mode 100644 amd/build/activityhelp.min.js.map
create mode 100644 amd/build/rating.min.js
create mode 100644 amd/build/rating.min.js.map
create mode 100644 amd/build/reviewing.min.js
create mode 100644 amd/build/reviewing.min.js.map
create mode 100644 amd/build/warnmodechange.min.js
create mode 100644 amd/build/warnmodechange.min.js.map
diff --git a/amd/build/activityhelp.min.js b/amd/build/activityhelp.min.js
new file mode 100644
index 0000000000..4e6f2f9007
--- /dev/null
+++ b/amd/build/activityhelp.min.js
@@ -0,0 +1,11 @@
+define("mod_moodleoverflow/activityhelp",["exports"],function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;
+/**
+ * Show a help string for the amount of activity column in userstats_table.php
+ *
+ * @module mod_moodleoverflow/activityhelp
+ * @copyright 2023 Tamaro Walter
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+const Selectors_actions={showHelpIcon:'[data-action="showhelpicon"]'};_exports.init=()=>{document.addEventListener("click",event=>{event.target.closest(Selectors_actions.showHelpIcon)&&event.preventDefault()})}});
+
+//# sourceMappingURL=activityhelp.min.js.map
\ No newline at end of file
diff --git a/amd/build/activityhelp.min.js.map b/amd/build/activityhelp.min.js.map
new file mode 100644
index 0000000000..1934ca29c6
--- /dev/null
+++ b/amd/build/activityhelp.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","_exports","init","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;AAyBA,MAAMA,kBACO,CACLC,aAAc,gCAapBC,SAAAC,KANkBA,KAChBC,SAASC,iBAAiB,QAASC,QAC3BA,MAAMC,OAAOC,QAAQR,kBAAkBC,eACvCK,MAAMG,mBAGhB"}
\ No newline at end of file
diff --git a/amd/build/rating.min.js b/amd/build/rating.min.js
new file mode 100644
index 0000000000..93a4db92d9
--- /dev/null
+++ b/amd/build/rating.min.js
@@ -0,0 +1,10 @@
+define("mod_moodleoverflow/rating",["exports","core/ajax","core/prefetch","core/str"],function(_exports,_ajax,_prefetch,_str){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
+/**
+ * Implements rating functionality
+ *
+ * @module mod_moodleoverflow/rating
+ * @copyright 2022 Justus Dieckmann WWU
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(userid,allowmultiplemarks){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","marknotsolved","markhelpful","marknothelpful","action_remove_upvote","action_upvote","action_remove_downvote","action_downvote"]),root.onclick=async event=>{const actionElement=event.target.closest("[data-moodleoverflow-action]");if(!actionElement)return;const action=actionElement.getAttribute("data-moodleoverflow-action"),postElement=actionElement.closest("[data-moodleoverflow-postid]"),postid=null==postElement?void 0:postElement.getAttribute("data-moodleoverflow-postid");switch(action){case"upvote":case"downvote":{const isupvote="upvote"===action;if("clicked"===actionElement.getAttribute("data-moodleoverflow-state"))await sendVote(postid,isupvote?RATING_REMOVE_UPVOTE:RATING_REMOVE_DOWNVOTE,userid),actionElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_"+action,"mod_moodleoverflow");else{const otherAction=isupvote?"downvote":"upvote";await sendVote(postid,isupvote?RATING_UPVOTE:RATING_DOWNVOTE,userid),actionElement.setAttribute("data-moodleoverflow-state","clicked");const otherElement=postElement.querySelector(`[data-moodleoverflow-action="${otherAction}"]`);otherElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_remove_"+action,"mod_moodleoverflow"),otherElement.title=await(0,_str.get_string)("action_"+otherAction,"mod_moodleoverflow")}}break;case"helpful":case"solved":{const isHelpful="helpful"===action,htmlclass=isHelpful?"markedhelpful":"markedsolution",shouldRemove=postElement.classList.contains(htmlclass),baseRating=isHelpful?RATING_HELPFUL:RATING_SOLVED,rating=shouldRemove?10*baseRating:baseRating;if(await sendVote(postid,rating,userid),allowmultiplemarks)shouldRemove&&(postElement.classList.remove(htmlclass),actionElement.textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"),changeStrings(htmlclass,action));else for(const el of root.querySelectorAll(".moodleoverflowpost."+htmlclass))el.classList.remove(htmlclass),el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow");shouldRemove||(postElement.classList.add(htmlclass),actionElement.textContent=await(0,_str.get_string)(`marknot${action}`,"mod_moodleoverflow"),allowmultiplemarks&&changeStrings(htmlclass,action))}}}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch);const RATING_DOWNVOTE=1,RATING_UPVOTE=2,RATING_REMOVE_DOWNVOTE=10,RATING_REMOVE_UPVOTE=20,RATING_SOLVED=3,RATING_HELPFUL=4,root=document.getElementById("moodleoverflow-root");async function sendVote(postid,rating,userid){const response=await _ajax.default.call([{methodname:"mod_moodleoverflow_record_vote",args:{postid:postid,ratingid:rating}}])[0];return root.querySelectorAll(`[data-moodleoverflow-userreputation="${userid}"]`).forEach(i=>{i.textContent=response.raterreputation}),root.querySelectorAll(`[data-moodleoverflow-userreputation="${response.ownerid}"]`).forEach(i=>{i.textContent=response.ownerreputation}),root.querySelectorAll(`[data-moodleoverflow-postreputation="${postid}"]`).forEach(i=>{i.textContent=response.postrating}),response}async function changeStrings(htmlclass,action){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","alsomarksolved","markhelpful","alsomarkhelpful"]);var othermarkedposts=!1;for(const el of root.querySelectorAll(".moodleoverflowpost"))if(el.classList.contains(htmlclass)){othermarkedposts=!0;break}for(const el of root.querySelectorAll(".moodleoverflowpost"))!el.classList.contains(htmlclass)&&el.querySelector(`[data-moodleoverflow-action="${action}"]`)&&(el.querySelector(`[data-moodleoverflow-action="${action}"]`).textContent=othermarkedposts?await(0,_str.get_string)(`alsomark${action}`,"mod_moodleoverflow"):await(0,_str.get_string)(`mark${action}`,"mod_moodleoverflow"))}});
+
+//# sourceMappingURL=rating.min.js.map
\ No newline at end of file
diff --git a/amd/build/rating.min.js.map b/amd/build/rating.min.js.map
new file mode 100644
index 0000000000..64af28a834
--- /dev/null
+++ b/amd/build/rating.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"rating.min.js","sources":["../src/rating.js"],"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 * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if multiplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["_interopRequireDefault","e","__esModule","default","userid","allowmultiplemarks","Prefetch","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","RATING_REMOVE_UPVOTE","RATING_REMOVE_DOWNVOTE","setAttribute","title","getString","otherAction","RATING_UPVOTE","RATING_DOWNVOTE","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","RATING_HELPFUL","RATING_SOLVED","rating","remove","textContent","changeStrings","el","querySelectorAll","add","_ajax","_prefetch","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":"8HAuBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EA+C9B,SAAcG,OAAQC,oBACzBC,UAAQH,QAACI,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,cACX,MAAMC,cAAgBC,MAAMC,OAAOC,QAAQ,gCAC3C,IAAKH,cACD,OAGJ,MAAMI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,uBAAAA,EAAAA,YAAaD,aAAa,8BAEzC,OAAQD,QACJ,IAAK,SACL,IAAK,WAAY,CACb,MAAMI,SAAsB,WAAXJ,OACjB,GAAgE,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SAAWE,qBAAuBC,uBAAwBlB,QACjFO,cAAcY,aAAa,4BAA6B,cACxDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,UAAYV,OAAQ,0BACvD,CACH,MAAMW,YAAcP,SAAW,WAAa,eACtCC,SAASF,OAAQC,SAAWQ,cAAgBC,gBAAiBxB,QACnEO,cAAcY,aAAa,4BAA6B,WACxD,MAAMM,aAAeZ,YAAYa,cAC7B,gCAAgCJ,iBACpCG,aAAaN,aAAa,4BAA6B,cACvDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,iBAAmBV,OAAQ,sBACjEc,aAAaL,YAAc,EAAAC,KAAAA,YAAU,UAAYC,YAAa,qBAClE,CACJ,CACA,MACA,IAAK,UACL,IAAK,SAAU,CACX,MAAMK,UAAuB,YAAXhB,OACZiB,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAehB,YAAYiB,UAAUC,SAASH,WAC9CI,WAAaL,UAAYM,eAAiBC,cAC1CC,OAASN,aAA4B,GAAbG,WAAkBA,WAQhD,SAPMhB,SAASF,OAAQqB,OAAQnC,QAO1BC,mBASG4B,eACAhB,YAAYiB,UAAUM,OAAOR,WAC7BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,OAAOV,SAAU,sBAC7D2B,cAAcV,UAAWjB,cAV7B,IAAK,MAAM4B,MAAMnC,KAAKoC,iBAAiB,uBAAyBZ,WAC5DW,GAAGT,UAAUM,OAAOR,WACpBW,GAAGb,cAAc,gCAAgCf,YAAY0B,kBACnD,EAAAhB,iBAAU,OAAOV,SAAU,sBAWxCkB,eACDhB,YAAYiB,UAAUW,IAAIb,WAC1BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,UAAUV,SAAU,sBAC5DV,oBACAqC,cAAcV,UAAWjB,QAIrC,GAIZ,EA7HA+B,MAAA9C,uBAAA8C,OACAC,UAAA/C,uBAAA+C,WAGA,MAAMnB,gBAAkB,EAClBD,cAAgB,EAChBL,uBAAyB,GACzBD,qBAAuB,GACvBiB,cAAgB,EAChBD,eAAiB,EAEjB7B,KAAOwC,SAASC,eAAe,uBASrCvC,eAAeU,SAASF,OAAQqB,OAAQnC,QACpC,MAAM8C,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACFpC,OAAQA,OACRqC,SAAUhB,WAEd,GAUJ,OATA/B,KAAKoC,iBAAiB,wCAAwCxC,YAAYoD,QAASC,IAC/EA,EAAEhB,YAAcS,SAASQ,kBAE7BlD,KAAKoC,iBAAiB,wCAAwCM,SAASS,aAAaH,QAASC,IACzFA,EAAEhB,YAAcS,SAASU,kBAE7BpD,KAAKoC,iBAAiB,wCAAwC1B,YAAYsC,QAASC,IAC/EA,EAAEhB,YAAcS,SAASW,aAEtBX,QACX,CA+FAxC,eAAegC,cAAcV,UAAWjB,QACpCT,UAAAA,QAASC,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,oBAGpD,IAAIuD,kBAAmB,EACvB,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,uBACnC,GAAID,GAAGT,UAAUC,SAASH,WAAY,CAClC8B,kBAAmB,EACnB,KACJ,CAGJ,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,wBAC9BD,GAAGT,UAAUC,SAASH,YAAcW,GAAGb,cAAc,gCAAgCf,cAElF4B,GAAGb,cAAc,gCAAgCf,YAAY0B,YAD7DqB,uBAEU,EAAArC,iBAAU,WAAWV,SAAU,4BAG/B,EAAAU,iBAAU,OAAOV,SAAU,sBAIrD,CAAC"}
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js b/amd/build/reviewing.min.js
new file mode 100644
index 0000000000..d027cc1635
--- /dev/null
+++ b/amd/build/reviewing.min.js
@@ -0,0 +1,10 @@
+define("mod_moodleoverflow/reviewing",["exports","core/ajax","core/prefetch","core/templates","core/str"],function(_exports,_ajax,_prefetch,_templates,_str){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
+/**
+ * Implements reviewing functionality
+ *
+ * @module mod_moodleoverflow/reviewing
+ * @copyright 2022 Justus Dieckmann WWU
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){_prefetch.default.prefetchTemplates(["mod_moodleoverflow/reject_post_form","mod_moodleoverflow/review_buttons"]),_prefetch.default.prefetchStrings("mod_moodleoverflow",["post_was_approved","jump_to_next_post_needing_review","there_are_no_posts_needing_review","post_was_rejected"]);document.getElementById("moodleoverflow-posts").onclick=async e=>{const action=e.target.getAttribute("data-moodleoverflow-action");if(!action)return;const post=e.target.closest("*[data-moodleoverflow-postid]"),reviewRow=e.target.closest(".reviewrow"),postID=post.getAttribute("data-moodleoverflow-postid");if("approve"===action){reviewRow.innerHTML=".";const nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_approve_post",args:{postid:postID}}])[0];let message=await(0,_str.get_string)("post_was_approved","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message,post.classList.remove("pendingreview")}else if("reject"===action)reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/reject_post_form",{});else if("reject-submit"===action){const rejectMessage=post.querySelector("textarea.reject-reason").value.toString().trim();reviewRow.innerHTML=".";const args={postid:postID,reason:rejectMessage||null},nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_reject_post",args:args}])[0];let message=await(0,_str.get_string)("post_was_rejected","mod_moodleoverflow")+" ";message+=nextPostURL?``+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message}else"reject-cancel"===action&&(reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/review_buttons",{}))}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch),_templates=_interopRequireDefault(_templates)});
+
+//# sourceMappingURL=reviewing.min.js.map
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js.map b/amd/build/reviewing.min.js.map
new file mode 100644
index 0000000000..9695518cff
--- /dev/null
+++ b/amd/build/reviewing.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.js"],"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 * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","Prefetch","prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","getString","get_string","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason","_ajax","_prefetch","_templates"],"mappings":"6JAwBuC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAMhC,WACHG,UAAQD,QAACE,kBAAkB,CAAC,sCAAuC,sCACnED,UAAAA,QAASE,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,QAAUC,UACX,MAAMC,OAASV,EAAEW,OAAOC,aAAa,8BAErC,IAAKF,OACD,OAGJ,MAAMG,KAAOb,EAAEW,OAAOG,QAAQ,iCACxBC,UAAYf,EAAEW,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,8BAEjC,GAAe,YAAXF,OAAsB,CACtBK,UAAUE,UAAY,IACtB,MAAMC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,GAEJ,IAAIQ,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,QACtBX,KAAKc,UAAUC,OAAO,gBAC1B,MAAO,GAAe,WAAXlB,OACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,sCAAuC,CAAA,QACjF,GAAe,kBAAXpB,OAA4B,CACnC,MAAMqB,cAAgBlB,KAAKmB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFpB,UAAUE,UAAY,IACtB,MAAMK,KAAO,CACTC,OAAQP,OACRoB,OAAQL,eAAgC,MAEtCb,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,GAEJ,IAAIE,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,OAC1B,KAAsB,kBAAXd,SACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,oCAAqC,CAAA,IAG9F,EAzEAO,MAAAtC,uBAAAsC,OACAC,UAAAvC,uBAAAuC,WACAC,WAAAxC,uBAAAwC,WAuEC"}
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js b/amd/build/warnmodechange.min.js
new file mode 100644
index 0000000000..605c6f767f
--- /dev/null
+++ b/amd/build/warnmodechange.min.js
@@ -0,0 +1,10 @@
+define("mod_moodleoverflow/warnmodechange",["exports","core/str","core/notification","core/prefetch"],function(_exports,_str,_notification,_prefetch){function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}
+/**
+ * Warns on changing the subscription mode.
+ *
+ * @module mod_moodleoverflow/warnmodechange
+ * @copyright 2022 Justus Dieckmann WWU
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(previousSetting){_prefetch.default.prefetchStrings("mod_moodleoverflow",["switchtooptional","switchtoauto"]),_prefetch.default.prefetchStrings("moodle",["confirm","cancel"]);const form=document.querySelector("form.mform"),select=document.getElementById("id_forcesubscribe");form.onsubmit=async e=>{const value=select.selectedOptions[0].value;value!=previousSetting&&1!=value&&3!=value&&(e.preventDefault(),await _notification.default.confirm(await(0,_str.get_string)("confirm"),await(0,_str.get_string)(0==value?"switchtooptional":"switchtoauto","mod_moodleoverflow"),await(0,_str.get_string)("confirm"),await(0,_str.get_string)("cancel"),()=>{form.onsubmit=void 0,form.requestSubmit(e.submitter)},void 0))}},_notification=_interopRequireDefault(_notification),_prefetch=_interopRequireDefault(_prefetch)});
+
+//# sourceMappingURL=warnmodechange.min.js.map
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js.map b/amd/build/warnmodechange.min.js.map
new file mode 100644
index 0000000000..b205af0c40
--- /dev/null
+++ b/amd/build/warnmodechange.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.js"],"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 * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","previousSetting","Prefetch","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","preventDefault","Notification","confirm","getString","undefined","requestSubmit","submitter","_notification","_prefetch"],"mappings":"sJAwBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAM9B,SAAcG,iBACjBC,UAAQF,QAACG,gBAAgB,qBAAsB,CAAC,mBAAoB,iBACpED,UAAQF,QAACG,gBAAgB,SAAU,CAAC,UAAW,WAC/C,MAAMC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,UACZ,MAAMC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAASV,iBAA4B,GAATU,OAAuB,GAATA,QAG9Cb,EAAEe,uBACIC,sBAAaC,cACT,EAAAC,iBAAU,iBACV,EAAAA,KAAAA,YAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,EAAAK,iBAAU,iBACV,EAAAA,KAAAA,YAAU,UAChB,KAEIZ,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcpB,EAAEqB,iBACtBF,IAEf,EA7BAG,cAAAvB,uBAAAuB,eACAC,UAAAxB,uBAAAwB,UA4BC"}
\ No newline at end of file
From f14eaf1f36456342d10edeb6fa77256d4d089a04 Mon Sep 17 00:00:00 2001
From: Tamaro Walter
Date: Mon, 7 Jul 2025 20:52:55 +0200
Subject: [PATCH 53/56] change js content
---
amd/build/activityhelp.min.js.map | 2 +-
amd/build/rating.min.js.map | 2 +-
amd/build/reviewing.min.js.map | 2 +-
amd/build/warnmodechange.min.js.map | 2 +-
amd/src/activityhelp.js | 2 --
amd/src/rating.js | 4 ++++
amd/src/reviewing.js | 5 ++++-
amd/src/warnmodechange.js | 1 +
8 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/amd/build/activityhelp.min.js.map b/amd/build/activityhelp.min.js.map
index 1934ca29c6..20737ae222 100644
--- a/amd/build/activityhelp.min.js.map
+++ b/amd/build/activityhelp.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","_exports","init","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;AAyBA,MAAMA,kBACO,CACLC,aAAc,gCAapBC,SAAAC,KANkBA,KAChBC,SAASC,iBAAiB,QAASC,QAC3BA,MAAMC,OAAOC,QAAQR,kBAAkBC,eACvCK,MAAMG,mBAGhB"}
\ No newline at end of file
+{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.js"],"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 * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help icon string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","_exports","init","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;AAuBA,MAAMA,kBACO,CACLC,aAAc,gCAapBC,SAAAC,KANkBA,KAChBC,SAASC,iBAAiB,QAASC,QAC3BA,MAAMC,OAAOC,QAAQR,kBAAkBC,eACvCK,MAAMG,mBAGhB"}
\ No newline at end of file
diff --git a/amd/build/rating.min.js.map b/amd/build/rating.min.js.map
index 64af28a834..76825615bf 100644
--- a/amd/build/rating.min.js.map
+++ b/amd/build/rating.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"rating.min.js","sources":["../src/rating.js"],"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 * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if multiplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["_interopRequireDefault","e","__esModule","default","userid","allowmultiplemarks","Prefetch","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","RATING_REMOVE_UPVOTE","RATING_REMOVE_DOWNVOTE","setAttribute","title","getString","otherAction","RATING_UPVOTE","RATING_DOWNVOTE","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","RATING_HELPFUL","RATING_SOLVED","rating","remove","textContent","changeStrings","el","querySelectorAll","add","_ajax","_prefetch","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":"8HAuBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EA+C9B,SAAcG,OAAQC,oBACzBC,UAAQH,QAACI,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,cACX,MAAMC,cAAgBC,MAAMC,OAAOC,QAAQ,gCAC3C,IAAKH,cACD,OAGJ,MAAMI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,uBAAAA,EAAAA,YAAaD,aAAa,8BAEzC,OAAQD,QACJ,IAAK,SACL,IAAK,WAAY,CACb,MAAMI,SAAsB,WAAXJ,OACjB,GAAgE,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SAAWE,qBAAuBC,uBAAwBlB,QACjFO,cAAcY,aAAa,4BAA6B,cACxDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,UAAYV,OAAQ,0BACvD,CACH,MAAMW,YAAcP,SAAW,WAAa,eACtCC,SAASF,OAAQC,SAAWQ,cAAgBC,gBAAiBxB,QACnEO,cAAcY,aAAa,4BAA6B,WACxD,MAAMM,aAAeZ,YAAYa,cAC7B,gCAAgCJ,iBACpCG,aAAaN,aAAa,4BAA6B,cACvDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,iBAAmBV,OAAQ,sBACjEc,aAAaL,YAAc,EAAAC,KAAAA,YAAU,UAAYC,YAAa,qBAClE,CACJ,CACA,MACA,IAAK,UACL,IAAK,SAAU,CACX,MAAMK,UAAuB,YAAXhB,OACZiB,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAehB,YAAYiB,UAAUC,SAASH,WAC9CI,WAAaL,UAAYM,eAAiBC,cAC1CC,OAASN,aAA4B,GAAbG,WAAkBA,WAQhD,SAPMhB,SAASF,OAAQqB,OAAQnC,QAO1BC,mBASG4B,eACAhB,YAAYiB,UAAUM,OAAOR,WAC7BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,OAAOV,SAAU,sBAC7D2B,cAAcV,UAAWjB,cAV7B,IAAK,MAAM4B,MAAMnC,KAAKoC,iBAAiB,uBAAyBZ,WAC5DW,GAAGT,UAAUM,OAAOR,WACpBW,GAAGb,cAAc,gCAAgCf,YAAY0B,kBACnD,EAAAhB,iBAAU,OAAOV,SAAU,sBAWxCkB,eACDhB,YAAYiB,UAAUW,IAAIb,WAC1BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,UAAUV,SAAU,sBAC5DV,oBACAqC,cAAcV,UAAWjB,QAIrC,GAIZ,EA7HA+B,MAAA9C,uBAAA8C,OACAC,UAAA/C,uBAAA+C,WAGA,MAAMnB,gBAAkB,EAClBD,cAAgB,EAChBL,uBAAyB,GACzBD,qBAAuB,GACvBiB,cAAgB,EAChBD,eAAiB,EAEjB7B,KAAOwC,SAASC,eAAe,uBASrCvC,eAAeU,SAASF,OAAQqB,OAAQnC,QACpC,MAAM8C,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACFpC,OAAQA,OACRqC,SAAUhB,WAEd,GAUJ,OATA/B,KAAKoC,iBAAiB,wCAAwCxC,YAAYoD,QAASC,IAC/EA,EAAEhB,YAAcS,SAASQ,kBAE7BlD,KAAKoC,iBAAiB,wCAAwCM,SAASS,aAAaH,QAASC,IACzFA,EAAEhB,YAAcS,SAASU,kBAE7BpD,KAAKoC,iBAAiB,wCAAwC1B,YAAYsC,QAASC,IAC/EA,EAAEhB,YAAcS,SAASW,aAEtBX,QACX,CA+FAxC,eAAegC,cAAcV,UAAWjB,QACpCT,UAAAA,QAASC,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,oBAGpD,IAAIuD,kBAAmB,EACvB,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,uBACnC,GAAID,GAAGT,UAAUC,SAASH,WAAY,CAClC8B,kBAAmB,EACnB,KACJ,CAGJ,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,wBAC9BD,GAAGT,UAAUC,SAASH,YAAcW,GAAGb,cAAc,gCAAgCf,cAElF4B,GAAGb,cAAc,gCAAgCf,YAAY0B,YAD7DqB,uBAEU,EAAArC,iBAAU,WAAWV,SAAU,4BAG/B,EAAAU,iBAAU,OAAOV,SAAU,sBAIrD,CAAC"}
\ No newline at end of file
+{"version":3,"file":"rating.min.js","sources":["../src/rating.js"],"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 * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if multiplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["_interopRequireDefault","e","__esModule","default","userid","allowmultiplemarks","Prefetch","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","RATING_REMOVE_UPVOTE","RATING_REMOVE_DOWNVOTE","setAttribute","title","getString","otherAction","RATING_UPVOTE","RATING_DOWNVOTE","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","RATING_HELPFUL","RATING_SOLVED","rating","remove","textContent","changeStrings","el","querySelectorAll","add","_ajax","_prefetch","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":"8HAuBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAmD9B,SAAcG,OAAQC,oBACzBC,UAAQH,QAACI,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,cACX,MAAMC,cAAgBC,MAAMC,OAAOC,QAAQ,gCAC3C,IAAKH,cACD,OAGJ,MAAMI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,uBAAAA,EAAAA,YAAaD,aAAa,8BAEzC,OAAQD,QACJ,IAAK,SACL,IAAK,WAAY,CACb,MAAMI,SAAsB,WAAXJ,OACjB,GAAgE,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SAAWE,qBAAuBC,uBAAwBlB,QACjFO,cAAcY,aAAa,4BAA6B,cACxDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,UAAYV,OAAQ,0BACvD,CACH,MAAMW,YAAcP,SAAW,WAAa,eACtCC,SAASF,OAAQC,SAAWQ,cAAgBC,gBAAiBxB,QACnEO,cAAcY,aAAa,4BAA6B,WACxD,MAAMM,aAAeZ,YAAYa,cAC7B,gCAAgCJ,iBACpCG,aAAaN,aAAa,4BAA6B,cACvDZ,cAAca,YAAc,EAAAC,KAAAA,YAAU,iBAAmBV,OAAQ,sBACjEc,aAAaL,YAAc,EAAAC,KAAAA,YAAU,UAAYC,YAAa,qBAClE,CACJ,CACA,MACA,IAAK,UACL,IAAK,SAAU,CACX,MAAMK,UAAuB,YAAXhB,OACZiB,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAehB,YAAYiB,UAAUC,SAASH,WAC9CI,WAAaL,UAAYM,eAAiBC,cAC1CC,OAASN,aAA4B,GAAbG,WAAkBA,WAQhD,SAPMhB,SAASF,OAAQqB,OAAQnC,QAO1BC,mBASG4B,eACAhB,YAAYiB,UAAUM,OAAOR,WAC7BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,OAAOV,SAAU,sBAC7D2B,cAAcV,UAAWjB,cAV7B,IAAK,MAAM4B,MAAMnC,KAAKoC,iBAAiB,uBAAyBZ,WAC5DW,GAAGT,UAAUM,OAAOR,WACpBW,GAAGb,cAAc,gCAAgCf,YAAY0B,kBACnD,EAAAhB,iBAAU,OAAOV,SAAU,sBAWxCkB,eACDhB,YAAYiB,UAAUW,IAAIb,WAC1BrB,cAAc8B,kBAAoB,EAAAhB,KAAAA,YAAU,UAAUV,SAAU,sBAC5DV,oBACAqC,cAAcV,UAAWjB,QAIrC,GAIZ,EAjIA+B,MAAA9C,uBAAA8C,OACAC,UAAA/C,uBAAA+C,WAGA,MAAMnB,gBAAkB,EAClBD,cAAgB,EAChBL,uBAAyB,GACzBD,qBAAuB,GACvBiB,cAAgB,EAChBD,eAAiB,EAEjB7B,KAAOwC,SAASC,eAAe,uBASrCvC,eAAeU,SAASF,OAAQqB,OAAQnC,QACpC,MAAM8C,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACFpC,OAAQA,OACRqC,SAAUhB,WAEd,GAcJ,OAZA/B,KAAKoC,iBAAiB,wCAAwCxC,YAAYoD,QAASC,IAC/EA,EAAEhB,YAAcS,SAASQ,kBAG7BlD,KAAKoC,iBAAiB,wCAAwCM,SAASS,aAAaH,QAASC,IACzFA,EAAEhB,YAAcS,SAASU,kBAG7BpD,KAAKoC,iBAAiB,wCAAwC1B,YAAYsC,QAASC,IAC/EA,EAAEhB,YAAcS,SAASW,aAGtBX,QACX,CA+FAxC,eAAegC,cAAcV,UAAWjB,QACpCT,UAAAA,QAASC,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,oBAGpD,IAAIuD,kBAAmB,EACvB,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,uBACnC,GAAID,GAAGT,UAAUC,SAASH,WAAY,CAClC8B,kBAAmB,EACnB,KACJ,CAGJ,IAAK,MAAMnB,MAAMnC,KAAKoC,iBAAiB,wBAC9BD,GAAGT,UAAUC,SAASH,YAAcW,GAAGb,cAAc,gCAAgCf,cAElF4B,GAAGb,cAAc,gCAAgCf,YAAY0B,YAD7DqB,uBAEU,EAAArC,iBAAU,WAAWV,SAAU,4BAG/B,EAAAU,iBAAU,OAAOV,SAAU,sBAIrD,CAAC"}
\ No newline at end of file
diff --git a/amd/build/reviewing.min.js.map b/amd/build/reviewing.min.js.map
index 9695518cff..37e6a1b752 100644
--- a/amd/build/reviewing.min.js.map
+++ b/amd/build/reviewing.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.js"],"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 * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","Prefetch","prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","getString","get_string","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason","_ajax","_prefetch","_templates"],"mappings":"6JAwBuC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAMhC,WACHG,UAAQD,QAACE,kBAAkB,CAAC,sCAAuC,sCACnED,UAAAA,QAASE,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,QAAUC,UACX,MAAMC,OAASV,EAAEW,OAAOC,aAAa,8BAErC,IAAKF,OACD,OAGJ,MAAMG,KAAOb,EAAEW,OAAOG,QAAQ,iCACxBC,UAAYf,EAAEW,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,8BAEjC,GAAe,YAAXF,OAAsB,CACtBK,UAAUE,UAAY,IACtB,MAAMC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,GAEJ,IAAIQ,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,QACtBX,KAAKc,UAAUC,OAAO,gBAC1B,MAAO,GAAe,WAAXlB,OACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,sCAAuC,CAAA,QACjF,GAAe,kBAAXpB,OAA4B,CACnC,MAAMqB,cAAgBlB,KAAKmB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFpB,UAAUE,UAAY,IACtB,MAAMK,KAAO,CACTC,OAAQP,OACRoB,OAAQL,eAAgC,MAEtCb,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,GAEJ,IAAIE,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,OAC1B,KAAsB,kBAAXd,SACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,oCAAqC,CAAA,IAG9F,EAzEAO,MAAAtC,uBAAAsC,OACAC,UAAAvC,uBAAAuC,WACAC,WAAAxC,uBAAAwC,WAuEC"}
\ No newline at end of file
+{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.js"],"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 * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved',\n 'jump_to_next_post_needing_review',\n 'there_are_no_posts_needing_review',\n 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","Prefetch","prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","getString","get_string","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason","_ajax","_prefetch","_templates"],"mappings":"6JAwBuC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAMhC,WACHG,UAAQD,QAACE,kBAAkB,CAAC,sCAAuC,sCACnED,UAAAA,QAASE,gBAAgB,qBACrB,CAAC,oBACM,mCACA,oCACA,sBAEEC,SAASC,eAAe,wBAChCC,QAAUC,UACX,MAAMC,OAASV,EAAEW,OAAOC,aAAa,8BAErC,IAAKF,OACD,OAGJ,MAAMG,KAAOb,EAAEW,OAAOG,QAAQ,iCACxBC,UAAYf,EAAEW,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,8BAEjC,GAAe,YAAXF,OAAsB,CACtBK,UAAUE,UAAY,IACtB,MAAMC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,GAEJ,IAAIQ,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,QACtBX,KAAKc,UAAUC,OAAO,gBAC1B,MAAO,GAAe,WAAXlB,OACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,sCAAuC,CAAA,QACjF,GAAe,kBAAXpB,OAA4B,CACnC,MAAMqB,cAAgBlB,KAAKmB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFpB,UAAUE,UAAY,IACtB,MAAMK,KAAO,CACTC,OAAQP,OACRoB,OAAQL,eAAgC,MAEtCb,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,GAEJ,IAAIE,cAAgB,EAAAC,KAAAA,YAAU,oBAAqB,sBAAwB,IAEvED,SADAN,YACW,YAAYA,sBACX,EAAAO,KAASC,YAAC,mCAAoC,sBACpD,aAEW,EAAAD,KAAAA,YAAU,oCAAqC,sBAEpEV,UAAUE,UAAYO,OAC1B,KAAsB,kBAAXd,SACPK,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBY,WAAS3B,QAAC4B,OAAO,oCAAqC,CAAA,IAG9F,EA5EAO,MAAAtC,uBAAAsC,OACAC,UAAAvC,uBAAAuC,WACAC,WAAAxC,uBAAAwC,WA0EC"}
\ No newline at end of file
diff --git a/amd/build/warnmodechange.min.js.map b/amd/build/warnmodechange.min.js.map
index b205af0c40..1d84d0f41f 100644
--- a/amd/build/warnmodechange.min.js.map
+++ b/amd/build/warnmodechange.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.js"],"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 * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","previousSetting","Prefetch","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","preventDefault","Notification","confirm","getString","undefined","requestSubmit","submitter","_notification","_prefetch"],"mappings":"sJAwBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAM9B,SAAcG,iBACjBC,UAAQF,QAACG,gBAAgB,qBAAsB,CAAC,mBAAoB,iBACpED,UAAQF,QAACG,gBAAgB,SAAU,CAAC,UAAW,WAC/C,MAAMC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,UACZ,MAAMC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAASV,iBAA4B,GAATU,OAAuB,GAATA,QAG9Cb,EAAEe,uBACIC,sBAAaC,cACT,EAAAC,iBAAU,iBACV,EAAAA,KAAAA,YAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,EAAAK,iBAAU,iBACV,EAAAA,KAAAA,YAAU,UAChB,KAEIZ,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcpB,EAAEqB,iBACtBF,IAEf,EA7BAG,cAAAvB,uBAAAuB,eACAC,UAAAxB,uBAAAwB,UA4BC"}
\ No newline at end of file
+{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.js"],"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 * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["_interopRequireDefault","e","__esModule","default","previousSetting","Prefetch","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","preventDefault","Notification","confirm","getString","undefined","requestSubmit","submitter","_notification","_prefetch"],"mappings":"sJAwBqC,SAAAA,uBAAAC,GAAAA,OAAAA,GAAAA,EAAAC,WAAAD,EAAAE,CAAAA,QAAAF,EAAA;;;;;;;2EAM9B,SAAcG,iBACjBC,UAAQF,QAACG,gBAAgB,qBAAsB,CAAC,mBAAoB,iBACpED,UAAQF,QAACG,gBAAgB,SAAU,CAAC,UAAW,WAC/C,MAAMC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,UACZ,MAAMC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAASV,iBAA4B,GAATU,OAAuB,GAATA,QAI9Cb,EAAEe,uBACIC,sBAAaC,cACT,EAAAC,iBAAU,iBACV,EAAAA,KAAAA,YAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,EAAAK,iBAAU,iBACV,EAAAA,KAAAA,YAAU,UAChB,KAEIZ,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcpB,EAAEqB,iBACtBF,IAEf,EA9BAG,cAAAvB,uBAAAuB,eACAC,UAAAxB,uBAAAwB,UA6BC"}
\ No newline at end of file
diff --git a/amd/src/activityhelp.js b/amd/src/activityhelp.js
index dc4127b6f2..58427b30b4 100644
--- a/amd/src/activityhelp.js
+++ b/amd/src/activityhelp.js
@@ -21,8 +21,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-
-
const Selectors = {
actions: {
showHelpIcon: '[data-action="showhelpicon"]',
diff --git a/amd/src/rating.js b/amd/src/rating.js
index f1cce7a268..259e2bc8c2 100644
--- a/amd/src/rating.js
+++ b/amd/src/rating.js
@@ -48,15 +48,19 @@ async function sendVote(postid, rating, userid) {
ratingid: rating
}
}])[0];
+
root.querySelectorAll(`[data-moodleoverflow-userreputation="${userid}"]`).forEach((i) => {
i.textContent = response.raterreputation;
});
+
root.querySelectorAll(`[data-moodleoverflow-userreputation="${response.ownerid}"]`).forEach((i) => {
i.textContent = response.ownerreputation;
});
+
root.querySelectorAll(`[data-moodleoverflow-postreputation="${postid}"]`).forEach((i) => {
i.textContent = response.postrating;
});
+
return response;
}
diff --git a/amd/src/reviewing.js b/amd/src/reviewing.js
index 0525609f59..72213cbb0d 100644
--- a/amd/src/reviewing.js
+++ b/amd/src/reviewing.js
@@ -31,7 +31,10 @@ import {get_string as getString} from 'core/str';
export function init() {
Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);
Prefetch.prefetchStrings('mod_moodleoverflow',
- ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);
+ ['post_was_approved',
+ 'jump_to_next_post_needing_review',
+ 'there_are_no_posts_needing_review',
+ 'post_was_rejected']);
const root = document.getElementById('moodleoverflow-posts');
root.onclick = async(e) => {
diff --git a/amd/src/warnmodechange.js b/amd/src/warnmodechange.js
index 4d59b2dc2e..afb4cee3e9 100644
--- a/amd/src/warnmodechange.js
+++ b/amd/src/warnmodechange.js
@@ -38,6 +38,7 @@ export function init(previousSetting) {
if (value == previousSetting || value == 1 || value == 3) {
return;
}
+
e.preventDefault();
await Notification.confirm(
await getString('confirm'),
From 1413737a039516095a87cb37ae58b3e24816dbde Mon Sep 17 00:00:00 2001
From: Tamaro Walter
Date: Mon, 7 Jul 2025 21:00:16 +0200
Subject: [PATCH 54/56] allow grunt error
---
.github/workflows/moodle-ci.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml
index 0b2eda27b5..023398ddf0 100644
--- a/.github/workflows/moodle-ci.yml
+++ b/.github/workflows/moodle-ci.yml
@@ -7,3 +7,4 @@ jobs:
uses: learnweb/moodle-workflows-learnweb/.github/workflows/moodle-ci.yml@main
with:
allow-mustache-lint-error: true
+ allow-grunt-error: true
From 13c58af7f1df97b641cf6a054b308f04e8e7fbe2 Mon Sep 17 00:00:00 2001
From: Tamaro Walter
Date: Mon, 7 Jul 2025 21:03:37 +0200
Subject: [PATCH 55/56] use right workflow configuration
---
.github/workflows/config.json | 30 ++++++++++++++++++++----------
.github/workflows/moodle-ci.yml | 1 -
2 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/.github/workflows/config.json b/.github/workflows/config.json
index 7da43e1a52..7a643bc495 100644
--- a/.github/workflows/config.json
+++ b/.github/workflows/config.json
@@ -1,12 +1,22 @@
{
- "main-moodle": "MOODLE_405_STABLE",
+ "moodle-plugin-ci": "4.5.7",
+ "main-moodle": "MOODLE_500_STABLE",
"main-php": "8.3",
- "moodle-php": {
- "MOODLE_401_STABLE": ["8.0", "8.1"],
- "MOODLE_402_STABLE": ["8.1", "8.2"],
- "MOODLE_403_STABLE": ["8.1", "8.2"],
- "MOODLE_404_STABLE": ["8.2", "8.3"],
- "MOODLE_405_STABLE": ["8.1", "8.2", "8.3"]
- },
- "moodle-plugin-ci": "4.5.5"
-}
+ "main-db": "pgsql",
+ "moodle-testmatrix": {
+ "MOODLE_401_STABLE": {
+ "php": ["8.0", "8.1"]
+ },
+ "MOODLE_404_STABLE": {
+ "php": ["8.1", "8.2", "8.3"]
+ },
+ "MOODLE_405_STABLE": {
+ "php": ["8.1", "8.2", "8.3"],
+ "db": ["pgsql", "mariadb", "mysqli"]
+ },
+ "MOODLE_500_STABLE": {
+ "php": ["8.2", "8.3", "8.4"],
+ "db": ["pgsql", "mariadb", "mysqli"]
+ }
+ }
+}
\ No newline at end of file
diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml
index 023398ddf0..0b2eda27b5 100644
--- a/.github/workflows/moodle-ci.yml
+++ b/.github/workflows/moodle-ci.yml
@@ -7,4 +7,3 @@ jobs:
uses: learnweb/moodle-workflows-learnweb/.github/workflows/moodle-ci.yml@main
with:
allow-mustache-lint-error: true
- allow-grunt-error: true
From bb339be5fe573b4923cba5f331cb1af8dc605a52 Mon Sep 17 00:00:00 2001
From: Tamaro Walter
Date: Mon, 7 Jul 2025 21:07:11 +0200
Subject: [PATCH 56/56] allow grunt error
---
.github/workflows/moodle-ci.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml
index 0b2eda27b5..023398ddf0 100644
--- a/.github/workflows/moodle-ci.yml
+++ b/.github/workflows/moodle-ci.yml
@@ -7,3 +7,4 @@ jobs:
uses: learnweb/moodle-workflows-learnweb/.github/workflows/moodle-ci.yml@main
with:
allow-mustache-lint-error: true
+ allow-grunt-error: true