/** * Send one backup controller to DB * * @param backup_controller $controller controller to send to DB * @param string $checksum hash of the controller to be checked * @param bool $includeobj to decide if the object itself must be updated (true) or no (false) * @param bool $cleanobj to decide if the object itself must be cleaned (true) or no (false) * @return int id of the controller record in the DB * @throws backup_controller_exception|backup_dbops_exception */ public static function save_controller($controller, $checksum, $includeobj = true, $cleanobj = false) { global $DB; // Check we are going to save one backup_controller if (!$controller instanceof backup_controller) { throw new backup_controller_exception('backup_controller_expected'); } // Check checksum is ok. Only if we are including object info. Sounds silly but it isn't ;-). if ($includeobj and !$controller->is_checksum_correct($checksum)) { throw new backup_dbops_exception('backup_controller_dbops_saving_checksum_mismatch'); } // Cannot request to $includeobj and $cleanobj at the same time. if ($includeobj and $cleanobj) { throw new backup_dbops_exception('backup_controller_dbops_saving_cannot_include_and_delete'); } // Get all the columns $rec = new stdclass(); $rec->backupid = $controller->get_backupid(); $rec->operation = $controller->get_operation(); $rec->type = $controller->get_type(); $rec->itemid = $controller->get_id(); $rec->format = $controller->get_format(); $rec->interactive = $controller->get_interactive(); $rec->purpose = $controller->get_mode(); $rec->userid = $controller->get_userid(); $rec->status = $controller->get_status(); $rec->execution = $controller->get_execution(); $rec->executiontime = $controller->get_executiontime(); $rec->checksum = $checksum; // Serialize information if ($includeobj) { $rec->controller = base64_encode(serialize($controller)); } else { if ($cleanobj) { $rec->controller = ''; } } // Send it to DB if ($recexists = $DB->get_record('backup_controllers', array('backupid' => $rec->backupid))) { $rec->id = $recexists->id; $rec->timemodified = time(); $DB->update_record('backup_controllers', $rec); } else { $rec->timecreated = time(); $rec->timemodified = 0; $rec->id = $DB->insert_record('backup_controllers', $rec); } return $rec->id; }
/** * Launches a automated backup routine for the given course * * @param stdClass $course * @param int $starttime * @param int $userid * @return bool */ public static function launch_automated_backup($course, $starttime, $userid) { $outcome = self::BACKUP_STATUS_OK; $config = get_config('backup'); $dir = $config->backup_auto_destination; $storage = (int) $config->backup_auto_storage; $bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_AUTOMATED, $userid); try { // Set the default filename. $format = $bc->get_format(); $type = $bc->get_type(); $id = $bc->get_id(); $users = $bc->get_plan()->get_setting('users')->get_value(); $anonymised = $bc->get_plan()->get_setting('anonymize')->get_value(); $bc->get_plan()->get_setting('filename')->set_value(backup_plan_dbops::get_default_backup_filename($format, $type, $id, $users, $anonymised)); $bc->set_status(backup::STATUS_AWAITING); $bc->execute_plan(); $results = $bc->get_results(); $outcome = self::outcome_from_results($results); $file = $results['backup_destination']; // May be empty if file already moved to target location. if (empty($dir) && $storage !== 0) { // This is intentionally left as a warning instead of an error because of the current behaviour of backup settings. // See MDL-48266 for details. $bc->log('No directory specified for automated backups', backup::LOG_WARNING); $outcome = self::BACKUP_STATUS_WARNING; } else { if ($storage !== 0 && (!file_exists($dir) || !is_dir($dir) || !is_writable($dir))) { // If we need to copy the backup file to an external dir and it is not writable, change status to error. $bc->log('Specified backup directory is not writable - ', backup::LOG_ERROR, $dir); $dir = null; $outcome = self::BACKUP_STATUS_ERROR; } } // Copy file only if there was no error. if ($file && !empty($dir) && $storage !== 0 && $outcome != self::BACKUP_STATUS_ERROR) { $filename = backup_plan_dbops::get_default_backup_filename($format, $type, $course->id, $users, $anonymised, !$config->backup_shortname); if (!$file->copy_content_to($dir . '/' . $filename)) { $bc->log('Attempt to copy backup file to the specified directory failed - ', backup::LOG_ERROR, $dir); $outcome = self::BACKUP_STATUS_ERROR; } if ($outcome != self::BACKUP_STATUS_ERROR && $storage === 1) { if (!$file->delete()) { $outcome = self::BACKUP_STATUS_WARNING; $bc->log('Attempt to delete the backup file from course automated backup area failed - ', backup::LOG_WARNING, $file->get_filename()); } } } } catch (moodle_exception $e) { $bc->log('backup_auto_failed_on_course', backup::LOG_ERROR, $course->shortname); // Log error header. $bc->log('Exception: ' . $e->errorcode, backup::LOG_ERROR, $e->a, 1); // Log original exception problem. $bc->log('Debug: ' . $e->debuginfo, backup::LOG_DEBUG, null, 1); // Log original debug information. $outcome = self::BACKUP_STATUS_ERROR; } // Delete the backup file immediately if something went wrong. if ($outcome === self::BACKUP_STATUS_ERROR) { // Delete the file from file area if exists. if (!empty($file)) { $file->delete(); } // Delete file from external storage if exists. if ($storage !== 0 && !empty($filename) && file_exists($dir . '/' . $filename)) { @unlink($dir . '/' . $filename); } } $bc->destroy(); unset($bc); return $outcome; }
/** * Launches a automated backup routine for the given course * * @param stdClass $course * @param int $starttime * @param int $userid * @return bool */ public static function launch_automated_backup($course, $starttime, $userid) { $config = get_config('backup'); $bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_AUTOMATED, $userid); try { $settings = array('users' => 'backup_auto_users', 'role_assignments' => 'backup_auto_role_assignments', 'activities' => 'backup_auto_activities', 'blocks' => 'backup_auto_blocks', 'filters' => 'backup_auto_filters', 'comments' => 'backup_auto_comments', 'completion_information' => 'backup_auto_userscompletion', 'logs' => 'backup_auto_logs', 'histories' => 'backup_auto_histories'); foreach ($settings as $setting => $configsetting) { if ($bc->get_plan()->setting_exists($setting)) { $bc->get_plan()->get_setting($setting)->set_value($config->{$configsetting}); } } // Set the default filename $format = $bc->get_format(); $type = $bc->get_type(); $id = $bc->get_id(); $users = $bc->get_plan()->get_setting('users')->get_value(); $anonymised = $bc->get_plan()->get_setting('anonymize')->get_value(); $bc->get_plan()->get_setting('filename')->set_value(backup_plan_dbops::get_default_backup_filename($format, $type, $id, $users, $anonymised)); $bc->set_status(backup::STATUS_AWAITING); $outcome = $bc->execute_plan(); $results = $bc->get_results(); $file = $results['backup_destination']; $dir = $config->backup_auto_destination; $storage = (int) $config->backup_auto_storage; if (!file_exists($dir) || !is_dir($dir) || !is_writable($dir)) { $dir = null; } if (!empty($dir) && $storage !== 0) { $filename = backup_plan_dbops::get_default_backup_filename($format, $type, $course->id, $users, $anonymised, true); $outcome = $file->copy_content_to($dir . '/' . $filename); if ($outcome && $storage === 1) { $file->delete(); } } $outcome = true; } catch (backup_exception $e) { $bc->log('backup_auto_failed_on_course', backup::LOG_WARNING, $course->shortname); $outcome = false; } $bc->destroy(); unset($bc); return true; }
/** * Launches a automated backup routine for the given course * * @param stdClass $course * @param int $starttime * @param int $userid * @return bool */ public static function launch_automated_backup($course, $starttime, $userid) { $outcome = self::BACKUP_STATUS_OK; $config = get_config('backup'); $dir = $config->backup_auto_destination; $storage = (int) $config->backup_auto_storage; $bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_AUTOMATED, $userid); try { $settings = array('users' => 'backup_auto_users', 'role_assignments' => 'backup_auto_role_assignments', 'activities' => 'backup_auto_activities', 'blocks' => 'backup_auto_blocks', 'filters' => 'backup_auto_filters', 'comments' => 'backup_auto_comments', 'badges' => 'backup_auto_badges', 'completion_information' => 'backup_auto_userscompletion', 'logs' => 'backup_auto_logs', 'histories' => 'backup_auto_histories', 'questionbank' => 'backup_auto_questionbank'); foreach ($settings as $setting => $configsetting) { if ($bc->get_plan()->setting_exists($setting)) { if (isset($config->{$configsetting})) { $bc->get_plan()->get_setting($setting)->set_value($config->{$configsetting}); } } } // Set the default filename. $format = $bc->get_format(); $type = $bc->get_type(); $id = $bc->get_id(); $users = $bc->get_plan()->get_setting('users')->get_value(); $anonymised = $bc->get_plan()->get_setting('anonymize')->get_value(); $bc->get_plan()->get_setting('filename')->set_value(backup_plan_dbops::get_default_backup_filename($format, $type, $id, $users, $anonymised)); $bc->set_status(backup::STATUS_AWAITING); $bc->execute_plan(); $results = $bc->get_results(); $outcome = self::outcome_from_results($results); $file = $results['backup_destination']; // May be empty if file already moved to target location. if (!file_exists($dir) || !is_dir($dir) || !is_writable($dir)) { $dir = null; } // Copy file only if there was no error. if ($file && !empty($dir) && $storage !== 0 && $outcome != self::BACKUP_STATUS_ERROR) { $filename = backup_plan_dbops::get_default_backup_filename($format, $type, $course->id, $users, $anonymised, !$config->backup_shortname); if (!$file->copy_content_to($dir . '/' . $filename)) { $outcome = self::BACKUP_STATUS_ERROR; } if ($outcome != self::BACKUP_STATUS_ERROR && $storage === 1) { $file->delete(); } } } catch (moodle_exception $e) { $bc->log('backup_auto_failed_on_course', backup::LOG_ERROR, $course->shortname); // Log error header. $bc->log('Exception: ' . $e->errorcode, backup::LOG_ERROR, $e->a, 1); // Log original exception problem. $bc->log('Debug: ' . $e->debuginfo, backup::LOG_DEBUG, null, 1); // Log original debug information. $outcome = self::BACKUP_STATUS_ERROR; } // Delete the backup file immediately if something went wrong. if ($outcome === self::BACKUP_STATUS_ERROR) { // Delete the file from file area if exists. if (!empty($file)) { $file->delete(); } // Delete file from external storage if exists. if ($storage !== 0 && !empty($filename) && file_exists($dir . '/' . $filename)) { @unlink($dir . '/' . $filename); } } $bc->destroy(); unset($bc); return $outcome; }
mtrace("Destination directory does not exists or not writable."); die; } } // Check that the course exists. if ($options['courseid']) { $course = $DB->get_record('course', array('id' => $options['courseid']), '*', MUST_EXIST); } else { if ($options['courseshortname']) { $course = $DB->get_record('course', array('shortname' => $options['courseshortname']), '*', MUST_EXIST); } } cli_heading('Performing backup...'); $bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE, backup::INTERACTIVE_YES, backup::MODE_GENERAL, $admin->id); // Set the default filename. $format = $bc->get_format(); $type = $bc->get_type(); $id = $bc->get_id(); $users = $bc->get_plan()->get_setting('users')->get_value(); $anonymised = $bc->get_plan()->get_setting('anonymize')->get_value(); $filename = backup_plan_dbops::get_default_backup_filename($format, $type, $id, $users, $anonymised); $bc->get_plan()->get_setting('filename')->set_value($filename); // Execution. $bc->finish_ui(); $bc->execute_plan(); $results = $bc->get_results(); $file = $results['backup_destination']; // May be empty if file already moved to target location. // Do we need to store backup somewhere else? if (!empty($dir)) { if ($file) {
/** * Gets the format for the backup * @return int */ public function get_format() { return $this->controller->get_format(); }