function restore_execute(&$restore, $info, $course_header, &$errorstr) { global $CFG, $USER; $status = true; //Checks for the required files/functions to restore every module //and include them if ($allmods = get_records("modules")) { foreach ($allmods as $mod) { $modname = $mod->name; $modfile = "{$CFG->dirroot}/mod/{$modname}/restorelib.php"; //If file exists and we have selected to restore that type of module if (file_exists($modfile) and !empty($restore->mods[$modname]) and $restore->mods[$modname]->restore) { include_once $modfile; } } } if (!defined('RESTORE_SILENTLY')) { //Start the main table echo "<table cellpadding=\"5\">"; echo "<tr><td>"; //Start the main ul echo "<ul>"; } //Location of the xml file $xml_file = $CFG->dataroot . "/temp/backup/" . $restore->backup_unique_code . "/moodle.xml"; //Preprocess the moodle.xml file spliting into smaller chucks (modules, users, logs...) //for optimal parsing later in the restore process. if (!empty($CFG->experimentalsplitrestore)) { if (!defined('RESTORE_SILENTLY')) { echo '<li>' . get_string('preprocessingbackupfile') . '</li>'; } //First of all, split moodle.xml into handy files if (!restore_split_xml($xml_file, $restore)) { if (!defined('RESTORE_SILENTLY')) { notify("Error proccessing moodle.xml file. Process ended."); } else { $errorstr = "Error proccessing moodle.xml file. Process ended."; } return false; } } //If we've selected to restore into new course //create it (course) //Saving conversion id variables into backup_tables if ($restore->restoreto == RESTORETO_NEW_COURSE) { if (!defined('RESTORE_SILENTLY')) { echo '<li>' . get_string('creatingnewcourse') . '</li>'; } $oldidnumber = $course_header->course_idnumber; if (!($status = restore_create_new_course($restore, $course_header))) { if (!defined('RESTORE_SILENTLY')) { notify("Error while creating the new empty course."); } else { $errorstr = "Error while creating the new empty course."; return false; } } //Print course fullname and shortname and category if ($status) { if (!defined('RESTORE_SILENTLY')) { echo "<ul>"; echo "<li>" . $course_header->course_fullname . " (" . $course_header->course_shortname . ")" . '</li>'; echo "<li>" . get_string("category") . ": " . $course_header->category->name . '</li>'; if (!empty($oldidnumber)) { echo "<li>" . get_string("nomoreidnumber", "moodle", $oldidnumber) . "</li>"; } echo "</ul>"; //Put the destination course_id } $restore->course_id = $course_header->course_id; } if ($status = restore_open_html($restore, $course_header)) { if (!defined('RESTORE_SILENTLY')) { echo "<li>Creating the Restorelog.html in the course backup folder</li>"; } } } else { $course = get_record("course", "id", $restore->course_id); if ($course) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("usingexistingcourse"); echo "<ul>"; echo "<li>" . get_string("from") . ": " . $course_header->course_fullname . " (" . $course_header->course_shortname . ")" . '</li>'; echo "<li>" . get_string("to") . ": " . format_string($course->fullname) . " (" . format_string($course->shortname) . ")" . '</li>'; if ($restore->deleting) { echo "<li>" . get_string("deletingexistingcoursedata") . '</li>'; } else { echo "<li>" . get_string("addingdatatoexisting") . '</li>'; } echo "</ul></li>"; } //If we have selected to restore deleting, we do it now. if ($restore->deleting) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("deletingolddata") . '</li>'; } $status = remove_course_contents($restore->course_id, false) and delete_dir_contents($CFG->dataroot . "/" . $restore->course_id, "backupdata"); if ($status) { //Now , this situation is equivalent to the "restore to new course" one (we //have a course record and nothing more), so define it as "to new course" $restore->restoreto = RESTORETO_NEW_COURSE; } else { if (!defined('RESTORE_SILENTLY')) { notify("An error occurred while deleting some of the course contents."); } else { $errrostr = "An error occurred while deleting some of the course contents."; return false; } } } } else { if (!defined('RESTORE_SILENTLY')) { notify("Error opening existing course."); $status = false; } else { $errorstr = "Error opening existing course."; return false; } } } //Now create users as needed if ($status and ($restore->users == 0 or $restore->users == 1)) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatingusers") . "<br />"; } if (!($status = restore_create_users($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not restore users."); } else { $errorstr = "Could not restore users."; return false; } } //Now print info about the work done if ($status) { $recs = get_records_sql("select old_id, new_id from {$CFG->prefix}backup_ids\n where backup_code = '{$restore->backup_unique_code}' and\n table_name = 'user'"); //We've records if ($recs) { $new_count = 0; $exists_count = 0; $student_count = 0; $teacher_count = 0; $counter = 0; //Iterate, filling counters foreach ($recs as $rec) { //Get full record, using backup_getids $record = backup_getid($restore->backup_unique_code, "user", $rec->old_id); if (strpos($record->info, "new") !== false) { $new_count++; } if (strpos($record->info, "exists") !== false) { $exists_count++; } if (strpos($record->info, "student") !== false) { $student_count++; } else { if (strpos($record->info, "teacher") !== false) { $teacher_count++; } } //Do some output $counter++; if ($counter % 10 == 0) { if (!defined('RESTORE_SILENTLY')) { echo "."; if ($counter % 200 == 0) { echo "<br />"; } } backup_flush(300); } } if (!defined('RESTORE_SILENTLY')) { //Now print information gathered echo " (" . get_string("new") . ": " . $new_count . ", " . get_string("existing") . ": " . $exists_count . ")"; echo "<ul>"; echo "<li>" . get_string("students") . ": " . $student_count . '</li>'; echo "<li>" . get_string("teachers") . ": " . $teacher_count . '</li>'; echo "</ul>"; } } else { if (!defined('RESTORE_SILENTLY')) { notify("No users were found!"); } // no need to return false here, it's recoverable. } } if (!defined('RESTORE_SILENTLY')) { echo "</li>"; } } //Now create groups as needed if ($status and ($restore->groups == RESTORE_GROUPS_ONLY or $restore->groups == RESTORE_GROUPS_GROUPINGS)) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatinggroups"); } if (!($status = restore_create_groups($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not restore groups!"); } else { $errorstr = "Could not restore groups!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } //Now create groupings as needed if ($status and ($restore->groups == RESTORE_GROUPINGS_ONLY or $restore->groups == RESTORE_GROUPS_GROUPINGS)) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatinggroupings"); } if (!($status = restore_create_groupings($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not restore groupings!"); } else { $errorstr = "Could not restore groupings!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } //Now create groupingsgroups as needed if ($status and $restore->groups == RESTORE_GROUPS_GROUPINGS) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatinggroupingsgroups"); } if (!($status = restore_create_groupings_groups($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not restore groups in groupings!"); } else { $errorstr = "Could not restore groups in groupings!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } //Now create the course_sections and their associated course_modules //we have to do this after groups and groupings are restored, because we need the new groupings id if ($status) { //Into new course if ($restore->restoreto == RESTORETO_NEW_COURSE) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatingsections"); } if (!($status = restore_create_sections($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Error creating sections in the existing course."); } else { $errorstr = "Error creating sections in the existing course."; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } //Into existing course } else { if ($restore->restoreto != RESTORETO_NEW_COURSE) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("checkingsections"); } if (!($status = restore_create_sections($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Error creating sections in the existing course."); } else { $errorstr = "Error creating sections in the existing course."; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } //Error } else { if (!defined('RESTORE_SILENTLY')) { notify("Neither a new course or an existing one was specified."); $status = false; } else { $errorstr = "Neither a new course or an existing one was specified."; return false; } } } } //Now create metacourse info if ($status and $restore->metacourse) { //Only to new courses! if ($restore->restoreto == RESTORETO_NEW_COURSE) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatingmetacoursedata"); } if (!($status = restore_create_metacourse($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Error creating metacourse in the course."); } else { $errorstr = "Error creating metacourse in the course."; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } } //Now create categories and questions as needed if ($status) { include_once "{$CFG->dirroot}/question/restorelib.php"; if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatingcategoriesandquestions"); echo "<ul>"; } if (!($status = restore_create_questions($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not restore categories and questions!"); } else { $errorstr = "Could not restore categories and questions!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo "</ul></li>"; } } //Now create user_files as needed if ($status and $restore->user_files) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("copyinguserfiles"); } if (!($status = restore_user_files($restore))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not restore user files!"); } else { $errorstr = "Could not restore user files!"; return false; } } //If all is ok (and we have a counter) if ($status and $status !== true) { //Inform about user dirs created from backup if (!defined('RESTORE_SILENTLY')) { echo "<ul>"; echo "<li>" . get_string("userzones") . ": " . $status; echo "</li></ul>"; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } //Now create course files as needed if ($status and $restore->course_files) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("copyingcoursefiles"); } if (!($status = restore_course_files($restore))) { if (empty($status)) { notify("Could not restore course files!"); } else { $errorstr = "Could not restore course files!"; return false; } } //If all is ok (and we have a counter) if ($status and $status !== true) { //Inform about user dirs created from backup if (!defined('RESTORE_SILENTLY')) { echo "<ul>"; echo "<li>" . get_string("filesfolders") . ": " . $status . '</li>'; echo "</ul>"; } } if (!defined('RESTORE_SILENTLY')) { echo "</li>"; } } //Now create site files as needed if ($status and $restore->site_files) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string('copyingsitefiles'); } if (!($status = restore_site_files($restore))) { if (empty($status)) { notify("Could not restore site files!"); } else { $errorstr = "Could not restore site files!"; return false; } } //If all is ok (and we have a counter) if ($status and $status !== true) { //Inform about user dirs created from backup if (!defined('RESTORE_SILENTLY')) { echo "<ul>"; echo "<li>" . get_string("filesfolders") . ": " . $status . '</li>'; echo "</ul>"; } } if (!defined('RESTORE_SILENTLY')) { echo "</li>"; } } //Now create messages as needed if ($status and $restore->messages) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatingmessagesinfo"); } if (!($status = restore_create_messages($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not restore messages!"); } else { $errorstr = "Could not restore messages!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo "</li>"; } } //Now create blogs as needed if ($status and $restore->blogs) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatingblogsinfo"); } if (!($status = restore_create_blogs($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not restore blogs!"); } else { $errorstr = "Could not restore blogs!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo "</li>"; } } //Now create scales as needed if ($status) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatingscales"); } if (!($status = restore_create_scales($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not restore custom scales!"); } else { $errorstr = "Could not restore custom scales!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } //Now create events as needed if ($status) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatingevents"); } if (!($status = restore_create_events($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not restore course events!"); } else { $errorstr = "Could not restore course events!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } //Now create course modules as needed if ($status) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatingcoursemodules"); } if (!($status = restore_create_modules($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not restore modules!"); } else { $errorstr = "Could not restore modules!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } //Bring back the course blocks -- do it AFTER the modules!!! if ($status) { //If we are deleting and bringing into a course or making a new course, same situation if ($restore->restoreto == RESTORETO_CURRENT_DELETING || $restore->restoreto == RESTORETO_EXISTING_DELETING || $restore->restoreto == RESTORETO_NEW_COURSE) { if (!defined('RESTORE_SILENTLY')) { echo '<li>' . get_string('creatingblocks'); } $course_header->blockinfo = !empty($course_header->blockinfo) ? $course_header->blockinfo : NULL; if (!($status = restore_create_blocks($restore, $info->backup_block_format, $course_header->blockinfo, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify('Error while creating the course blocks'); } else { $errorstr = "Error while creating the course blocks"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } } if ($status) { //If we are deleting and bringing into a course or making a new course, same situation if ($restore->restoreto == RESTORETO_CURRENT_DELETING || $restore->restoreto == RESTORETO_EXISTING_DELETING || $restore->restoreto == RESTORETO_NEW_COURSE) { if (!defined('RESTORE_SILENTLY')) { echo '<li>' . get_string('courseformatdata'); } if (!($status = restore_set_format_data($restore, $xml_file))) { $error = "Error while setting the course format data"; if (!defined('RESTORE_SILENTLY')) { notify($error); } else { $errorstr = $error; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } } //Now create log entries as needed if ($status and $restore->logs) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatinglogentries"); } if (!($status = restore_create_logs($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not restore logs!"); } else { $errorstr = "Could not restore logs!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } //Now, if all is OK, adjust the instance field in course_modules !! //this also calculates the final modinfo information so, after this, //code needing it can be used (like role_assignments. MDL-13740) if ($status) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("checkinginstances"); } if (!($status = restore_check_instances($restore))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not adjust instances in course_modules!"); } else { $errorstr = "Could not adjust instances in course_modules!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } //Now, if all is OK, adjust activity events if ($status) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("refreshingevents"); } if (!($status = restore_refresh_events($restore))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not refresh events for activities!"); } else { $errorstr = "Could not refresh events for activities!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } //Now, if all is OK, adjust inter-activity links if ($status) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("decodinginternallinks"); } if (!($status = restore_decode_content_links($restore))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not decode content links!"); } else { $errorstr = "Could not decode content links!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } //Now, with backup files prior to version 2005041100, //convert all the wiki texts in the course to markdown if ($status && $restore->backup_version < 2005041100) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("convertingwikitomarkdown"); } if (!($status = restore_convert_wiki2markdown($restore))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not convert wiki texts to markdown!"); } else { $errorstr = "Could not convert wiki texts to markdown!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } //Now create gradebook as needed -- AFTER modules and blocks!!! if ($status) { if ($restore->backup_version > 2007090500) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatinggradebook"); } if (!($status = restore_create_gradebook($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not restore gradebook!"); } else { $errorstr = "Could not restore gradebook!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } else { // for moodle versions before 1.9, those grades need to be converted to use the new gradebook // this code needs to execute *after* the course_modules are sorted out if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("migratinggrades"); } /// force full refresh of grading data before migration == crete all items first if (!($status = restore_migrate_old_gradebook($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not migrate gradebook!"); } else { $errorstr = "Could not migrade gradebook!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } /// force full refresh of grading data after all items are created grade_force_full_regrading($restore->course_id); grade_grab_course_grades($restore->course_id); } /******************************************************************************* ************* Restore of Roles and Capabilities happens here ****************** *******************************************************************************/ // try to restore roles even when restore is going to fail - teachers might have // at least some role assigned - this is not correct though $status = restore_create_roles($restore, $xml_file) && $status; $status = restore_roles_settings($restore, $xml_file) && $status; //Now if all is OK, update: // - course modinfo field // - categories table // - add user as teacher if ($status) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("checkingcourse"); } //categories table $course = get_record("course", "id", $restore->course_id); fix_course_sortorder(); // Check if the user has course update capability in the newly restored course // there is no need to load his capabilities again, because restore_roles_settings // would have loaded it anyway, if there is any assignments. // fix for MDL-6831 $newcontext = get_context_instance(CONTEXT_COURSE, $restore->course_id); if (!has_capability('moodle/course:manageactivities', $newcontext)) { // fix for MDL-9065, use the new config setting if exists if ($CFG->creatornewroleid) { role_assign($CFG->creatornewroleid, $USER->id, 0, $newcontext->id); } else { if ($legacyteachers = get_roles_with_capability('moodle/legacy:editingteacher', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM))) { if ($legacyteacher = array_shift($legacyteachers)) { role_assign($legacyteacher->id, $USER->id, 0, $newcontext->id); } } else { notify('Could not find a legacy teacher role. You might need your moodle admin to assign a role with editing privilages to this course.'); } } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } //Cleanup temps (files and db) if ($status) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("cleaningtempdata"); } if (!($status = clean_temp_data($restore))) { if (!defined('RESTORE_SILENTLY')) { notify("Could not clean up temporary data from files and database"); } else { $errorstr = "Could not clean up temporary data from files and database"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } // this is not a critical check - the result can be ignored if (restore_close_html($restore)) { if (!defined('RESTORE_SILENTLY')) { echo '<li>Closing the Restorelog.html file.</li>'; } } else { if (!defined('RESTORE_SILENTLY')) { notify("Could not close the restorelog.html file"); } } if (!defined('RESTORE_SILENTLY')) { //End the main ul echo "</ul>"; //End the main table echo "</td></tr>"; echo "</table>"; } return $status; }
function restore_execute(&$restore, $info, $course_header, &$errorstr) { global $CFG, $USER, $DB, $OUTPUT; $status = true; //Now create events as needed if ($status) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("creatingevents"); } if (!($status = restore_create_events($restore, $xml_file))) { if (!defined('RESTORE_SILENTLY')) { echo $OUTPUT->notification("Could not restore course events!"); } else { $errorstr = "Could not restore course events!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } if ($status) { //If we are deleting and bringing into a course or making a new course, same situation if ($restore->restoreto == RESTORETO_CURRENT_DELETING || $restore->restoreto == RESTORETO_EXISTING_DELETING || $restore->restoreto == RESTORETO_NEW_COURSE) { if (!defined('RESTORE_SILENTLY')) { echo '<li>' . get_string('courseformatdata'); } if (!($status = restore_set_format_data($restore, $xml_file))) { $error = "Error while setting the course format data"; if (!defined('RESTORE_SILENTLY')) { echo $OUTPUT->notification($error); } else { $errorstr = $error; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } } //Now, if all is OK, adjust activity events if ($status) { if (!defined('RESTORE_SILENTLY')) { echo "<li>" . get_string("refreshingevents"); } if (!($status = restore_refresh_events($restore))) { if (!defined('RESTORE_SILENTLY')) { echo $OUTPUT->notification("Could not refresh events for activities!"); } else { $errorstr = "Could not refresh events for activities!"; return false; } } if (!defined('RESTORE_SILENTLY')) { echo '</li>'; } } }