예제 #1
0
echo $OUTPUT->box_start();
//Adjust some php variables to the execution of this script
@ini_set("max_execution_time", "3000");
if (empty($CFG->extramemorylimit)) {
    raise_memory_limit('128M');
} else {
    raise_memory_limit($CFG->extramemorylimit);
}
//Call the form, depending the step we are
if (!$launch) {
    include_once "restore_precheck.html";
} else {
    if ($launch == "form") {
        if (!empty($SESSION->restore->importing)) {
            // set up all the config stuff and skip asking the user about it.
            restore_setup_for_check($SESSION->restore, $backup_unique_code);
            include_once "restore_execute.html";
        } else {
            include_once "restore_form.html";
        }
    } else {
        if ($launch == "check") {
            include_once "restore_check.html";
            //To avoid multiple restore executions...
            $SESSION->cancontinue = true;
        } else {
            if ($launch == "execute") {
                //Prevent multiple restore executions...
                if (empty($SESSION->cancontinue)) {
                    print_error('multiplerestorenotallow');
                }
예제 #2
0
/** this function will restore an entire backup.zip into the specified course
 * using standard moodle backup/restore functions, but silently.
 * @param string $pathtofile the absolute path to the backup file.
 * @param int $destinationcourse the course id to restore to.
 * @param boolean $emptyfirst whether to delete all coursedata first.
 * @param boolean $userdata whether to include any userdata that may be in the backup file.
 * @param array $preferences optional, 0 will be used.  Can contain:
 *   metacourse
 *   logs
 *   course_files
 *   messages
 */
function import_backup_file_silently($pathtofile, $destinationcourse, $emptyfirst = false, $userdata = false, $preferences = array())
{
    global $CFG, $SESSION, $USER, $DB;
    // is there such a thing on cron? I guess so..
    global $restore;
    // ick
    if (!defined('RESTORE_SILENTLY')) {
        define('RESTORE_SILENTLY', true);
        // don't output all the stuff to us.
    }
    $debuginfo = 'import_backup_file_silently: ';
    $cleanupafter = false;
    $errorstr = '';
    // passed by reference to restore_precheck to get errors from.
    if (!($course = $DB->get_record('course', array('id' => $destinationcourse)))) {
        mtrace($debuginfo . 'Course with id $destinationcourse was not a valid course!');
        return false;
    }
    // first check we have a valid file.
    if (!file_exists($pathtofile) || !is_readable($pathtofile)) {
        mtrace($debuginfo . 'File ' . $pathtofile . ' either didn\'t exist or wasn\'t readable');
        return false;
    }
    // now make sure it's a zip file
    require_once $CFG->dirroot . '/lib/filelib.php';
    $filename = substr($pathtofile, strrpos($pathtofile, '/') + 1);
    $mimetype = mimeinfo("type", $filename);
    if ($mimetype != 'application/zip') {
        mtrace($debuginfo . 'File ' . $pathtofile . ' was of wrong mimetype (' . $mimetype . ')');
        return false;
    }
    // restore_precheck wants this within dataroot, so lets put it there if it's not already..
    if (strstr($pathtofile, $CFG->dataroot) === false) {
        // first try and actually move it..
        if (!check_dir_exists($CFG->dataroot . '/temp/backup/', true)) {
            mtrace($debuginfo . 'File ' . $pathtofile . ' outside of dataroot and couldn\'t move it! ');
            return false;
        }
        if (!copy($pathtofile, $CFG->dataroot . '/temp/backup/' . $filename)) {
            mtrace($debuginfo . 'File ' . $pathtofile . ' outside of dataroot and couldn\'t move it! ');
            return false;
        } else {
            $pathtofile = 'temp/backup/' . $filename;
            $cleanupafter = true;
        }
    } else {
        // it is within dataroot, so take it off the path for restore_precheck.
        $pathtofile = substr($pathtofile, strlen($CFG->dataroot . '/'));
    }
    if (!backup_required_functions()) {
        mtrace($debuginfo . 'Required function check failed (see backup_required_functions)');
        return false;
    }
    @ini_set("max_execution_time", "3000");
    if (empty($CFG->extramemorylimit)) {
        raise_memory_limit('128M');
    } else {
        raise_memory_limit($CFG->extramemorylimit);
    }
    if (!($backup_unique_code = restore_precheck($destinationcourse, $pathtofile, $errorstr, true))) {
        mtrace($debuginfo . 'Failed restore_precheck (error was ' . $errorstr . ')');
        return false;
    }
    $SESSION->restore = new StdClass();
    // add on some extra stuff we need...
    $SESSION->restore->metacourse = $restore->metacourse = isset($preferences['restore_metacourse']) ? $preferences['restore_metacourse'] : 0;
    $SESSION->restore->restoreto = $restore->restoreto = 1;
    $SESSION->restore->users = $restore->users = $userdata;
    $SESSION->restore->groups = $restore->groups = isset($preferences['restore_groups']) ? $preferences['restore_groups'] : RESTORE_GROUPS_NONE;
    $SESSION->restore->logs = $restore->logs = isset($preferences['restore_logs']) ? $preferences['restore_logs'] : 0;
    $SESSION->restore->user_files = $restore->user_files = $userdata;
    $SESSION->restore->messages = $restore->messages = isset($preferences['restore_messages']) ? $preferences['restore_messages'] : 0;
    $SESSION->restore->blogs = $restore->blogs = isset($preferences['restore_blogs']) ? $preferences['restore_blogs'] : 0;
    $SESSION->restore->course_id = $restore->course_id = $destinationcourse;
    $SESSION->restore->restoreto = 1;
    $SESSION->restore->course_id = $destinationcourse;
    $SESSION->restore->deleting = $emptyfirst;
    $SESSION->restore->restore_course_files = $restore->course_files = isset($preferences['restore_course_files']) ? $preferences['restore_course_files'] : 0;
    $SESSION->restore->restore_site_files = $restore->site_files = isset($preferences['restore_site_files']) ? $preferences['restore_site_files'] : 0;
    $SESSION->restore->backup_version = $SESSION->info->backup_backup_version;
    $SESSION->restore->course_startdateoffset = $course->startdate - $SESSION->course_header->course_startdate;
    restore_setup_for_check($SESSION->restore, $backup_unique_code);
    // maybe we need users (defaults to 2 in restore_setup_for_check)
    if (!empty($userdata)) {
        $SESSION->restore->users = 1;
    }
    // we also need modules...
    if ($allmods = $DB->get_records("modules")) {
        foreach ($allmods as $mod) {
            $modname = $mod->name;
            //Now check that we have that module info in the backup file
            if (isset($SESSION->info->mods[$modname]) && $SESSION->info->mods[$modname]->backup == "true") {
                $SESSION->restore->mods[$modname]->restore = true;
                $SESSION->restore->mods[$modname]->userinfo = $userdata;
            } else {
                // avoid warnings
                $SESSION->restore->mods[$modname]->restore = false;
                $SESSION->restore->mods[$modname]->userinfo = false;
            }
        }
    }
    $restore = clone $SESSION->restore;
    if (!restore_execute($SESSION->restore, $SESSION->info, $SESSION->course_header, $errorstr)) {
        mtrace($debuginfo . 'Failed restore_execute (error was ' . $errorstr . ')');
        return false;
    }
    return true;
}
예제 #3
0
/** this function will restore an entire backup.zip into the specified course
 * using standard moodle backup/restore functions, but silently.
 * @param string $pathtofile the absolute path to the backup file.
 * @param int $destinationcourse the course id to restore to.
 * @param boolean $emptyfirst whether to delete all coursedata first.
 * @param boolean $userdata whether to include any userdata that may be in the backup file.
 */
function import_backup_file_silently($pathtofile, $destinationcourse, $emptyfirst = false, $userdata = false)
{
    global $CFG, $SESSION, $USER;
    // is there such a thing on cron? I guess so..
    if (empty($USER)) {
        $USER = get_admin();
        $USER->admin = 1;
        // not sure why, but this doesn't get set
    }
    define('RESTORE_SILENTLY', true);
    // don't output all the stuff to us.
    $debuginfo = 'import_backup_file_silently: ';
    $cleanupafter = false;
    $errorstr = '';
    // passed by reference to restore_precheck to get errors from.
    if (!($course = get_record('course', 'id', $destinationcourse))) {
        mtrace($debuginfo . 'Course with id $destinationcourse was not a valid course!');
        return false;
    }
    // first check we have a valid file.
    if (!file_exists($pathtofile) || !is_readable($pathtofile)) {
        mtrace($debuginfo . 'File ' . $pathtofile . ' either didn\'t exist or wasn\'t readable');
        return false;
    }
    // now make sure it's a zip file
    require_once $CFG->dirroot . '/lib/filelib.php';
    $filename = substr($pathtofile, strrpos($pathtofile, '/') + 1);
    $mimetype = mimeinfo("type", $filename);
    if ($mimetype != 'application/zip') {
        mtrace($debuginfo . 'File ' . $pathtofile . ' was of wrong mimetype (' . $mimetype . ')');
        return false;
    }
    // restore_precheck wants this within dataroot, so lets put it there if it's not already..
    if (strstr($pathtofile, $CFG->dataroot) === false) {
        // first try and actually move it..
        if (!check_dir_exists($CFG->dataroot . '/temp/backup/', true)) {
            mtrace($debuginfo . 'File ' . $pathtofile . ' outside of dataroot and couldn\'t move it! ');
            return false;
        }
        if (!copy($pathtofile, $CFG->dataroot . '/temp/backup/' . $filename)) {
            mtrace($debuginfo . 'File ' . $pathtofile . ' outside of dataroot and couldn\'t move it! ');
            return false;
        } else {
            $pathtofile = 'temp/backup/' . $filename;
            $cleanupafter = true;
        }
    } else {
        // it is within dataroot, so take it off the path for restore_precheck.
        $pathtofile = substr($pathtofile, strlen($CFG->dataroot . '/'));
    }
    if (!backup_required_functions()) {
        mtrace($debuginfo . 'Required function check failed (see backup_required_functions)');
        return false;
    }
    @ini_set("max_execution_time", "3000");
    raise_memory_limit("192M");
    if (!($backup_unique_code = restore_precheck($destinationcourse, $pathtofile, $errorstr, true))) {
        mtrace($debuginfo . 'Failed restore_precheck (error was ' . $errorstr . ')');
        return false;
    }
    restore_setup_for_check($SESSION->restore, $backup_unique_code);
    // add on some extra stuff we need...
    $SESSION->restore->restoreto = 1;
    $SESSION->restore->course_id = $destinationcourse;
    $SESSION->restore->deleting = $emptyfirst;
    // maybe we need users (defaults to 2 in restore_setup_for_check)
    if (!empty($userdata)) {
        $SESSION->restore->users = 1;
    }
    // we also need modules...
    if ($allmods = get_records("modules")) {
        foreach ($allmods as $mod) {
            $modname = $mod->name;
            //Now check that we have that module info in the backup file
            if (isset($SESSION->info->mods[$modname]) && $SESSION->info->mods[$modname]->backup == "true") {
                $SESSION->restore->mods[$modname]->restore = true;
                $SESSION->restore->mods[$modname]->userinfo = $userdata;
            }
        }
    }
    if (!restore_execute($SESSION->restore, $SESSION->info, $SESSION->course_header, $errorstr)) {
        mtrace($debuginfo . 'Failed restore_execute (error was ' . $errorstr . ')');
        return false;
    }
    return true;
}
예제 #4
0
/** this function will restore an entire backup.zip into the specified course
 * using standard moodle backup/restore functions, but silently.
 * @param string $pathtofile the absolute path to the backup file.
 * @param int $destinationcourse the course id to restore to.
 * @param boolean $emptyfirst whether to delete all coursedata first.
 * @param boolean $userdata whether to include any userdata that may be in the backup file.
 * @param array $preferences optional, 0 will be used.  Can contain:
 *   metacourse
 *   logs
 *   course_files
 *   messages
 */
function import_backup_file_silently($pathtofile, $destinationcourse, $emptyfirst = false, $userdata = false, $preferences = array())
{
    global $CFG, $SESSION, $USER;
    // is there such a thing on cron? I guess so..
    if (!defined('RESTORE_SILENTLY')) {
        define('RESTORE_SILENTLY', true);
        // don't output all the stuff to us.
    }
    $debuginfo = 'import_backup_file_silently: ';
    $cleanupafter = false;
    $errorstr = '';
    // passed by reference to restore_precheck to get errors from.
    $course = null;
    if ($destinationcourse && !($course = get_record('course', 'id', $destinationcourse))) {
        mtrace($debuginfo . 'Course with id $destinationcourse was not a valid course!');
        return false;
    }
    // first check we have a valid file.
    if (!file_exists($pathtofile) || !is_readable($pathtofile)) {
        mtrace($debuginfo . 'File ' . $pathtofile . ' either didn\'t exist or wasn\'t readable');
        return false;
    }
    // now make sure it's a zip file
    require_once $CFG->dirroot . '/lib/filelib.php';
    $filename = substr($pathtofile, strrpos($pathtofile, '/') + 1);
    $mimetype = mimeinfo("type", $filename);
    if ($mimetype != 'application/zip') {
        mtrace($debuginfo . 'File ' . $pathtofile . ' was of wrong mimetype (' . $mimetype . ')');
        return false;
    }
    // restore_precheck wants this within dataroot, so lets put it there if it's not already..
    if (strstr($pathtofile, $CFG->dataroot) === false) {
        // first try and actually move it..
        if (!check_dir_exists($CFG->dataroot . '/temp/backup/', true)) {
            mtrace($debuginfo . 'File ' . $pathtofile . ' outside of dataroot and couldn\'t move it! ');
            return false;
        }
        if (!copy($pathtofile, $CFG->dataroot . '/temp/backup/' . $filename)) {
            mtrace($debuginfo . 'File ' . $pathtofile . ' outside of dataroot and couldn\'t move it! ');
            return false;
        } else {
            $pathtofile = 'temp/backup/' . $filename;
            $cleanupafter = true;
        }
    } else {
        // it is within dataroot, so take it off the path for restore_precheck.
        $pathtofile = substr($pathtofile, strlen($CFG->dataroot . '/'));
    }
    if (!backup_required_functions()) {
        mtrace($debuginfo . 'Required function check failed (see backup_required_functions)');
        return false;
    }
    @ini_set("max_execution_time", "3000");
    if (empty($CFG->extramemorylimit)) {
        raise_memory_limit('128M');
    } else {
        raise_memory_limit($CFG->extramemorylimit);
    }
    if (!($backup_unique_code = restore_precheck($destinationcourse, $pathtofile, $errorstr, true))) {
        mtrace($debuginfo . 'Failed restore_precheck (error was ' . $errorstr . ')');
        return false;
    }
    global $restore;
    // ick
    $restore = new StdClass();
    // copy back over the stuff that gets set in restore_precheck
    $restore->course_header = $SESSION->course_header;
    $restore->info = $SESSION->info;
    $xmlfile = "{$CFG->dataroot}/temp/backup/{$backup_unique_code}/moodle.xml";
    $info = restore_read_xml_roles($xmlfile);
    $restore->rolesmapping = array();
    if (isset($info->roles) && is_array($info->roles)) {
        foreach ($info->roles as $id => $info) {
            if ($newroleid = get_field('role', 'id', 'shortname', $info->shortname)) {
                $restore->rolesmapping[$id] = $newroleid;
            }
        }
    }
    // add on some extra stuff we need...
    $restore->metacourse = isset($preferences['restore_metacourse']) ? $preferences['restore_metacourse'] : 0;
    $restore->course_id = $destinationcourse;
    if ($destinationcourse) {
        $restore->restoreto = RESTORETO_CURRENT_ADDING;
        $restore->course_startdateoffset = $course->startdate - $restore->course_header->course_startdate;
    } else {
        $restore->restoreto = RESTORETO_NEW_COURSE;
        $restore->restore_restorecatto = 0;
        // let this be handled by the headers
        $restore->course_startdateoffset = 0;
    }
    $restore->users = $userdata;
    $restore->user_files = $userdata;
    $restore->deleting = $emptyfirst;
    $restore->groups = isset($preferences['restore_groups']) ? $preferences['restore_groups'] : RESTORE_GROUPS_NONE;
    $restore->logs = isset($preferences['restore_logs']) ? $preferences['restore_logs'] : 0;
    $restore->messages = isset($preferences['restore_messages']) ? $preferences['restore_messages'] : 0;
    $restore->blogs = isset($preferences['restore_blogs']) ? $preferences['restore_blogs'] : 0;
    $restore->course_files = isset($preferences['restore_course_files']) ? $preferences['restore_course_files'] : 0;
    $restore->site_files = isset($preferences['restore_site_files']) ? $preferences['restore_site_files'] : 0;
    $restore->backup_version = $restore->info->backup_backup_version;
    $restore->original_wwwroot = $restore->info->original_wwwroot;
    // now copy what we have over to the session
    // this needs to happen before restore_setup_for_check
    // which for some reason reads the session
    $SESSION->restore =& $restore;
    // rename the things that are called differently
    $SESSION->restore->restore_course_files = $restore->course_files;
    $SESSION->restore->restore_site_files = $restore->site_files;
    $SESSION->restore->backup_version = $restore->info->backup_backup_version;
    restore_setup_for_check($restore, $backup_unique_code);
    // maybe we need users (defaults to 2 (none) in restore_setup_for_check)
    // so set this again here
    if (!empty($userdata)) {
        $restore->users = 1;
    }
    // we also need modules...
    if ($allmods = get_records("modules")) {
        foreach ($allmods as $mod) {
            $modname = $mod->name;
            //Now check that we have that module info in the backup file
            if (isset($restore->info->mods[$modname]) && $restore->info->mods[$modname]->backup == "true") {
                $restore->mods[$modname]->restore = true;
                $restore->mods[$modname]->userinfo = $userdata;
            } else {
                // avoid warnings
                $restore->mods[$modname]->restore = false;
                $restore->mods[$modname]->userinfo = false;
            }
        }
    }
    if (!($status = restore_execute($restore, $restore->info, $restore->course_header, $errorstr))) {
        mtrace($debuginfo . 'Failed restore_execute (error was ' . $errorstr . ')');
        return false;
    }
    // now get out the new courseid and return that
    if ($restore->restoreto = RESTORETO_NEW_COURSE) {
        if (!empty($SESSION->restore->course_id)) {
            return $SESSION->restore->course_id;
        }
        return false;
    }
    return true;
}
예제 #5
0
/**
 * This function will restore an entire backup.zip into the specified course
 * using standard moodle backup/restore functions, but silently.
 *
 * @see /backup/lib.php
 * @param string $pathtofile the absolute path to the backup file.
 * @param int $destinationcourse the course id to restore to.
 * @param boolean $emptyfirst whether to delete all coursedata first.
 * @param boolean $userdata whether to include any userdata that may be in the backup file.
 * @param array $preferences optional, 0 will be used.  Can contain:
 *   metacourse
 *   logs
 *   course_files
 *   messages
 */
function rollover_import_backup_file_silently($backup_unique_code, $destinationcourse, $emptyfirst = false, $userdata = false, $preferences = array())
{
    global $CFG, $SESSION, $USER;
    // is there such a thing on cron? I guess so..
    global $restore;
    // ick
    if (empty($USER)) {
        $USER = get_admin();
        $USER->admin = 1;
        // not sure why, but this doesn't get set
    }
    if (!defined('RESTORE_SILENTLY')) {
        define('RESTORE_SILENTLY', true);
        // don't output all the stuff to us.
    }
    $debuginfo = 'import_backup_file_silently: ';
    $cleanupafter = false;
    $errorstr = '';
    // passed by reference to restore_precheck to get errors from.
    // first check we have a valid file.
    /* Skip the file checking stuff, because we're not using a zip file
            if (!file_exists($pathtofile) || !is_readable($pathtofile)) {
                mtrace($debuginfo.'File '.$pathtofile.' either didn\'t exist or wasn\'t readable');
                return false;
            }
    
            // now make sure it's a zip file
            require_once($CFG->dirroot.'/lib/filelib.php');
            $filename = substr($pathtofile,strrpos($pathtofile,'/')+1);
            $mimetype = mimeinfo("type", $filename);
            if ($mimetype != 'application/zip') {
                mtrace($debuginfo.'File '.$pathtofile.' was of wrong mimetype ('.$mimetype.')' );
                return false;
            }
    
            // restore_precheck wants this within dataroot, so lets put it there if it's not already..
            if (strstr($pathtofile,$CFG->dataroot) === false) {
                // first try and actually move it..
                if (!check_dir_exists($CFG->dataroot.'/temp/backup/',true)) {
                    mtrace($debuginfo.'File '.$pathtofile.' outside of dataroot and couldn\'t move it! ');
                    return false;
                }
                if (!copy($pathtofile,$CFG->dataroot.'/temp/backup/'.$filename)) {
                    mtrace($debuginfo.'File '.$pathtofile.' outside of dataroot and couldn\'t move it! ');
                    return false;
                } else {
                    $pathtofile = 'temp/backup/'.$filename;
                    $cleanupafter = true;
                }
            } else {
                // it is within dataroot, so take it off the path for restore_precheck.
                $pathtofile = substr($pathtofile,strlen($CFG->dataroot.'/'));
            }
            */
    if (!backup_required_functions()) {
        mtrace($debuginfo . 'Required function check failed (see backup_required_functions)');
        return false;
    }
    @ini_set('max_execution_time', '3000');
    if (empty($CFG->extramemorylimit)) {
        raise_memory_limit('128M');
    } else {
        raise_memory_limit($CFG->extramemorylimit);
    }
    /*if (!$backup_unique_code = restore_precheck($destinationcourse,$pathtofile,$errorstr,true)) {*/
    //if (!$backup_unique_code = restore_precheck(/*NOT NEEDED*/0,$pathtofile,$errorstr,true)) {
    //    mtrace($debuginfo.'Failed restore_precheck (error was '.$errorstr.')');
    //    return false;
    //}
    // RL: the following few lines are normally handled by restore_precheck
    $xml_file = $CFG->dataroot . "/temp/backup/" . $backup_unique_code . "/moodle.xml";
    //Reading info from file
    $info = restore_read_xml_info($xml_file);
    //Reading course_header from file
    $course_header = restore_read_xml_course_header($xml_file);
    if (!is_object($course_header)) {
        // ensure we fail if there is no course header
        $course_header = false;
    }
    $SESSION->info = $info;
    $SESSION->course_header = $course_header;
    $SESSION->restore = new StdClass();
    // add on some extra stuff we need...
    $SESSION->restore->metacourse = $restore->metacourse = isset($preferences['restore_metacourse']) ? $preferences['restore_metacourse'] : 0;
    $SESSION->restore->users = $restore->users = $userdata;
    $SESSION->restore->logs = $restore->logs = isset($preferences['restore_logs']) ? $preferences['restore_logs'] : 0;
    $SESSION->restore->user_files = $restore->user_files = $userdata;
    $SESSION->restore->messages = $restore->messages = isset($preferences['restore_messages']) ? $preferences['restore_messages'] : 0;
    //$SESSION->restore->restoreto    = 0; // Make sure we delete content and add everything from the source course.
    $SESSION->restore->restoreto = RESTORETO_NEW_COURSE;
    $SESSION->restore->course_id = $restore->course_id = $destinationcourse;
    $SESSION->restore->deleting = $emptyfirst;
    $SESSION->restore->restore_course_files = $restore->course_files = isset($preferences['restore_course_files']) ? $preferences['restore_course_files'] : 0;
    $SESSION->restore->restore_site_files = $restore->restore_site_files = isset($preferences['restore_site_files']) ? $preferences['restore_site_files'] : 0;
    $SESSION->restore->backup_version = $SESSION->info->backup_backup_version;
    // If a start date was specified, determine the difference between the start date of the template course
    // and the one specified for use in module dates.
    if (!empty($preferences['restore_startdate'])) {
        $SESSION->restore->course_startdateoffset = $preferences['restore_startdate'] - $SESSION->course_header->course_startdate;
    } else {
        $SESSION->restore->course_startdateoffset = 0;
    }
    // Set restore groups to 0
    $SESSION->restore->groups = $restore->groups = RESTORE_GROUPS_NONE;
    // Set restore cateogry to 0, restorelib.php will look in the backup xml file
    $SESSION->restore->restore_restorecatto = $restore->restore_restorecatto = 0;
    $SESSION->restore->blogs = $restore->blogs = 0;
    restore_setup_for_check($SESSION->restore, $backup_unique_code);
    // maybe we need users (defaults to 2 in restore_setup_for_check)
    /*        if (!empty($userdata)) {
                $SESSION->restore->users = 1;
            }
    */
    // we also need modules...
    if ($allmods = get_records('modules')) {
        foreach ($allmods as $mod) {
            $modname = $mod->name;
            //Now check that we have that module info in the backup file
            if (isset($SESSION->info->mods[$modname]) && $SESSION->info->mods[$modname]->backup == "true") {
                $SESSION->restore->mods[$modname]->restore = true;
                $SESSION->restore->mods[$modname]->userinfo = $userdata;
            } else {
                // avoid warnings
                $SESSION->restore->mods[$modname]->restore = false;
                $SESSION->restore->mods[$modname]->userinfo = false;
            }
        }
    }
    $restore = clone $SESSION->restore;
    if (!restore_execute($restore, $SESSION->info, $SESSION->course_header, $errorstr)) {
        mtrace($debuginfo . 'Failed restore_execute (error was ' . $errorstr . ')');
        return false;
    }
    rebuild_course_cache($SESSION->restore->course_id);
    return $SESSION->restore->course_id;
}