protected function after_execute()
 {
     global $DB, $CFG;
     $transaction = $DB->start_delegated_transaction();
     $ouwikiid = $this->get_task()->get_activityid();
     // Flush out any unsaved versions.
     $this->flush_versions();
     // Add ouwiki related files, no need to match by itemname (just internally handled context).
     $this->add_related_files('mod_ouwiki', 'intro', null);
     $this->add_related_files('mod_ouwiki', 'template', 'ouwiki');
     // Add post related files.
     $this->add_related_files('mod_ouwiki', 'attachment', 'ouwiki_version');
     $this->add_related_files('mod_ouwiki', 'content', 'ouwiki_version');
     // Update firstversionid.
     $sql = 'SELECT v.pageid,
                 (SELECT MIN(id)
                 FROM {ouwiki_versions} v3
                 WHERE v3.pageid = p.id AND v3.deletedat IS NULL)
                 AS firstversionid
             FROM
                 {ouwiki} o
                 JOIN {ouwiki_subwikis} s ON s.wikiid = o.id
                 JOIN {ouwiki_pages} p ON p.subwikiid = s.id
                 JOIN {ouwiki_versions} v ON v.pageid = p.id
             WHERE
                 o.id = ?
             GROUP BY v.pageid, p.id
             ORDER BY v.pageid';
     $rs = $DB->get_recordset_sql($sql, array($ouwikiid));
     foreach ($rs as $entry) {
         if ($entry->firstversionid) {
             $DB->set_field('ouwiki_pages', 'firstversionid', $entry->firstversionid, array('id' => $entry->pageid));
         }
     }
     $rs->close();
     // Update previousversionid.
     $sql = 'SELECT v.id AS versionid,
                 (SELECT MAX(v2.id)
                 FROM {ouwiki_versions} v2
                 WHERE v2.pageid = p.id AND v2.id < v.id)
                 AS previousversionid
             FROM
                 {ouwiki} o
                 JOIN {ouwiki_subwikis} s ON s.wikiid = o.id
                 JOIN {ouwiki_pages} p ON p.subwikiid = s.id
                 JOIN {ouwiki_versions} v ON v.pageid = p.id
             WHERE
                 o.id = ?';
     $rs = $DB->get_recordset_sql($sql, array($ouwikiid));
     foreach ($rs as $entry) {
         if ($entry->previousversionid) {
             $DB->set_field('ouwiki_versions', 'previousversionid', $entry->previousversionid, array('id' => $entry->versionid));
         }
     }
     $rs->close();
     // Update all the page ids for links.
     $sql = 'SELECT l.id AS linkid, l.topageid
             FROM
                 {ouwiki} o
                 JOIN {ouwiki_subwikis} s ON s.wikiid = o.id
                 JOIN {ouwiki_pages} p ON p.subwikiid = s.id
                 JOIN {ouwiki_versions} v ON v.pageid = p.id
                 JOIN {ouwiki_links} l ON l.fromversionid = v.id
             WHERE
                 o.id = ? AND l.topageid IS NOT NULL';
     $rs = $DB->get_recordset_sql($sql, array($ouwikiid));
     $errors = array();
     foreach ($rs as $entry) {
         $newpageid = $this->get_mappingid('ouwiki_page', $entry->topageid, null);
         if (!$newpageid && empty($errors[$entry->topageid])) {
             $errors[$entry->topageid] = true;
             $this->get_logger()->process('OU wiki: link to missing pageid ' . $entry->topageid . ' not restored properly.', backup::LOG_WARNING);
         }
         $DB->set_field('ouwiki_links', 'topageid', $newpageid, array('id' => $entry->linkid));
     }
     $rs->close();
     // Update xhtml field with correct annotations.
     // Get all table entries in ouwiki_versions table for this wiki.
     $sql = "SELECT v.id, v.xhtml\n                    FROM {ouwiki_subwikis} s\n                    JOIN {ouwiki_pages} p ON p.subwikiid = s.id\n                    JOIN {ouwiki_versions} v ON v.pageid = p.id\n                    WHERE s.wikiid = ?\n                    ORDER BY v.id";
     $rs = $DB->get_recordset_sql($sql, array($ouwikiid));
     // Go through annotation elements ids replacing old annotation ids with new annotation ids in xhtml field of result set.
     foreach ($rs as $entry) {
         $matches = array();
         // Check to see whether this contains any annotations to be replaced.
         $found = preg_match_all('~(span id=")(annotation[0-9]+)(")~', $entry->xhtml, $matches, PREG_SET_ORDER);
         if ($found) {
             foreach ($matches as $arr) {
                 // Check to see whether an old array key exist.
                 if (array_key_exists($arr[2], $this->elementsids)) {
                     // Do the replace.
                     $replacestr = 'span id="' . $this->elementsids[$arr[2]] . '"';
                     $entry->xhtml = str_replace($arr[0], $replacestr, $entry->xhtml);
                 }
             }
             // Set the xhtml field if any annotation ids replaced.
             $DB->set_field('ouwiki_versions', 'xhtml', $entry->xhtml, array('id' => $entry->id));
         }
     }
     // Close the result set.
     $rs->close();
     $transaction->allow_commit();
     require_once $CFG->dirroot . '/mod/ouwiki/locallib.php';
     // Create search index if user data restored.
     if ($this->get_setting_value('userinfo') && ouwiki_search_installed()) {
         ouwiki_ousearch_update_all(false, $this->get_courseid());
     }
 }
