function backup_execute(&$preferences, &$errorstr) { global $CFG; $status = true; //Check for temp and backup and backup_unique_code directory //Create them as needed if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("creatingtemporarystructures") . '</li>'; } $status = check_and_create_backup_dir($preferences->backup_unique_code); //Empty dir if ($status) { $status = clear_backup_dir($preferences->backup_unique_code); } //Delete old_entries from backup tables if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("deletingolddata") . '</li>'; } $status = backup_delete_old_data(); if (!$status) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred deleting old backup data"); } else { $errorstr = "An error occurred deleting old backup data"; return false; } } //Create the moodle.xml file if ($status) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("creatingxmlfile"); //Begin a new list to xml contents echo "<ul>"; echo "<li>" . get_string("writingheader") . '</li>'; } //Obtain the xml file (create and open) and print prolog information $backup_file = backup_open_xml($preferences->backup_unique_code); if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("writinggeneralinfo") . '</li>'; } //Prints general info about backup to file if ($backup_file) { if (!($status = backup_general_info($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up general info"); } else { $errorstr = "An error occurred while backing up general info"; return false; } } } if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("writingcoursedata"); //Start new ul (for course) echo "<ul>"; echo "<li>" . get_string("courseinfo") . '</li>'; } //Prints course start (tag and general info) if ($status) { if (!($status = backup_course_start($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up course start"); } else { $errorstr = "An error occurred while backing up course start"; return false; } } } //Metacourse information if ($status && $preferences->backup_metacourse) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("metacourse") . '</li>'; } if (!($status = backup_course_metacourse($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up metacourse info"); } else { $errorstr = "An error occurred while backing up metacourse info"; return false; } } } if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("blocks") . '</li>'; } //Blocks information if ($status) { if (!($status = backup_course_blocks($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up course blocks"); } else { $errorstr = "An error occurred while backing up course blocks"; return false; } } } if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("sections") . '</li>'; } //Section info if ($status) { if (!($status = backup_course_sections($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up course sections"); } else { $errorstr = "An error occurred while backing up course sections"; return false; } } } //End course contents (close ul) if (!defined('BACKUP_SILENTLY')) { echo "</ul></li>"; } //User info if ($status) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("writinguserinfo") . '</li>'; } if (!($status = backup_user_info($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up user info"); } else { $errorstr = "An error occurred while backing up user info"; return false; } } } //If we have selected to backup messages and we are //doing a SITE backup, let's do it if ($status && $preferences->backup_messages && $preferences->backup_course == SITEID) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("writingmessagesinfo") . '</li>'; } if (!($status = backup_messages($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up messages"); } else { $errorstr = "An error occurred while backing up messages"; return false; } } } //If we have selected to backup blogs and we are //doing a SITE backup, let's do it if ($status && $preferences->backup_blogs && $preferences->backup_course == SITEID) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("writingblogsinfo") . '</li>'; } if (!($status = backup_blogs($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up blogs"); } else { $errorstr = "An error occurred while backing up blogs"; return false; } } } //If we have selected to backup quizzes or other modules that use questions //we've already added ids of categories and questions to backup to backup_ids table if ($status) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("writingcategoriesandquestions") . '</li>'; } require_once $CFG->dirroot . '/question/backuplib.php'; if (!($status = backup_question_categories($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up quiz categories"); } else { $errorstr = "An error occurred while backing up quiz categories"; return false; } } } //Print logs if selected if ($status) { if ($preferences->backup_logs) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("writingloginfo") . '</li>'; } if (!($status = backup_log_info($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up log info"); } else { $errorstr = "An error occurred while backing up log info"; return false; } } } } //Print scales info if ($status) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("writingscalesinfo") . '</li>'; } if (!($status = backup_scales_info($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up scales"); } else { $errorstr = "An error occurred while backing up scales"; return false; } } } //Print groups info if ($status) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("writinggroupsinfo") . '</li>'; } if (!($status = backup_groups_info($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up groups"); } else { $errostr = "An error occurred while backing up groups"; return false; } } } //Print groupings info if ($status) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("writinggroupingsinfo") . '</li>'; } if (!($status = backup_groupings_info($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up groupings"); } else { $errorstr = "An error occurred while backing up groupings"; return false; } } } //Print groupings_groups info if ($status) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("writinggroupingsgroupsinfo") . '</li>'; } if (!($status = backup_groupings_groups_info($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up groupings groups"); } else { $errorstr = "An error occurred while backing up groupings groups"; return false; } } } //Print events info if ($status) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("writingeventsinfo") . '</li>'; } if (!($status = backup_events_info($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up events"); } else { $errorstr = "An error occurred while backing up events"; return false; } } } //Print gradebook info if ($status) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("writinggradebookinfo") . '</li>'; } if (!($status = backup_gradebook_info($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up gradebook"); } else { $errorstr = "An error occurred while backing up gradebook"; return false; } } } //Module info, this unique function makes all the work!! //db export and module fileis copy if ($status) { $mods_to_backup = false; //Check if we have any mod to backup foreach ($preferences->mods as $module) { if ($module->backup) { $mods_to_backup = true; } } //If we have to backup some module if ($mods_to_backup) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("writingmoduleinfo"); } //Start modules tag if (!($status = backup_modules_start($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up module info"); } else { $errorstr = "An error occurred while backing up module info"; return false; } } //Open ul for module list if (!defined('BACKUP_SILENTLY')) { echo "<ul>"; } //Iterate over modules and call backup foreach ($preferences->mods as $module) { if ($module->backup and $status) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("modulenameplural", $module->name) . '</li>'; } if (!($status = backup_module($backup_file, $preferences, $module->name))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up '{$module->name}'"); } else { $errorstr = "An error occurred while backing up '{$module->name}'"; return false; } } } } //Close ul for module list if (!defined('BACKUP_SILENTLY')) { echo "</ul></li>"; } //Close modules tag if (!($status = backup_modules_end($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while finishing the module backups"); } else { $errorstr = "An error occurred while finishing the module backups"; return false; } } } } //Backup course format data, if any. if (!defined('BACKUP_SILENTLY')) { echo '<li>' . get_string("courseformatdata") . '</li>'; } if ($status) { if (!($status = backup_format_data($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while backing up the course format data"); } else { $errorstr = "An error occurred while backing up the course format data"; return false; } } } //Prints course end if ($status) { if (!($status = backup_course_end($backup_file, $preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while closing the course backup"); } else { $errorstr = "An error occurred while closing the course backup"; return false; } } } //Close the xml file and xml data if ($backup_file) { backup_close_xml($backup_file); } //End xml contents (close ul) if (!defined('BACKUP_SILENTLY')) { echo "</ul></li>"; } } //Now, if selected, copy user files if ($status) { if ($preferences->backup_user_files) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("copyinguserfiles") . '</li>'; } if (!($status = backup_copy_user_files($preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while copying user files"); } else { $errorstr = "An error occurred while copying user files"; return false; } } } } //Now, if selected, copy course files if ($status) { if ($preferences->backup_course_files) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("copyingcoursefiles") . '</li>'; } if (!($status = backup_copy_course_files($preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while copying course files"); } else { $errorstr = "An error occurred while copying course files"; return false; } } } } //Now, if selected, copy site files if ($status) { if ($preferences->backup_site_files) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("copyingsitefiles") . '</li>'; } if (!($status = backup_copy_site_files($preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while copying site files"); } else { $errorstr = "An error occurred while copying site files"; return false; } } } } //Now, zip all the backup directory contents if ($status) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("zippingbackup") . '</li>'; } if (!($status = backup_zip($preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while zipping the backup"); } else { $errorstr = "An error occurred while zipping the backup"; return false; } } } //Now, copy the zip file to course directory if ($status) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("copyingzipfile") . '</li>'; } if (!($status = copy_zip_to_course_dir($preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while copying the zip file to the course directory"); } else { $errorstr = "An error occurred while copying the zip file to the course directory"; return false; } } } //Now, clean temporary data (db and filesystem) if ($status) { if (!defined('BACKUP_SILENTLY')) { echo "<li>" . get_string("cleaningtempdata") . '</li>'; } if (!($status = clean_temp_data($preferences))) { if (!defined('BACKUP_SILENTLY')) { notify("An error occurred while cleaning up temporary data"); } else { $errorstr = "An error occurred while cleaning up temporary data"; return false; } } } return $status; }
/** * @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; }
function schedule_backup_cron() { global $CFG, $DB; $status = true; $emailpending = false; //Check for required functions... if (!function_exists('utf8_encode')) { mtrace(" ERROR: You need to add XML support to your PHP installation!"); return true; } //Get now $now = time(); //First of all, we have to see if the scheduled is active and detect //that there isn't another cron running mtrace(" Checking backup status", '...'); $backup_config = backup_get_config(); if (!isset($backup_config->backup_sche_active) || !$backup_config->backup_sche_active) { mtrace("INACTIVE"); return true; } else { if (isset($backup_config->backup_sche_running) && $backup_config->backup_sche_running) { mtrace("RUNNING"); //Now check if it's a really running task or something very old looking //for info in backup_logs to unlock status as necessary $timetosee = 1800; //Half an hour looking for activity $timeafter = time() - $timetosee; $numofrec = $DB->count_records_select("backup_log", "time > ? AND backuptype = ?", array($timeafter, 'scheduledbackup')); if (!$numofrec) { $timetoseemin = $timetosee / 60; mtrace(" No activity in last " . $timetoseemin . " minutes. Unlocking status"); } else { mtrace(" Scheduled backup seems to be running. Execution delayed"); return true; } } else { mtrace("OK"); //Mark backup_sche_running backup_set_config("backup_sche_running", "1"); } } //Now we get the main admin user (we'll use his timezone, mail...) mtrace(" Getting admin info"); $admin = get_admin(); if (!$admin) { $status = false; } //Delete old_entries from backup tables if ($status) { mtrace(" Deleting old data"); if (!backup_delete_old_data()) { $errorstr = "An error occurred deleting old backup data"; add_to_backup_log(time(), $preferences->backup_course, $errorstr, 'scheduledbackup'); mtrace(" " . $errorstr); } } //Now we get a list of courses in the server if ($status) { mtrace(" Checking courses"); //First of all, we delete everything from backup tables related to deleted courses mtrace(" Skipping deleted courses"); $skipped = 0; if ($bckcourses = $DB->get_records('backup_courses')) { foreach ($bckcourses as $bckcourse) { //Search if it exists if (!($exists = $DB->get_record('course', array('id' => $bckcourse->courseid)))) { //Doesn't exist, so delete from backup tables $DB->delete_records('backup_courses', array('courseid' => $bckcourse->courseid)); $DB->delete_records('backup_log', array('courseid' => $bckcourse->courseid)); $skipped++; } } } mtrace(" {$skipped} courses"); //Now process existing courses $courses = $DB->get_records("course"); //For each course, we check (insert, update) the backup_course table //with needed data foreach ($courses as $course) { if ($status) { mtrace(" {$course->fullname}"); //We check if the course exists in backup_course $backup_course = $DB->get_record("backup_courses", array("courseid" => $course->id)); //If it doesn't exist, create if (!$backup_course) { $temp_backup_course->courseid = $course->id; $newid = $DB->insert_record("backup_courses", $temp_backup_course); //And get it from db $backup_course = $DB->get_record("backup_courses", array("id" => $newid)); } //If it doesn't exist now, error if (!$backup_course) { mtrace(" ERROR (in backup_courses detection)"); $status = false; continue; } // Skip backup of unavailable courses that have remained unmodified in a month $skipped = false; if (!$course->visible && $now - $course->timemodified > 31 * 24 * 60 * 60) { //Hidden + unmodified last month mtrace(" SKIPPING - hidden+unmodified"); $DB->set_field("backup_courses", "laststatus", "3", array("courseid" => $backup_course->courseid)); $skipped = true; } //Now we backup every non skipped course with nextstarttime < now if (!$skipped && $backup_course->nextstarttime > 0 && $backup_course->nextstarttime < $now) { //We have to send a email because we have included at least one backup $emailpending = true; //Only make the backup if laststatus isn't 2-UNFINISHED (uncontrolled error) if ($backup_course->laststatus != 2) { //Set laststarttime $starttime = time(); $DB->set_field("backup_courses", "laststarttime", $starttime, array("courseid" => $backup_course->courseid)); //Set course status to unfinished, the process will reset it $DB->set_field("backup_courses", "laststatus", "2", array("courseid" => $backup_course->courseid)); //Launch backup $course_status = schedule_backup_launch_backup($course, $starttime); //Set lastendtime $DB->set_field("backup_courses", "lastendtime", time(), array("courseid" => $backup_course->courseid)); //Set laststatus if ($course_status) { $DB->set_field("backup_courses", "laststatus", "1", array("courseid" => $backup_course->courseid)); } else { $DB->set_field("backup_courses", "laststatus", "0", array("courseid" => $backup_course->courseid)); } } } //Now, calculate next execution of the course $nextstarttime = schedule_backup_next_execution($backup_course, $backup_config, $now, $admin->timezone); //Save it to db $DB->set_field("backup_courses", "nextstarttime", $nextstarttime, array("courseid" => $backup_course->courseid)); //Print it to screen as necessary $showtime = "undefined"; if ($nextstarttime > 0) { $showtime = userdate($nextstarttime, "", $admin->timezone); } mtrace(" Next execution: {$showtime}"); } } } //Delete old logs if (!empty($CFG->loglifetime)) { mtrace(" Deleting old logs"); $loglifetime = $now - $CFG->loglifetime * 86400; $DB->delete_records_select("backup_log", "laststarttime < ?", array($loglifetime)); } //Send email to admin if necessary if ($emailpending) { mtrace(" Sending email to admin"); $message = ""; //Get info about the status of courses $count_all = $DB->count_records('backup_courses'); $count_ok = $DB->count_records('backup_courses', array('laststatus' => '1')); $count_error = $DB->count_records('backup_courses', array('laststatus' => '0')); $count_unfinished = $DB->count_records('backup_courses', array('laststatus' => '2')); $count_skipped = $DB->count_records('backup_courses', array('laststatus' => '3')); //Build the message text //Summary $message .= get_string('summary') . "\n"; $message .= "==================================================\n"; $message .= " " . get_string('courses') . ": " . $count_all . "\n"; $message .= " " . get_string('ok') . ": " . $count_ok . "\n"; $message .= " " . get_string('skipped') . ": " . $count_skipped . "\n"; $message .= " " . get_string('error') . ": " . $count_error . "\n"; $message .= " " . get_string('unfinished') . ": " . $count_unfinished . "\n\n"; //Reference if ($count_error != 0 || $count_unfinished != 0) { $message .= " " . get_string('backupfailed') . "\n\n"; $dest_url = "{$CFG->wwwroot}/{$CFG->admin}/report/backups/index.php"; $message .= " " . get_string('backuptakealook', '', $dest_url) . "\n\n"; //Set message priority $admin->priority = 1; //Reset unfinished to error $DB->set_field('backup_courses', 'laststatus', '0', array('laststatus' => '2')); } else { $message .= " " . get_string('backupfinished') . "\n"; } //Build the message subject $site = get_site(); $prefix = format_string($site->shortname, true, array('context' => get_context_instance(CONTEXT_COURSE, SITEID))) . ": "; if ($count_error != 0 || $count_unfinished != 0) { $prefix .= "[" . strtoupper(get_string('error')) . "] "; } $subject = $prefix . get_string("scheduledbackupstatus"); //Send the message $eventdata = new stdClass(); $eventdata->modulename = 'moodle'; $eventdata->userfrom = $admin; $eventdata->userto = $admin; $eventdata->subject = $subject; $eventdata->fullmessage = $message; $eventdata->fullmessageformat = FORMAT_PLAIN; $eventdata->fullmessagehtml = ''; $eventdata->smallmessage = ''; message_send($eventdata); } //Everything is finished stop backup_sche_running backup_set_config("backup_sche_running", "0"); return $status; }
protected function prepareDir() { // 一時ディレクトリを作成して中身を空にする if (!check_and_create_backup_dir($this->getUnique()) || !clear_backup_dir($this->getUnique())) { throw new SharingCart_Exception('Preparation failure'); } // 残っている古い(=4時間以上前の)バックアップデータを削除 if (!backup_delete_old_data()) { throw new SharingCart_Exception('Preparation failure'); } }
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; }
function schedule_backup_cron() { global $CFG; $status = true; $emailpending = false; //Check for required functions... if (!function_exists('utf8_encode')) { mtrace(" ERROR: You need to add XML support to your PHP installation!"); return true; } //Get now $now = time(); //First of all, we have to see if the scheduled is active and detect //that there isn't another cron running mtrace(" Checking backup status", '...'); $backup_config = backup_get_config(); if (!isset($backup_config->backup_sche_active) || !$backup_config->backup_sche_active) { mtrace("INACTIVE"); return true; } else { if (isset($backup_config->backup_sche_running) && $backup_config->backup_sche_running) { mtrace("RUNNING"); //Now check if it's a really running task or something very old looking //for info in backup_logs to unlock status as necessary $timetosee = 1800; //Half an hour looking for activity $timeafter = time() - $timetosee; $numofrec = count_records_select("backup_log", "time > {$timeafter}"); if (!$numofrec) { $timetoseemin = $timetosee / 60; mtrace(" No activity in last " . $timetoseemin . " minutes. Unlocking status"); } else { mtrace(" Scheduled backup seems to be running. Execution delayed"); return true; } } else { mtrace("OK"); //Mark backup_sche_running backup_set_config("backup_sche_running", "1"); } } //Now we get the main admin user (we'll use his timezone, mail...) mtrace(" Getting admin info"); $admin = get_admin(); if (!$admin) { $status = false; } //Delete old_entries from backup tables if ($status) { mtrace(" Deleting old data"); $status = backup_delete_old_data(); } //Now we get a list of courses in the server if ($status) { mtrace(" Checking courses"); //First of all, we delete everything from backup tables related to deleted courses mtrace(" Skipping deleted courses"); $skipped = 0; if ($bckcourses = get_records('backup_courses')) { foreach ($bckcourses as $bckcourse) { //Search if it exists if (!($exists = get_record('course', 'id', "{$bckcourse->courseid}"))) { //Doesn't exist, so delete from backup tables delete_records('backup_courses', 'courseid', "{$bckcourse->courseid}"); delete_records('backup_log', 'courseid', "{$bckcourse->courseid}"); $skipped++; } } } mtrace(" {$skipped} courses"); //Now process existing courses $courses = get_records("course"); //For each course, we check (insert, update) the backup_course table //with needed data foreach ($courses as $course) { if ($status) { mtrace(" {$course->fullname}"); //We check if the course exists in backup_course $backup_course = get_record("backup_courses", "courseid", $course->id); //If it doesn't exist, create if (!$backup_course) { $temp_backup_course->courseid = $course->id; $newid = insert_record("backup_courses", $temp_backup_course); //And get it from db $backup_course = get_record("backup_courses", "id", $newid); } //If it doesn't exist now, error if (!$backup_course) { mtrace(" ERROR (in backup_courses detection)"); $status = false; continue; } // Skip courses that do not yet need backup $skipped = !($backup_course->nextstarttime > 0 && $backup_course->nextstarttime < $now); // Skip backup of unavailable courses that have remained unmodified in a month if (!$skipped && !$course->visible && $now - $course->timemodified > 31 * 24 * 60 * 60) { //Hidden + settings were unmodified last month //Check log if there were any modifications to the course content $sql = 'SELECT l.id FROM ' . $CFG->prefix . 'log l WHERE ' . 'l.course=' . $course->id . ' AND l.time>' . ($now - 31 * 24 * 60 * 60) . " AND lower(l.action) not like '%view%'"; $logexists = record_exists_sql($sql); if (!$logexists) { mtrace(" SKIPPING - hidden+unmodified"); set_field("backup_courses", "laststatus", "3", "courseid", $backup_course->courseid); $skipped = true; } } //Now we backup every non-skipped course if (!$skipped) { //We have to send a email because we have included at least one backup $emailpending = true; //Only make the backup if laststatus isn't 2-UNFINISHED (uncontrolled error) if ($backup_course->laststatus != 2) { //Set laststarttime $starttime = time(); set_field("backup_courses", "laststarttime", $starttime, "courseid", $backup_course->courseid); //Set course status to unfinished, the process will reset it set_field("backup_courses", "laststatus", "2", "courseid", $backup_course->courseid); //Launch backup $course_status = schedule_backup_launch_backup($course, $starttime); //Set lastendtime set_field("backup_courses", "lastendtime", time(), "courseid", $backup_course->courseid); //Set laststatus if ($course_status) { set_field("backup_courses", "laststatus", "1", "courseid", $backup_course->courseid); } else { set_field("backup_courses", "laststatus", "0", "courseid", $backup_course->courseid); } } } //Now, calculate next execution of the course $nextstarttime = schedule_backup_next_execution($backup_course, $backup_config, $now, $admin->timezone); //Save it to db set_field("backup_courses", "nextstarttime", $nextstarttime, "courseid", $backup_course->courseid); //Print it to screen as necessary $showtime = "undefined"; if ($nextstarttime > 0) { $showtime = userdate($nextstarttime, "", $admin->timezone); } mtrace(" Next execution: {$showtime}"); } } } //Delete old logs if (!empty($CFG->loglifetime)) { mtrace(" Deleting old logs"); $loglifetime = $now - $CFG->loglifetime * 86400; delete_records_select("backup_log", "laststarttime < '{$loglifetime}'"); } //Send email to admin if necessary if ($emailpending) { mtrace(" Sending email to admin"); $message = ""; //Get info about the status of courses $count_all = count_records('backup_courses'); $count_ok = count_records('backup_courses', 'laststatus', '1'); $count_error = count_records('backup_courses', 'laststatus', '0'); $count_unfinished = count_records('backup_courses', 'laststatus', '2'); $count_skipped = count_records('backup_courses', 'laststatus', '3'); //Build the message text //Summary $message .= get_string('summary') . "\n"; $message .= "==================================================\n"; $message .= " " . get_string('courses') . ": " . $count_all . "\n"; $message .= " " . get_string('ok') . ": " . $count_ok . "\n"; $message .= " " . get_string('skipped') . ": " . $count_skipped . "\n"; $message .= " " . get_string('error') . ": " . $count_error . "\n"; $message .= " " . get_string('unfinished') . ": " . $count_unfinished . "\n\n"; //Reference if ($count_error != 0 || $count_unfinished != 0) { $message .= " " . get_string('backupfailed') . "\n\n"; $dest_url = "{$CFG->wwwroot}/{$CFG->admin}/report/backups/index.php"; $message .= " " . get_string('backuptakealook', '', $dest_url) . "\n\n"; //Set message priority $admin->priority = 1; //Reset unfinished to error set_field('backup_courses', 'laststatus', '0', 'laststatus', '2'); } else { $message .= " " . get_string('backupfinished') . "\n"; } //Build the message subject $site = get_site(); $prefix = $site->shortname . ": "; if ($count_error != 0 || $count_unfinished != 0) { $prefix .= "[" . strtoupper(get_string('error')) . "] "; } $subject = $prefix . get_string("scheduledbackupstatus"); //Send the message email_to_user($admin, $admin, $subject, $message); } //Everything is finished stop backup_sche_running backup_set_config("backup_sche_running", "0"); return $status; }