From 715e1320ea7bfda7c4a770767b2b1fc6b88a6807 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Tue, 13 Jun 2023 17:52:15 +0200 Subject: [PATCH 01/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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/62] 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'] . '
' . 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/62] 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/62] 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 140bef2ea99e20a80b606627ac20b60bcfc10016 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Mon, 11 Mar 2024 18:00:48 +0100 Subject: [PATCH 37/62] add deprecated comments --- .../backup_moodleoverflow_stepslib.php | 14 +++--- classes/manager/mail_manager.php | 3 +- classes/observer.php | 2 +- classes/privacy/provider.php | 10 ++--- classes/ratings.php | 2 +- classes/subscriptions.php | 4 +- classes/tables/userstats_table.php | 6 +-- classes/task/send_daily_mail.php | 2 +- index.php | 1 + lib.php | 3 +- locallib.php | 6 +-- post.php | 4 +- tests/behat/behat_mod_moodleoverflow.php | 2 +- tests/dailymail_test.php | 8 ++-- tests/locallib_test.php | 8 ++-- tests/post_test.php | 4 +- tests/privacy_provider_test.php | 36 +++++++-------- tests/ratings_test.php | 8 ++-- tests/readtracking_test.php | 4 +- tests/review_test.php | 12 ++--- tests/subscriptions_test.php | 44 +++++++++---------- tests/userstats_test.php | 14 +++--- userstats.php | 2 +- 23 files changed, 101 insertions(+), 98 deletions(-) diff --git a/backup/moodle2/backup_moodleoverflow_stepslib.php b/backup/moodle2/backup_moodleoverflow_stepslib.php index 91c7499684..b7d8ad154e 100644 --- a/backup/moodle2/backup_moodleoverflow_stepslib.php +++ b/backup/moodle2/backup_moodleoverflow_stepslib.php @@ -47,23 +47,23 @@ protected function define_structure() { $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', ['id'], [ - 'name', 'firstpost', 'userid', 'timemodified', 'usermodified', 'timestart']); + 'name', 'firstpost', 'userid', 'timemodified', 'usermodified', 'timestart', ]); $posts = new backup_nested_element('posts'); $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', ['id'], [ - 'userid', 'rating', 'firstrated', 'lastchanged']); + 'userid', 'rating', 'firstrated', 'lastchanged', ]); $discussionsubs = new backup_nested_element('discuss_subs'); @@ -75,18 +75,18 @@ protected function define_structure() { $subscriptions = new backup_nested_element('subscriptions'); $subscription = new backup_nested_element('subscription', ['id'], [ - 'userid']); + 'userid', ]); $readposts = new backup_nested_element('readposts'); $read = new backup_nested_element('read', ['id'], [ 'userid', 'discussionid', 'postid', 'firstread', - 'lastread']); + 'lastread', ]); $tracking = new backup_nested_element('tracking'); $track = new backup_nested_element('track', ['id'], [ - 'userid']); + 'userid', ]); // Build the tree. $moodleoverflow->add_child($discussions); diff --git a/classes/manager/mail_manager.php b/classes/manager/mail_manager.php index 81d7a94142..9cc0d8cf70 100644 --- a/classes/manager/mail_manager.php +++ b/classes/manager/mail_manager.php @@ -406,7 +406,7 @@ private static function send_post($userto, $post, array &$coursemodules, array & ['userid' => $dataobject->userid, 'courseid' => $dataobject->courseid, 'forumid' => $dataobject->forumid, - 'forumdiscussionid' => $dataobject->forumdiscussionid], + 'forumdiscussionid' => $dataobject->forumdiscussionid, ], 'numberofposts, id'); if (is_object($record)) { $dataset = $record; @@ -497,6 +497,7 @@ private static function send_post($userto, $post, array &$coursemodules, array & // 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); + // TODO: deprecated, option array should not contain context objects. $shortname = format_string($course->shortname, true, ['context' => $coursecontext]); // Define a header to make mails easier to track. diff --git a/classes/observer.php b/classes/observer.php index 78dce0f41a..8dc215b203 100644 --- a/classes/observer.php +++ b/classes/observer.php @@ -95,7 +95,7 @@ public static function role_assigned(\core\event\role_assigned $event) { WHERE m.course = :courseid AND m.forcesubscribe = :initial AND mo.name = 'moodleoverflow' AND ms.id IS NULL"; $params = ['courseid' => $context->instanceid, 'userid' => $userid, - 'initial' => MOODLEOVERFLOW_INITIALSUBSCRIBE]; + 'initial' => MOODLEOVERFLOW_INITIALSUBSCRIBE, ]; $moodleoverflows = $DB->get_records_sql($sql, $params); // Loop through all moodleoverflows. diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php index d29f6b22e8..d1bf9e7644 100644 --- a/classes/privacy/provider.php +++ b/classes/privacy/provider.php @@ -324,22 +324,22 @@ 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 diff --git a/classes/ratings.php b/classes/ratings.php index e19568613a..8756545d21 100644 --- a/classes/ratings.php +++ b/classes/ratings.php @@ -57,7 +57,7 @@ public static function moodleoverflow_add_rating($moodleoverflow, $postid, $rati // Is the submitted rating valid? $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'); } diff --git a/classes/subscriptions.php b/classes/subscriptions.php index 23464b306f..83af4181d2 100644 --- a/classes/subscriptions.php +++ b/classes/subscriptions.php @@ -438,7 +438,7 @@ public static function get_unsubscribable_moodleoverflows() { WHERE m.forcesubscribe <> :forcesubscribe AND ms.id IS NOT NULL AND cm.course $coursesql"; $params = ['modulename' => 'moodleoverflow', 'userid' => $USER->id, - 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE]; + 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE, ]; $mergedparams = array_merge($courseparams, $params); $moodleoverflows = $DB->get_recordset_sql($sql, $mergedparams); @@ -670,7 +670,7 @@ public static function subscribe_user($userid, $moodleoverflow, $context, $userr $params = [ 'userid' => $userid, 'moodleoverflowid' => $moodleoverflow->id, - 'preference' => self::MOODLEOVERFLOW_DISCUSSION_UNSUBSCRIBED]; + 'preference' => self::MOODLEOVERFLOW_DISCUSSION_UNSUBSCRIBED, ]; $where = 'userid = :userid AND moodleoverflow = :moodleoverflowid AND preference <> :preference'; $DB->delete_records_select('moodleoverflow_discuss_subs', $where, $params); diff --git a/classes/tables/userstats_table.php b/classes/tables/userstats_table.php index 94458c5ba0..dfb176fd06 100644 --- a/classes/tables/userstats_table.php +++ b/classes/tables/userstats_table.php @@ -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'); @@ -277,7 +277,7 @@ public function set_helpactivity() { 'tabindex' => '0', 'data-content' => '

' . get_string('helpamountofactivity', 'moodleoverflow') . - '

']; + '

', ]; $this->helpactivity->object = \html_writer::span($this->helpactivity->icon, $this->helpactivity->class, diff --git a/classes/task/send_daily_mail.php b/classes/task/send_daily_mail.php index 2370b8cf83..48ac7a67b2 100644 --- a/classes/task/send_daily_mail.php +++ b/classes/task/send_daily_mail.php @@ -76,7 +76,7 @@ public function execute() { $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. diff --git a/index.php b/index.php index 2c0ae5352d..c4390d12d6 100644 --- a/index.php +++ b/index.php @@ -214,6 +214,7 @@ $returnto = moodleoverflow_go_back_to($url); // Prepare the message to be displayed. + // TODO: Deprecated, options should not contain a context object. $shortname = format_string($course->shortname, true, ['context' => context_course::instance($course->id)]); $notification = \core\output\notification::NOTIFY_SUCCESS; diff --git a/lib.php b/lib.php index 2285625507..18fe92bcf3 100644 --- a/lib.php +++ b/lib.php @@ -788,7 +788,7 @@ function moodleoverflow_send_mails() { ['userid' => $dataobject->userid, 'courseid' => $dataobject->courseid, 'forumid' => $dataobject->forumid, - 'forumdiscussionid' => $dataobject->forumdiscussionid], + 'forumdiscussionid' => $dataobject->forumdiscussionid, ], 'numberofposts, id'); if (is_object($record)) { $dataset = $record; @@ -884,6 +884,7 @@ 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); + // TODO: Deprecated, options should not contain a context object. $shortname = format_string($course->shortname, true, ['context' => $coursecontext]); // Define a header to make mails easier to track. diff --git a/locallib.php b/locallib.php index 917889e8cf..10632384a6 100644 --- a/locallib.php +++ b/locallib.php @@ -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); @@ -325,7 +325,7 @@ 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, ['courseid' => $moodleoverflow->course, - 'link' => false]); + '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; @@ -2061,7 +2061,7 @@ function moodleoverflow_update_user_grade_on_db($moodleoverflow, $postuserrating if ($DB->record_exists('moodleoverflow_grades', ['userid' => $userid, 'moodleoverflowid' => $moodleoverflow->id])) { $DB->set_field('moodleoverflow_grades', 'grade', $grade, ['userid' => $userid, - 'moodleoverflowid' => $moodleoverflow->id]); + 'moodleoverflowid' => $moodleoverflow->id, ]); } else { diff --git a/post.php b/post.php index fe228c6563..976c8f538c 100644 --- a/post.php +++ b/post.php @@ -653,7 +653,7 @@ 'other' => [ '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) { @@ -705,7 +705,7 @@ 'other' => [ 'discussionid' => $discussion->id, 'moodleoverflowid' => $moodleoverflow->id, - ]]; + ], ]; $event = \mod_moodleoverflow\event\post_created::create($params); $event->trigger(); redirect( 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 922050e033..cc2e122a7e 100644 --- a/tests/dailymail_test.php +++ b/tests/dailymail_test.php @@ -136,7 +136,7 @@ private function helper_run_send_mails() { * Test if the task send_daily_mail sends a mail to the user. * @covers \send_daily_mail::execute */ - public function test_mail_delivery() { + public function test_mail_delivery(): void { // Create user with maildigest = on. $this->helper_create_user_and_discussion('1'); @@ -154,7 +154,7 @@ public function test_mail_delivery() { * Test if the content of the mail matches the supposed content. * @covers \send_daily_mail::execute */ - public function test_content_of_mail_delivery() { + public function test_content_of_mail_delivery(): void { // Create user with maildigest = on. $this->helper_create_user_and_discussion('1'); @@ -189,7 +189,7 @@ public function test_content_of_mail_delivery() { * Test if the task does not send a mail when maildigest = 0 * @covers \send_daily_mail::execute */ - public function test_mail_not_send() { + public function test_mail_not_send(): void { // Creat user with daily_mail = off. $this->helper_create_user_and_discussion('0'); @@ -205,7 +205,7 @@ public function test_mail_not_send() { * Test if database is updated after sending a mail * @covers \send_daily_mail::execute */ - public function test_records_removed() { + public function test_records_removed(): void { global $DB; // Create user with maildigest = on. $this->helper_create_user_and_discussion('1'); diff --git a/tests/locallib_test.php b/tests/locallib_test.php index cc3fb54265..9207c21bf3 100644 --- a/tests/locallib_test.php +++ b/tests/locallib_test.php @@ -50,7 +50,7 @@ public function tearDown(): void { * Test subscription using automatic subscription on create. * @covers \mod_moodleoverflow\subscriptions Subscription of users as default. */ - public function test_moodleoverflow_auto_subscribe_on_create() { + public function test_moodleoverflow_auto_subscribe_on_create(): void { global $DB; $this->resetAfterTest(); @@ -83,7 +83,7 @@ public function test_moodleoverflow_auto_subscribe_on_create() { * Test subscription using forced subscription on create. * @covers \mod_moodleoverflow\subscriptions sorced Subscription of users. */ - public function test_moodleoverflow_forced_subscribe_on_create() { + public function test_moodleoverflow_forced_subscribe_on_create(): void { global $DB; $this->resetAfterTest(); @@ -115,7 +115,7 @@ public function test_moodleoverflow_forced_subscribe_on_create() { * Test subscription using optional subscription on create. * @covers \mod_moodleoverflow\subscriptions optional subscription. */ - public function test_moodleoverflow_optional_subscribe_on_create() { + public function test_moodleoverflow_optional_subscribe_on_create(): void { global $DB; $this->resetAfterTest(); @@ -146,7 +146,7 @@ public function test_moodleoverflow_optional_subscribe_on_create() { * Test subscription using disallow subscription on create. * @covers \mod_moodleoverflow\subscriptions prohibit Subscription of users. */ - public function test_moodleoverflow_disallow_subscribe_on_create() { + public function test_moodleoverflow_disallow_subscribe_on_create(): void { global $DB; $this->resetAfterTest(); diff --git a/tests/post_test.php b/tests/post_test.php index 6e7d6394d9..b29614c879 100644 --- a/tests/post_test.php +++ b/tests/post_test.php @@ -75,7 +75,7 @@ public function tearDown(): void { * Test if a post and its attachment are deleted successfully. * @covers ::moodleoverflow_delete_post */ - public function test_moodleoverflow_delete_post() { + public function test_moodleoverflow_delete_post(): void { global $DB; // The attachment should exist. @@ -95,7 +95,7 @@ public function test_moodleoverflow_delete_post() { * Test if a post and its attachment are deleted successfully. * @covers ::moodleoverflow_delete_discussion */ - public function test_moodleoverflow_delete_discussion() { + public function test_moodleoverflow_delete_discussion(): void { global $DB; $numberofattachments = count($DB->get_records('files', ['itemid' => $this->post->id, 'filearea' => 'attachment'])); diff --git a/tests/privacy_provider_test.php b/tests/privacy_provider_test.php index 4e083dd469..5b6d7b60a3 100644 --- a/tests/privacy_provider_test.php +++ b/tests/privacy_provider_test.php @@ -119,7 +119,7 @@ protected function assert_post_data($expected, $actual, $writer) { * @return void * @throws \coding_exception */ - public function test_user_has_never_posted() { + public function test_user_has_never_posted(): void { // Create a course with moodleoverflow forums. list($course, $forum) = $this->create_courses_and_modules(3); // Create users. @@ -150,7 +150,7 @@ public function test_user_has_never_posted() { * posted and has subscribed to the forum will have relevant * information returned. */ - public function test_user_has_never_posted_subscribed_to_forum() { + public function test_user_has_never_posted_subscribed_to_forum(): void { // Create a course, with a forum, our user under test, another user, and a discussion + post from the other user. list($course, $forum) = $this->create_courses_and_modules(3); list($user, $otheruser) = $this->create_and_enrol_users($course, 2); @@ -183,7 +183,7 @@ public function test_user_has_never_posted_subscribed_to_forum() { * posted and has subscribed to the discussion will have relevant * information returned. */ - public function test_user_has_never_posted_subscribed_to_discussion() { + public function test_user_has_never_posted_subscribed_to_discussion(): void { // Create a course, with a forum, our user under test, another user, and a discussion + post from the other user. list($course, $forum) = $this->create_courses_and_modules(3); // Create users. @@ -228,7 +228,7 @@ public function test_user_has_never_posted_subscribed_to_discussion() { * Test that a user who has posted their own discussion will have all * content returned. */ - public function test_user_has_posted_own_discussion() { + public function test_user_has_posted_own_discussion(): void { list($course, $forum) = $this->create_courses_and_modules(3); list($user, $otheruser) = $this->create_users($course, 2); // Post twice - only the second discussion should be included. @@ -256,7 +256,7 @@ public function test_user_has_posted_own_discussion() { * Test that a user who has posted a reply to another users discussion * will have all content returned. */ - public function test_user_has_posted_reply() { + public function test_user_has_posted_reply(): void { global $DB; // Create several courses and forums. We only insert data into the final one. list($course, $forum) = $this->create_courses_and_modules(3); @@ -296,7 +296,7 @@ public function test_user_has_posted_reply() { * Test that the rating of another users content will have only the * rater's information returned. */ - public function test_user_has_rated_others() { + public function test_user_has_rated_others(): void { $course = $this->getDataGenerator()->create_course(); $forum = $this->getDataGenerator()->create_module('moodleoverflow', [ 'course' => $course->id, @@ -339,7 +339,7 @@ public function test_user_has_rated_others() { /** * Test that ratings of a users own content will all be returned. */ - public function test_user_has_been_rated() { + public function test_user_has_been_rated(): void { $course = $this->getDataGenerator()->create_course(); $forum = $this->getDataGenerator()->create_module('moodleoverflow', [ 'course' => $course->id, @@ -377,7 +377,7 @@ public function test_user_has_been_rated() { /** * Test that the per-user, per-forum user tracking data is exported. */ - public function test_user_tracking_data() { + public function test_user_tracking_data(): void { $course = $this->getDataGenerator()->create_course(); $forumoff = $this->getDataGenerator()->create_module('moodleoverflow', ['course' => $course->id]); $cmoff = get_coursemodule_from_instance('moodleoverflow', $forumoff->id); @@ -403,7 +403,7 @@ public function test_user_tracking_data() { /** * Test that the posts which a user has read are returned correctly. */ - public function test_user_read_posts() { + public function test_user_read_posts(): void { global $DB; $course = $this->getDataGenerator()->create_course(); $forum1 = $this->getDataGenerator()->create_module('moodleoverflow', ['course' => $course->id]); @@ -534,7 +534,7 @@ public function test_user_read_posts() { /** * Test that posts with attachments have their attachments correctly exported. */ - public function test_post_attachment_inclusion() { + public function test_post_attachment_inclusion(): void { global $DB; $fs = get_file_storage(); $course = $this->getDataGenerator()->create_course(); @@ -1132,7 +1132,7 @@ public function test_delete_data_for_users() { /** * Ensure that the discussion author is listed as a user in the context. */ - public function test_get_users_in_context_post_author() { + public function test_get_users_in_context_post_author(): void { global $DB; $component = 'mod_moodleoverflow'; @@ -1157,7 +1157,7 @@ public function test_get_users_in_context_post_author() { /** * Ensure that all post authors are included as a user in the context. */ - public function test_get_users_in_context_post_authors() { + public function test_get_users_in_context_post_authors(): void { global $DB; $component = 'mod_moodleoverflow'; @@ -1192,7 +1192,7 @@ public function test_get_users_in_context_post_authors() { * Ensure that all post raters are included as a user in the context --> this is different from the forum ratings, * since ratings in moodle overflow are saved in a separate table */ - public function test_get_users_in_context_post_ratings() { + public function test_get_users_in_context_post_ratings(): void { global $DB; $component = 'mod_moodleoverflow'; @@ -1234,7 +1234,7 @@ public function test_get_users_in_context_post_ratings() { /** * Ensure that all users with a moodleoverflow subscription preference included as a user in the context. */ - public function test_get_users_in_context_with_subscription() { + public function test_get_users_in_context_with_subscription(): void { global $DB; $component = 'mod_moodleoverflow'; @@ -1271,7 +1271,7 @@ public function test_get_users_in_context_with_subscription() { /** * Ensure that all users with a per-discussion subscription preference included as a user in the context. */ - public function test_get_users_in_context_with_discussion_subscription() { + public function test_get_users_in_context_with_discussion_subscription(): void { $component = 'mod_moodleoverflow'; $course = $this->getDataGenerator()->create_course(); @@ -1310,7 +1310,7 @@ public function test_get_users_in_context_with_discussion_subscription() { /** * Ensure that all users with read tracking are included as a user in the context. */ - public function test_get_users_in_context_with_read_post_tracking() { + public function test_get_users_in_context_with_read_post_tracking(): void { $component = 'mod_moodleoverflow'; $course = $this->getDataGenerator()->create_course(); @@ -1366,7 +1366,7 @@ public function test_get_users_in_context_with_read_post_tracking() { /** * Ensure that all users with tracking preferences are included as a user in the context. */ - public function test_get_users_in_context_with_tracking_preferences() { + public function test_get_users_in_context_with_tracking_preferences(): void { global $DB; $component = 'mod_moodleoverflow'; @@ -1421,7 +1421,7 @@ public function test_get_users_in_context_with_tracking_preferences() { * @throws coding_exception * @throws dml_exception */ - public function test_grades() { + public function test_grades(): void { global $DB; $course = self::getDataGenerator()->create_course(); diff --git a/tests/ratings_test.php b/tests/ratings_test.php index daa2a7aff2..f0dccc267b 100644 --- a/tests/ratings_test.php +++ b/tests/ratings_test.php @@ -107,7 +107,7 @@ public function tearDown(): void { * Test case: Every group of rating exists (helful and solved posts, only helpful/solved and none) * @covers \ratings::moodleoverflow_sort_answer_by_ratings() */ - public function test_answersorting_everygroup() { + public function test_answersorting_everygroup(): void { // Create helpful, solved, up and downvotes ratings. $this->create_everygroup(); @@ -132,7 +132,7 @@ public function test_answersorting_everygroup() { * Test case: One group of rating does not exist * @covers \ratings::moodleoverflow_sort_answer_by_ratings() */ - public function test_answersorting_threegroups() { + public function test_answersorting_threegroups(): void { // Create helpful, solved, up and downvotes ratings. $this->create_everygroup(); @@ -178,7 +178,7 @@ public function test_answersorting_threegroups() { * Test case: two groups of rating do not exist * @covers \ratings::moodleoverflow_sort_answer_by_ratings() */ - public function test_answersorting_twogroups() { + public function test_answersorting_twogroups(): void { $this->set_ratingpreferences(0); // Test case 1: helpful and solved post, only solved posts. @@ -228,7 +228,7 @@ public function test_answersorting_twogroups() { * Extended Test Case: If the votesdifference is the same, the post should be sorted by their time of creation/modification. * @covers \ratings::moodleoverflow_sort_answer_by_ratings() */ - public function test_answersorting_onegroup() { + public function test_answersorting_onegroup(): void { $this->set_ratingpreferences(0); // Test case 1: only solved and helpful posts. diff --git a/tests/readtracking_test.php b/tests/readtracking_test.php index a4bfa108d3..015d7f4403 100644 --- a/tests/readtracking_test.php +++ b/tests/readtracking_test.php @@ -43,7 +43,7 @@ class readtracking_test extends advanced_testcase { /** * Test the logic in the moodleoverflow_can_track_moodleoverflows() function. */ - public function test_moodleoverflow_can_track_moodleoverflows() { + public function test_moodleoverflow_can_track_moodleoverflows(): void { // Reset after testing. $this->resetAfterTest(); @@ -92,7 +92,7 @@ public function test_moodleoverflow_can_track_moodleoverflows() { /** * Test the logic in the test_forum_tp_is_tracked() function. */ - public function test_moodleoverflow_is_tracked() { + public function test_moodleoverflow_is_tracked(): void { $this->resetAfterTest(); diff --git a/tests/review_test.php b/tests/review_test.php index b0124c5e90..d6ceeb90e6 100644 --- a/tests/review_test.php +++ b/tests/review_test.php @@ -108,12 +108,12 @@ protected function tearDown(): void { * * @runInSeparateProcess */ - public function test_forum_review_everything() { + public function test_forum_review_everything(): void { global $DB, $CFG; require_once($CFG->dirroot . '/mod/moodleoverflow/externallib.php'); $options = ['course' => $this->course->id, 'needsreview' => review::EVERYTHING, - 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE]; + 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE, ]; $posts = $this->create_post($options); $this->check_mail_records($posts['teacherpost'], $posts['studentpost'], 1, 0, MOODLEOVERFLOW_MAILED_REVIEW_SUCCESS); @@ -173,12 +173,12 @@ public function test_forum_review_everything() { * * @runInSeparateProcess */ - public function test_forum_review_only_questions() { + public function test_forum_review_only_questions(): void { global $DB, $CFG; require_once($CFG->dirroot . '/mod/moodleoverflow/externallib.php'); $options = ['course' => $this->course->id, 'needsreview' => review::QUESTIONS, - 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE]; + 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE, ]; $posts = $this->create_post($options); $this->check_mail_records($posts['teacherpost'], $posts['studentpost'], 1, 0, MOODLEOVERFLOW_MAILED_REVIEW_SUCCESS); @@ -214,9 +214,9 @@ public function test_forum_review_only_questions() { /** * Test reviews functionality when reviewing is allowed in admin settings. */ - public function test_forum_review_disallowed() { + public function test_forum_review_disallowed(): void { $options = ['course' => $this->course->id, 'needsreview' => review::EVERYTHING, - 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE]; + 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE, ]; set_config('allowreview', 0, 'moodleoverflow'); diff --git a/tests/subscriptions_test.php b/tests/subscriptions_test.php index 28f5776a9d..2c8651e26e 100644 --- a/tests/subscriptions_test.php +++ b/tests/subscriptions_test.php @@ -110,7 +110,7 @@ protected function helper_post_to_moodleoverflow($moodleoverflow, $author) { /** * Test to set subscription modes. */ - public function test_subscription_modes() { + public function test_subscription_modes(): void { global $DB; // Reset the database after testing. @@ -162,7 +162,7 @@ public function test_subscription_modes() { /** * Test fetching unsubscribable moodleoverflows. */ - public function test_unsubscribable_moodleoverflows() { + public function test_unsubscribable_moodleoverflows(): void { // Reset the database after testing. $this->resetAfterTest(true); @@ -211,7 +211,7 @@ public function test_unsubscribable_moodleoverflows() { /** * Test that toggeling the moodleoverflow-level subscription for a different user does not affect their discussion-level. */ - public function test_moodleoverflow_toggle_as_other() { + public function test_moodleoverflow_toggle_as_other(): void { global $DB; // Reset the database after testing. @@ -384,7 +384,7 @@ public function test_moodleoverflow_toggle_as_other() { /** * Test that a user unsubscribed from a moodleoverflow is not subscribed to it's discussions by default. */ - public function test_moodleoverflow_discussion_subscription_moodleoverflow_unsubscribed() { + public function test_moodleoverflow_discussion_subscription_moodleoverflow_unsubscribed(): void { // Reset the database after the test. $this->resetAfterTest(true); @@ -411,7 +411,7 @@ public function test_moodleoverflow_discussion_subscription_moodleoverflow_unsub /** * Test that the act of subscribing to a moodleoverflow subscribes the user to it's discussions by default. */ - public function test_moodleoverflow_discussion_subscription_moodleoverflow_subscribed() { + public function test_moodleoverflow_discussion_subscription_moodleoverflow_subscribed(): void { // Reset the database after testing. $this->resetAfterTest(true); @@ -450,7 +450,7 @@ public function test_moodleoverflow_discussion_subscription_moodleoverflow_subsc /** * Test that a user unsubscribed from a moodleoverflow can be subscribed to a discussion. */ - public function test_moodleoverflow_discussion_subscription_moodleoverflow_unsubscribed_discussion_subscribed() { + public function test_moodleoverflow_discussion_subscription_moodleoverflow_unsubscribed_discussion_subscribed(): void { // Reset the database after testing. $this->resetAfterTest(true); @@ -494,7 +494,7 @@ public function test_moodleoverflow_discussion_subscription_moodleoverflow_unsub /** * Test that a user subscribed to a moodleoverflow can be unsubscribed from a discussion. */ - public function test_moodleoverflow_discussion_subscription_moodleoverflow_subscribed_discussion_unsubscribed() { + public function test_moodleoverflow_discussion_subscription_moodleoverflow_subscribed_discussion_unsubscribed(): void { // Reset the database after testing. $this->resetAfterTest(true); @@ -536,7 +536,7 @@ public function test_moodleoverflow_discussion_subscription_moodleoverflow_subsc /** * Test the effect of toggling the discussion subscription status when subscribed to the moodleoverflow. */ - public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed() { + public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed(): void { global $DB; // Reset the database after testing. @@ -715,7 +715,7 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_subscribed( /** * Test the effect of toggling the discussion subscription status when unsubscribed from the moodleoverflow. */ - public function test_moodleoverflow_discussion_toggle_moodleoverflow_unsubscribed() { + public function test_moodleoverflow_discussion_toggle_moodleoverflow_unsubscribed(): void { global $DB; // Reset the database after testing. @@ -816,7 +816,7 @@ public function test_moodleoverflow_discussion_toggle_moodleoverflow_unsubscribe * Test that the correct users are returned when fetching subscribed users * from a moodleoverflow where users can choose to subscribe and unsubscribe. */ - public function test_fetch_subscribed_users_subscriptions() { + public function test_fetch_subscribed_users_subscriptions(): void { global $CFG; // Reset the database after testing. @@ -859,7 +859,7 @@ public function test_fetch_subscribed_users_subscriptions() { * Test that the correct users are returned hwen fetching subscribed users from a moodleoverflow where users are forcibly * subscribed. */ - public function test_fetch_subscribed_users_forced() { + public function test_fetch_subscribed_users_forced(): void { // Reset the database after testing. $this->resetAfterTest(true); @@ -884,7 +884,7 @@ public function test_fetch_subscribed_users_forced() { /** * Test that unusual combinations of discussion subscriptions do not affect the subscribed user list. */ - public function test_fetch_subscribed_users_discussion_subscriptions() { + public function test_fetch_subscribed_users_discussion_subscriptions(): void { global $DB; // Reset after testing. @@ -970,7 +970,7 @@ public function test_fetch_subscribed_users_discussion_subscriptions() { /** * Test whether a user is force-subscribed to a moodleoverflow. */ - public function test_force_subscribed_to_moodleoverflow() { + public function test_force_subscribed_to_moodleoverflow(): void { global $DB; // Reset database after testing. @@ -1003,7 +1003,7 @@ public function test_force_subscribed_to_moodleoverflow() { /** * Test that the subscription cache can be pre-filled. */ - public function test_subscription_cache_prefill() { + public function test_subscription_cache_prefill(): void { global $DB; // Reset the database after testing. @@ -1037,7 +1037,7 @@ public function test_subscription_cache_prefill() { /** * Test that the subscription cache can filled user-at-a-time. */ - public function test_subscription_cache_fill() { + public function test_subscription_cache_fill(): void { global $DB; // Reset the database after testing. @@ -1069,7 +1069,7 @@ public function test_subscription_cache_fill() { /** * Test that the discussion subscription cache can filled course-at-a-time. */ - public function test_discussion_subscription_cache_fill_for_course() { + public function test_discussion_subscription_cache_fill_for_course(): void { global $DB; // Reset the database after testing. @@ -1122,7 +1122,7 @@ public function test_discussion_subscription_cache_fill_for_course() { /** * Test that the discussion subscription cache can be forcibly updated for a user. */ - public function test_discussion_subscription_cache_prefill() { + public function test_discussion_subscription_cache_prefill(): void { global $DB; // Reset the database after testing. @@ -1189,7 +1189,7 @@ public function test_discussion_subscription_cache_prefill() { /** * Test that the discussion subscription cache can filled user-at-a-time. */ - public function test_discussion_subscription_cache_fill() { + public function test_discussion_subscription_cache_fill(): void { global $DB; // Reset the database after testing. @@ -1262,7 +1262,7 @@ public function test_discussion_subscription_cache_fill() { * Test that after toggling the moodleoverflow subscription as another user, * the discussion subscription functionality works as expected. */ - public function test_moodleoverflow_subscribe_toggle_as_other_repeat_subscriptions() { + public function test_moodleoverflow_subscribe_toggle_as_other_repeat_subscriptions(): void { global $DB; // Reset the database after testing. @@ -1398,7 +1398,7 @@ public function is_subscribable_provider() { * * @dataProvider is_subscribable_provider */ - public function test_is_subscribable_logged_out($options) { + public function test_is_subscribable_logged_out($options): void { $this->resetAfterTest(true); // Create a course, with a moodleoverflow. @@ -1417,7 +1417,7 @@ public function test_is_subscribable_logged_out($options) { * * @dataProvider is_subscribable_provider */ - public function test_is_subscribable_is_guest($options) { + public function test_is_subscribable_is_guest($options): void { global $DB; $this->resetAfterTest(true); @@ -1467,7 +1467,7 @@ public function is_subscribable_loggedin_provider() { * * @dataProvider is_subscribable_loggedin_provider */ - public function test_is_subscribable_loggedin($options, $expect) { + public function test_is_subscribable_loggedin($options, $expect): void { // Reset the database after testing. $this->resetAfterTest(true); diff --git a/tests/userstats_test.php b/tests/userstats_test.php index 598a92edd4..b6078f1670 100644 --- a/tests/userstats_test.php +++ b/tests/userstats_test.php @@ -103,7 +103,7 @@ public function tearDown(): void { * Test, if a upvote is being counted. * @covers \userstats_table */ - public function test_upvote() { + public function test_upvote(): void { // Teacher upvotes the discussion and the answer of user2. $this->create_upvote($this->teacher, $this->discussion1[1], $this->answer1); @@ -117,7 +117,7 @@ public function test_upvote() { * Test, if a downvote is being counted. * @covers \userstats_table */ - public function test_downvote() { + public function test_downvote(): void { // Teacher downvotes the discussion and the answer of user1. $this->create_downvote($this->teacher, $this->discussion2[1], $this->answer2); @@ -131,7 +131,7 @@ public function test_downvote() { * Test, if the activity is calculated correctly. * @covers \userstats_table */ - public function test_activity() { + public function test_activity(): void { // User1 will rates 3 times. $this->create_helpful($this->user1, $this->discussion1[1], $this->answer1); $this->create_upvote($this->user1, $this->discussion1[1], $this->answer1); @@ -148,7 +148,7 @@ public function test_activity() { * Test, if the reputation is calculated correctly. * @covers \userstats_table */ - public function test_reputation() { + public function test_reputation(): void { // User1 creates some ratings for user2, Teacher creates some ratings for user2. $this->create_helpful($this->user1, $this->discussion1[1], $this->answer1); $this->create_upvote($this->user1, $this->discussion1[1], $this->answer1); @@ -168,7 +168,7 @@ public function test_reputation() { * Test, if userstats are calculated correctly if the moodleoverflow is partially anonymous. * @covers \userstats_table */ - public function test_partial_anonymous() { + public function test_partial_anonymous(): void { global $DB; // Test case: Only topic startes are anonymous. $this->make_anonymous(1); @@ -224,7 +224,7 @@ public function test_partial_anonymous() { * Test, if userstats are calculated correctly if the moodleoverflow is partially anonymous. * @covers \userstats_table */ - public function test_total_anonymous() { + public function test_total_anonymous(): void { // Test case: Only topic startes are anonymous. $this->make_anonymous(2); @@ -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(); diff --git a/userstats.php b/userstats.php index a2984f8e95..1b5eecf165 100644 --- a/userstats.php +++ b/userstats.php @@ -57,7 +57,7 @@ if (has_capability('mod/moodleoverflow:viewanyrating', $context) && get_config('moodleoverflow', 'showuserstats')) { // Print the page header. $PAGE->set_url('/mod/moodleoverflow/userstats.php', ['id' => $cm->id, - 'courseid' => $course->id, 'mid' => $moodleoverflow->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)); From bb98d3310c8af494ab3fda32cce38fc6f1b3dcba Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Mon, 11 Mar 2024 18:36:46 +0100 Subject: [PATCH 38/62] bootstrap adjustments for Moodle 4.4. --- classes/tables/userstats_table.php | 4 ++-- locallib.php | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/classes/tables/userstats_table.php b/classes/tables/userstats_table.php index dfb176fd06..677dc7d081 100644 --- a/classes/tables/userstats_table.php +++ b/classes/tables/userstats_table.php @@ -356,10 +356,10 @@ public function col_coursereputation($row) { */ private function badge_render($number) { if ($number > 0) { - return \html_writer::tag('h5', \html_writer::start_span('badge badge-success') . + return \html_writer::tag('h5', \html_writer::start_span('badge bg-success') . $number . \html_writer::end_span()); } else { - return \html_writer::tag('h5', \html_writer::start_span('badge badge-warning') . + return \html_writer::tag('h5', \html_writer::start_span('badge bg-warning') . $number . \html_writer::end_span()); } } diff --git a/locallib.php b/locallib.php index 10632384a6..1c2e5e2188 100644 --- a/locallib.php +++ b/locallib.php @@ -1446,6 +1446,7 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co $mustachedata->withinreviewperiod = $reviewable; // Prepare the post. + // TODO: Deprecated $courseiddonotuse deprecated course id, use context option instead. $mustachedata->postcontent = format_text($post->message, $post->messageformat, $options, $course->id); // Load the attachments. From a705aa068d00a49f218053602bce12712ff3ad5e Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Tue, 12 Mar 2024 19:00:07 +0100 Subject: [PATCH 39/62] Completed updates for moodle 404 --- classes/manager/mail_manager.php | 6 +++--- index.php | 6 ++++-- lib.php | 7 ++++--- locallib.php | 22 +++++----------------- post.php | 7 +++++-- tests/review_test.php | 9 ++++++--- tests/subscriptions_test.php | 2 ++ 7 files changed, 29 insertions(+), 30 deletions(-) diff --git a/classes/manager/mail_manager.php b/classes/manager/mail_manager.php index 9cc0d8cf70..388c017eaf 100644 --- a/classes/manager/mail_manager.php +++ b/classes/manager/mail_manager.php @@ -26,6 +26,7 @@ use context_course; use context_module; +use core\context\course; use core_php_time_limit; use mod_moodleoverflow\anonymous; use mod_moodleoverflow\output\moodleoverflow_email; @@ -496,9 +497,8 @@ private static function send_post($userto, $post, array &$coursemodules, array & // 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); - // TODO: deprecated, option array should not contain context objects. - $shortname = format_string($course->shortname, true, ['context' => $coursecontext]); + $formatter = \core\di::get(\core\formatting::class); + $shortname = $formatter->format_string($course->shortname, true, course::instance($course->id)); // Define a header to make mails easier to track. $emailmessageid = generate_email_messageid('moodlemoodleoverflow' . $moodleoverflow->id); diff --git a/index.php b/index.php index c4390d12d6..0431279801 100644 --- a/index.php +++ b/index.php @@ -23,6 +23,8 @@ */ // Require needed files. +use core\context\course; + require_once(dirname(dirname(dirname(__FILE__))) . '/config.php'); require_once(dirname(__FILE__) . '/locallib.php'); require_once($CFG->dirroot . '/course/lib.php'); @@ -214,8 +216,8 @@ $returnto = moodleoverflow_go_back_to($url); // Prepare the message to be displayed. - // TODO: Deprecated, options should not contain a context object. - $shortname = format_string($course->shortname, true, ['context' => context_course::instance($course->id)]); + $formatter = \core\di::get(\core\formatting::class); + $shortname = $formatter->format_string($course->shortname, true, course::instance($course->id)); $notification = \core\output\notification::NOTIFY_SUCCESS; // Redirect the user depending on the subscription state. diff --git a/lib.php b/lib.php index 18fe92bcf3..0ade1d1b42 100644 --- a/lib.php +++ b/lib.php @@ -29,6 +29,8 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use core\context\course; + defined('MOODLE_INTERNAL') || die(); require_once(dirname(__FILE__) . '/locallib.php'); @@ -883,9 +885,8 @@ 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); - // TODO: Deprecated, options should not contain a context object. - $shortname = format_string($course->shortname, true, ['context' => $coursecontext]); + $formatter = \core\di::get(\core\formatting::class); + $shortname = $formatter->format_string($course->shortname, true, course::instance($course->id)); // Define a header to make mails easier to track. $emailmessageid = generate_email_messageid('moodlemoodleoverflow' . $moodleoverflow->id); diff --git a/locallib.php b/locallib.php index 1c2e5e2188..4009c021c8 100644 --- a/locallib.php +++ b/locallib.php @@ -24,7 +24,6 @@ * @copyright 2017 Kennet Winter * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ - use mod_moodleoverflow\anonymous; use mod_moodleoverflow\capabilities; use mod_moodleoverflow\event\post_deleted; @@ -928,12 +927,7 @@ function moodleoverflow_print_discussion($course, $cm, $moodleoverflow, $discuss // Retrieve all posts of the discussion. $posts = moodleoverflow_get_all_discussion_posts($discussion->id, $istracked, $modulecontext); - /*$newpost = []; - foreach($posts as $posti) { - $newpost[] = $posti->message; - } - var_dump($newpost); - */$usermapping = anonymous::get_userid_mapping($moodleoverflow, $discussion->id); + $usermapping = anonymous::get_userid_mapping($moodleoverflow, $discussion->id); // Start with the parent post. $post = $posts[$post->id]; @@ -1432,12 +1426,6 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co } $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; @@ -1446,8 +1434,8 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co $mustachedata->withinreviewperiod = $reviewable; // Prepare the post. - // TODO: Deprecated $courseiddonotuse deprecated course id, use context option instead. - $mustachedata->postcontent = format_text($post->message, $post->messageformat, $options, $course->id); + $formatter = \core\di::get(\core\formatting::class); + $mustachedata->postcontent = $formatter->format_text($post->message, $post->messageformat, context_module::instance($cm->id)); // Load the attachments. $mustachedata->attachments = get_attachments($post, $cm); @@ -1857,10 +1845,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(); } diff --git a/post.php b/post.php index 976c8f538c..303ba6223c 100644 --- a/post.php +++ b/post.php @@ -25,6 +25,7 @@ // TODO refactor this. For more readability, and to avoid security issues. // Include config and locallib. +use mod_moodleoverflow\anonymous; use mod_moodleoverflow\review; require_once(dirname(dirname(dirname(__FILE__))) . '/config.php'); @@ -490,7 +491,9 @@ empty($post->id) ? null : $post->id, mod_moodleoverflow_post_form::attachment_options($moodleoverflow)); -if ($draftitemid && $edit && \mod_moodleoverflow\anonymous::is_post_anonymous($discussion, $moodleoverflow, $post->userid) && $post->userid != $USER->id) { +if ($draftitemid && $edit && anonymous::is_post_anonymous($discussion, $moodleoverflow, $post->userid) + && $post->userid != $USER->id) { + $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) { @@ -634,7 +637,7 @@ if ($realpost->userid == $USER->id) { $message .= get_string('postupdated', 'moodleoverflow'); } else { - if (\mod_moodleoverflow\anonymous::is_post_anonymous($discussion, $moodleoverflow, $realpost->userid)) { + if (anonymous::is_post_anonymous($discussion, $moodleoverflow, $realpost->userid)) { $name = get_string('anonymous', 'moodleoverflow'); } else { $realuser = $DB->get_record('user', ['id' => $realpost->userid]); diff --git a/tests/review_test.php b/tests/review_test.php index d6ceeb90e6..13d54ce7af 100644 --- a/tests/review_test.php +++ b/tests/review_test.php @@ -292,15 +292,18 @@ 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], + $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], + $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], + $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])); diff --git a/tests/subscriptions_test.php b/tests/subscriptions_test.php index 2c8651e26e..756a67eae5 100644 --- a/tests/subscriptions_test.php +++ b/tests/subscriptions_test.php @@ -1397,6 +1397,7 @@ public function is_subscribable_provider() { * @param array $options * * @dataProvider is_subscribable_provider + * @return void */ public function test_is_subscribable_logged_out($options): void { $this->resetAfterTest(true); @@ -1416,6 +1417,7 @@ public function test_is_subscribable_logged_out($options): void { * @param array $options * * @dataProvider is_subscribable_provider + * @return void */ public function test_is_subscribable_is_guest($options): void { global $DB; From 397d407c81283bb0124d02492083802c540b40fe Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Tue, 12 Mar 2024 19:43:32 +0100 Subject: [PATCH 40/62] user old format_string functions for compatibility --- classes/manager/mail_manager.php | 3 +-- index.php | 3 +-- lib.php | 3 +-- locallib.php | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/classes/manager/mail_manager.php b/classes/manager/mail_manager.php index 388c017eaf..15a592c5cf 100644 --- a/classes/manager/mail_manager.php +++ b/classes/manager/mail_manager.php @@ -497,8 +497,7 @@ private static function send_post($userto, $post, array &$coursemodules, array & // Preapare to actually send the post now. Build up the content. $cleanname = str_replace('"', "'", strip_tags(format_string($moodleoverflow->name))); - $formatter = \core\di::get(\core\formatting::class); - $shortname = $formatter->format_string($course->shortname, true, course::instance($course->id)); + $shortname = format_string($course->shortname, true, ['context' => course::instance($course->id)]); // Define a header to make mails easier to track. $emailmessageid = generate_email_messageid('moodlemoodleoverflow' . $moodleoverflow->id); diff --git a/index.php b/index.php index 0431279801..037a175317 100644 --- a/index.php +++ b/index.php @@ -216,8 +216,7 @@ $returnto = moodleoverflow_go_back_to($url); // Prepare the message to be displayed. - $formatter = \core\di::get(\core\formatting::class); - $shortname = $formatter->format_string($course->shortname, true, course::instance($course->id)); + $shortname = format_string($course->shortname, true, ['context' => course::instance($course->id)]); $notification = \core\output\notification::NOTIFY_SUCCESS; // Redirect the user depending on the subscription state. diff --git a/lib.php b/lib.php index 0ade1d1b42..e21b2e7444 100644 --- a/lib.php +++ b/lib.php @@ -885,8 +885,7 @@ function moodleoverflow_send_mails() { // Preapare to actually send the post now. Build up the content. $cleanname = str_replace('"', "'", strip_tags(format_string($moodleoverflow->name))); - $formatter = \core\di::get(\core\formatting::class); - $shortname = $formatter->format_string($course->shortname, true, course::instance($course->id)); + $shortname = format_string($course->shortname, true, ['context' => course::instance($course->id)]); // Define a header to make mails easier to track. $emailmessageid = generate_email_messageid('moodlemoodleoverflow' . $moodleoverflow->id); diff --git a/locallib.php b/locallib.php index 4009c021c8..2f04bdefe0 100644 --- a/locallib.php +++ b/locallib.php @@ -1434,8 +1434,7 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co $mustachedata->withinreviewperiod = $reviewable; // Prepare the post. - $formatter = \core\di::get(\core\formatting::class); - $mustachedata->postcontent = $formatter->format_text($post->message, $post->messageformat, context_module::instance($cm->id)); + $mustachedata->postcontent = format_text($post->message, $post->messageformat, context_module::instance($cm->id)); // Load the attachments. $mustachedata->attachments = get_attachments($post, $cm); From 586cf03cec2e94d046b9a7d7a8c7b31f56aa04c1 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Tue, 12 Mar 2024 20:01:19 +0100 Subject: [PATCH 41/62] fix fails --- classes/manager/mail_manager.php | 2 +- index.php | 2 +- lib.php | 2 +- locallib.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/classes/manager/mail_manager.php b/classes/manager/mail_manager.php index 15a592c5cf..9fc7118b0a 100644 --- a/classes/manager/mail_manager.php +++ b/classes/manager/mail_manager.php @@ -497,7 +497,7 @@ private static function send_post($userto, $post, array &$coursemodules, array & // Preapare to actually send the post now. Build up the content. $cleanname = str_replace('"', "'", strip_tags(format_string($moodleoverflow->name))); - $shortname = format_string($course->shortname, true, ['context' => course::instance($course->id)]); + $shortname = format_string($course->shortname, true, ['context' => context_course::instance($course->id)]); // Define a header to make mails easier to track. $emailmessageid = generate_email_messageid('moodlemoodleoverflow' . $moodleoverflow->id); diff --git a/index.php b/index.php index 037a175317..979e43a7f1 100644 --- a/index.php +++ b/index.php @@ -216,7 +216,7 @@ $returnto = moodleoverflow_go_back_to($url); // Prepare the message to be displayed. - $shortname = format_string($course->shortname, true, ['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. diff --git a/lib.php b/lib.php index e21b2e7444..b49ed4cd0d 100644 --- a/lib.php +++ b/lib.php @@ -885,7 +885,7 @@ function moodleoverflow_send_mails() { // Preapare to actually send the post now. Build up the content. $cleanname = str_replace('"', "'", strip_tags(format_string($moodleoverflow->name))); - $shortname = format_string($course->shortname, true, ['context' => course::instance($course->id)]); + $shortname = format_string($course->shortname, true, ['context' => context_course::instance($course->id)]); // Define a header to make mails easier to track. $emailmessageid = generate_email_messageid('moodlemoodleoverflow' . $moodleoverflow->id); diff --git a/locallib.php b/locallib.php index 2f04bdefe0..a816a6e1a1 100644 --- a/locallib.php +++ b/locallib.php @@ -1434,7 +1434,7 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co $mustachedata->withinreviewperiod = $reviewable; // Prepare the post. - $mustachedata->postcontent = format_text($post->message, $post->messageformat, context_module::instance($cm->id)); + $mustachedata->postcontent = format_text($post->message, $post->messageformat, $modulecontext); // Load the attachments. $mustachedata->attachments = get_attachments($post, $cm); From cc3e169612ac88d18ef6f40947db986240bd2b04 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Tue, 12 Mar 2024 20:01:51 +0100 Subject: [PATCH 42/62] delete workflows for unsupported versions --- .github/workflows/moodle-ci.yml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml index c020ab22d4..d4d8b7a0fa 100644 --- a/.github/workflows/moodle-ci.yml +++ b/.github/workflows/moodle-ci.yml @@ -114,24 +114,6 @@ jobs: moodle-branch: ['MOODLE_401_STABLE', 'MOODLE_402_STABLE'] database: ['mariadb', 'pgsql'] include: - - php: '7.4' - moodle-branch: 'MOODLE_39_STABLE' - database: 'mariadb' - - php: '7.4' - moodle-branch: 'MOODLE_39_STABLE' - database: 'pgsql' - - php: '8.0' - moodle-branch: 'MOODLE_311_STABLE' - database: 'mariadb' - - php: '8.0' - moodle-branch: 'MOODLE_311_STABLE' - database: 'pgsql' - - php: '8.0' - moodle-branch: 'MOODLE_400_STABLE' - database: 'mariadb' - - php: '8.0' - moodle-branch: 'MOODLE_400_STABLE' - database: 'pgsql' steps: - name: Start MariaDB From 411d8de0ef100d02ab631239eb1570caa5b799b2 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Wed, 13 Mar 2024 15:30:56 +0100 Subject: [PATCH 43/62] include new moodle versions --- .github/workflows/moodle-ci.yml | 20 ++++++++++++++++---- locallib.php | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml index d4d8b7a0fa..7aae84517c 100644 --- a/.github/workflows/moodle-ci.yml +++ b/.github/workflows/moodle-ci.yml @@ -8,8 +8,8 @@ jobs: strategy: matrix: - php: ['8.1'] - moodle-branch: ['MOODLE_402_STABLE'] + php: ['8.2'] + moodle-branch: ['MOODLE_404_STABLE'] database: ['pgsql'] steps: @@ -110,10 +110,22 @@ jobs: strategy: fail-fast: false matrix: - php: ['8.0', '8.1'] - moodle-branch: ['MOODLE_401_STABLE', 'MOODLE_402_STABLE'] + php: [8.1'] + moodle-branch: ['MOODLE_401_STABLE', 'MOODLE_402_STABLE', 'MOODLE_403_STABLE'] database: ['mariadb', 'pgsql'] include: + - php: '8.2' + moodle-branch: 'MOODLE_402_STABLE' + database: 'mariadb' + - php: '8.2' + moodle-branch: 'MOODLE_402_STABLE' + database: 'pgsql' + - php: '8.2' + moodle-branch: 'MOODLE_403_STABLE' + database: 'mariadb' + - php: '8.2' + moodle-branch: 'MOODLE_403_STABLE' + database: 'pgsql' steps: - name: Start MariaDB diff --git a/locallib.php b/locallib.php index a816a6e1a1..bd60ab4e0c 100644 --- a/locallib.php +++ b/locallib.php @@ -1434,7 +1434,7 @@ function moodleoverflow_print_post($post, $discussion, $moodleoverflow, $cm, $co $mustachedata->withinreviewperiod = $reviewable; // Prepare the post. - $mustachedata->postcontent = format_text($post->message, $post->messageformat, $modulecontext); + $mustachedata->postcontent = format_text($post->message, $post->messageformat, ['context' => $modulecontext]); // Load the attachments. $mustachedata->attachments = get_attachments($post, $cm); From 5c96fd638ee5d9b2d833872663ce84074f502d6a Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Wed, 13 Mar 2024 15:35:40 +0100 Subject: [PATCH 44/62] test against master --- .github/workflows/moodle-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml index 7aae84517c..a1bc1253ef 100644 --- a/.github/workflows/moodle-ci.yml +++ b/.github/workflows/moodle-ci.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: php: ['8.2'] - moodle-branch: ['MOODLE_404_STABLE'] + moodle-branch: ['master'] database: ['pgsql'] steps: From cf17932c1987191653cafc24f2be1925a0ea7c52 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Wed, 13 Mar 2024 15:41:00 +0100 Subject: [PATCH 45/62] syntax fix in workflows --- .github/workflows/moodle-ci.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml index a1bc1253ef..300f3b545e 100644 --- a/.github/workflows/moodle-ci.yml +++ b/.github/workflows/moodle-ci.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: php: ['8.2'] - moodle-branch: ['master'] + moodle-branch: ['MOODLE_403_STABLE'] database: ['pgsql'] steps: @@ -115,17 +115,17 @@ jobs: database: ['mariadb', 'pgsql'] include: - php: '8.2' - moodle-branch: 'MOODLE_402_STABLE' - database: 'mariadb' + moodle-branch: 'MOODLE_402_STABLE' + database: 'mariadb' - php: '8.2' - moodle-branch: 'MOODLE_402_STABLE' - database: 'pgsql' + moodle-branch: 'MOODLE_402_STABLE' + database: 'pgsql' - php: '8.2' - moodle-branch: 'MOODLE_403_STABLE' - database: 'mariadb' + moodle-branch: 'MOODLE_403_STABLE' + database: 'mariadb' - php: '8.2' - moodle-branch: 'MOODLE_403_STABLE' - database: 'pgsql' + moodle-branch: 'MOODLE_403_STABLE' + database: 'pgsql' steps: - name: Start MariaDB From fb8ec84c6464d995de6c13945d29db9752ae3c0d Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Tue, 23 Apr 2024 16:02:47 +0200 Subject: [PATCH 46/62] adapt CI to moodle 4.4 --- .github/workflows/moodle-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml index 300f3b545e..d21a29d565 100644 --- a/.github/workflows/moodle-ci.yml +++ b/.github/workflows/moodle-ci.yml @@ -8,8 +8,8 @@ jobs: strategy: matrix: - php: ['8.2'] - moodle-branch: ['MOODLE_403_STABLE'] + php: ['8.3'] + moodle-branch: ['MOODLE_404_STABLE'] database: ['pgsql'] steps: From c03c799f82d903afff2dff08db28252212358d97 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Tue, 23 Apr 2024 18:18:40 +0200 Subject: [PATCH 47/62] 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 48/62] 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 b6ecbf534f90884de44d5cda76bbbbb796e921fa Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Thu, 2 May 2024 11:30:40 +0200 Subject: [PATCH 49/62] Shell escape the release notes in the release workflow --- .github/workflows/moodle-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/moodle-release.yml b/.github/workflows/moodle-release.yml index 317a7916fa..432e765867 100644 --- a/.github/workflows/moodle-release.yml +++ b/.github/workflows/moodle-release.yml @@ -42,7 +42,7 @@ jobs: --data-urlencode "vcstag=${TAGNAME}" \ --data-urlencode "changelogurl=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/commits/${TAGNAME}" \ --data-urlencode "altdownloadurl=${ZIPURL}" \ - --data-urlencode "releasenotes=${BODY}" \ + --data-urlencode "releasenotes=${BODY@Q}" \ --data-urlencode "releasenotesformat=4") echo "response=${RESPONSE}" >> $GITHUB_OUTPUT - name: Evaluate the response From 7e81760386779c5c6ccbecfe947b6ab0410e0d48 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Wed, 8 May 2024 16:45:16 +0200 Subject: [PATCH 50/62] adapt workflow matrix to Moodle 404 --- .github/workflows/moodle-ci.yml | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml index a628f1b00f..11b0d3ca71 100644 --- a/.github/workflows/moodle-ci.yml +++ b/.github/workflows/moodle-ci.yml @@ -110,22 +110,27 @@ jobs: strategy: fail-fast: false matrix: - php: [8.1'] - moodle-branch: ['MOODLE_401_STABLE', 'MOODLE_402_STABLE', 'MOODLE_403_STABLE'] + php: ['8.0', '8.1', '8.2', '8.3'] + moodle-branch: ['MOODLE_401_STABLE', 'MOODLE_402_STABLE', 'MOODLE_403_STABLE', 'MOODLE_404_STABLE'] database: ['mariadb', 'pgsql'] - include: - - php: '8.2' - moodle-branch: 'MOODLE_402_STABLE' - database: 'mariadb' + exclude: + - php: '8.0' + moodle-branch: 'MOODLE_404_STABLE' - php: '8.2' + moodle-branch: 'MOODLE_401_STABLE' + - php: '8.3' + moodle-branch: 'MOODLE_401_STABLE' + - php: '8.3' moodle-branch: 'MOODLE_402_STABLE' - database: 'pgsql' - - php: '8.2' - moodle-branch: 'MOODLE_403_STABLE' - database: 'mariadb' - - php: '8.2' + - php: '8.3' moodle-branch: 'MOODLE_403_STABLE' + include: + - php: '7.4' + moodle-branch: 'MOODLE_401_STABLE' database: 'pgsql' + - php: '7.4' + moodle-branch: 'MOODLE_401_STABLE' + database: 'mariadb' steps: - name: Start MariaDB From d2413a3d6a8476f08772ad70d2884ea2459013bf Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Thu, 23 May 2024 11:11:45 +0200 Subject: [PATCH 51/62] fixes for M4.4 --- classes/privacy/data_export_helper.php | 4 ++-- tests/behat/add_moodleoverflow.feature | 2 +- tests/behat/delete_file.feature | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/classes/privacy/data_export_helper.php b/classes/privacy/data_export_helper.php index ed0bfb3aa6..858ae859f0 100644 --- a/classes/privacy/data_export_helper.php +++ b/classes/privacy/data_export_helper.php @@ -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 @@ -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 diff --git a/tests/behat/add_moodleoverflow.feature b/tests/behat/add_moodleoverflow.feature index 939fdd84cd..84555e63f5 100644 --- a/tests/behat/add_moodleoverflow.feature +++ b/tests/behat/add_moodleoverflow.feature @@ -19,7 +19,7 @@ Feature: Add moodleoverflow activities and discussions And I log in as "teacher1" And I am on "Course 1" course homepage And I turn editing mode on - And I add a "Moodleoverflow" to section "1" and I fill the form with: + And I add a "Moodleoverflow" activity to course "C1" section "1" and I fill the form with: | Moodleoverflow name | Test moodleoverflow name | | Description | Test forum description | And I add a new discussion to "Test moodleoverflow name" moodleoverflow with: diff --git a/tests/behat/delete_file.feature b/tests/behat/delete_file.feature index 24b9de2c3f..62fb50b7c3 100644 --- a/tests/behat/delete_file.feature +++ b/tests/behat/delete_file.feature @@ -17,7 +17,7 @@ Feature: Delete attachments And I log in as "teacher1" And I am on "Course 1" course homepage And I turn editing mode on - And I add a "Moodleoverflow" to section "1" and I fill the form with: + And I add a "Moodleoverflow" activity to course "C1" section "1" and I fill the form with: | Moodleoverflow name | Test moodleoverflow name | | Description | Test forum description | And I add a new discussion to "Test moodleoverflow name" moodleoverflow with: From 07ec785700fa02117684d99fb46fce1cb5d3d726 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Thu, 23 May 2024 11:36:22 +0200 Subject: [PATCH 52/62] more fixes for M4.4 --- lib.php | 3 ++- tests/behat/add_moodleoverflow.feature | 2 +- tests/behat/behat_mod_moodleoverflow.php | 25 ++++++++++++++++++++++++ tests/behat/delete_file.feature | 2 +- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/lib.php b/lib.php index b49ed4cd0d..8a0e2627a0 100644 --- a/lib.php +++ b/lib.php @@ -885,7 +885,8 @@ function moodleoverflow_send_mails() { // Preapare to actually send the post now. Build up the content. $cleanname = str_replace('"', "'", strip_tags(format_string($moodleoverflow->name))); - $shortname = format_string($course->shortname, true, ['context' => context_course::instance($course->id)]); + $coursecontext = context_course::instance($course->id); + $shortname = format_string($course->shortname, true, ['context' => $coursecontext]); // Define a header to make mails easier to track. $emailmessageid = generate_email_messageid('moodlemoodleoverflow' . $moodleoverflow->id); diff --git a/tests/behat/add_moodleoverflow.feature b/tests/behat/add_moodleoverflow.feature index 84555e63f5..f810bcdb30 100644 --- a/tests/behat/add_moodleoverflow.feature +++ b/tests/behat/add_moodleoverflow.feature @@ -19,7 +19,7 @@ Feature: Add moodleoverflow activities and discussions And I log in as "teacher1" And I am on "Course 1" course homepage And I turn editing mode on - And I add a "Moodleoverflow" activity to course "C1" section "1" and I fill the form with: + And I add a moodleoverflow to course "C1" section "1" and I fill the form with: | Moodleoverflow name | Test moodleoverflow name | | Description | Test forum description | And I add a new discussion to "Test moodleoverflow name" moodleoverflow with: diff --git a/tests/behat/behat_mod_moodleoverflow.php b/tests/behat/behat_mod_moodleoverflow.php index 4569c1c2ca..e53743bde2 100644 --- a/tests/behat/behat_mod_moodleoverflow.php +++ b/tests/behat/behat_mod_moodleoverflow.php @@ -41,6 +41,31 @@ */ class behat_mod_moodleoverflow extends behat_base { + /** + * Adds a new moodleoverflow to the specified course and section. + * + * @Given I add a moodleoverflow to course :coursefullname section :sectionnum and I fill the form with: + * @param $courseshortname + * @param $sectionnumber + * @param $data + * @return void + */ + public function i_add_a_moodleoverflow_to_course_section_and_fill_form($courseshortname, $sectionnumber, TableNode $data) { + global $CFG; + + if ($CFG->branch >= 404) { + $this->execute( + "behat_course::i_add_to_course_section_and_i_fill_the_form_with", + [$this->escape('moodleoverflow'), $this->escape($courseshortname), $this->escape($sectionnumber), $data] + ); + } else { + $this->execute( + "behat_course_deprecated::i_add_to_section_and_i_fill_the_form_with", + [$this->escape('moodleoverflow'), $this->escape($sectionnumber), $data] + ); + } + } + /** * Adds a topic to the moodleoverflow specified by it's name. Useful for the Announcements and blog-style moodleoverflow. * diff --git a/tests/behat/delete_file.feature b/tests/behat/delete_file.feature index 62fb50b7c3..39bc9871dc 100644 --- a/tests/behat/delete_file.feature +++ b/tests/behat/delete_file.feature @@ -17,7 +17,7 @@ Feature: Delete attachments And I log in as "teacher1" And I am on "Course 1" course homepage And I turn editing mode on - And I add a "Moodleoverflow" activity to course "C1" section "1" and I fill the form with: + And I add a moodleoverflow to course "C1" section "1" and I fill the form with: | Moodleoverflow name | Test moodleoverflow name | | Description | Test forum description | And I add a new discussion to "Test moodleoverflow name" moodleoverflow with: From 6e882c676ea2dc586d4bd903c44a7c873c87defb Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Thu, 23 May 2024 11:54:17 +0200 Subject: [PATCH 53/62] use deprecated behat funtion directly --- tests/behat/behat_mod_moodleoverflow.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/behat/behat_mod_moodleoverflow.php b/tests/behat/behat_mod_moodleoverflow.php index e53743bde2..c6f1cffc93 100644 --- a/tests/behat/behat_mod_moodleoverflow.php +++ b/tests/behat/behat_mod_moodleoverflow.php @@ -59,10 +59,21 @@ public function i_add_a_moodleoverflow_to_course_section_and_fill_form($coursesh [$this->escape('moodleoverflow'), $this->escape($courseshortname), $this->escape($sectionnumber), $data] ); } else { + // This is the code from the deprecated behat function "i_add_to_section_and_i_fill_the_form_with". + // Add activity to section. $this->execute( - "behat_course_deprecated::i_add_to_section_and_i_fill_the_form_with", - [$this->escape('moodleoverflow'), $this->escape($sectionnumber), $data] + "behat_course::i_add_to_section", + [$this->escape('moodleoverflow'), $this->escape($sectionnumber)] ); + + // Wait to be redirected. + $this->execute('behat_general::wait_until_the_page_is_ready'); + + // Set form fields. + $this->execute("behat_forms::i_set_the_following_fields_to_these_values", $data); + + // Save course settings. + $this->execute("behat_forms::press_button", get_string('savechangesandreturntocourse')); } } From 9605eba8fc5fbbe17416c2f9e70eee50fc5d376a Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Thu, 23 May 2024 12:46:39 +0200 Subject: [PATCH 54/62] refactor deprecated phpunit function --- tests/review_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/review_test.php b/tests/review_test.php index 13d54ce7af..32db0c1688 100644 --- a/tests/review_test.php +++ b/tests/review_test.php @@ -260,7 +260,7 @@ private function assert_matches_properties($expected, $actual) { $expected = (array)$expected; $actual = (object)$actual; foreach ($expected as $key => $value) { - $this->assertObjectHasAttribute($key, $actual, "Failed asserting that attribute '$key' exists."); + $this->assertObjectHasProperty($key, $actual, "Failed asserting that attribute '$key' exists."); $this->assertEquals($value, $actual->$key, "Failed asserting that \$obj->$key '" . $actual->$key . "' equals '$value'"); } } From 7ea9f0ecba7d85ba1f62994afa179ed6f66d4836 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Thu, 23 May 2024 12:55:58 +0200 Subject: [PATCH 55/62] add condition to use deprecated function in older Moodle versions --- tests/review_test.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/review_test.php b/tests/review_test.php index 32db0c1688..4ab9fa6544 100644 --- a/tests/review_test.php +++ b/tests/review_test.php @@ -257,10 +257,15 @@ private function run_send_mails() { * @param object|array $actual */ private function assert_matches_properties($expected, $actual) { + global $CFG; $expected = (array)$expected; $actual = (object)$actual; foreach ($expected as $key => $value) { - $this->assertObjectHasProperty($key, $actual, "Failed asserting that attribute '$key' exists."); + if ($CFG->branch >= 404) { + $this->assertObjectHasProperty($key, $actual, "Failed asserting that attribute '$key' exists."); + } else { + $this->assertObjectHasAttribute($key, $actual, "Failed asserting that attribute '$key' exists."); + } $this->assertEquals($value, $actual->$key, "Failed asserting that \$obj->$key '" . $actual->$key . "' equals '$value'"); } } From d215afa084c5d2beed3723903843cdbfb3e65834 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Fri, 24 May 2024 19:14:59 +0200 Subject: [PATCH 56/62] add delay for pgsql --- tests/review_test.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/review_test.php b/tests/review_test.php index 4ab9fa6544..a8567e18d4 100644 --- a/tests/review_test.php +++ b/tests/review_test.php @@ -118,6 +118,9 @@ public function test_forum_review_everything(): void { $posts = $this->create_post($options); $this->check_mail_records($posts['teacherpost'], $posts['studentpost'], 1, 0, MOODLEOVERFLOW_MAILED_REVIEW_SUCCESS); + if ($CFG->branch >= 404) { + sleep(1); // Added delay + } $this->assertEquals(1, $this->mailsink->count()); // Teacher has to approve student message. $this->assertEquals(2, $this->messagesink->count()); // Student and teacher get notification for student message. @@ -182,6 +185,9 @@ public function test_forum_review_only_questions(): void { $posts = $this->create_post($options); $this->check_mail_records($posts['teacherpost'], $posts['studentpost'], 1, 0, MOODLEOVERFLOW_MAILED_REVIEW_SUCCESS); + if ($CFG->branch >= 404) { + sleep(1); // Added delay + } $this->assertEquals(1, $this->mailsink->count()); // Teacher has to approve student message. $this->assertEquals(2, $this->messagesink->count()); // Student and teacher get notification for student message. @@ -215,6 +221,7 @@ public function test_forum_review_only_questions(): void { * Test reviews functionality when reviewing is allowed in admin settings. */ public function test_forum_review_disallowed(): void { + global $CFG; $options = ['course' => $this->course->id, 'needsreview' => review::EVERYTHING, 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE, ]; @@ -223,6 +230,9 @@ public function test_forum_review_disallowed(): void { $posts = $this->create_post($options); $this->check_mail_records($posts['teacherpost'], $posts['studentpost'], 1, 1, MOODLEOVERFLOW_MAILED_SUCCESS); + if ($CFG->branch >= 404) { + sleep(1); // Added delay + } $this->assertEquals(0, $this->mailsink->count()); // Teacher has to approve student message. $this->assertEquals(4, $this->messagesink->count()); // Student and teacher get notification for student message. From f207468fff0b6af519a2ce98b16d69c95e6306b4 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Fri, 24 May 2024 19:29:55 +0200 Subject: [PATCH 57/62] rollback --- tests/review_test.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/review_test.php b/tests/review_test.php index a8567e18d4..4ab9fa6544 100644 --- a/tests/review_test.php +++ b/tests/review_test.php @@ -118,9 +118,6 @@ public function test_forum_review_everything(): void { $posts = $this->create_post($options); $this->check_mail_records($posts['teacherpost'], $posts['studentpost'], 1, 0, MOODLEOVERFLOW_MAILED_REVIEW_SUCCESS); - if ($CFG->branch >= 404) { - sleep(1); // Added delay - } $this->assertEquals(1, $this->mailsink->count()); // Teacher has to approve student message. $this->assertEquals(2, $this->messagesink->count()); // Student and teacher get notification for student message. @@ -185,9 +182,6 @@ public function test_forum_review_only_questions(): void { $posts = $this->create_post($options); $this->check_mail_records($posts['teacherpost'], $posts['studentpost'], 1, 0, MOODLEOVERFLOW_MAILED_REVIEW_SUCCESS); - if ($CFG->branch >= 404) { - sleep(1); // Added delay - } $this->assertEquals(1, $this->mailsink->count()); // Teacher has to approve student message. $this->assertEquals(2, $this->messagesink->count()); // Student and teacher get notification for student message. @@ -221,7 +215,6 @@ public function test_forum_review_only_questions(): void { * Test reviews functionality when reviewing is allowed in admin settings. */ public function test_forum_review_disallowed(): void { - global $CFG; $options = ['course' => $this->course->id, 'needsreview' => review::EVERYTHING, 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE, ]; @@ -230,9 +223,6 @@ public function test_forum_review_disallowed(): void { $posts = $this->create_post($options); $this->check_mail_records($posts['teacherpost'], $posts['studentpost'], 1, 1, MOODLEOVERFLOW_MAILED_SUCCESS); - if ($CFG->branch >= 404) { - sleep(1); // Added delay - } $this->assertEquals(0, $this->mailsink->count()); // Teacher has to approve student message. $this->assertEquals(4, $this->messagesink->count()); // Student and teacher get notification for student message. From 730b256f1be2e4b8dac47cfce9a3eb2a760ec5bb Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Tue, 28 May 2024 15:16:21 +0200 Subject: [PATCH 58/62] WIP: try to fix phpunit test for postgresql --- tests/review_test.php | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/tests/review_test.php b/tests/review_test.php index 4ab9fa6544..d9478552bc 100644 --- a/tests/review_test.php +++ b/tests/review_test.php @@ -281,6 +281,15 @@ 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); + // Explicitly setting the fields + $teacherpost->mailed = MOODLEOVERFLOW_MAILED_PENDING; + $teacherpost->reviewed = 0; + $teacherpost->timereviewed = null; + + $studentpost->mailed = MOODLEOVERFLOW_MAILED_PENDING; + $studentpost->reviewed = 0; + $studentpost->timereviewed = null; + return ['teacherpost' => $teacherpost, 'studentpost' => $studentpost]; } @@ -297,20 +306,24 @@ 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])); + // Fetch the posts directly after creation + $teacherpostDB = $DB->get_record('moodleoverflow_posts', ['id' => $teacherpost->id]); + $studentpostDB = $DB->get_record('moodleoverflow_posts', ['id' => $studentpost->id]); + + // Assert initial state + $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_PENDING, 'reviewed' => $review1, 'timereviewed' => null], $teacherpostDB); + $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_PENDING, 'reviewed' => $review2, 'timereviewed' => null], $studentpostDB); $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' => $mailed, 'reviewed' => $review2, 'timereviewed' => null], - $DB->get_record('moodleoverflow_posts', ['id' => $studentpost->id])); + // Fetch the posts after mailing + $teacherpostDB = $DB->get_record('moodleoverflow_posts', ['id' => $teacherpost->id]); + $studentpostDB = $DB->get_record('moodleoverflow_posts', ['id' => $studentpost->id]); + + // Assert post-mail state + $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_SUCCESS, 'reviewed' => $review1, 'timereviewed' => null], $teacherpostDB); + $this->assert_matches_properties(['mailed' => $mailed, 'reviewed' => $review2, 'timereviewed' => null], $studentpostDB); } + } From 334f6199649e5915e1e9c806df1cc209f04c6023 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Tue, 28 May 2024 15:29:41 +0200 Subject: [PATCH 59/62] codecleaning --- classes/task/send_daily_mail.php | 4 ++-- tests/dailymail_test.php | 4 ++-- tests/review_test.php | 16 ++++++++-------- tests/subscriptions_test.php | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/classes/task/send_daily_mail.php b/classes/task/send_daily_mail.php index 75f110ab3a..a4494bea74 100644 --- a/classes/task/send_daily_mail.php +++ b/classes/task/send_daily_mail.php @@ -56,13 +56,13 @@ public function execute() { $mail = []; // Fill the $mail array. foreach ($userdata as $row) { - $currentcourse = $DB->get_record('course', array('id' => $row->courseid), 'fullname, id'); + $currentcourse = $DB->get_record('course', ['id' => $row->courseid], 'fullname, id'); // Check if the user is enrolled in the course, if not, go to the next row. if (!is_enrolled(\context_course::instance($row->courseid), $user->userid, '', true)) { continue; } - $currentforum = $DB->get_record('moodleoverflow', array('id' => $row->forumid), 'name, 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', ['id' => $row->forumdiscussionid], 'name, id'); $unreadposts = $row->numberofposts; diff --git a/tests/dailymail_test.php b/tests/dailymail_test.php index c6e45123e1..3badfa178a 100644 --- a/tests/dailymail_test.php +++ b/tests/dailymail_test.php @@ -98,7 +98,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(['firstname' => 'Tamaro', 'email' => 'tamaromail@example.com', - 'maildigest' => $maildigest]); + 'maildigest' => $maildigest, ]); $this->getDataGenerator()->enrol_user($this->user->id, $this->course->id, 'student'); // Create a new discussion and post within the moodleoverflow. @@ -165,7 +165,7 @@ public function test_delivery_not_enrolled(): void { $location = ['course' => $course->id, 'forcesubscribe' => MOODLEOVERFLOW_FORCESUBSCRIBE]; $moodleoverflow = $this->getDataGenerator()->create_module('moodleoverflow', $location); $student = $this->getDataGenerator()->create_user(['firstname' => 'Ethan', 'email' => 'ethanmail@example.com', - 'maildigest' => '1']); + 'maildigest' => '1', ]); $this->getDataGenerator()->enrol_user($student->id, $course->id, 'teacher'); $discussion = $this->generator->post_to_forum($moodleoverflow, $student); diff --git a/tests/review_test.php b/tests/review_test.php index d9478552bc..43d91d57a1 100644 --- a/tests/review_test.php +++ b/tests/review_test.php @@ -307,23 +307,23 @@ private function check_mail_records($teacherpost, $studentpost, $review1, $revie global $DB; // Fetch the posts directly after creation - $teacherpostDB = $DB->get_record('moodleoverflow_posts', ['id' => $teacherpost->id]); - $studentpostDB = $DB->get_record('moodleoverflow_posts', ['id' => $studentpost->id]); + $teacherpostdb = $DB->get_record('moodleoverflow_posts', ['id' => $teacherpost->id]); + $studentpostdb = $DB->get_record('moodleoverflow_posts', ['id' => $studentpost->id]); // Assert initial state - $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_PENDING, 'reviewed' => $review1, 'timereviewed' => null], $teacherpostDB); - $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_PENDING, 'reviewed' => $review2, 'timereviewed' => null], $studentpostDB); + $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_PENDING, 'reviewed' => $review1, 'timereviewed' => null], $teacherpostdb); + $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_PENDING, 'reviewed' => $review2, 'timereviewed' => null], $studentpostdb); $this->run_send_mails(); $this->run_send_mails(); // Execute twice to ensure no duplicate mails. // Fetch the posts after mailing - $teacherpostDB = $DB->get_record('moodleoverflow_posts', ['id' => $teacherpost->id]); - $studentpostDB = $DB->get_record('moodleoverflow_posts', ['id' => $studentpost->id]); + $teacherpostdb = $DB->get_record('moodleoverflow_posts', ['id' => $teacherpost->id]); + $studentpostdb = $DB->get_record('moodleoverflow_posts', ['id' => $studentpost->id]); // Assert post-mail state - $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_SUCCESS, 'reviewed' => $review1, 'timereviewed' => null], $teacherpostDB); - $this->assert_matches_properties(['mailed' => $mailed, 'reviewed' => $review2, 'timereviewed' => null], $studentpostDB); + $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_SUCCESS, 'reviewed' => $review1, 'timereviewed' => null], $teacherpostdb); + $this->assert_matches_properties(['mailed' => $mailed, 'reviewed' => $review2, 'timereviewed' => null], $studentpostdb); } } diff --git a/tests/subscriptions_test.php b/tests/subscriptions_test.php index 756a67eae5..2de58cf8b2 100644 --- a/tests/subscriptions_test.php +++ b/tests/subscriptions_test.php @@ -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]; @@ -1440,7 +1440,7 @@ public function test_is_subscribable_is_guest($options): void { * Returns subscription obtions. * @return array */ - public function is_subscribable_loggedin_provider() { + public function is_subscribable_loggedin_provider(): array { return [ [ ['forcesubscribe' => MOODLEOVERFLOW_DISALLOWSUBSCRIBE], From 9bb30d1f550ea11c5ef08790735b60f3c409ca98 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Tue, 28 May 2024 16:08:09 +0200 Subject: [PATCH 60/62] enable transaction rollback --- tests/review_test.php | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/tests/review_test.php b/tests/review_test.php index 43d91d57a1..9654f7dba8 100644 --- a/tests/review_test.php +++ b/tests/review_test.php @@ -85,7 +85,6 @@ protected function setUp(): void { unset_config('noemailever'); $this->mailsink = $this->redirectEmails(); - $this->preventResetByRollback(); $this->messagesink = $this->redirectMessages(); } @@ -281,15 +280,6 @@ 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); - // Explicitly setting the fields - $teacherpost->mailed = MOODLEOVERFLOW_MAILED_PENDING; - $teacherpost->reviewed = 0; - $teacherpost->timereviewed = null; - - $studentpost->mailed = MOODLEOVERFLOW_MAILED_PENDING; - $studentpost->reviewed = 0; - $studentpost->timereviewed = null; - return ['teacherpost' => $teacherpost, 'studentpost' => $studentpost]; } @@ -306,24 +296,20 @@ private function create_post($options) { private function check_mail_records($teacherpost, $studentpost, $review1, $review2, $mailed) { global $DB; - // Fetch the posts directly after creation - $teacherpostdb = $DB->get_record('moodleoverflow_posts', ['id' => $teacherpost->id]); - $studentpostdb = $DB->get_record('moodleoverflow_posts', ['id' => $studentpost->id]); - - // Assert initial state - $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_PENDING, 'reviewed' => $review1, 'timereviewed' => null], $teacherpostdb); - $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_PENDING, 'reviewed' => $review2, 'timereviewed' => null], $studentpostdb); + $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. - // Fetch the posts after mailing - $teacherpostdb = $DB->get_record('moodleoverflow_posts', ['id' => $teacherpost->id]); - $studentpostdb = $DB->get_record('moodleoverflow_posts', ['id' => $studentpost->id]); - - // Assert post-mail state - $this->assert_matches_properties(['mailed' => MOODLEOVERFLOW_MAILED_SUCCESS, 'reviewed' => $review1, 'timereviewed' => null], $teacherpostdb); - $this->assert_matches_properties(['mailed' => $mailed, 'reviewed' => $review2, 'timereviewed' => null], $studentpostdb); + $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 0eb61303d289b377932703c0dea24d15c8a64a31 Mon Sep 17 00:00:00 2001 From: TamaroWalter Date: Thu, 30 May 2024 12:20:36 +0200 Subject: [PATCH 61/62] 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 62/62] 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; }