/** * Create a usage list item, detailing a total, user image and some info * @param mod_forumng $forum * @param int $total * @param object $user * @param string $info * @return string */ public function render_usage_list_item($forum, $total, $user, $info) { global $OUTPUT; if (is_null($user)) { $userimage = html_writer::empty_tag('img', array('src' => $this->pix_url('u/f2'), 'alt' => '')); } else { $userimage = $OUTPUT->user_picture($user); if ($forum->is_shared()) { // Strip course id if shared forum. $userimage = str_replace('&course=' . $forum->get_course()->id, '', $userimage); } } $toreturn = html_writer::div($total, 'forumng_usage_list_tot') . html_writer::div($userimage, 'forumng_usage_list_pic') . html_writer::div($info, 'forumng_usage_list_info'); return $toreturn; }
/** * Moves discussion to another forum. This will also move any attachments * in the filesystem. You can also use this method to change group. * (Note that once a discussion has been moved its data fields are no longer * valid and the object should be discarded.) * @param mod_forumng $targetforum Target forum for move * @param int $targetforumngid New forum ID * @param int $targetgroupid New group ID */ public function move($targetforum, $targetgroupid) { global $DB; $update = new StdClass(); if ($targetforum->get_id() != $this->discussionfields->forumngid) { $update->forumngid = $targetforum->get_id(); } if ($targetgroupid != $this->discussionfields->groupid) { $update->groupid = $targetgroupid; } if (count((array) $update) == 0) { // No change return; } //Delete search data for this discussion before moving $this->ismakingsearchchange = true; $root = $this->get_root_post(); $root->search_update(); $root->search_update_children(); $this->ismakingsearchchange = false; $update->id = $this->discussionfields->id; $transaction = $DB->start_delegated_transaction(); $DB->update_record('forumng_discussions', $update); $targetcloneid = $targetforum->is_shared() ? $targetforum->get_course_module_id() : 0; $newdiscussion = self::get_from_id($this->get_id(), $targetcloneid, -1); if ($targetforum->get_id() != $this->forum->get_id()) { // Moving to different forum, we need to move attachments if any... // Get old and new contexts $fs = get_file_storage(); $filecontext = $this->get_forum()->get_context(true); $newfilecontext = $targetforum->get_context(true); // Get list of all affected post ids (includes edited, deleted) // that have attachments $postids = $DB->get_records('forumng_posts', array('discussionid' => $this->get_id(), 'attachments' => 1), '', 'id'); // Loop through all posts copying attachments & deleting old one foreach ($postids as $postid => $junk) { foreach (array('attachment', 'message') as $filearea) { $oldfiles = $fs->get_area_files($filecontext->id, 'mod_forumng', $filearea, $postid, 'id', false); foreach ($oldfiles as $oldfile) { $filerecord = new stdClass(); $filerecord->contextid = $newfilecontext->id; $fs->create_file_from_storedfile($filerecord, $oldfile); $oldfile->delete(); } } } // Completion status may have changed in source and target forums // Performance optimise: only do this if completion is enabled if ($this->forum->is_auto_completion_enabled()) { $this->update_completion(false); $newdiscussion->update_completion(true); } } //Update the search data after the move $newroot = $newdiscussion->get_root_post(); $newroot->search_update(); $newroot->search_update_children(); $this->uncache(); $transaction->allow_commit(); }
/** * Queries for all forums on a course, including additional data about unread * posts etc. * NOTE: If shared forums are in use, this will usually return the CLONE * forum object, which doesn't hold any data about the actual forum; * the exception is that unread data will be obtained from the real forum. * If you would like to obtain the real forum instead, please make sure * $realforums is set to true. This has a performance cost. * @param object $course Moodle course object * @param int $userid User ID, 0 = current user, -1 = no unread data is needed * @param bool $unreadasbinary If true, unread data MAY BE binary (1/0) * instead of containing the full number; this improves performance but * only works on some databases * @param array $specificids If array has no entries, returns all forums * on the course; if it has at least one entry, returns only those forums * with course-module ID listed in the array * @param bool $realforums Set this to true to obtain real forums * if any are clones; has a performance cost if shared forums are used * @return array Array of forum objects (keys are forum IDs; in the case of * shared forums, the id is of the clone not the forum, even if * $realforums is set) */ public static function get_course_forums($course, $userid = 0, $unread = self::UNREAD_DISCUSSIONS, $specificids = array(), $realforums = false) { global $USER, $DB; $userid = mod_forumng_utils::get_real_userid($userid); $result = array(); // Added $userid parameter to obtain modinfo for specific user rather than current user. $modinfo = get_fast_modinfo($course, $userid); // Obtains extra information needed only when acquiring unread data $aagforums = array(); $viewhiddenforums = array(); $groups = array(); $contexts = array(); if ($unread != self::UNREAD_NONE) { foreach ($modinfo->cms as $cmid => $cm) { if (count($specificids) && !in_array($cmid, $specificids)) { continue; } if ($cm->modname == 'forumng') { $context = context_module::instance($cmid); $contexts[$cmid] = $context; if (has_capability('moodle/site:accessallgroups', $context, $userid)) { $aagforums[] = $cm->instance; } if (has_capability('mod/forumng:viewallposts', $context, $userid)) { $viewhiddenforums[] = $cm->instance; } } } if ($userid == $USER->id && isset($USER->groupmember)) { if (array_key_exists($course->id, $USER->groupmember)) { $groups = $USER->groupmember[$course->id]; } // Else do nothing - groups list should be empty } else { $rs = $DB->get_recordset_sql("\nSELECT\n g.id\nFROM\n {groups} g\n INNER JOIN {groups_members} gm ON g.id = gm.groupid\nWHERE\n g.courseid = ?\n AND gm.userid = ?", array($course->id, $userid)); foreach ($rs as $rec) { $groups[] = $rec->id; } $rs->close(); } } $rows = self::query_forums($specificids, $course, $userid, $unread, $groups, $aagforums, $viewhiddenforums); foreach ($rows as $rec) { // Check course-module exists if (!array_key_exists($rec->cm_id, $modinfo->cms)) { continue; } $cm = $modinfo->cms[$rec->cm_id]; if ($cm->modname != 'forumng') { continue; } // Mess about with binary setting to ensure result is same, whatever // the database if ($unread == self::UNREAD_BINARY) { // Set binary to 0/1 even if database returns 't'/'f' if ($rec->f_hasunreaddiscussions === 'f') { $rec->f_hasunreaddiscussions = 0; } else { if ($rec->f_hasunreaddiscussions) { $rec->f_hasunreaddiscussions = 1; } else { $rec->f_hasunreaddiscussions = 0; } } } // Get context if we didn't already get it. if (!empty($contexts[$rec->cm_id])) { $context = $contexts[$rec->cm_id]; } else { $context = context_module::instance($rec->cm_id); } // Create a new forum object from the database details $forumfields = mod_forumng_utils::extract_subobject($rec, 'f_'); $forum = new mod_forumng($course, $cm, $context, $forumfields); $result[$forumfields->id] = $forum; if ($forum->is_shared()) { $forum->set_clone_reference(self::CLONE_DIRECT); } // For clone forums (only pointers to genuine shared forums) if ($forum->is_clone()) { // If we are retrieving the real forum, get it individually if ($realforums) { $othercourse = $DB->get_record_sql("\nSELECT\n c.*\nFROM\n {course_modules} cm\n INNER JOIN {course} c ON c.id = cm.course\nWHERE\n cm.id = ?", array($forumfields->originalcmid), '*', MUST_EXIST); $extra = self::get_course_forums($othercourse, $userid, $unread, array($forumfields->originalcmid)); if (count($extra) != 1) { throw new coding_exception('Unable to find shared forum ' . $forumfields->originalcmid); } foreach ($extra as $extraforum) { $extraforum->set_clone_reference($cm->id); $result[$forumfields->id] = $extraforum; } } else { if ($unread != self::UNREAD_NONE) { // Even if not retrieving the real forum, we still use // its undead data when unread data is on $forum->init_unread_from_original($unread); } } } } return $result; }
/** * Obtains the next forum from the list. * @param mod_forumng &$forum Forum (out variable) * @param object &$cm Course-module object (out variable) * @param object &$context Context object (out variable) * @param object &$course Course object (out variable) */ function next_forum(&$forum, &$cm, &$context, &$course) { // Skip if required to get to new forum while ($this->forum != null) { $this->next_discussion($discussion); } // Get record if ($this->storedrecord) { $record = $this->storedrecord; $this->storedrecord = null; } else { if (!$this->rs) { // Already used entire list and closed recordset return false; } else { if (!$this->rs->valid()) { // End of the line. Mark everything as mailed $this->mark_mailed($this->time); $this->rs->close(); $this->rs = null; return false; } $record = $this->rs->current(); $this->rs->next(); } } // Set data $this->storedrecord = clone $record; $cm = mod_forumng_utils::extract_subobject($record, 'cm_'); $course = mod_forumng_utils::extract_subobject($record, 'c_'); context_helper::preload_from_record(mod_forumng_utils::extract_subobject($record, 'x_')); $context = context_module::instance($cm->id); $forum = new mod_forumng($course, $cm, $context, mod_forumng_utils::extract_subobject($record, 'f_')); if ($forum->is_shared()) { $forum->set_clone_reference($record->cloneid); $cm = $forum->get_course_module(); $course = $forum->get_course(); $context = $forum->get_context(); } $this->forum = $forum; return true; }