From dc1048c301d5884dfbdc57b601c2d46735418514 Mon Sep 17 00:00:00 2001 From: ScottVerbeek Date: Thu, 25 Mar 2021 15:44:08 +1000 Subject: [PATCH] MDL-71190 backup: Include users last access to course Backup the table user_lastaccess which holds data for when a user last accessed a course. And also restore to the table user_lastaccess from the .xml file created in the backup. --- backup/moodle2/backup_course_task.class.php | 2 + backup/moodle2/backup_stepslib.php | 49 ++++++++++++++ backup/moodle2/restore_final_task.class.php | 2 + backup/moodle2/restore_stepslib.php | 75 +++++++++++++++++++++ 4 files changed, 128 insertions(+) diff --git a/backup/moodle2/backup_course_task.class.php b/backup/moodle2/backup_course_task.class.php index d2ac8c5994b..28046611c4d 100644 --- a/backup/moodle2/backup_course_task.class.php +++ b/backup/moodle2/backup_course_task.class.php @@ -125,6 +125,8 @@ class backup_course_task extends backup_task { $this->add_step(new backup_course_logs_structure_step('course_logs', 'logs.xml')); // New log stores. $this->add_step(new backup_course_logstores_structure_step('course_logstores', 'logstores.xml')); + // Last access to course logs. + $this->add_step(new backup_course_loglastaccess_structure_step('course_loglastaccess', 'loglastaccess.xml')); } // Generate the course competencies. diff --git a/backup/moodle2/backup_stepslib.php b/backup/moodle2/backup_stepslib.php index 4339b0c232d..2a77b0316dc 100644 --- a/backup/moodle2/backup_stepslib.php +++ b/backup/moodle2/backup_stepslib.php @@ -1639,6 +1639,55 @@ class backup_course_logstores_structure_step extends backup_structure_step { } } +/** + * Structure step in charge of constructing the loglastaccess.xml file for the course logs. + * + * This backup step will backup the logs of the user_lastaccess table. + */ +class backup_course_loglastaccess_structure_step extends backup_structure_step { + + /** + * This function creates the structures for the loglastaccess.xml file. + * Expected structure would look like this. + * + * + * 5 + * 1616887341 + * + * + * + * @return backup_nested_element + */ + protected function define_structure() { + + // To know if we are including userinfo. + $userinfo = $this->get_setting_value('users'); + + // Define the structure of logstores container. + $lastaccesses = new backup_nested_element('lastaccesses'); + $lastaccess = new backup_nested_element('lastaccess', array('id'), array('userid', 'timeaccess')); + + // Define build tree. + $lastaccesses->add_child($lastaccess); + + // This element should only happen if we are including user info. + if ($userinfo) { + // Define sources. + $lastaccess->set_source_sql(' + SELECT id, userid, timeaccess + FROM {user_lastaccess} + WHERE courseid = ?', + array(backup::VAR_COURSEID)); + + // Define userid annotation to user. + $lastaccess->annotate_ids('user', 'userid'); + } + + // Return the root element (lastaccessess). + return $lastaccesses; + } +} + /** * Structure step in charge of constructing the logstores.xml file for the activity logs. * diff --git a/backup/moodle2/restore_final_task.class.php b/backup/moodle2/restore_final_task.class.php index b0b6b765b53..83da7e1a059 100644 --- a/backup/moodle2/restore_final_task.class.php +++ b/backup/moodle2/restore_final_task.class.php @@ -93,6 +93,8 @@ class restore_final_task extends restore_task { $this->add_step(new restore_course_logs_structure_step('course_logs', 'course/logs.xml')); // New log stores. $this->add_step(new restore_course_logstores_structure_step('course_logstores', 'course/logstores.xml')); + // Last access to course logs. + $this->add_step(new restore_course_loglastaccess_structure_step('course_loglastaccess', 'course/loglastaccess.xml')); } // Review all the executed tasks having one after_restore method diff --git a/backup/moodle2/restore_stepslib.php b/backup/moodle2/restore_stepslib.php index 1397c74905f..8c63c499ae8 100644 --- a/backup/moodle2/restore_stepslib.php +++ b/backup/moodle2/restore_stepslib.php @@ -3428,6 +3428,81 @@ class restore_course_logstores_structure_step extends restore_structure_step { } } +/** + * Structure step in charge of restoring the loglastaccess.xml file for the course logs. + * + * This restore step will rebuild the table for user_lastaccess table. + */ +class restore_course_loglastaccess_structure_step extends restore_structure_step { + + /** + * Conditionally decide if this step should be executed. + * + * This function checks the following parameter: + * + * 1. the loglastaccess.xml file exists + * + * @return bool true is safe to execute, false otherwise + */ + protected function execute_condition() { + // 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 loglastaccess.xml information. + return false; + } + + return true; + } + + /** + * Return the elements to be processed on restore of loglastaccess. + * + * @return restore_path_element[] array of elements to be processed on restore. + */ + protected function define_structure() { + + $paths = array(); + // To know if we are including userinfo. + $userinfo = $this->get_setting_value('users'); + + if ($userinfo) { + $paths[] = new restore_path_element('lastaccess', '/lastaccesses/lastaccess'); + } + // Return the paths wrapped. + return $paths; + } + + /** + * Process the 'lastaccess' elements. + * + * @param array $data element data + */ + protected function process_lastaccess($data) { + global $DB; + + $data = (object)$data; + + $data->courseid = $this->get_courseid(); + if (!$data->userid = $this->get_mappingid('user', $data->userid)) { + return; // Nothing to do, not able to find the user to set the lastaccess time. + } + + // Check if record does exist. + $exists = $DB->get_record('user_lastaccess', array('courseid' => $data->courseid, 'userid' => $data->userid)); + if ($exists) { + // If the time of last access of the restore is newer, then replace and update. + if ($exists->timeaccess < $data->timeaccess) { + $exists->timeaccess = $data->timeaccess; + $DB->update_record('user_lastaccess', $exists); + } + } else { + $DB->insert_record('user_lastaccess', $data); + } + } +} + /** * Structure step in charge of restoring the logstores.xml file for the activity logs. *