/**
  * Deletes an existing draft message.
  */
 function delete()
 {
     forum_utils::start_transaction();
     // Delete record
     forum_utils::delete_records('forumng_drafts', 'id', $this->draftfields->id);
     // Delete attachments
     $folder = $this->get_attachment_folder();
     if (is_dir($folder)) {
         $handle = forum_utils::opendir($folder);
         while (false !== ($name = readdir($handle))) {
             if ($name != '.' && $name != '..') {
                 forum_utils::unlink("{$folder}/{$name}");
             }
         }
         closedir($handle);
         forum_utils::rmdir($folder);
     }
     forum_utils::finish_transaction();
 }
 /**
  * Marks this discussion unread.
  * @param int $userid User who's not read the discussion (0=current)
  */
 public function mark_unread($userid = 0)
 {
     $userid = forum_utils::get_real_userid($userid);
     forum_utils::delete_records('forumng_read', 'userid', $userid, 'discussionid', $this->discussionfields->id);
     if ($this->incache) {
         $this->discussionfields->timeread = null;
         $this->cache($this->incache->userid);
     }
 }
 /**
  * Rates this post or updates an existing rating.
  * @param $rating Rating (value depends on scale used) or NO_RATING
  * @param $userid User ID or 0 for current user
  */
 function rate($rating, $userid = 0)
 {
     if (!$userid) {
         global $USER;
         $userid = $USER->id;
     }
     forum_utils::start_transaction();
     // Delete any existing rating
     forum_utils::delete_records('forumng_ratings', 'postid', $this->postfields->id, 'userid', $userid);
     // Add new rating
     if ($rating != self::NO_RATING) {
         $ratingobj = new StdClass();
         $ratingobj->userid = $userid;
         $ratingobj->postid = $this->postfields->id;
         $ratingobj->time = time();
         $ratingobj->rating = $rating;
         forum_utils::insert_record('forumng_ratings', $ratingobj);
     }
     // Tell grade to update
     if ($this->get_forum()->get_grading()) {
         $this->get_forum()->update_grades($this->get_user()->id);
     }
     forum_utils::finish_transaction();
     $this->get_discussion()->uncache();
 }
 /**
  * Update the forumng_subscription table to incorporate the group subscription feature.
  * @param bool $moodleupdate If this is true, the function is running as part of the 
  *   moodle upgrade.php for Sep 2010 release. In this case, the database queries must
  *   not be changed and other code must work the same way (avoid calls to functions
  *   except Moodle standard ones)
  */
 public function group_subscription_update($moodleupdate = false, $cmid = 0)
 {
     global $CFG;
     forum_utils::start_transaction();
     if ($cmid) {
         //only update one forum
         $optionalquery = "AND cm.id = {$cmid}";
     } else {
         $optionalquery = '';
     }
     // Query get the distinct forums
     $sql_count = "\nSELECT\n    COUNT(DISTINCT cm.id) AS totalnumberforum\nFROM \n    {$CFG->prefix}forumng_subscriptions fs\n    INNER JOIN {$CFG->prefix}course_modules cm on fs.forumid = cm.instance \n    INNER JOIN {$CFG->prefix}modules m on cm.module = m.id \n    INNER JOIN {$CFG->prefix}course c on c.id = cm.course \nWHERE \n    discussionid IS NULL AND m.name='forumng' {$optionalquery}\n    AND (CASE WHEN c.groupmodeforce=1 THEN c.groupmode ELSE cm.groupmode END ) = 1";
     //Query lists all subscriptions to forums that have separate groups
     $sql_sub = "\nSELECT\n    cm.id AS cmid, fs.id AS subid, fs.userid, fs.forumid, c.id AS courseid, cm.groupingid \nFROM\n    {$CFG->prefix}forumng_subscriptions fs\n    INNER JOIN {$CFG->prefix}course_modules cm on fs.forumid = cm.instance \n    INNER JOIN {$CFG->prefix}modules m on cm.module = m.id \n    INNER JOIN {$CFG->prefix}course c on c.id = cm.course \nWHERE \n    discussionid IS NULL and m.name='forumng' {$optionalquery}\n    AND (CASE WHEN c.groupmodeforce=1 THEN c.groupmode ELSE cm.groupmode END ) = 1 \nORDER BY cm.id, fs.id";
     //Query lists all groups that the user belongs to from the above query
     $sql_group = "\nSELECT\n    subs.subid, g.id AS groupid\nFROM\n    ({$sql_sub}) subs \n    INNER JOIN {$CFG->prefix}groups_members gm ON gm.userid = subs.userid \n    INNER JOIN {$CFG->prefix}groups g ON gm.groupid = g.id AND g.courseid = subs.courseid \n    LEFT JOIN {$CFG->prefix}groupings_groups gg ON gg.groupid = g.id AND subs.groupingid = gg.groupingid \nWHERE\n    (subs.groupingid = 0 or gg.id IS NOT NULL)\nORDER BY\n    subs.cmid, subs.subid";
     $rs = forum_utils::get_recordset_sql($sql_group);
     $results = array();
     while ($rec = rs_fetch_next_record($rs)) {
         if (!array_key_exists($rec->subid, $results)) {
             $results[$rec->subid] = array();
         }
         $results[$rec->subid][] = $rec->groupid;
     }
     rs_close($rs);
     $rs = forum_utils::get_recordset_sql($sql_sub);
     $lastcmid = 0;
     $forumcount = 1;
     $totalforumcount = 0;
     $totalforumcount = count_records_sql($sql_count);
     while ($rec = rs_fetch_next_record($rs)) {
         if ($lastcmid != $rec->cmid) {
             if ($moodleupdate) {
                 print "Updating the subscriptions {$forumcount}/{$totalforumcount} (current cmid:{$rec->cmid}) <br />";
             }
             $context = get_context_instance(CONTEXT_MODULE, $rec->cmid);
             $aagusers = get_users_by_capability($context, 'moodle/site:accessallgroups', 'u.id');
             $aagusers = $aagusers ? $aagusers : array();
             $lastcmid = $rec->cmid;
             $forumcount++;
         }
         if (!array_key_exists($rec->userid, $aagusers)) {
             //Delete the whole forum subscription
             forum_utils::delete_records('forumng_subscriptions', 'id', $rec->subid);
             //check if the subid exists in the results array
             if (array_key_exists($rec->subid, $results)) {
                 foreach ($results[$rec->subid] as $groupid) {
                     $subrecord = new StdClass();
                     $subrecord->userid = $rec->userid;
                     $subrecord->forumid = $rec->forumid;
                     $subrecord->subscribed = 1;
                     $subrecord->groupid = $groupid;
                     forum_utils::insert_record('forumng_subscriptions', $subrecord);
                 }
             }
         }
     }
     forum_utils::finish_transaction();
 }
