$mform->set_data($link); // Print the header if ($blogtype == 'personal') { $PAGE->navbar->add(fullname($oubloguser), new moodle_url('/user/view.php', array('id' => $oubloguser->id))); $PAGE->navbar->add(format_string($oublog->name), new moodle_url('/mod/oublog/view.php', array('blog' => $blog))); } else { $PAGE->navbar->add($linkid ? $streditlink : $straddlink); } $PAGE->set_title(format_string($oublog->name)); $PAGE->set_heading(format_string($course->fullname)); echo $OUTPUT->header(); echo '<br />'; $mform->display(); echo $OUTPUT->footer(); } else { if ($frmlink->link) { $frmlink->id = $frmlink->link; $frmlink->oublogid = $oublog->id; if (!oublog_edit_link($frmlink)) { print_error('couldnotaddlink', 'oublog'); } } else { unset($frmlink->id); $frmlink->oublogid = $oublog->id; $frmlink->oubloginstancesid = $bloginstancesid; if (!oublog_add_link($frmlink)) { print_error('couldnotaddlink', 'oublog'); } } redirect($viewurl); }
/** * Start the import of personal blog data * @param string $dir path of directory containing backup data */ function migrate_backup($dir) { global $DB, $CFG, $SOURCESERVER; $SOURCESERVER = 'http://learn.open.ac.uk'; if (optional_param('acct', false, PARAM_BOOL)) { $SOURCESERVER = 'http://learnacct.open.ac.uk'; } if ($kill = optional_param('kill', false, PARAM_BOOL)) { output('<b>Trial run</b>, will perform rollback on each instance.'); } if ($tagsonly = optional_param('tagsonly', false, PARAM_BOOL)) { output('<b>Tags only</b>, will only fix tags, not add posts.'); } // Load in XML. $doc = new DOMDocument(); $doc->load($dir . '/oublog.xml'); $instancetags = $doc->getElementsByTagName('INSTANCE'); output('Total = ' . $instancetags->length . ' instances '); $total = required_param('total', PARAM_INT); $max = $total == 0 ? $instancetags->length + 1 : $total; output('Max instances to process: ' . $max); // Get xml that stores old instance ID's of those instances already processed. $donedoc = new DOMDocument(); $done = array(); $donetag = null; if (!optional_param('ignore', false, PARAM_BOOL) && file_exists($dir . '/imported.xml')) { $donedoc->load($dir . '/imported.xml'); $donestr = $donedoc->saveXML(); $donetag = $donedoc->getElementsByTagName('imported')->item(0); $tags = $donetag->childNodes->item(0); while ($tags != null) { // Store ids in array using fast looping. $done[$tags->nodeValue] = ''; $tags->parentNode->removeChild($tags); $tags = $donetag->childNodes->item(0); } // Reinstate childnodes. $donedoc->loadXML($donestr); $donestr = null; output('Have already processed ' . count($done) . ' instances'); } else { $donedoc->appendChild($donedoc->createElement('imported')); } $donetag = $donedoc->getElementsByTagName('imported')->item(0); $count = 0; $instances = array(); // Stores data (as object) about each instance in array. $tags = $instancetags->item(0); // Fast looping of node list by always accessing first tag (faster than foreach). while ($tags != null && $count < $max) { $info = childnodes_to_object($tags); // Remove tag we just processed. $tags->parentNode->removeChild($tags); // Get the next tag to parse. $tags = $instancetags->item(0); // Have we processed this instance before? If so, skip. if (isset($done[$info->id])) { $info = null; continue; } $instances[$info->id] = $info; $info = null; $count++; } // Throw away xml as no longer need. $doc = null; $instancetags = null; $tags = null; output("Ready to process {$count} instances"); // Process each blog instance - checking for existing user instance. $blog = $DB->get_record('oublog', array('global' => 1), 'id', MUST_EXIST); $blog->global = 1; output('Got global blog record'); if (!($cm = get_coursemodule_from_instance('oublog', $blog->id))) { print_error('invalidcoursemodule'); } $blogcontext = context_module::instance($cm->id); // Vars used to store blog user content xml data. $xmlcontent = new DOMDocument(); $xmlfilenum = -1; $xpath = null; // Xpath for current content xml file. foreach ($instances as &$instance) { // Transaction per instance (ensure any existing are cleared up). if (isset($trans) && $trans instanceof moodle_transaction) { // Commit what has been done (errors will have rolled back already). $DB->commit_delegated_transaction($trans); $trans = null; } $trans = $DB->start_delegated_transaction(); try { // Find/create user. if (!($instance->newuserid = oublog_search_create_user($instance))) { output("<b>Error: Skipping blog for {$instance->username}</b>"); continue; } // Work out new instance number (either from new or existing record). if ($bloginst = $DB->get_record('oublog_instances', array('oublogid' => $blog->id, 'userid' => $instance->newuserid), 'id')) { $instance->newid = $bloginst->id; $bloginst = null; } else { if ($tagsonly) { output("<b>Error: Skipping create instance for {$instance->username} as in tag only mode</b>"); continue; } // Create instance. $newbloginst = new stdClass(); $newbloginst->oublogid = $blog->id; $newbloginst->userid = $instance->newuserid; $newbloginst->name = $instance->name; $newbloginst->summary = blogxml_isempty($instance->summary) ? '' : $instance->summary; $newbloginst->summary = oublog_decode_perbloglinks($newbloginst->summary, $xpath); $newbloginst->accesstoken = $instance->accesstoken; $newbloginst->views = $instance->views; if (!($instance->newid = $DB->insert_record('oublog_instances', $newbloginst))) { output("<b>Failed to add blog instance {$instance->name}</b>"); continue; } $newbloginst = null; // Migrate any mystuff images in summary. if (strpos($instance->summary, '@@PLUGINFILE@@') || stripos($instance->summary, $SOURCESERVER . '/pix/smartpix.php/ou/s/')) { $updaterec = new stdClass(); $updaterec->id = $instance->newid; $updaterec->summary = oublog_add_files($instance->summary, $dir, $blogcontext->id, 'summary', $instance->newid); $DB->update_record('oublog_instances', $updaterec); $updaterec = null; } } output('Finished setup blog instance for ' . $instance->username . ' :new id=' . $instance->newid); // What is XML file for current instance, load if not current one. $instfilenum = get_filenumber($instance->id); if ($instfilenum != $xmlfilenum) { // Load our XML into current var. if (!$xmlcontent->load($dir . '/i' . $instfilenum . '.xml')) { output('<b>Error: Failed to load user data</b> file number ' . $instfilenum); continue; } $xmlfilenum = $instfilenum; $xpath = new DOMXPath($xmlcontent); // Get data from XML into vars for quick access. $alllinks = array(); $linktags = $xmlcontent->getElementsByTagName('LINK'); foreach ($linktags as $l) { $linkob = childnodes_to_object($l); if (!isset($alllinks[$linkob->oubloginstancesid])) { $alllinks[$linkob->oubloginstancesid] = array(); } $alllinks[$linkob->oubloginstancesid][] = $linkob; $linkob = null; } $linktags = null; if ($tagsonly) { $alllinks = array(); // Ignore any links in tag fix mode; } $allusers = array(); $usertags = $xmlcontent->getElementsByTagName('USER'); foreach ($usertags as $t) { $allusers[$t->getAttribute('id')] = childnodes_to_object($t); } $usertags = null; $allposts = array(); $posttags = $xmlcontent->getElementsByTagName('POST'); $tag = $posttags->item(0); // Fast looping for posts as probably the most tags. while ($tag != null) { $linkob = childnodes_to_object($tag); $tag->parentNode->removeChild($tag); $tag = $posttags->item(0); if (!isset($linkob->oubloginstancesid)) { continue; } if (!isset($allposts[$linkob->oubloginstancesid])) { $allposts[$linkob->oubloginstancesid] = array(); } $allposts[$linkob->oubloginstancesid][] = $linkob; $linkob = null; } $posttags = null; $alltags = array(); $tagtags = $xmlcontent->getElementsByTagName('TAG'); foreach ($tagtags as $l) { $linkob = childnodes_to_object($l); if (!isset($linkob->postid)) { continue; } if (!isset($alltags[$linkob->postid])) { $alltags[$linkob->postid] = array(); } $alltags[$linkob->postid][] = $linkob; $linkob = null; } $tagtags = null; $alledits = array(); $edittags = $xmlcontent->getElementsByTagName('EDIT'); foreach ($edittags as $l) { $linkob = childnodes_to_object($l); if (!isset($linkob->postid)) { continue; } if (!isset($alledits[$linkob->postid])) { $alledits[$linkob->postid] = array(); } $alledits[$linkob->postid][] = $linkob; $linkob = null; } $edittags = null; if ($tagsonly) { $alledits = array(); // Ignore any edits in tag fix mode; } $allcomments = array(); $commenttags = $xmlcontent->getElementsByTagName('COMMENT'); foreach ($commenttags as $l) { $linkob = childnodes_to_object($l); if (!isset($linkob->postid)) { continue; } if (!isset($allcomments[$linkob->postid])) { $allcomments[$linkob->postid] = array(); } $allcomments[$linkob->postid][] = $linkob; $linkob = null; } $commenttags = null; if ($tagsonly) { $allcomments = array(); // Ignore any comments in tag fix mode; } output('Loaded user data file ' . $xmlfilenum); } // Store posts info for this instance (used in link checks). $postinfo = array(); if (isset($allposts[$instance->id])) { // Create a clone of the array as it contains objects... $postinfo = serialize($allposts[$instance->id]); $postinfo = unserialize($postinfo); } // Create instance links. // $links = $xpath->query("/DATA/LINKS/LINK[OUBLOGINSTANCESID=$instance->id]"); $links = array(); if (isset($alllinks[$instance->id])) { $links = $alllinks[$instance->id]; } $linksa = array(); // Sort by SORTORDER - so lowest first. foreach ($links as $newlink) { // Create new link object and add to our new array. // $newlink = childnodes_to_object($link); $newlink->oubloginstancesid = $instance->newid; $newlink->oublogid = $blog->id; unset($newlink->id); if (!isset($newlink->sortorder)) { $newlink->sortorder = 0; } $linksa[] = $newlink; } $links = null; // Sort by SORTORDER - so lowest first. usort($linksa, 'oublog_sort_links'); foreach ($linksa as $link) { // Create link. $link->url = oublog_decode_perbloglinks($link->url, $xpath, $postinfo, $instance->userid); if (!oublog_add_link($link)) { output("Error: Failed to create link for blog:{$instance->newid}"); } } $linksa = null; // End of link creation code. output('Finished links'); output('Processing posts'); // PROCESS Blog posts. $instance->postmapping = array(); // Store old + new ids. // $posts = $xpath->query("/DATA/POSTS/POST[OUBLOGINSTANCESID=$instance->id]"); $posts = array(); if (isset($allposts[$instance->id])) { $posts = $allposts[$instance->id]; } output(count($posts) . ' posts to process'); foreach ($posts as $newpost) { // Sort out post object ready to save. // $newpost = childnodes_to_object($post); $oldid = $newpost->id; unset($newpost->id); $newpost->groupid = 0; // Just in case! $newpost->oubloginstancesid = $instance->newid; if (!is_null($newpost->deletedby)) { if ($tagsonly) { continue; // Don't update deleted post tags. } if ($newpost->deletedby == $instance->userid) { // Most of the time will be blog user. $newpost->deletedby = $instance->newuserid; } else { // Find mapped user id in this system. // $users = $xpath->query("/DATA/USERS/USER[@id=$newpost->deletedby]"); $users = isset($allusers[$newpost->deletedby]) ? $allusers[$newpost->deletedby] : false; if (!$users) { $newpost->deletedby = false; } else { $newpost->deletedby = oublog_search_create_user($users); } if ($newpost->deletedby == false) { output("Error: Failed to get/make user id for deletedby, old post id: {$oldid}"); $newpost->deletedby = $instance->newuserid; } } } if (!$tagsonly) { if (!is_null($newpost->lasteditedby)) { if ($newpost->lasteditedby == $instance->userid) { // Most of the time will be blog user. $newpost->lasteditedby = $instance->newuserid; } else { // Find mapped user id in this system. // $users = $xpath->query("/DATA/USERS/USER[@id=$newpost->lasteditedby]"); $users = isset($allusers[$newpost->lasteditedby]) ? $allusers[$newpost->lasteditedby] : false; if (!$users) { $newpost->lasteditedby = false; } else { $newpost->lasteditedby = oublog_search_create_user($users); } if ($newpost->lasteditedby == false) { output("Error: Failed to get/make user id for edited by, old post id: {$oldid}"); $newpost->lasteditedby = $instance->newuserid; } } } $newpost->message = oublog_decode_perbloglinks($newpost->message, $xpath, $postinfo, $instance->userid); if (!($postid = $DB->insert_record('oublog_posts', $newpost))) { output("<b>Error: Failed to create post, old id = {$oldid}</b>"); continue; } } else { // Tag fix only mode. Search for post previously created to use as $postid. if (!($post = $DB->get_record_sql('select id, message from {oublog_posts} where oubloginstancesid = :oubloginstancesid and timeposted = :timeposted and title = :title and deletedby is null', array('oubloginstancesid' => $instance->newid, 'timeposted' => $newpost->timeposted, 'title' => $newpost->title)))) { output("<b>Error: Failed to find post (TAG FIX), old id = {$oldid}</b>"); continue; } $postid = $post->id; $newpost->message = $post->message; // Ensure matches that on system. // Store existing tags so any extra added not removed. $tagnames = oublog_get_post_tags($post); $post = null; } $instance->postmapping[$oldid] = $postid; // Record old/new id mapping. output('', true); // Output dots. // Migrate any mystuff images in message. if (!$tagsonly && (strpos($newpost->message, '@@PLUGINFILE@@') || stripos($newpost->message, $SOURCESERVER . '/pix/smartpix.php/ou/s/'))) { $updaterec = new stdClass(); $updaterec->id = $postid; $updaterec->message = oublog_add_files($newpost->message, $dir, $blogcontext->id, 'message', $postid); $DB->update_record('oublog_posts', $updaterec); $updaterec = null; } // Add post tags (also used in search to save DB query). $newpost->tags = array(); // $tags = $xpath->query("/DATA/TAGS/TAG[POSTID=$oldid]"); if (!$tagsonly || empty($tagnames)) { $tagnames = array(); } $tags = array(); if (isset($alltags[$oldid])) { $tags = $alltags[$oldid]; } foreach ($tags as $tag) { $tagnames[] = $tag->tagname; } if (!empty($tagnames)) { $tagnames = array_unique(array_filter($tagnames)); oublog_update_item_tags($instance->newid, $postid, $tagnames); $newpost->tags = $tagnames; $tagnames = null; } if (is_null($newpost->deletedby)) { // Update search. $newpost->id = $postid; $newpost->userid = $instance->newuserid; oublog_search_update($newpost, $cm); output('', true); } $newpost = null; } $posts = null; // End Blog post processing. output('Finished Posts'); // From now on all data is got from looping through postmapping array each time. // PROCESS Blog EDITS. foreach ($instance->postmapping as $oldpostid => $newpostid) { // $edits = $xpath->query("/DATA/EDITS/EDIT[POSTID=$oldpostid]"); $edits = array(); if (isset($alledits[$oldpostid])) { $edits = $alledits[$oldpostid]; } foreach ($edits as $newedit) { // Sort out edit object ready to save. // $newedit = childnodes_to_object($edit); unset($newedit->id); $newedit->postid = $newpostid; if ($newedit->userid == $instance->userid) { // Most of the time will be blog user. $newedit->userid = $instance->newuserid; } else { // Find mapped user id in this system. // $users = $xpath->query("/DATA/USERS/USER[@id=$newedit->userid]"); $users = isset($allusers[$newedit->userid]) ? $allusers[$newedit->userid] : false; if (!$users) { $newedit->userid = false; } else { $newedit->userid = oublog_search_create_user($users); } if ($newedit->userid == false) { output("Error: Failed to get/make user id for edit rec, old post id: {$oldpostid}"); $newedit->userid = $instance->newuserid; } } $newedit->oldmessage = oublog_decode_perbloglinks($newedit->oldmessage, $xpath, $postinfo, $instance->userid); output('', true); // Output dots. // Migrate any mystuff images in message. if (strpos($newedit->oldmessage, '@@PLUGINFILE@@') || stripos($newedit->oldmessage, $SOURCESERVER . '/pix/smartpix.php/ou/s/')) { $newedit->oldmessage = oublog_add_files($newedit->oldmessage, $dir, $blogcontext->id, 'message', $newpostid); } if (!($newid = $DB->insert_record('oublog_edits', $newedit))) { output("Error: Failed to create edit for old post id: {$oldpostid}"); continue; } $newedit = null; } $edits = null; } output('Finished edits'); // End Blog EDITS processing. // Process blog comments (Standard + Approved only). foreach ($instance->postmapping as $oldpostid => $newpostid) { // $comments = $xpath->query("/DATA/COMMENTS/COMMENT[POSTID=$oldpostid]"); $comments = array(); if (isset($allcomments[$oldpostid])) { $comments = $allcomments[$oldpostid]; } foreach ($comments as $newcomment) { // Sort out edit object ready to save. // $newcomment = childnodes_to_object($comment); $newcomment->postid = $newpostid; if (!blogxml_isempty($newcomment->userid)) { if ($newcomment->userid == $instance->userid) { // Most of the time will be blog user. $newcomment->userid = $instance->newuserid; } else { // Find mapped user id in this system. // $users = $xpath->query("/DATA/USERS/USER[@id='$newcomment->userid']"); $users = isset($allusers[$newcomment->userid]) ? $allusers[$newcomment->userid] : false; if (!$users || empty($users)) { $newcomment->userid = false; } else { $newcomment->userid = oublog_search_create_user($users); } if ($newcomment->userid == false) { output("Error: Failed to get/make user id for comment, old id: {$newcomment->id} file:{$xmlfilenum}"); continue; // Skip this comment. } } } if (!blogxml_isempty($newcomment->deletedby)) { if ($newcomment->deletedby == $instance->userid) { // Most of the time will be blog user. $newcomment->deletedby = $instance->newuserid; } else { // Find mapped user id in this system. // $users = $xpath->query("/DATA/USERS/USER[@id=$newcomment->deletedby]"); $users = isset($allusers[$newcomment->deletedby]) ? $allusers[$newcomment->deletedby] : false; if (!$users) { $newcomment->deletedby = false; } else { $newcomment->deletedby = oublog_search_create_user($users); } if ($newcomment->deletedby == false) { output("Error: Failed to get/make user id for comment deletedby, old id: {$newcomment->id}"); $newcomment->deletedby = $instance->newuserid; } } } $newcomment->message = oublog_decode_perbloglinks($newcomment->message, $xpath, $postinfo, $instance->userid); unset($newcomment->id); if (!($newid = $DB->insert_record('oublog_comments', $newcomment))) { output("Error: Failed to create comment for old post id: {$oldpostid}"); continue; } output('', true); // Output dots. // Migrate any mystuff images in message. if (strpos($newcomment->message, '@@PLUGINFILE@@') || stripos($newcomment->message, $SOURCESERVER . '/pix/smartpix.php/ou/s/')) { $updaterec = new stdClass(); $updaterec->id = $newid; $updaterec->message = oublog_add_files($newcomment->message, $dir, $blogcontext->id, 'messagecomment', $newid); $DB->update_record('oublog_comments', $updaterec); $updaterec = null; } $newcomment = null; } $comments = null; } output('Finished comments'); // End comments. // Commit everything in this instance. if ($kill) { throw new moodle_exception('kill'); } else { // Commit and save that instance has been imported. $trans->allow_commit(); $trans->dispose(); $donetag->appendChild($donedoc->createElement('instance', $instance->id)); if (!$donedoc->save($dir . '/imported.xml')) { output('<b>Error saving xml record of instance, will be picked up next save</b>'); } } } catch (moodle_exception $e) { output('<b>Code error:</b> ' . $e->debuginfo); try { output('Rollback transation'); $trans->rollback($e); } catch (moodle_exception $e) { output('<b>Code error:</b> ' . $e->debuginfo); $trans = null; continue; } catch (Exception $e) { output('<b>Code error:</b> ' . $e->debuginfo); $trans = null; continue; } } catch (Exception $e) { output('<b>Code error:</b> ' . $e->debuginfo); $trans->rollback($e); $trans = null; continue; } $trans = null; } output('<b>Finished</b>'); }