mirror of
https://github.com/moodle/moodle.git
synced 2025-04-22 08:55:15 +02:00
backup MDL-22254 Added backup and restore of course completion information
This commit is contained in:
parent
f64e29e133
commit
bd39b6f226
@ -173,7 +173,7 @@ abstract class backup_activity_task extends backup_task {
|
||||
// Find activity_included_setting
|
||||
if (!$this->get_setting_value('included')) {
|
||||
$this->log('activity skipped by _included setting', backup::LOG_DEBUG, $this->name);
|
||||
|
||||
$this->plan->set_excluding_activities();
|
||||
} else { // Setting tells us it's ok to execute
|
||||
parent::execute();
|
||||
}
|
||||
|
@ -73,6 +73,9 @@ class backup_final_task extends backup_task {
|
||||
// execute_condition() so only will be excuted if ALL module grade_items in course have been exported
|
||||
$this->add_step(new backup_gradebook_structure_step('course_gradebook','gradebook.xml'));
|
||||
|
||||
// Generate the course completion
|
||||
$this->add_step(new backup_course_completion_structure_step('course_completion', 'completion.xml'));
|
||||
|
||||
// Generate the scales file with all the (final) annotated scales
|
||||
$this->add_step(new backup_final_scales_structure_step('scaleslist', 'scales.xml'));
|
||||
|
||||
|
@ -1544,3 +1544,82 @@ class backup_activity_grades_structure_step extends backup_structure_step {
|
||||
return $book;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Backups up the course completion information for the course.
|
||||
*/
|
||||
class backup_course_completion_structure_step extends backup_structure_step {
|
||||
|
||||
protected function execute_condition() {
|
||||
// Check that all activities have been included
|
||||
if ($this->task->is_excluding_activities()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The structure of the course completion backup
|
||||
*
|
||||
* @return backup_nested_element
|
||||
*/
|
||||
protected function define_structure() {
|
||||
|
||||
// To know if we are including user completion info
|
||||
$userinfo = $this->get_setting_value('userscompletion');
|
||||
|
||||
$cc = new backup_nested_element('course_completion');
|
||||
|
||||
$criteria = new backup_nested_element('course_completion_criteria', array('id'), array(
|
||||
'course','criteriatype', 'module', 'moduleinstance', 'courseinstanceshortname', 'enrolperiod', 'timeend', 'gradepass', 'role'
|
||||
));
|
||||
|
||||
$criteriacompletions = new backup_nested_element('course_completion_crit_completions');
|
||||
|
||||
$criteriacomplete = new backup_nested_element('course_completion_crit_compl', array('id'), array(
|
||||
'criteriaid', 'userid','gradefinal','unenrolled','deleted','timecompleted'
|
||||
));
|
||||
|
||||
$coursecompletions = new backup_nested_element('course_completions', array('id'), array(
|
||||
'userid', 'course', 'deleted', 'timenotified', 'timeenrolled','timestarted','timecompleted','reaggregate'
|
||||
));
|
||||
|
||||
$notify = new backup_nested_element('course_completion_notify', array('id'), array(
|
||||
'course','role','message','timesent'
|
||||
));
|
||||
|
||||
$aggregatemethod = new backup_nested_element('course_completion_aggr_methd', array('id'), array(
|
||||
'course','criteriatype','method','value'
|
||||
));
|
||||
|
||||
$cc->add_child($criteria);
|
||||
$criteria->add_child($criteriacompletions);
|
||||
$criteriacompletions->add_child($criteriacomplete);
|
||||
$cc->add_child($coursecompletions);
|
||||
$cc->add_child($notify);
|
||||
$cc->add_child($aggregatemethod);
|
||||
|
||||
// We need to get the courseinstances shortname rather than an ID for restore
|
||||
$criteria->set_source_sql("SELECT ccc.*, c.shortname courseinstanceshortname
|
||||
FROM {course_completion_criteria} ccc
|
||||
LEFT JOIN {course} c ON c.id = ccc.courseinstance
|
||||
WHERE ccc.course = ?", array(backup::VAR_COURSEID));
|
||||
|
||||
|
||||
$notify->set_source_table('course_completion_notify', array('course' => backup::VAR_COURSEID));
|
||||
$aggregatemethod->set_source_table('course_completion_aggr_methd', array('course' => backup::VAR_COURSEID));
|
||||
|
||||
if ($userinfo) {
|
||||
$criteriacomplete->set_source_table('course_completion_crit_compl', array('criteriaid' => backup::VAR_PARENTID));
|
||||
$coursecompletions->set_source_table('course_completions', array('course' => backup::VAR_COURSEID));
|
||||
}
|
||||
|
||||
$criteria->annotate_ids('role', 'role');
|
||||
$criteriacomplete->annotate_ids('user', 'userid');
|
||||
$coursecompletions->annotate_ids('user', 'userid');
|
||||
$notify->annotate_ids('role', 'role');
|
||||
|
||||
return $cc;
|
||||
|
||||
}
|
||||
}
|
@ -47,6 +47,9 @@ class restore_final_task extends restore_task {
|
||||
$this->add_step(new restore_gradebook_structure_step('gradebook_step','gradebook.xml'));
|
||||
}
|
||||
|
||||
// Course completion
|
||||
$this->add_step(new restore_course_completion_structure_step('course_completion', 'completion.xml'));
|
||||
|
||||
// Review all the module_availability records in backup_ids in order
|
||||
// to match them with existing modules / grade items.
|
||||
$this->add_step(new restore_process_course_modules_availability('process_modules_availability'));
|
||||
|
@ -1226,6 +1226,253 @@ class restore_comments_structure_step extends restore_structure_step {
|
||||
}
|
||||
}
|
||||
|
||||
class restore_course_completion_structure_step extends restore_structure_step {
|
||||
|
||||
/**
|
||||
* Conditionally decide if this step should be executed.
|
||||
*
|
||||
* This function checks parameters that are not immediate settings to ensure
|
||||
* that the enviroment is suitable for the restore of course completion info.
|
||||
*
|
||||
* This function checks the following four parameters:
|
||||
*
|
||||
* 1. Course completion is enabled on the site
|
||||
* 2. The backup includes course completion information
|
||||
* 3. All modules are restorable
|
||||
* 4. All modules are marked for restore.
|
||||
*
|
||||
* @return bool True is safe to execute, false otherwise
|
||||
*/
|
||||
protected function execute_condition() {
|
||||
global $CFG;
|
||||
|
||||
// First check course completion is enabled on this site
|
||||
if (empty($CFG->enablecompletion)) {
|
||||
// Disabled, don't restore course completion
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check it is included in the backup
|
||||
$fullpath = $this->task->get_taskbasepath();
|
||||
$fullpath = rtrim($fullpath, '/') . '/' . $this->filename;
|
||||
if (!file_exists($fullpath)) {
|
||||
// Not found, can't restore course completion
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check we are able to restore all backed up modules
|
||||
if ($this->task->is_missing_modules()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Finally check all modules within the backup are being restored.
|
||||
if ($this->task->is_excluding_activities()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the course completion structure
|
||||
*
|
||||
* @return array Array of restore_path_element
|
||||
*/
|
||||
protected function define_structure() {
|
||||
|
||||
// To know if we are including user completion info
|
||||
$userinfo = $this->get_setting_value('userscompletion');
|
||||
|
||||
$paths = array();
|
||||
$paths[] = new restore_path_element('course_completion_criteria', '/course_completion/course_completion_criteria');
|
||||
$paths[] = new restore_path_element('course_completion_notify', '/course_completion/course_completion_notify');
|
||||
$paths[] = new restore_path_element('course_completion_aggr_methd', '/course_completion/course_completion_aggr_methd');
|
||||
|
||||
if ($userinfo) {
|
||||
$paths[] = new restore_path_element('course_completion_crit_compl', '/course_completion/course_completion_criteria/course_completion_crit_completions/course_completion_crit_compl');
|
||||
$paths[] = new restore_path_element('course_completions', '/course_completion/course_completions');
|
||||
}
|
||||
|
||||
return $paths;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Process course completion criteria
|
||||
*
|
||||
* @global moodle_database $DB
|
||||
* @param stdClass $data
|
||||
*/
|
||||
public function process_course_completion_criteria($data) {
|
||||
global $DB;
|
||||
|
||||
$data = (object)$data;
|
||||
$data->course = $this->get_courseid();
|
||||
|
||||
// Apply the date offset to the time end field
|
||||
$data->timeend = $this->apply_date_offset($data->timeend);
|
||||
|
||||
// Map the role from the criteria
|
||||
if (!empty($data->role)) {
|
||||
$data->role = $this->get_mappingid('role', $data->role);
|
||||
}
|
||||
|
||||
// If the completion criteria is for a module we need to map the module instance
|
||||
// to the new module id.
|
||||
if (!empty($data->moduleinstance) && !empty($data->module)) {
|
||||
$data->moduleinstance = $this->get_mappingid('course_module', $data->moduleinstance);
|
||||
} else {
|
||||
$data->module = null;
|
||||
$data->moduleinstance = null;
|
||||
}
|
||||
|
||||
// We backup the course shortname rather than the ID so that we can match back to the course
|
||||
$skipcriteria = false;
|
||||
if (!empty($data->courseinstanceshortname)) {
|
||||
$courseinstanceid = $DB->get_field('course', 'id', array('shortname'=>$data->courseinstanceshortname));
|
||||
if (!$courseinstanceid) {
|
||||
$skipcriteria = true;
|
||||
}
|
||||
} else {
|
||||
$courseinstanceid = null;
|
||||
}
|
||||
$data->courseinstance = $courseinstanceid;
|
||||
|
||||
if (!$skipcriteria) {
|
||||
$params = array(
|
||||
'course' => $data->course,
|
||||
'criteriatype' => $data->criteriatype,
|
||||
'enrolperiod' => $data->enrolperiod,
|
||||
'courseinstance' => $data->courseinstance,
|
||||
'module' => $data->module,
|
||||
'moduleinstance' => $data->moduleinstance,
|
||||
'timeend' => $data->timeend,
|
||||
'gradepass' => $data->gradepass,
|
||||
'role' => $data->role
|
||||
);
|
||||
$newid = $DB->insert_record('course_completion_criteria', $params);
|
||||
$this->set_mapping('course_completion_criteria', $data->id, $newid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes course compltion criteria complete records
|
||||
*
|
||||
* @global moodle_database $DB
|
||||
* @param stdClass $data
|
||||
*/
|
||||
public function process_course_completion_crit_compl($data) {
|
||||
global $DB;
|
||||
|
||||
$data = (object)$data;
|
||||
|
||||
// This may be empty if criteria could not be restored
|
||||
$data->criteriaid = $this->get_mappingid('course_completion_criteria', $data->criteriaid);
|
||||
|
||||
$data->course = $this->get_courseid();
|
||||
$data->userid = $this->get_mappingid('user', $data->userid);
|
||||
|
||||
if (!empty($data->criteriaid) && !empty($data->userid)) {
|
||||
$params = array(
|
||||
'userid' => $data->userid,
|
||||
'course' => $data->course,
|
||||
'criteriaid' => $data->criteriaid,
|
||||
'timecompleted' => $this->apply_date_offset($data->timecompleted)
|
||||
);
|
||||
if (isset($data->gradefinal)) {
|
||||
$params['gradefinal'] = $data->gradefinal;
|
||||
}
|
||||
if (isset($data->unenroled)) {
|
||||
$params['unenroled'] = $data->unenroled;
|
||||
}
|
||||
if (isset($data->deleted)) {
|
||||
$params['deleted'] = $data->deleted;
|
||||
}
|
||||
$DB->insert_record('course_completion_crit_compl', $params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process course completions
|
||||
*
|
||||
* @global moodle_database $DB
|
||||
* @param stdClass $data
|
||||
*/
|
||||
public function process_course_completions($data) {
|
||||
global $DB;
|
||||
|
||||
$data = (object)$data;
|
||||
|
||||
$data->course = $this->get_courseid();
|
||||
$data->userid = $this->get_mappingid('user', $data->userid);
|
||||
|
||||
if (!empty($data->userid)) {
|
||||
$params = array(
|
||||
'userid' => $data->userid,
|
||||
'course' => $data->course,
|
||||
'deleted' => $data->deleted,
|
||||
'timenotified' => $this->apply_date_offset($data->timenotified),
|
||||
'timeenrolled' => $this->apply_date_offset($data->timeenrolled),
|
||||
'timestarted' => $this->apply_date_offset($data->timestarted),
|
||||
'timecompleted' => $this->apply_date_offset($data->timecompleted),
|
||||
'reaggregate' => $data->reaggregate
|
||||
);
|
||||
$DB->insert_record('course_completions', $params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process course completion notification records.
|
||||
*
|
||||
* Note: As of Moodle 2.0 this table is not being used however it has been
|
||||
* left in in the hopes that one day the functionality there will be completed
|
||||
*
|
||||
* @global moodle_database $DB
|
||||
* @param stdClass $data
|
||||
*/
|
||||
public function process_course_completion_notify($data) {
|
||||
global $DB;
|
||||
|
||||
$data = (object)$data;
|
||||
|
||||
$data->course = $this->get_courseid();
|
||||
if (!empty($data->role)) {
|
||||
$data->role = $this->get_mappingid('role', $data->role);
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'course' => $data->course,
|
||||
'role' => $data->role,
|
||||
'message' => $data->message,
|
||||
'timesent' => $this->apply_date_offset($data->timesent),
|
||||
);
|
||||
$DB->insert_record('course_completion_notify', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process course completion aggregate methods
|
||||
*
|
||||
* @global moodle_database $DB
|
||||
* @param stdClass $data
|
||||
*/
|
||||
public function process_course_completion_aggr_methd($data) {
|
||||
global $DB;
|
||||
|
||||
$data = (object)$data;
|
||||
|
||||
$data->course = $this->get_courseid();
|
||||
|
||||
$params = array(
|
||||
'course' => $data->course,
|
||||
'criteriatype' => $data->criteriatype,
|
||||
'method' => $data->method,
|
||||
'value' => $data->value,
|
||||
);
|
||||
$DB->insert_record('course_completion_aggr_methd', $params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This structure step restores the grade items associated with one activity
|
||||
* All the grade items are made child of the "course" grade item but the original
|
||||
|
@ -31,6 +31,7 @@ class backup_plan extends base_plan implements loggable {
|
||||
|
||||
protected $controller; // The backup controller building/executing this plan
|
||||
protected $basepath; // Fullpath to dir where backup is created
|
||||
protected $excludingdactivities;
|
||||
|
||||
/**
|
||||
* Constructor - instantiates one object of this class
|
||||
@ -67,6 +68,14 @@ class backup_plan extends base_plan implements loggable {
|
||||
return $this->controller->get_logger();
|
||||
}
|
||||
|
||||
public function is_excluding_activities() {
|
||||
return $this->excludingdactivities;
|
||||
}
|
||||
|
||||
public function set_excluding_activities() {
|
||||
$this->excludingdactivities = true;
|
||||
}
|
||||
|
||||
public function log($message, $level, $a = null, $depth = null, $display = false) {
|
||||
backup_helper::log($message, $level, $a, $depth, $display, $this->get_logger());
|
||||
}
|
||||
|
@ -42,6 +42,10 @@ abstract class backup_task extends base_task {
|
||||
public function get_backupid() {
|
||||
return $this->plan->get_backupid();
|
||||
}
|
||||
|
||||
public function is_excluding_activities() {
|
||||
return $this->plan->is_excluding_activities();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user