function forumng_delete_instance($id, $ociskip = true)
{
    require_once dirname(__FILE__) . '/forum.php';
    try {
        $forum = forum::get_from_id($id, forum::CLONE_DIRECT);
        // avoid deleting OCI specific forum if running in upload block
        if ($ociskip) {
            global $restore;
            if (isset($restore) && $restore->restoreto == 0 && strpos($_SERVER['HTTP_REFERER'], 'blocks/versions/upload.php') !== false) {
                if ($forum->get_name() == get_string('newunitforumname', 'createcourse')) {
                    //Unit forum
                    echo ' found forumng ' . $forum->get_id() . ' ' . $forum->get_name();
                    return true;
                }
            }
        }
        $forum->delete_all_data();
        if (forum::search_installed()) {
            $cm = $forum->get_course_module();
            ousearch_document::delete_module_instance_data($cm);
        }
    } catch (Exception $e) {
        return false;
    }
    return delete_records('forumng', 'id', $id);
}
<?php

require_once '../../config.php';
require_once $CFG->dirroot . '/mod/forumng/forum.php';
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
// This script is for use only temporarily to respond to a glitch in the
// forum -> ForumNG conversion script where it didn't build search indexes.
// This file lets the search index be manually rebuilt. We should probably
// delete it later.
$cmid = required_param('id', PARAM_INT);
$cloneid = optional_param('clone', 0, PARAM_INT);
try {
    $forum = forum::get_from_cmid($cmid, $cloneid);
    $cm = $forum->get_course_module();
    forum::search_installed();
    // This script is not very user friendly. Once it finishes, it's done...
    print_header();
    forum::search_update_all(true, $cm->course, $cm->id);
    print_footer();
} catch (forum_exception $e) {
    forum_utils::handle_exception($e);
}
 /**
  * Used by forum_post when creating a reply. Do not call directly.
  * @param forum_post $parentpost Parent post object (NULL when creating root post)
  * @param string $subject Subject
  * @param string $message Message
  * @param int $format Moodle format used for message
  * @param array $attachments Array of paths to temporary files of
  *   attachments in post. [Note that these should have already been checked
  *   and renamed by the Moodle upload manager. They will be moved or
  *   deleted by the time this method returns.]
  * @param bool $setimportant If true, highlight the post
  * @param bool $mailnow If true, sends mail ASAP
  * @param int $userid User ID (0 = current)
  *
  * @return int ID of newly-created post
  */
 function create_reply($parentpost, $subject, $message, $format, $attachments = array(), $setimportant = false, $mailnow = false, $userid = 0)
 {
     if ($userid == 0) {
         global $USER;
         $userid = $USER->id;
         if (!$userid) {
             throw new forum_exception('Cannot determine user ID');
         }
     }
     // Prepare post object
     $postobj = new StdClass();
     $postobj->discussionid = $this->discussionfields->id;
     $postobj->parentpostid = $parentpost ? $parentpost->get_id() : null;
     $postobj->userid = $userid;
     $postobj->created = time();
     $postobj->modified = $postobj->created;
     $postobj->deleted = 0;
     $postobj->mailstate = $mailnow ? forum::MAILSTATE_NOW_NOT_MAILED : forum::MAILSTATE_NOT_MAILED;
     $postobj->important = $setimportant ? 1 : 0;
     $postobj->oldversion = 0;
     $postobj->edituserid = null;
     $postobj->subject = strlen(trim($subject)) == 0 ? null : addslashes($subject);
     $postobj->message = addslashes($message);
     $postobj->format = $format;
     $postobj->attachments = count($attachments) > 0;
     forum_utils::start_transaction();
     try {
         // Create post
         $postobj->id = forum_utils::insert_record('forumng_posts', $postobj);
         $post = new forum_post($this, $postobj);
         // For replies, update last post id
         if ($parentpost) {
             $discussionchange = new stdClass();
             $discussionchange->id = $parentpost->get_discussion()->get_id();
             $discussionchange->lastpostid = $postobj->id;
             forum_utils::update_record('forumng_discussions', $discussionchange);
         }
         // Place attachments
         foreach ($attachments as $path) {
             $post->add_attachment($path);
         }
         // Update search index (replies only)
         if (forum::search_installed() && $parentpost) {
             $post->search_update();
         }
         // Update completion state
         $post->update_completion(true);
         // Outside the catch so we don't commit transaction if something
         // fails
         forum_utils::finish_transaction();
         return $post->get_id();
     } catch (Exception $e) {
         // Erase attachments from temp storage if error occurs
         foreach ($attachments as $path) {
             unlink($path);
         }
         throw $e;
     }
 }
    /**
     * Returns HTML for search form, or blank if there is no search facility
     * in this forum.
     * @param string $querytext Text of query (not escaped)
     * @return string HTML code for search form
     */
    public function display_search_form($querytext = '')
    {
        $cmid = $this->get_course_module_id();
        $strsearchthisactivity = get_string('searchthisforum', 'forumng');
        $queryesc = htmlspecialchars($querytext);
        $linkfields = $this->get_link_params(forum::PARAM_FORM);
        $buttontext = !forum::search_installed() ? '' : <<<EOF
<form action="search.php" method="get"><div>
{$linkfields}
  <label class="accesshide" for="forumng-searchquery">{$strsearchthisactivity}</label>
  <input type="text" name="query" id="forumng-searchquery" value="{$queryesc}"/>
  <input type="submit" value="{$strsearchthisactivity}"/>
</div></form>
EOF;
        return $buttontext;
    }
 /**
  * Calls search_update on each child of the current post, and recurses.
  * Used when the subject's discussion is changed.
  */
 function search_update_children()
 {
     if (!forum::search_installed()) {
         return;
     }
     // If the in-memory post object isn't already part of a full
     // discussion...
     if (!is_array($this->children)) {
         // ...then get one
         $discussion = forum_discussion::get_from_id($this->discussion->get_id(), $this->get_forum()->get_course_module_id());
         $post = $discussion->get_root_post()->find_child($this->get_id());
         // Do this update on the new discussion
         $post->search_update_children();
         return;
     }
     // Loop through all children
     foreach ($this->children as $child) {
         // Update its search fields
         $child->search_update();
         // Recurse
         $child->search_update_children();
     }
 }
