/**
  * 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;
 }
 /**
  * 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);
     }
 }
 /**
  * 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());
 }
 /**
  * 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;
 }