/** * Displays the view page (usually showing a list of discussions). * @param mod_forumng $forum Forum * @param int $groupid Group ID */ function print_view_page($forum, $groupid) { global $PAGE; $out = mod_forumng_utils::get_renderer(); $forumngid = $forum->get_id(); $baseurl = 'list.php?' . $forum->get_link_params(mod_forumng::PARAM_PLAIN); $sortorder = optional_param('sort', '', PARAM_ALPHA); if (!$sortorder) { $sortlink = optional_param('sortlink', '', PARAM_ALPHA); if ($sortlink) { $sortorder = $sortlink; } else { $sortorder = 'd'; } } $page = optional_param('page', 0, PARAM_INT); if (!$page) { $page = 1; } $baseurl .= '&page=' . $page; $sortchar = substr($sortorder, 0, 1); if (strlen($sortorder) == 2) { $sortreverse = substr($sortorder, 1, 1) == 'r' ? true : false; } else { $sortreverse = false; } $baseurl .= '&sort=' . $sortchar; $baseurl .= $sortreverse ? 'r' : ''; $sort = mod_forumng::get_sort_code($sortchar); $list = $forum->get_discussion_list($groupid, $forum->can_view_hidden(), $page, $sort, $sortreverse); $normal = $list->get_normal_discussions(); $fg = new forumngtype_general(); // Remove discussions from list if the forumtype thinks we can't see them or they are not deleted. foreach ($normal as $key => $value) { if (!$fg->can_view_discussion($value) || !$value->is_deleted()) { unset($normal[$key]); } } $pagecount = get_page_count(count($normal), $page); // Intro. print $out->render_intro($forum); print display_paging_bar($baseurl, $pagecount, $page); if (count($normal) > 0) { print $out->render_discussion_list_start($forum, $groupid, $baseurl, $sort, $sortreverse); foreach ($normal as $discussion) { if ($discussion->is_deleted()) { print $out->render_discussion_list_item($discussion, $groupid, $discussion == end($normal)); } } print $out->render_discussion_list_end($forum, $groupid); } else { print '<p class="forumng-nodiscussions">' . get_string('nodeleteddiscussions', 'forumngfeature_deletedposts') . '</p>'; } print display_paging_bar($baseurl, $pagecount, $page); }
/** * Copy the discussion and its posts to another forum and/or group. * @param mod_forumng $targetforum Forum to copy the discussion to * @param int $groupid If 'All participants' has been selected from the * separate groups dropdown box, use default value 0 */ function copy($targetforum, $groupid) { global $SESSION, $DB; $oldforum = $this->get_forum(); $oldforumngid = $oldforum->get_id(); $oldcourseid = $oldforum->get_course_id(); $targetforumngid = $targetforum->get_id(); $targetcourseid = $targetforum->get_course_id(); //Clone the old discussion $discussionobj = clone $this->discussionfields; unset($discussionobj->id); //update the forumngid and gruopid to the target forumngid and selected groupid $discussionobj->forumngid = $targetforumngid; unset($discussionobj->groupid); if ($targetforum->get_group_mode() && $groupid) { $discussionobj->groupid = $groupid; } $transaction = $DB->start_delegated_transaction(); $newdiscussionid = $DB->insert_record('forumng_discussions', $discussionobj); $rs = $DB->get_recordset('forumng_posts', array('discussionid' => $this->get_id())); //$newids and $parentused are temp arrays used to //$newids is a array of new postids using the indices of its old postids //update the parentid of the post records copied over //$hasattachments is a temp array for record the posts which has attachments. $newids = array(); $parentsused = array(); $hasattachments = array(); foreach ($rs as $postrec) { $oldpostid = $postrec->id; unset($postrec->id); $postrec->discussionid = $newdiscussionid; $postrec->mailstate = mod_forumng::MAILSTATE_DIGESTED; $newpostid = $DB->insert_record('forumng_posts', $postrec); $newids[$oldpostid] = $newpostid; if ($postrec->parentpostid) { $parentsused[$postrec->parentpostid] = true; } if ($postrec->attachments == 1) { $hasattachments[$oldpostid] = $newpostid; } } $rs->close(); // Update the postid and lastpostid in the discussion table no matter if they // are null or not $newpostid = $newids[$discussionobj->postid]; $newlastpostid = $newids[$discussionobj->lastpostid]; $DB->execute("UPDATE {forumng_discussions} SET postid = ?, lastpostid = ? WHERE id = ?", array($newpostid, $newlastpostid, $newdiscussionid)); foreach ($parentsused as $key => $value) { $newparentpostid = $newids[$key]; //Update the parentpostids which have just been copied over $DB->execute("UPDATE {forumng_posts} SET parentpostid = ? " . "WHERE parentpostid = ? AND discussionid = ?", array($newparentpostid, $key, $newdiscussionid)); } // Copy attachments $fs = get_file_storage(); $oldfilecontext = $oldforum->get_context(true); $newfilecontext = $targetforum->get_context(true); foreach ($hasattachments as $oldpostid => $newpostid) { foreach (array('attachment', 'message') as $filearea) { $oldfiles = $fs->get_area_files($oldfilecontext->id, 'mod_forumng', $filearea, $oldpostid, 'id', false); foreach ($oldfiles as $oldfile) { $filerecord = new stdClass(); $filerecord->contextid = $newfilecontext->id; $filerecord->itemid = $newpostid; $fs->create_file_from_storedfile($filerecord, $oldfile); } } } // Update the search data after the copy $newdiscussion = self::get_from_id($newdiscussionid, $this->get_forum()->get_course_module_id(), -1); $root = $newdiscussion->get_root_post(); $root->search_update(); $root->search_update_children(); $transaction->allow_commit(); }
/** * Copy the discussion and its posts to another forum and/or group. * @param mod_forumng $targetforum Forum to copy the discussion to * @param int $groupid If 'All participants' has been selected from the * separate groups dropdown box, use default value 0 */ public function copy($targetforum, $groupid) { global $SESSION, $DB; $oldforum = $this->get_forum(); $oldforumngid = $oldforum->get_id(); $oldcourseid = $oldforum->get_course_id(); $targetforumngid = $targetforum->get_id(); $targetcourseid = $targetforum->get_course_id(); // Clone the old discussion. $discussionobj = clone $this->discussionfields; unset($discussionobj->id); // Update the forumngid and gruopid to the target forumngid and selected groupid. $discussionobj->forumngid = $targetforumngid; unset($discussionobj->groupid); if ($targetforum->get_group_mode() && $groupid) { $discussionobj->groupid = $groupid; } $transaction = $DB->start_delegated_transaction(); $newdiscussionid = $DB->insert_record('forumng_discussions', $discussionobj); $rs = $DB->get_recordset('forumng_posts', array('discussionid' => $this->get_id())); // $newids and $parentused are temp arrays used to // $newids is a array of new postids using the indices of its old postids // Update the parentid of the post records copied over // $hasattachments is a temp array for record the posts which has attachments. $newids = array(); $parentsused = array(); $hasattachments = array(); foreach ($rs as $postrec) { $oldpostid = $postrec->id; unset($postrec->id); $postrec->discussionid = $newdiscussionid; $postrec->mailstate = mod_forumng::MAILSTATE_DIGESTED; $newpostid = $DB->insert_record('forumng_posts', $postrec); $newids[$oldpostid] = $newpostid; if ($postrec->parentpostid) { $parentsused[$postrec->parentpostid] = true; } if ($postrec->attachments == 1) { $hasattachments[$oldpostid] = $newpostid; } } $rs->close(); // Duplicate core ratings if enabled and both forums in same course. if ($oldforum->get_enableratings() == mod_forumng::FORUMNG_STANDARD_RATING && $oldforum->get_course(true)->id == $targetforum->get_course(true)->id) { list($in, $inparams) = $DB->get_in_or_equal(array_keys($newids)); if ($ratings = $DB->get_records_sql("SELECT * FROM {rating} WHERE itemid {$in} AND component\n = ? AND ratingarea = ? AND contextid = ?", array_merge($inparams, array('mod_forumng', 'post', $oldforum->get_context(true)->id)))) { foreach ($ratings as $rating) { $newrate = new stdClass(); $newrate->contextid = $targetforum->get_context(true)->id; $newrate->component = 'mod_forumng'; $newrate->ratingarea = 'post'; $newrate->itemid = $newids[$rating->itemid]; $newrate->scaleid = $rating->scaleid; $newrate->userid = $rating->userid; $newrate->rating = $rating->rating; $newrate->timecreated = $rating->timecreated; $newrate->timemodified = time(); $DB->insert_record('rating', $newrate); } $targetforum->update_grades(); } } // Update the postid and lastpostid in the discussion table no matter if they // are null or not $newpostid = $newids[$discussionobj->postid]; $newlastpostid = $newids[$discussionobj->lastpostid]; $DB->execute("UPDATE {forumng_discussions} SET postid = ?, lastpostid = ? WHERE id = ?", array($newpostid, $newlastpostid, $newdiscussionid)); foreach ($parentsused as $key => $value) { $newparentpostid = $newids[$key]; // Update the parentpostids which have just been copied over. $DB->execute("UPDATE {forumng_posts} SET parentpostid = ? " . "WHERE parentpostid = ? AND discussionid = ?", array($newparentpostid, $key, $newdiscussionid)); } // Copy attachments $fs = get_file_storage(); $oldfilecontext = $oldforum->get_context(true); $newfilecontext = $targetforum->get_context(true); foreach ($hasattachments as $oldpostid => $newpostid) { foreach (array('attachment', 'message') as $filearea) { $oldfiles = $fs->get_area_files($oldfilecontext->id, 'mod_forumng', $filearea, $oldpostid, 'id', false); foreach ($oldfiles as $oldfile) { $filerecord = new stdClass(); $filerecord->contextid = $newfilecontext->id; $filerecord->itemid = $newpostid; $fs->create_file_from_storedfile($filerecord, $oldfile); } } } // Update the search data after the copy $newdiscussion = self::get_from_id($newdiscussionid, $this->get_forum()->get_course_module_id(), -1); $root = $newdiscussion->get_root_post(); $root->search_update(); $root->search_update_children(); $transaction->allow_commit(); // Update any discussion tags. $tagslist = $this->get_tags(); if ($tagslist) { $tags = array(); foreach ($tagslist as $key => $value) { array_push($tags, $value); } $newdiscussion->edit_settings(self::NOCHANGE, self::NOCHANGE, self::NOCHANGE, self::NOCHANGE, self::NOCHANGE, $tags); } }
/** * Displays the view page (usually showing a list of discussions). * @param mod_forumng $forum Forum * @param int $groupid Group ID */ public function print_view_page($forum, $groupid) { global $SESSION, $PAGE, $USER; $out = mod_forumng_utils::get_renderer(); $forumngid = $forum->get_id(); $baseurl = 'view.php?' . $forum->get_link_params(mod_forumng::PARAM_PLAIN); if (isset($SESSION->forumng_discussionlist[$forumngid]) && property_exists($SESSION->forumng_discussionlist[$forumngid], 'groupid') && $SESSION->forumng_discussionlist[$forumngid]->groupid != $groupid) { unset($SESSION->forumng_discussionlist[$forumngid]->page); unset($SESSION->forumng_discussionlist[$forumngid]->groupid); } // Remember the sort order and page number in session variables // Unset the page session variable when the sort links are clicked // or groupid has been changed (using the group dropdown box) $sortorder = optional_param('sort', '', PARAM_ALPHA); if (!$sortorder) { if (isset($SESSION->forumng_discussionlist[$forumngid]->sort)) { $sortorder = $SESSION->forumng_discussionlist[$forumngid]->sort; } else { $sortorder = 'd'; } } else { if (optional_param('sortlink', '', PARAM_ALPHA)) { if (!isset($SESSION->forumng_discussionlist[$forumngid])) { $SESSION->forumng_discussionlist[$forumngid] = new stdClass(); } $SESSION->forumng_discussionlist[$forumngid]->sort = $sortorder; unset($SESSION->forumng_discussionlist[$forumngid]->page); } } $page = optional_param('page', 0, PARAM_INT); if (!$page) { if (isset($SESSION->forumng_discussionlist[$forumngid]->page)) { $page = $SESSION->forumng_discussionlist[$forumngid]->page; } else { $page = 1; } } else { if (!isset($SESSION->forumng_discussionlist[$forumngid])) { $SESSION->forumng_discussionlist[$forumngid] = new stdClass(); } $SESSION->forumng_discussionlist[$forumngid]->page = $page; $SESSION->forumng_discussionlist[$forumngid]->groupid = $groupid; } $baseurl .= '&page=' . $page; $sortchar = substr($sortorder, 0, 1); if (strlen($sortorder) == 2) { $sortreverse = substr($sortorder, 1, 1) == 'r' ? true : false; } else { $sortreverse = false; } $baseurl .= '&sort=' . $sortchar; $baseurl .= $sortreverse ? 'r' : ''; $sort = mod_forumng::get_sort_code($sortchar); // Get tagid if used. $tag = optional_param('tag', null, PARAM_ALPHANUM); $list = $forum->get_discussion_list($groupid, $forum->can_view_hidden(), $page, $sort, $sortreverse, 0, true, $tag); $sticky = $list->get_sticky_discussions(); $normal = $list->get_normal_discussions(); // Remove discussions from list if the forumtype thinks we can't see // them foreach ($sticky as $key => $value) { if (!$this->can_view_discussion($value)) { unset($sticky[$key]); } } foreach ($normal as $key => $value) { if (!$this->can_view_discussion($value)) { unset($normal[$key]); } } // Intro print $out->render_intro($forum); // Flagged posts skip link. $flaggedposts = $forum->get_flagged_posts(); $flagdiscussions = $forum->get_flagged_discussions(); $flaggeddiscussions = array(); // Need to loop through flagged discussions removing any that can not be viewed by user. foreach ($flagdiscussions as $discussion) { if ($discussion->can_view($USER->id)) { // Add to flagged discussions. array_push($flaggeddiscussions, $discussion); } } if (count($flaggedposts) + count($flaggeddiscussions) > 0) { $output = html_writer::start_tag('div', array('class' => 'forumng-flagged-link')); $output .= $out->render_flagged_list_link($flaggeddiscussions, true); $output .= $out->render_flagged_list_link($flaggedposts); $output .= html_writer::end_tag('div'); echo $output; } // Draft posts $drafts = $forum->get_drafts(); if (count($drafts) > 0) { print $out->render_draft_list_start(); foreach ($drafts as $draft) { print $out->render_draft_list_item($forum, $draft, $draft == end($drafts)); } print $out->render_draft_list_end(); } // Print info about the start and end dates of the forum from the form setting $stringend = has_capability('mod/forumng:ignorepostlimits', $forum->get_context()) ? 'capable' : ''; $startdate = $forum->get_postingfrom(); $enddate = $forum->get_postinguntil(); // Before start date if (time() < $startdate) { $message = get_string('beforestartdate' . $stringend, 'forumng', mod_forumng_utils::display_date($startdate)); print "<div class='forumng-show-dates'>{$message}</div>"; } else { if (time() < $enddate) { $message = get_string('beforeenddate' . $stringend, 'forumng', mod_forumng_utils::display_date($enddate)); print "<div class='forumng-show-dates'>{$message}</div>"; } } // After end date if ($enddate && time() >= $enddate) { $message = get_string('afterenddate' . $stringend, 'forumng', mod_forumng_utils::display_date($enddate)); print "<div class='forumng-show-dates'>{$message}</div>"; } // Show Alert info. if ($forum->has_reporting_email()) { print $out->box(get_string('alert_intro', 'forumng'), 'generalbox', 'forumng-reportingon'); } // Post button - temporarily disabled when in all-groups mode print $groupid == null ? '' : $forum->display_post_button($groupid); if ($taglist = $forum->get_tags_used($groupid)) { print $out->render_tag_filter($taglist, $forum, $tag); } // Provide link to skip sticky discussions. if (count($sticky) > 0 && count($normal) > 0) { print $out->render_skip_link(key($normal)); } print $list->display_paging_bar($baseurl); if (count($sticky) + count($normal) > 0) { print $out->render_discussion_list_start($forum, $groupid, $baseurl, $sort, $sortreverse); foreach ($sticky as $discussion) { print $out->render_discussion_list_item($discussion, $groupid, count($normal) == 0 && $discussion == end($sticky)); } if (count($sticky) > 0 && count($normal) > 0) { print $out->render_discussion_list_divider($forum, $groupid); } foreach ($normal as $discussion) { print $out->render_discussion_list_item($discussion, $groupid, $discussion == end($normal)); } print $out->render_discussion_list_end($forum, $groupid); } else { print '<p class="forumng-nodiscussions">' . $this->get_string($forum, 'nodiscussions') . '</p>'; } print $list->display_paging_bar($baseurl); print $forum->display_forumngfeature_discussion_lists($groupid); // Flagged discussions. if (count($flaggeddiscussions) > 0) { print $out->render_flagged_list_start(true); foreach ($flaggeddiscussions as $discussion) { print $out->render_flagged_discuss_list_item($discussion, $discussion === end($flaggeddiscussions)); } print $out->render_flagged_list_end(); } // Flagged posts. if (count($flaggedposts) > 0) { print $out->render_flagged_list_start(); foreach ($flaggedposts as $post) { print $out->render_flagged_list_item($post, $post === end($flaggedposts)); } print $out->render_flagged_list_end(); } // Subscribe and view subscribers links print $forum->display_subscribe_options(); // Atom/RSS links print $forum->display_feed_links($groupid); // display the warning message for invalid archive setting print $forum->display_archive_warning(); // Display sharing information print $forum->display_sharing_info(); }
/** * Updates the in-memory digest records to add a new post to the given * user's digests. * @param object $user User object (must include special ->emailtype, etc) * @param array $userdigests Array of user id => digest information object * @param mod_forumng_post $post Post object * @param mod_forumng_post $inreplyto Parent post * @param mod_forumng_discussion $discussion Discus * @param mod_forumng $forum * @param object $cm * @param object $course * @param object $context */ private static function digest_add_post_for_user(&$user, &$userdigests, &$post, &$inreplyto, &$discussion, &$forum, &$cm, &$course, &$context) { global $CFG; // Set up digest for user if required if (!array_key_exists($user->id, $userdigests)) { $userdigests[$user->id] = new StdClass(); $userdigests[$user->id]->discussionid = -1; // So we do header next $userdigests[$user->id]->user = $user; $userdigests[$user->id]->forumngid = -1; // Get header text $headerdata = new object(); $headerdata->sitename = format_string($course->fullname, true); $headerdata->userprefs = $CFG->wwwroot . '/user/edit.php?id=' . $user->id . '&course=' . $course->id; $userdigests[$user->id]->text = get_string('digestmailheader', 'forumng', $headerdata) . "\n\n"; // Get header HTML $html = "<body id='forumng-email'>\n"; $headerdata->userprefs = '<a target="_blank" href="' . $headerdata->userprefs . '">' . get_string('digestmailprefs', 'forumng') . '</a>'; $html .= '<div class="forumng-emailheader"><p>' . get_string('digestmailheader', 'forumng', $headerdata) . '</p></div><hr size="1" noshade="noshade" />'; $userdigests[$user->id]->html = $html; // Get email subject $userdigests[$user->id]->subject = get_string('digestmailsubject', 'forumng', format_string($course->shortname, true)); } // New forum? if ($userdigests[$user->id]->forumngid != $forum->get_id()) { $userdigests[$user->id]->forumngid = $forum->get_id(); } // Is this a new discussion? if ($userdigests[$user->id]->discussionid != $discussion->get_id()) { $strforums = get_string('forums', 'forumng'); // Per-discussion header (text mode) $text = "\n \n"; $text .= '====================================================================='; $text .= "\n \n"; $text .= "{$course->shortname} -> {$strforums} -> " . format_string($forum->get_name(), true); if ($discussion->get_subject(false) !== $forum->get_name()) { $text .= " -> " . format_string($discussion->get_subject(false), true); } $text .= "\n"; // HTML mode $html = '<hr size="1" noshade="noshade" />'; $html .= "<div class='forumng-breadcrumbs'>" . "<a target='_blank' href='{$CFG->wwwroot}/course/view.php?" . "id={$course->id}'>{$course->shortname}</a> -> " . "<a target='_blank' href='{$CFG->wwwroot}/mod/forumng/index.php?" . "id={$course->id}'>{$strforums}</a> -> " . "<a target='_blank' href='{$CFG->wwwroot}/mod/forumng/view.php?" . $forum->get_link_params(mod_forumng::PARAM_HTML) . "'>" . format_string($forum->get_name(), true) . "</a>"; if ($discussion->get_subject(false) !== $forum->get_name()) { $html .= " -> <a target='_blank' href='{$CFG->wwwroot}/mod/forumng/discuss.php?" . $discussion->get_link_params(mod_forumng::PARAM_HTML) . "'>" . format_string($discussion->get_subject(false), true) . "</a>"; } $html .= '</div>'; $userdigests[$user->id]->text .= $text; $userdigests[$user->id]->html .= $html; $userdigests[$user->id]->discussionid = $discussion->get_id(); } // Get both plaintext and html versions (and subject). // The html version will be blank if set to // plain text mode. $post->build_email($inreplyto, $subject, $text, $html, $user->emailtype & 1, $user->emailtype & 2, $user->emailtype & 4, $user->lang, $user->timezone, true); $userdigests[$user->id]->text .= $text; $userdigests[$user->id]->html .= $html; }
/** * Render single user's grading form. * * @param int $cmid course module id * @param mod_forumng $forumng Forum * @param object $user object * @param int $groupid id of group to which user belongs */ function forumngfeature_userposts_display_user_grade($cmid, mod_forumng $forumng, $user, $groupid) { global $CFG; require_once $CFG->libdir . '/gradelib.php'; $grades = grade_get_grades($forumng->get_course_id(), 'mod', 'forumng', $forumng->get_id(), $user->id); if ($grades) { if (!isset($grades->items[0]->grades[$user->id]->grade)) { $user->grade = -1; } else { $user->grade = abs($grades->items[0]->grades[$user->id]->grade); } $grademenu = make_grades_menu($forumng->get_grading_scale()); $grademenu[-1] = get_string('nograde'); $formparams = array(); $formparams['id'] = $cmid; $formparams['user'] = $user->id; $formparams['group'] = $groupid; $formaction = new moodle_url('/mod/forumng/feature/userposts/savegrades.php', $formparams); $mform = new MoodleQuickForm('savegrade', 'post', $formaction, '', array('class' => 'savegrade')); $mform->addElement('header', 'usergrade', get_string('usergrade', 'forumngfeature_userposts')); $mform->addElement('select', 'grade', get_string('grade'), $grademenu); $mform->setDefault('grade', $user->grade); $mform->addElement('submit', 'savechanges', get_string('savechanges')); $mform->display(); } }
/** * Create a discussion using the generator, returns discussion object * @param mod_forumng $forum * @param array $options Must contain userid * @return mod_forumng_discussion */ public function get_new_discussion(mod_forumng $forum, array $options) { $options['forum'] = $forum->get_id(); $options['course'] = $forum->get_course_id(); $generator = $this->getDataGenerator()->get_plugin_generator('mod_forumng'); $dis = $generator->create_discussion($options); return mod_forumng_discussion::get_from_id($dis[0], mod_forumng::CLONE_DIRECT); }
/** * Checks forum object created in test_get_forum() * In function so same tests can be carried out on multiple forum setups * @param object $forum * @param object $course * @param object $cm */ private function check_forum_settings(mod_forumng $forum, $course, $cm) { $this->assertEquals('TEST', $forum->get_name()); $this->assertEquals('abc123', $forum->get_intro()); $this->assertEquals('abc123', $forum->get_intro(true)); // Pick up errors in abbreviation. $this->assertEquals(FORMAT_MOODLE, $forum->get_intro_format()); $this->assertEquals($cm->instance, $forum->get_id()); $this->assertEquals($course->id, $forum->get_course_id()); $this->assertEquals($course->id, $forum->get_course()->id); $this->assertEquals($cm->id, $forum->get_course_module_id()); $this->assertEquals(mod_forumng::NO_GROUPS, $forum->get_activity_group($cm)); $context = context_module::instance($cm->id); $this->assertEquals($context->id, $forum->get_context()->id); $this->assertInstanceOf('forumngtype', $forum->get_type()); }