function forumng_restore_mods($mod, $restore)
{
    global $CFG;
    $status = true;
    //Get record from backup_ids
    $forumid = 0;
    if ($data = backup_getid($restore->backup_unique_code, $mod->modtype, $mod->id)) {
        try {
            if (!defined('RESTORE_SILENTLY')) {
                $name = $data->info['MOD']['#']['NAME']['0']['#'];
                echo "<li>" . get_string('modulename', 'forumng') . ' "' . htmlspecialchars($name) . '"</li>';
            }
            // Boom. Now try restoring!
            $xml = $data->info['MOD']['#'];
            $userdata = restore_userdata_selected($restore, 'forumng', $mod->id);
            $forumng = new stdClass();
            $forumng->course = $restore->course_id;
            $forumng->name = addslashes($xml['NAME'][0]['#']);
            // ForumNG-specific data
            if (isset($xml['TYPE'][0]['#'])) {
                $forumng->type = backup_todb($xml['TYPE'][0]['#']);
            }
            if (isset($xml['INTRO'][0]['#'])) {
                $forumng->intro = backup_todb($xml['INTRO'][0]['#']);
            } else {
                $forumng->intro = null;
            }
            $forumng->ratingscale = $xml['RATINGSCALE'][0]['#'];
            $forumng->ratingfrom = $xml['RATINGFROM'][0]['#'];
            $forumng->ratinguntil = $xml['RATINGUNTIL'][0]['#'];
            $forumng->ratingthreshold = $xml['RATINGTHRESHOLD'][0]['#'];
            $forumng->grading = $xml['GRADING'][0]['#'];
            $forumng->attachmentmaxbytes = $xml['ATTACHMENTMAXBYTES'][0]['#'];
            if (isset($xml['REPORTINGEMAIL'][0]['#'])) {
                $forumng->reportingemail = backup_todb($xml['REPORTINGEMAIL'][0]['#']);
            }
            $forumng->subscription = $xml['SUBSCRIPTION'][0]['#'];
            $forumng->feedtype = $xml['FEEDTYPE'][0]['#'];
            $forumng->feeditems = $xml['FEEDITEMS'][0]['#'];
            $forumng->maxpostsperiod = $xml['MAXPOSTSPERIOD'][0]['#'];
            $forumng->maxpostsblock = $xml['MAXPOSTSBLOCK'][0]['#'];
            $forumng->postingfrom = $xml['POSTINGFROM'][0]['#'];
            $forumng->postinguntil = $xml['POSTINGUNTIL'][0]['#'];
            if (isset($xml['TYPEDATA'][0]['#'])) {
                $forumng->typedata = backup_todb($xml['TYPEDATA'][0]['#']);
            }
            $forumng->magicnumber = $xml['MAGICNUMBER'][0]['#'];
            $forumng->completiondiscussions = $xml['COMPLETIONDISCUSSIONS'][0]['#'];
            $forumng->completionreplies = $xml['COMPLETIONREPLIES'][0]['#'];
            $forumng->completionposts = $xml['COMPLETIONPOSTS'][0]['#'];
            if (isset($xml['REMOVEAFTER'][0]['#'])) {
                $forumng->removeafter = $xml['REMOVEAFTER'][0]['#'];
            }
            if (isset($xml['REMOVETO'][0]['#'])) {
                $forumng->removeto = backup_todb($xml['REMOVETO'][0]['#']);
            }
            if (isset($xml['SHARED'][0]['#'])) {
                $forumng->shared = $xml['SHARED'][0]['#'];
            }
            // To protect the forum intro field from molestation if some idiot
            // sets it to a weird value...
            if (preg_match('~%%CMIDNUMBER:[^%]+%%$~', $forumng->intro)) {
                $forumng->intro .= '%%REMOVETHIS%%';
            }
            if (isset($xml['ORIGINALCMIDNUMBER'][0]['#'])) {
                if ($forumng->intro === null) {
                    $forumng->intro = '';
                }
                // This is a bit of a hack, but we need to wait until everything
                // is restored, and it is a text value; so temporarily, add it
                // to the end of the intro field.
                $forumng->intro .= '%%CMIDNUMBER:' . backup_todb($xml['ORIGINALCMIDNUMBER'][0]['#']) . '%%';
            }
            // Insert main record
            if (!($forumng->id = insert_record('forumng', $forumng))) {
                throw new forum_exception('Error creating forumng instance');
            }
            $forumid = $forumng->id;
            backup_putid($restore->backup_unique_code, $mod->modtype, $mod->id, $forumng->id);
            if ($userdata) {
                if (isset($xml['DISCUSSIONS'][0]['#']['DISCUSSION'])) {
                    foreach ($xml['DISCUSSIONS'][0]['#']['DISCUSSION'] as $xml_sub) {
                        forumng_restore_discussion($restore, $xml_sub['#'], $forumng);
                    }
                }
                if (isset($xml['SUBSCRIPTIONS'][0]['#']['SUBSCRIPTION'])) {
                    foreach ($xml['SUBSCRIPTIONS'][0]['#']['SUBSCRIPTION'] as $xml_sub) {
                        forumng_restore_subscription($restore, $xml_sub['#'], $forumng);
                    }
                }
                // Attachments
                xml_backup::restore_module_files($restore->backup_unique_code, $restore->course_id, 'forumng', $mod->id);
                $basepath = $CFG->dataroot . '/' . $restore->course_id . '/moddata/forumng';
                rename($basepath . '/' . $mod->id, $basepath . '/' . $forumng->id);
            }
        } catch (Exception $e) {
            // Clean out any partially-created data
            try {
                forum_utils::execute_sql("\nDELETE FROM {$CFG->prefix}forumng_ratings\nWHERE postid IN (\nSELECT fp.id\nFROM\n    {$CFG->prefix}forumng_discussions fd\n    INNER JOIN {$CFG->prefix}forumng_posts fp ON fp.discussionid = fd.id\nWHERE\n    fd.forumid = {$forumid}\n)");
                $discussionquery = "\nWHERE discussionid IN (\nSELECT id FROM {$CFG->prefix}forumng_discussions WHERE forumid={$forumid})";
                forum_utils::execute_sql("DELETE FROM {$CFG->prefix}forumng_posts {$discussionquery}");
                forum_utils::execute_sql("DELETE FROM {$CFG->prefix}forumng_read {$discussionquery}");
                forum_utils::delete_records('forumng_subscriptions', 'forumid', $forumid);
                forum_utils::delete_records('forumng_discussions', 'forumid', $forumid);
                forum_utils::delete_records('forumng', 'id', $forumid);
            } catch (Exception $e) {
                debugging('Error occurred when trying to clean partial data');
            }
            forum_utils::handle_backup_exception($e, 'restore');
            $status = false;
        }
    }
    return $status;
}