Example #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;
}
Example #2
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;
 }
 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();
 }
Example #4
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;
}