+ * @copyright 2023 Tamaro Walter
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
+use mod_moodleoverflow\post\post_control;
// Include config and locallib.
use mod_moodleoverflow\anonymous;
use mod_moodleoverflow\review;
@@ -31,31 +32,16 @@
require_once(dirname(__FILE__) . '/locallib.php');
require_once($CFG->libdir . '/completionlib.php');
-// Declare optional parameters.
+// 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', [
- '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 = ['moodleoverflow' => $moodleoverflow, 'reply' => $reply, 'edit' => $edit];
@@ -63,757 +49,105 @@
// 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', ['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', ['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', ['id' => $discussion->moodleoverflow])) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
- }
-
- // Get the related course.
- if (!$course = $DB->get_record('course', ['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');
- }
+// Create a post_control object to control and lead the process.
+$postcontrol = new post_control();
- // Get the context of the module.
- $modulecontext = context_module::instance($cm->id);
+// 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;
- // 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.
+// LEARNWEB-TODO: should course or id really be zero?.
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', ['id' => $moodleoverflow])) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
-
- // Get the related course.
- if (!$course = $DB->get_record('course', ['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', [
- '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', ['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', ['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', ['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 if Limitedanswertime is on. If so, replies are not possible.
- $limitedanswersetting = $DB->get_record('moodleoverflow', ['id' => $moodleoverflow->id], 'la_starttime, la_endtime');
- $lastarttime = $limitedanswersetting->la_starttime;
- $laendtime = $limitedanswersetting->la_endtime;
-
- $roleid = $DB->get_field('role', 'id', ['shortname' => 'editingteacher']);
- $iseditteacher = $DB->record_exists('role_assignments', ['userid' => $USER->id, 'roleid' => $roleid]);
-
- $roleidteacher = $DB->get_field('role', 'id', ['shortname' => 'teacher']);
- $isteacher = $DB->record_exists('role_assignments', ['userid' => $USER->id, 'roleid' => $roleidteacher]);
-
- if (($lastarttime > time() || $laendtime != 0 && $laendtime < time()) &&
- (!has_capability('mod/moodleoverflow:addinstance', $modulecontext))) {
- // Redirect to the moodleoverflow.
- $link = new \moodle_url('/mod/moodleoverflow/view.php', ['id' => $cm->id]);
- redirect($link);
- }
-
- // 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',
- ['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', ['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', ['id' => $discussion->moodleoverflow])) {
- throw new moodle_exception('invalidmoodleoverflowid', 'moodleoverflow');
- }
-
- // Check if the post refers to a valid course.
- if (!$course = $DB->get_record('course', ['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', ['id' => $post->discussion])) {
- throw new moodle_exception('notpartofdiscussion', 'moodleoverflow');
- }
-
- // Get the related moodleoverflow instance.
- if (!$moodleoverflow = $DB->get_record('moodleoverflow', ['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', ['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', ['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', ['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 = [
- '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', ['d' => $discussion->id]);
- redirect(moodleoverflow_go_back_to($discussionurl));
- exit;
-
- } else {
- // Something went wrong.
- throw new moodle_exception('errorwhiledelete', 'moodleoverflow');
- }
- }
+ $postcontrol->execute_delete();
} 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',
- ['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();
}
- 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.
-$postid = empty($post->id) ? null : $post->id;
-$draftitemid = file_get_submitted_draft_itemid('attachments');
-file_prepare_draft_area($draftitemid,
- $modulecontext->id,
- 'mod_moodleoverflow',
- 'attachment',
- $postid,
- mod_moodleoverflow_post_form::attachment_options($moodleoverflow));
-
-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) {
- $file->set_author($anonymousstr);
- }
-}
-
-$draftideditor = file_get_submitted_draft_itemid('message');
-$currenttext = file_prepare_draft_area($draftideditor, $modulecontext->id, 'mod_moodleoverflow', 'post', $postid,
- mod_moodleoverflow_post_form::editor_options($modulecontext, $postid), $post->message);
-
-// Prepare the form.
-$formarray = [
- 'course' => $course,
- 'cm' => $cm,
- 'coursecontext' => $coursecontext,
- 'modulecontext' => $modulecontext,
- 'moodleoverflow' => $moodleoverflow,
- 'post' => $post,
- 'edit' => $edit,
-];
-$mformpost = new mod_moodleoverflow_post_form('post.php', $formarray, 'post', '', ['id' => 'mformmoodleoverflow']);
+// A post will be created or edited. For that the post_control builds a post_form.
+$mformpost = $postcontrol->build_postform($pageparams);
-// The current user is not the original author.
-// Append the message to the end of the message.
-if ($USER->id != $post->userid) {
+// The User now entered information in the form. The post.php now needs to process the information and call the right function.
- // Create a temporary object.
- $data = new stdClass();
- $data->date = userdate($post->modified);
- $post->messageformat = editors_get_preferred_format();
+// Get attributes from the postcontrol.
+$information = $postcontrol->get_information();
+$prepost = $postcontrol->get_prepost();
- // 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');
-}
-
-// Set data for the form.
-// TODO Refactor.
-$param1 = (isset($discussion->id) ? [$discussion->id] : []);
-$param2 = (isset($post->format) ? ['format' => $post->format] : []);
-$param3 = (isset($discussion->timestart) ? ['timestart' => $discussion->timestart] : []);
-$param4 = (isset($discussion->timeend) ? ['timeend' => $discussion->timeend] : []);
-$param5 = (isset($discussion->id) ? ['discussion' => $discussion->id] : []);
-$mformpost->set_data([
- 'attachments' => $draftitemid,
- 'general' => $heading,
- 'subject' => $subject,
- 'message' => [
- 'text' => $currenttext,
- 'format' => editors_get_preferred_format(),
- 'itemid' => $draftideditor,
- ],
- 'userid' => $post->userid,
- 'parent' => $post->parent,
- 'discussion' => $post->discussion,
- 'course' => $course->id,
- ] + $pageparams + $param1 + $param2 + $param3 + $param4 + $param5);
-
-// 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', ['m' => $moodleoverflow->id]));
+ if (!isset($prepost->discussionid)) {
+ redirect(new moodle_url('/mod/moodleoverflow/view.php', ['m' => $prepost->moodleoverflowid]));
} else {
- redirect(new moodle_url('/mod/moodleoverflow/discussion.php', ['d' => $discussion->id]));
+ redirect(new moodle_url('/mod/moodleoverflow/discussion.php', ['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->draftideditor = $fromform->message['itemid'];
- $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', ['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 (anonymous::is_post_anonymous($discussion, $moodleoverflow, $realpost->userid)) {
- $name = get_string('anonymous', 'moodleoverflow');
- } else {
- $realuser = $DB->get_record('user', ['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', ['d' => $discussion->id], 'p' . $fromform->id);
-
- // Set some parameters.
- $params = [
- 'context' => $modulecontext,
- 'objectid' => $fromform->id,
- '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) {
- $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($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, ['d' => $discussion->id], 'p' . $fromform->id);
-
- // Trigger post created event.
- $params = [
- 'context' => $modulecontext,
- 'objectid' => $fromform->id,
- 'other' => [
- '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', ['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 = [
- 'context' => $modulecontext,
- 'objectid' => $discussion->id,
- 'other' => [
- 'moodleoverflowid' => $moodleoverflow->id,
- ],
- ];
-
- $message = '' . get_string("postaddedsuccess", "moodleoverflow") . '
';
-
- // Trigger the discussion created event.
- $params = [
- '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($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->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/tests/discussion_test.php b/tests/discussion_test.php
new file mode 100644
index 0000000000..e5ee1c6c31
--- /dev/null
+++ b/tests/discussion_test.php
@@ -0,0 +1,164 @@
+.
+
+/**
+ * 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
+ */
+final 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 {
+ parent::setUp();
+ $this->resetAfterTest();
+ $this->helper_course_set_up();
+ }
+
+ public function tearDown(): void {
+ // Clear all caches.
+ subscriptions::reset_moodleoverflow_cache();
+ subscriptions::reset_discussion_cache();
+ parent::tearDown();
+ }
+
+ /**
+ * Test, if a discussion is being created correctly
+ */
+ public function test_create_discussion(): void {
+ 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', ['id' => $discussion->get_id()]);
+ $this->assertEquals($dbdiscussion->id, $discussionid);
+ $this->assertEquals('Discussion Topic', $dbdiscussion->name);
+
+ $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);
+ }
+
+ /**
+ * Test, if a post and its attachment are deleted successfully.
+ * @covers ::moodleoverflow_delete_post
+ */
+ public function test_delete_discussion(): void {
+ 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', ['id' => $discussionid]));
+ $this->assertEquals(0, $discussion);
+
+ $post = count($DB->get_records('moodleoverflow_posts', ['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 = ['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(['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', ['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/post_test.php b/tests/post_test.php
index a4727b0b3f..8b16739bbd 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,50 @@
*/
namespace mod_moodleoverflow;
+// Use the post class.
+use context;
+use mod_moodleoverflow\post\post;
+use mod_moodleoverflow\discussion\discussion;
+use stdClass;
+
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__ . '/../locallib.php');
/**
- * 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
*/
final class post_test extends \advanced_testcase {
- /** @var \stdClass test course */
+ /** @var stdClass test course */
private $course;
- /** @var \stdClass coursemodule */
+ /** @var stdClass coursemodule */
private $coursemodule;
- /** @var \stdClass test moodleoverflow */
+ /** @var stdClass modulecontext */
+ private $modulecontext;
+
+ /** @var stdClass test moodleoverflow */
private $moodleoverflow;
- /** @var \stdClass test teacher */
+ /** @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 {
parent::setUp();
$this->resetAfterTest();
@@ -68,47 +75,79 @@ 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();
parent::tearDown();
}
/**
- * 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(): void {
+ public function test_create_post(): void {
+ 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', ['id' => $post->get_id()]));
+ $this->assertEquals(1, $postscount);
+ }
+
+ /**
+ * Test, if the message of a post can be edited successfully.
+ */
+ public function test_edit_post(): void {
global $DB;
- // The attachment should exist.
- $numberofattachments = count($DB->get_records('files', ['itemid' => $this->post->id]));
- $this->assertEquals(2, $numberofattachments);
+ // The post and the attachment should exist.
+ $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', ['id' => $this->post->get_id()]));
+ $this->assertEquals(1, $post);
- // Delete the post from the teacher with its attachment.
- moodleoverflow_delete_post($this->post, false, $this->coursemodule, $this->moodleoverflow);
+ // Gather important parameters.
+ $message = 'a new message';
- // Now try to get the attachment.
- $numberofattachments = count($DB->get_records('files', ['itemid' => $this->post->id]));
+ $time = time();
- $this->assertEquals(0, $numberofattachments);
+ // 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', ['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(): void {
+ public function test_moodleoverflow_delete_post(): void {
global $DB;
- $numberofattachments = count($DB->get_records('files', ['itemid' => $this->post->id, 'filearea' => 'attachment']));
- $this->assertEquals(2, $numberofattachments);
+ // The post and the attachment should exist.
+ $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', ['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', ['itemid' => $this->post->id]));
+ // Now try to get the attachment, it should be deleted from the database.
+ $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', ['id' => $postid]));
+ $this->assertEquals(0, $post);
}
/**
@@ -123,6 +162,7 @@ private function helper_course_set_up() {
$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(['firstname' => 'Tamaro', 'lastname' => 'Walter']);
@@ -130,29 +170,41 @@ 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', ['id' => $this->discussion[0]->firstpost], '*');
+ $discussion = $this->generator->post_to_forum($this->moodleoverflow, $this->teacher);
+ $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', ['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', ['id' => $this->discussion->get_firstpostid()]);
+ $this->post = post::from_record($postrecord);
+ }
+ /**
+ * Adds a new attachment to a post.
+ *
+ * @param stdClass $object The post object to which the attachment should be added.
+ * @param context $modulecontext The context of the module.
+ * @param string $filename The name of the file to be added.
+ * @param string $filecontent The content of the file to be added.
+ */
+ private function add_new_attachment($object, $modulecontext, $filename, $filecontent) {
+ global $DB;
$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);
}
}
diff --git a/tests/ratings_test.php b/tests/ratings_test.php
index bf28d09e3d..5c3682ce5e 100644
--- a/tests/ratings_test.php
+++ b/tests/ratings_test.php
@@ -39,6 +39,27 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class ratings_test extends \advanced_testcase {
+ /** @var stdClass test course */
+ private $course;
+
+ /** @var stdClass coursemodule */
+ private $coursemodule;
+
+ /** @var stdClass test moodleoverflow */
+ private $moodleoverflow;
+
+ /** @var stdClass test teacher */
+ private $teacher;
+
+ /** @var stdClass test user */
+ private $user1;
+
+ /** @var stdClass another test user */
+ private $user2;
+
+ /** @var stdClass a discussion */
+ private $discussion;
+
/** @var stdClass a post from the teacher*/
private $post;
@@ -60,6 +81,9 @@ final class ratings_test extends \advanced_testcase {
/** @var stdClass answer from user 2 */
private $answer6;
+ /** @var \mod_moodleoverflow_generator $generator */
+ private $generator;
+
/**
* Test setUp.
*/
diff --git a/tests/subscriptions_test.php b/tests/subscriptions_test.php
index 9e5a76e47e..e5a695249c 100644
--- a/tests/subscriptions_test.php
+++ b/tests/subscriptions_test.php
@@ -1228,7 +1228,7 @@ public function test_is_subscribable_is_guest($options): void {
}
/**
- * Returns subscription obtions.
+ * Returns subscription options.
* @return array
*/
public static function is_subscribable_loggedin_provider(): array {
diff --git a/tests/userstats_test.php b/tests/userstats_test.php
index 61a670129c..45a82819c9 100644
--- a/tests/userstats_test.php
+++ b/tests/userstats_test.php
@@ -94,8 +94,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();
parent::tearDown();
}
@@ -223,7 +223,7 @@ public function test_partial_anonymous(): void {
}
/**
- * 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(): void {
@@ -232,6 +232,7 @@ public function test_total_anonymous(): void {
// Get the current userstats to compare later.
$olduserstats = $this->create_statstable();
+ $oldupvotesuser1 = $this->get_specific_userstats($olduserstats, $this->user1, 'receivedupvotes');
$oldactivityuser1 = $this->get_specific_userstats($olduserstats, $this->user1, 'forumactivity');
$oldupvotesuser2 = $this->get_specific_userstats($olduserstats, $this->user2, 'receivedupvotes');
@@ -304,7 +305,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
*/
diff --git a/version.php b/version.php
index 3fc2c38d83..6f099b71c6 100644
--- a/version.php
+++ b/version.php
@@ -21,15 +21,15 @@
*
* @package mod_moodleoverflow
* @copyright 2025 Thomas Niedermaier, University MΓΌnster
- * @copyright 2017 Kennet Winter
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
+$plugin->version = 2025070700;
+$plugin->requires = 2022112819; // Require Moodle 4.1.
+$plugin->supported = [401, 500];
$plugin->component = 'mod_moodleoverflow';
-$plugin->version = 2025050601;
-$plugin->requires = 2022112800;
-$plugin->release = 'v4.5-r2';
-$plugin->supported = [401, 405];
-$plugin->maturity = MATURITY_STABLE;
+$plugin->maturity = MATURITY_RC;
+$plugin->release = 'v5.0-rc1';
+$plugin->dependencies = [];