function xmldb_forumng_upgrade($oldversion = 0)
{
    global $CFG, $THEME, $db;
    require_once $CFG->dirroot . '/mod/forumng/forum.php';
    $result = true;
    /// And upgrade begins here. For each one, you'll need one
    /// block of code similar to the next one. Please, delete
    /// this comment lines once this file start handling proper
    /// upgrade code.
    /// if ($result && $oldversion < YYYYMMDD00) { //New version in version.php
    ///     $result = result of "/lib/ddllib.php" function calls
    /// }
    if ($result && $oldversion < 2009071703) {
        /// Add search data
        require_once dirname(__FILE__) . '/../lib.php';
        require_once dirname(__FILE__) . '/../forum.php';
        if (forum::search_installed()) {
            global $db;
            $olddebug = $db->debug;
            $db->debug = false;
            print '<ul>';
            forumng_ousearch_update_all(true);
            print '</ul>';
            $db->debug = $olddebug;
        }
    }
    if ($result && $oldversion < 2009102001) {
        /// Define table forumng_drafts to be created
        $table = new XMLDBTable('forumng_drafts');
        /// Adding fields to table forumng_drafts
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('forumid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('groupid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('parentpostid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('subject', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('message', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('format', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('attachments', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('saved', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('options', XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null);
        /// Adding keys to table forumng_drafts
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        $table->addKeyInfo('forumid', XMLDB_KEY_FOREIGN, array('forumid'), 'forumng', array('id'));
        $table->addKeyInfo('parentpostid', XMLDB_KEY_FOREIGN, array('parentpostid'), 'forumng_posts', array('id'));
        /// Launch create table for forumng_drafts
        $result = $result && create_table($table);
    }
    if ($result && $oldversion < 2009110401) {
        /// Define field important to be added to forumng_posts
        $table = new XMLDBTable('forumng_posts');
        $field = new XMLDBField('important');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'deleteuserid');
        /// Launch add field important
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2009110600) {
        /// Define field subscribed to be added to forumng_subscriptions
        $table = new XMLDBTable('forumng_subscriptions');
        $field = new XMLDBField('subscribed');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1', 'forumid');
        /// Launch add field subscribed
        $result = $result && add_field($table, $field);
        /// Changing the default of field subscribed on table forumng_subscriptions to drop it
        $table = new XMLDBTable('forumng_subscriptions');
        $field = new XMLDBField('subscribed');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'forumid');
        /// Launch change of default for field subscribed
        $result = $result && change_field_default($table, $field);
    }
    if ($result && $oldversion < 2009111001) {
        /// Define field reportingemail to be added to forumng
        $table = new XMLDBTable('forumng');
        $field = new XMLDBField('reportingemail');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null, 'attachmentmaxbytes');
        /// Launch add field reportingemail
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2009111002) {
        /// Define table forumng_flags to be created
        $table = new XMLDBTable('forumng_flags');
        /// Adding fields to table forumng_flags
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('postid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('flagged', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table forumng_flags
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        $table->addKeyInfo('postid', XMLDB_KEY_FOREIGN, array('postid'), 'forumng_posts', array('id'));
        /// Launch create table for forumng_flags
        $result = $result && create_table($table);
    }
    if ($result && $oldversion < 2009120200) {
        // For OU version only, rebuild course cache - it is missing some of
        // the completion information
        if (class_exists('ouflags')) {
            rebuild_course_cache(0, true);
        }
    }
    if ($result && $oldversion < 2010020200) {
        /// Define field discussionid to be added to forumng_subscriptions
        $table = new XMLDBTable('forumng_subscriptions');
        $field = new XMLDBField('discussionid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'subscribed');
        /// Launch add field discussionid
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2010051300) {
        /// Define field removeafter to be added to forumng
        $table = new XMLDBTable('forumng');
        $field = new XMLDBField('removeafter');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'completionposts');
        /// Launch add field removeafter
        $result = $result && add_field($table, $field);
        $field = new XMLDBField('removeto');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'removeafter');
        /// Launch add field removeto
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2010071900) {
        /// Define field shared to be added to forumng
        $table = new XMLDBTable('forumng');
        $field = new XMLDBField('shared');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'removeto');
        /// Launch add field shared
        $result = $result && add_field($table, $field);
        /// Define field originalcmid to be added to forumng
        $field = new XMLDBField('originalcmid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'shared');
        /// Launch add field originalcmid
        $result = $result && add_field($table, $field);
        /// Define key originalcmid (foreign) to be added to forumng
        $key = new XMLDBKey('originalcmid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('originalcmid'), 'course_modules', array('id'));
        /// Launch add key originalcmid
        $result = $result && add_key($table, $key);
    }
    if ($result && $oldversion < 2010072100) {
        /// Define field clonecmid to be added to forumng_subscriptions
        $table = new XMLDBTable('forumng_subscriptions');
        $field = new XMLDBField('clonecmid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'discussionid');
        /// Launch add field clonecmid
        $result = $result && add_field($table, $field);
        /// Define key clonecmid (foreign) to be added to forumng_subscriptions
        $key = new XMLDBKey('clonecmid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('clonecmid'), 'course_modules', array('id'));
        /// Launch add key clonecmid
        $result = $result && add_key($table, $key);
    }
    if ($result && $oldversion < 2010073000) {
        /// Define field groupid to be added to forumng_subscriptions
        $table = new XMLDBTable('forumng_subscriptions');
        $field = new XMLDBField('groupid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'clonecmid');
        /// Launch add field groupid
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2010073001) {
        $db->debug = false;
        forum::group_subscription_update(true);
        $db->debug = true;
    }
    return $result;
}
function forumng_decode_content_links_caller($restore)
{
    // Get all the items that might have links in, from the relevant new course
    try {
        global $CFG, $db;
        // 1. Intros
        if ($intros = get_records_select('forumng', 'course=' . $restore->course_id . ' AND intro IS NOT NULL', '', 'id, intro, name')) {
            foreach ($intros as $intro) {
                $newintro = $intro->intro;
                // Special behaviour hidden in intro
                $matches = array();
                if (preg_match('~%%CMIDNUMBER:([^%]+)%%$~', $newintro, $matches)) {
                    $newintro = substr($newintro, 0, -strlen($matches[0]));
                    $idnumber = $matches[1];
                    $cm = forum::get_shared_cm_from_idnumber($idnumber);
                    if ($cm) {
                        set_field('forumng', 'originalcmid', $cm->id, 'id', $intro->id);
                    } else {
                        // The original forum cannot be found, so restore
                        // this as not shared
                        if (!defined('RESTORE_SILENTLY')) {
                            $a = (object) array('name' => s($intro->name), 'idnumber' => s($idnumber));
                            print '<br />' . get_string('error_nosharedforum', 'forumng', $a) . '<br />';
                        }
                    }
                }
                if (preg_match('~%%REMOVETHIS%%$~', $newintro)) {
                    $newintro = substr($newintro, 0, -14);
                }
                $newintro = restore_decode_content_links_worker($newintro, $restore);
                if ($newintro != $intro->intro) {
                    if (!set_field('forumng', 'intro', addslashes($newintro), 'id', $intro->id)) {
                        throw new forum_exception("Failed to set intro for forum {$intro->id}: " . $db->ErrorMsg());
                    }
                }
            }
        }
        // 2. Post content
        $rs = get_recordset_sql("\nSELECT\n    fp.id, fp.message, fp.format\nFROM\n    {$CFG->prefix}forumng f\n    INNER JOIN {$CFG->prefix}forumng_discussions d ON d.forumid = f.id\n    INNER JOIN {$CFG->prefix}forumng_posts fp ON fp.discussionid = d.id\nWHERE\n    f.course={$restore->course_id}\n");
        if (!$rs) {
            throw new forum_exception("Failed to query for forum data: " . $db->ErrorMsg());
        }
        while ($rec = rs_fetch_next_record($rs)) {
            $newcontent = restore_decode_content_links_worker($rec->message, $restore);
            if ($newcontent != $rec->message) {
                if (!set_field('forumng_posts', 'message', addslashes($newcontent), 'id', $rec->id)) {
                    throw new forum_exception("Failed to update content {$ec->id}: " . $db->ErrorMsg());
                }
            }
        }
        rs_close($rs);
        // 3. Update search data (note this is not actually do with content
        //    links, but it has to be done here because we need a course-module
        //    id.
        if (forum::search_installed()) {
            forumng_ousearch_update_all(false, $restore->course_id);
        }
        return true;
    } catch (Exception $e) {
        forum_utils::handle_backup_exception($e, 'restore');
        return false;
    }
}