function ouwiki_decode_content_links_caller($restore)
{
    // Get all the items that might have links in, from the relevant new course
    try {
        global $CFG, $db;
        // 1. Summaries
        if ($summaries = get_records_select('ouwiki', 'course=' . $restore->course_id . ' AND summary IS NOT NULL', '', 'id,summary')) {
            foreach ($summaries as $summary) {
                $newsummary = restore_decode_content_links_worker($summary->summary, $restore);
                if ($newsummary != $summary->summary) {
                    if (!set_field('ouwiki', 'summary', addslashes($newsummary), 'id', $summary->id)) {
                        throw new Exception("Failed to set summary for wiki {$summary->id}: " . $db->ErrorMsg());
                    }
                }
            }
        }
        // 2. Actual content
        $rs = get_recordset_sql("\nSELECT\n    v.id,v.xhtml     \nFROM\n    {$CFG->prefix}ouwiki w\n    INNER JOIN {$CFG->prefix}ouwiki_subwikis s ON w.id=s.wikiid\n    INNER JOIN {$CFG->prefix}ouwiki_pages p ON s.id=p.subwikiid\n    INNER JOIN {$CFG->prefix}ouwiki_versions v ON p.id=v.pageid     \nWHERE\n    w.course={$restore->course_id} \n");
        if (!$rs) {
            throw new Exception("Failed to query for wiki data: " . $db->ErrorMsg());
        }
        while (!$rs->EOF) {
            $newcontent = restore_decode_content_links_worker($rs->fields['xhtml'], $restore);
            if ($newcontent != $rs->fields['xhtml']) {
                if (!set_field('ouwiki_versions', 'xhtml', addslashes($newcontent), 'id', $rs->fields['id'])) {
                    throw new Exception("Failed to update content {$rs->fields['id']}: " . $db->ErrorMsg());
                }
            }
            $rs->MoveNext();
        }
        // 3. This is a bit crappy, as it isn't directly to do with content links, but
        //    we can't do it until we have a course-module so it can't happen earlier.
        if (ouwiki_search_installed()) {
            ouwiki_ousearch_update_all(false, $restore->course_id);
        }
        return true;
    } catch (Exception $e) {
        ouwiki_handle_backup_exception($e, 'restore');
        return false;
    }
}