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