Esempio n. 1
0
/**
 * @param string $errorstr passed by reference, if silent is true,
 * errorstr will be populated and this function will return false rather than calling error() or notify()
 * @param boolean $noredirect (optional) if this is passed, this function will not print continue, or
 * redirect to the next step in the restore process, instead will return $backup_unique_code
 */
function restore_precheck($id, $file, &$errorstr, $noredirect = false)
{
    global $CFG, $SESSION;
    //Prepend dataroot to variable to have the absolute path
    $file = $CFG->dataroot . "/" . $file;
    if (!defined('RESTORE_SILENTLY')) {
        //Start the main table
        echo "<table cellpadding=\"5\">";
        echo "<tr><td>";
        //Start the mail ul
        echo "<ul>";
    }
    //Check the file exists
    if (!is_file($file)) {
        if (!defined('RESTORE_SILENTLY')) {
            error("File not exists ({$file})");
        } else {
            $errorstr = "File not exists ({$file})";
            return false;
        }
    }
    //Check the file name ends with .zip
    if (!substr($file, -4) == ".zip") {
        if (!defined('RESTORE_SILENTLY')) {
            error("File has an incorrect extension");
        } else {
            $errorstr = 'File has an incorrect extension';
            return false;
        }
    }
    //Now calculate the unique_code for this restore
    $backup_unique_code = time();
    //Now check and create the backup dir (if it doesn't exist)
    if (!defined('RESTORE_SILENTLY')) {
        echo "<li>" . get_string("creatingtemporarystructures") . '</li>';
    }
    $status = check_and_create_backup_dir($backup_unique_code);
    //Empty dir
    if ($status) {
        $status = clear_backup_dir($backup_unique_code);
    }
    //Now delete old data and directories under dataroot/temp/backup
    if ($status) {
        if (!defined('RESTORE_SILENTLY')) {
            echo "<li>" . get_string("deletingolddata") . '</li>';
        }
        $status = backup_delete_old_data();
    }
    //Now copy he zip file to dataroot/temp/backup/backup_unique_code
    if ($status) {
        if (!defined('RESTORE_SILENTLY')) {
            echo "<li>" . get_string("copyingzipfile") . '</li>';
        }
        if (!($status = backup_copy_file($file, $CFG->dataroot . "/temp/backup/" . $backup_unique_code . "/" . basename($file)))) {
            if (!defined('RESTORE_SILENTLY')) {
                notify("Error copying backup file. Invalid name or bad perms.");
            } else {
                $errorstr = "Error copying backup file. Invalid name or bad perms";
                return false;
            }
        }
    }
    //Now unzip the file
    if ($status) {
        if (!defined('RESTORE_SILENTLY')) {
            echo "<li>" . get_string("unzippingbackup") . '</li>';
        }
        if (!($status = restore_unzip($CFG->dataroot . "/temp/backup/" . $backup_unique_code . "/" . basename($file)))) {
            if (!defined('RESTORE_SILENTLY')) {
                notify("Error unzipping backup file. Invalid zip file.");
            } else {
                $errorstr = "Error unzipping backup file. Invalid zip file.";
                return false;
            }
        }
    }
    //Check for Blackboard backups and convert
    if ($status) {
        require_once "{$CFG->dirroot}/backup/bb/restore_bb.php";
        if (!defined('RESTORE_SILENTLY')) {
            echo "<li>" . get_string("checkingforbbexport") . '</li>';
        }
        $status = blackboard_convert($CFG->dataroot . "/temp/backup/" . $backup_unique_code);
    }
    //Now check for the moodle.xml file
    if ($status) {
        $xml_file = $CFG->dataroot . "/temp/backup/" . $backup_unique_code . "/moodle.xml";
        if (!defined('RESTORE_SILENTLY')) {
            echo "<li>" . get_string("checkingbackup") . '</li>';
        }
        if (!($status = restore_check_moodle_file($xml_file))) {
            if (!is_file($xml_file)) {
                $errorstr = 'Error checking backup file. moodle.xml not found at root level of zip file.';
            } else {
                $errorstr = 'Error checking backup file. moodle.xml is incorrect or corrupted.';
            }
            if (!defined('RESTORE_SILENTLY')) {
                notify($errorstr);
            } else {
                return false;
            }
        }
    }
    $info = "";
    $course_header = "";
    //Now read the info tag (all)
    if ($status) {
        if (!defined('RESTORE_SILENTLY')) {
            echo "<li>" . get_string("readinginfofrombackup") . '</li>';
        }
        //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;
        }
    }
    if (!defined('RESTORE_SILENTLY')) {
        //End the main ul
        echo "</ul>\n";
        //End the main table
        echo "</td></tr>";
        echo "</table>";
    }
    //We compare Moodle's versions
    if ($CFG->version < $info->backup_moodle_version && $status) {
        $message = new object();
        $message->serverversion = $CFG->version;
        $message->serverrelease = $CFG->release;
        $message->backupversion = $info->backup_moodle_version;
        $message->backuprelease = $info->backup_moodle_release;
        print_simple_box(get_string('noticenewerbackup', '', $message), "center", "70%", '', "20", "noticebox");
    }
    //Now we print in other table, the backup and the course it contains info
    if ($info and $course_header and $status) {
        //First, the course info
        if (!defined('RESTORE_SILENTLY')) {
            $status = restore_print_course_header($course_header);
        }
        //Now, the backup info
        if ($status) {
            if (!defined('RESTORE_SILENTLY')) {
                $status = restore_print_info($info);
            }
        }
    }
    //Save course header and info into php session
    if ($status) {
        $SESSION->info = $info;
        $SESSION->course_header = $course_header;
    }
    //Finally, a little form to continue
    //with some hidden fields
    if ($status) {
        if (!defined('RESTORE_SILENTLY')) {
            echo "<br /><div style='text-align:center'>";
            $hidden["backup_unique_code"] = $backup_unique_code;
            $hidden["launch"] = "form";
            $hidden["file"] = $file;
            $hidden["id"] = $id;
            print_single_button("restore.php", $hidden, get_string("continue"), "post");
            echo "</div>";
        } else {
            if (empty($noredirect)) {
                // in 2.0 we must not print "Continue" redirect link here, because ppl click on it and the execution gets interrupted on next page!!!
                // imo RESTORE_SILENTLY is an ugly hack :-P
                $sillystr = get_string('donotclickcontinue');
                redirect($CFG->wwwroot . '/backup/restore.php?backup_unique_code=' . $backup_unique_code . '&launch=form&file=' . $file . '&id=' . $id, $sillystr, 0);
            } else {
                return $backup_unique_code;
            }
        }
    }
    if (!$status) {
        if (!defined('RESTORE_SILENTLY')) {
            error("An error has ocurred");
        } else {
            $errorstr = "An error has occured";
            // helpful! :P
            return false;
        }
    }
    return true;
}
 protected function parseXml()
 {
     global $CFG;
     // moodle.xml チェック
     $xml_file = $this->getTempDir() . '/moodle.xml';
     if (!restore_check_moodle_file($xml_file)) {
         throw new SharingCart_XmlException('check');
     }
     // XML をオブジェクトに読込
     $xml = new stdClass();
     $xml->info = restore_read_xml_info($xml_file);
     if (!$xml->info) {
         throw new SharingCart_XmlException('read');
     }
     // バージョンチェック
     if ($CFG->version < $xml->info->backup_moodle_version) {
         throw new SharingCart_XmlException('version');
     }
     // 必要な変数をリストア設定オブジェクトにコピー
     $property_map = array('backup_moodle_version' => 'backup_version', 'original_wwwroot' => 'original_wwwroot', 'original_siteidentifier' => 'original_siteidentifier');
     foreach ($property_map as $name => $prop) {
         $this->setParam($prop, $xml->info->{$name});
     }
     // コースヘッダ
     $xml->course_header = restore_read_xml_course_header($xml_file);
     if (!$xml->course_header) {
         throw new SharingCart_XmlException('course');
     }
     // 問題バンク
     $this->restoreQuestions();
     // モジュール
     $this->prefs->mods = array();
     if (!empty($xml->info->mods)) {
         foreach ($xml->info->mods as $name => $mod) {
             $this->prefs->mods[$name] = new stdClass();
             $this->prefs->mods[$name]->restore = $mod->backup == 'true';
             $this->prefs->mods[$name]->userinfo = $mod->userinfo == 'true';
             $this->prefs->mods[$name]->instances = array();
             // モジュール個別のリストアライブラリをインクルード
             if ($this->prefs->mods[$name]->restore) {
                 $mod_restorelib = "{$CFG->dirroot}/mod/{$name}/restorelib.php";
                 if (is_file($mod_restorelib)) {
                     require_once $mod_restorelib;
                 }
             }
             // モジュールインスタンス
             if (!empty($mod->instances)) {
                 foreach ($mod->instances as $inst) {
                     $this->prefs->mods[$name]->instances[$inst->id] = new stdClass();
                     $this->prefs->mods[$name]->instances[$inst->id]->restore = $inst->backup == 'true';
                     $this->prefs->mods[$name]->instances[$inst->id]->userinfo = $inst->userinfo == 'true';
                 }
             }
         }
     }
     // モジュールをリストア
     if (!restore_create_modules($this->prefs, $xml_file)) {
         throw new SharingCart_XmlException('modules');
     }
     if (!restore_check_instances($this->prefs)) {
         throw new SharingCart_XmlException('modules');
     }
     // リンクの張り直し (Moodle 標準)
     if (!restore_decode_content_links($this->prefs)) {
         throw new SharingCart_XmlException('decode links');
     }
     // セクションをリストア
     $this->restoreSection();
 }
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";
    // Re-assure xml file is in place before any further process
    if (!($status = restore_check_moodle_file($xml_file))) {
        if (!is_file($xml_file)) {
            $errorstr = 'Error checking backup file. moodle.xml not found. Session problem?';
        } else {
            $errorstr = 'Error checking backup file. moodle.xml is incorrect or corrupted. Session problem?';
        }
        if (!defined('RESTORE_SILENTLY')) {
            notify($errorstr);
        }
        return false;
    }
    //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)) {
            $errorstr = "Error proccessing moodle.xml file. Process ended.";
            if (!defined('RESTORE_SILENTLY')) {
                notify($errorstr);
            }
            return false;
        }
    }
    // Precheck the users section, detecting various situations that can lead to problems, so
    // we stop restore before performing any further action
    if (!defined('RESTORE_SILENTLY')) {
        echo '<li>' . get_string('restoreusersprecheck') . '</li>';
    }
    if (!restore_precheck_users($xml_file, $restore, $problems)) {
        $errorstr = get_string('restoreusersprecheckerror');
        if (!empty($problems)) {
            $errorstr .= ' (' . implode(', ', $problems) . ')';
        }
        if (!defined('RESTORE_SILENTLY')) {
            notify($errorstr);
        }
        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 $info->backup_logs == 'true' && $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;
}
Esempio n. 4
0
 public static function restoreCourse($preferences, $session)
 {
     global $Out;
     // the initial set of preferences should be enough to get the restore started.
     // once in progress the restore will obtain the preferences from the backup file
     // itself
     if (!isset($preferences)) {
         return null;
     }
     // Assumes the backup file is in the course data directory and the
     // preferences are in the backup file itself.
     global $CFG;
     // for large files uncomment following code
     //@ini_set("max_execution_time","3000");
     //raise_memory_limit("192M");
     $file = self::createBackupFilePath($preferences->course_id);
     $file .= '/' . $preferences->backup_name;
     //path to file
     //Check the file exists
     if (!is_file($file)) {
         return false;
     }
     //Check the file name ends with .zip
     if (!substr($file, -4) == ".zip") {
         return false;
     }
     //Now calculate the unique_code for this restore
     $backup_unique_code = $preferences->backup_unique_code;
     //Now check and create the backup dir (if it doesn't exist)
     $status = check_and_create_backup_dir($backup_unique_code);
     //Empty dir
     if ($status) {
         $status = clear_backup_dir($backup_unique_code);
     }
     //Now delete old data and directories under dataroot/temp/backup
     if ($status) {
         $status = backup_delete_old_data();
     }
     $tempBackupPath = synch_backup_controller::createTempBackupPath($backup_unique_code);
     //Now copy the zip file to dataroot/temp/backup/backup_unique_code
     if ($status) {
         if (!($status = backup_copy_file($file, $tempBackupPath . "/" . basename($file)))) {
             // There has been a problem. Invalid name or bad perms
             return false;
         }
     }
     //Now unzip the file
     if ($status) {
         if (!($status = restore_unzip($tempBackupPath . "/" . basename($file)))) {
             // error: Invalid zip file
             return false;
         }
     }
     //Check for Blackboard backups and convert
     if ($status) {
         require_once "{$CFG->dirroot}/backup/bb/restore_bb.php";
         $status = blackboard_convert($tempBackupPath);
     }
     // backup file has now been unpacked. Retrieve the serialized preferences
     $preferencesPath = $tempBackupPath . '/' . self::getPreferencesFileName();
     $preferences = FileSystem::unSerializeFromFile($preferencesPath);
     // Now we have the preferences from the backup we need to tailor it to our current needs
     // should we be updating an existing item or creating one.
     $dataItemId = SynchContentHierarchy::generateDataItemId($preferences->course_id, synch_view_controller::$TYPE_ID_COURSE);
     global $SynchManager, $SynchServerController;
     $itemExists = $SynchManager->getSessionItemExistsByServerId($SynchServerController->getServerId(), $session);
     if (isset($itemExists) && is_array($itemExists) && in_array($dataItemId, $itemExists)) {
         $preferences->restoreto = 1;
         $preferences->deleting = 1;
     } else {
         $preferences->restoreto = 2;
     }
     //Now check for the moodle.xml file
     if ($status) {
         $xml_file = $tempBackupPath . "/moodle.xml";
         if (!($status = restore_check_moodle_file($xml_file))) {
             if (!is_file($xml_file)) {
                 //Error checking backup file. moodle.xml not found at root level of zip file
                 return false;
             } else {
                 //Error checking backup file. moodle.xml is incorrect or corrupted.
                 return false;
             }
         }
     }
     //unpack backup file
     //read contents
     //Reading info from file
     $info = restore_read_xml_info($xml_file);
     //Reading course_header from file
     $courseHeader = restore_read_xml_course_header($xml_file);
     //Save course header and info into php session
     if ($status) {
         //$SESSION->info = $info;
         //$SESSION->course_header = $course_header;
     }
     global $restore;
     $restore = $preferences;
     $message = null;
     $restoreSuccess = restore_execute($preferences, $info, $courseHeader, $message);
     return $restoreSuccess;
 }