diff --git a/backup/moodle2/backup_activity_task.class.php b/backup/moodle2/backup_activity_task.class.php index f3a22b70b79..e8c83f8d8ac 100644 --- a/backup/moodle2/backup_activity_task.class.php +++ b/backup/moodle2/backup_activity_task.class.php @@ -142,6 +142,11 @@ abstract class backup_activity_task extends backup_task { $this->add_step(new backup_activity_logs_structure_step('activity_logs', 'logs.xml')); } + // Generate the calendar events file (conditionally) + if ($this->get_setting_value('calendarevents')) { + $this->add_step(new backup_calendarevents_structure_step('activity_calendar', 'calendar.xml')); + } + // Fetch all the activity grade items and put them to backup_ids $this->add_step(new backup_activity_grade_items_to_ids('fetch_activity_grade_items')); diff --git a/backup/moodle2/backup_course_task.class.php b/backup/moodle2/backup_course_task.class.php index 070506cef7a..823e6bf5547 100644 --- a/backup/moodle2/backup_course_task.class.php +++ b/backup/moodle2/backup_course_task.class.php @@ -103,6 +103,11 @@ class backup_course_task extends backup_task { $this->add_step(new backup_comments_structure_step('course_comments', 'comments.xml')); } + // Generate the calender events file (conditionally) + if ($this->get_setting_value('calendarevents')) { + $this->add_step(new backup_calendarevents_structure_step('course_calendar', 'calendar.xml')); + } + // Generate the logs file (conditionally) if ($this->get_setting_value('logs')) { $this->add_step(new backup_course_logs_structure_step('course_logs', 'logs.xml')); diff --git a/backup/moodle2/backup_root_task.class.php b/backup/moodle2/backup_root_task.class.php index 6765fbbb360..e8a9cc6ce3f 100644 --- a/backup/moodle2/backup_root_task.class.php +++ b/backup/moodle2/backup_root_task.class.php @@ -114,6 +114,12 @@ class backup_root_task extends backup_task { $this->add_setting($comments); $users->add_dependency($comments); + // Define calendar events (dependent of users) + $events = new backup_calendarevents_setting('calendarevents', base_setting::IS_BOOLEAN, true); + $events->set_ui(new backup_setting_ui_checkbox($events, get_string('rootsettingcalendarevents', 'backup'))); + $this->add_setting($events); + $users->add_dependency($events); + // Define completion (dependent of users) $completion = new backup_userscompletion_setting('userscompletion', base_setting::IS_BOOLEAN, true); $completion->set_ui(new backup_setting_ui_checkbox($completion, get_string('rootsettinguserscompletion', 'backup'))); diff --git a/backup/moodle2/backup_settingslib.php b/backup/moodle2/backup_settingslib.php index 29641ecbdfd..46948cd25c9 100644 --- a/backup/moodle2/backup_settingslib.php +++ b/backup/moodle2/backup_settingslib.php @@ -89,6 +89,13 @@ class backup_logs_setting extends backup_anonymize_setting {} */ class backup_comments_setting extends backup_anonymize_setting {} +/** + * root setting to control if backup will include + * calender events or no (any level), depends of @backup_users_setting + * exactly in the same way than @backup_anonymize_setting so we extend from it + */ +class backup_calendarevents_setting extends backup_anonymize_setting {} + /** * root setting to control if backup will include * users completion data or no (any level), depends of @backup_users_setting diff --git a/backup/moodle2/backup_stepslib.php b/backup/moodle2/backup_stepslib.php index 3cd1418bfb5..bd1f783d012 100644 --- a/backup/moodle2/backup_stepslib.php +++ b/backup/moodle2/backup_stepslib.php @@ -767,6 +767,48 @@ class backup_comments_structure_step extends backup_structure_step { } } +/** + * structure step in charge of constructing the calender.xml file for all the events found + * in a given context + */ +class backup_calendarevents_structure_step extends backup_structure_step { + + protected function define_structure() { + + // Define each element separated + + $events = new backup_nested_element('events'); + + $event = new backup_nested_element('event', array('id'), array( + 'name', 'description', 'format', 'courseid', 'groupid', 'userid', + 'repeatid', 'modulename', 'instance', 'eventtype', 'timestart', + 'timeduration', 'visible', 'uuid', 'sequence', 'timemodified')); + + // Build the tree + $events->add_child($event); + + // Define sources + if ($this->name == 'course_calendar') { + $calendar_items_sql ="SELECT * FROM {event} + WHERE courseid = :courseid + AND (eventtype = 'course' OR eventtype = 'group')"; + $calendar_items_params = array('courseid'=>backup::VAR_COURSEID); + $event->set_source_sql($calendar_items_sql, $calendar_items_params); + } else { + $event->set_source_table('event', array('courseid' => backup::VAR_COURSEID, 'instance' => backup::VAR_ACTIVITYID, 'modulename' => backup::VAR_MODNAME)); + } + + // Define id annotations + + $event->annotate_ids('user', 'userid'); + $event->annotate_ids('group', 'groupid'); + $event->annotate_files('calendar', 'event_description', 'id'); + + // Return the root element (events) + return $events; + } +} + /** * structure step in charge of constructing the gradebook.xml file for all the gradebook config in the course * NOTE: the backup of the grade items themselves is handled by backup_activity_grades_structure_step diff --git a/backup/moodle2/restore_activity_task.class.php b/backup/moodle2/restore_activity_task.class.php index 50f305dbdc2..bf8e3eabc2b 100644 --- a/backup/moodle2/restore_activity_task.class.php +++ b/backup/moodle2/restore_activity_task.class.php @@ -147,6 +147,11 @@ abstract class restore_activity_task extends restore_task { $this->add_step(new restore_comments_structure_step('activity_comments', 'comments.xml')); } + // Calendar events (conditionally) + if ($this->get_setting_value('calendarevents')) { + $this->add_step(new restore_calendarevents_structure_step('activity_calendar', 'calendar.xml')); + } + // Grades (module-related, rest of gradebook is restored later if possible: cats, calculations...) $this->add_step(new restore_activity_grades_structure_step('activity_grades', 'grades.xml')); diff --git a/backup/moodle2/restore_course_task.class.php b/backup/moodle2/restore_course_task.class.php index 1ab98bf3306..b5da9702fe2 100644 --- a/backup/moodle2/restore_course_task.class.php +++ b/backup/moodle2/restore_course_task.class.php @@ -84,6 +84,11 @@ class restore_course_task extends restore_task { $this->add_step(new restore_comments_structure_step('course_comments', 'comments.xml')); } + // Calendar events (conditionally) + if ($this->get_setting_value('calendarevents')) { + $this->add_step(new restore_calendarevents_structure_step('course_calendar', 'calendar.xml')); + } + // At the end, mark it as built $this->built = true; } diff --git a/backup/moodle2/restore_root_task.class.php b/backup/moodle2/restore_root_task.class.php index e547f267ef9..583c6f89fe3 100644 --- a/backup/moodle2/restore_root_task.class.php +++ b/backup/moodle2/restore_root_task.class.php @@ -170,6 +170,19 @@ class restore_root_task extends restore_task { $this->add_setting($comments); $users->add_dependency($comments); + // Define Calendar events (dependent of users) + $defaultvalue = false; // Safer default + $changeable = false; + if (isset($rootsettings['calendarevents']) && $rootsettings['calendarevents']) { // Only enabled when available + $defaultvalue = true; + $changeable = true; + } + $events = new restore_calendarevents_setting('calendarevents', base_setting::IS_BOOLEAN, $defaultvalue); + $events->set_ui(new backup_setting_ui_checkbox($events, get_string('rootsettingcalendarevents', 'backup'))); + $events->get_ui()->set_changeable($changeable); + $this->add_setting($events); + $users->add_dependency($events); + // Define completion (dependent of users) $defaultvalue = false; // Safer default $changeable = false; diff --git a/backup/moodle2/restore_settingslib.php b/backup/moodle2/restore_settingslib.php index 899af5e896b..4b2558d36b2 100644 --- a/backup/moodle2/restore_settingslib.php +++ b/backup/moodle2/restore_settingslib.php @@ -58,6 +58,13 @@ class restore_activities_setting extends restore_generic_setting {} */ class restore_comments_setting extends restore_role_assignments_setting {} +/** + * root setting to control if restore will create + * events or no, depends of @restore_users_setting + * exactly in the same way than @restore_role_assignments_setting so we extend from it + */ +class restore_calendarevents_setting extends restore_role_assignments_setting {} + /** * root setting to control if restore will create * completion info or no, depends of @restore_users_setting diff --git a/backup/moodle2/restore_stepslib.php b/backup/moodle2/restore_stepslib.php index f2babe6e323..a3e4dc02e8f 100644 --- a/backup/moodle2/restore_stepslib.php +++ b/backup/moodle2/restore_stepslib.php @@ -1566,6 +1566,76 @@ class restore_comments_structure_step extends restore_structure_step { } } +/** + * This structure steps restores the calendar events + */ +class restore_calendarevents_structure_step extends restore_structure_step { + + protected function define_structure() { + + $paths = array(); + + $paths[] = new restore_path_element('calendarevents', '/events/event'); + + return $paths; + } + + public function process_calendarevents($data) { + global $DB; + + $data = (object)$data; + $oldid = $data->id; + $restorefiles = true; // We'll restore the files + // Find the userid and the groupid associated with the event. Return if not found. + $data->userid = $this->get_mappingid('user', $data->userid); + if ($data->userid === false) { + return; + } + if (!empty($data->groupid)) { + $data->groupid = $this->get_mappingid('group', $data->groupid); + if ($data->groupid === false) { + return; + } + } + + $params = array( + 'name' => $data->name, + 'description' => $data->description, + 'format' => $data->format, + 'courseid' => $this->get_courseid(), + 'groupid' => $data->groupid, + 'userid' => $data->userid, + 'repeatid' => $data->repeatid, + 'modulename' => $data->modulename, + 'eventtype' => $data->eventtype, + 'timestart' => $this->apply_date_offset($data->timestart), + 'timeduration' => $data->timeduration, + 'visible' => $data->visible, + 'uuid' => $data->uuid, + 'sequence' => $data->sequence, + 'timemodified' => $this->apply_date_offset($data->timemodified)); + if ($this->name == 'activity_calendar') { + $params['instance'] = $this->task->get_activityid(); + } else { + $params['instance'] = 0; + } + $sql = 'SELECT id FROM {event} WHERE name = ? AND courseid = ? AND + repeatid = ? AND modulename = ? AND timestart = ? AND timeduration =? + AND ' . $DB->sql_compare_text('description', 255) . ' = ' . $DB->sql_compare_text('?', 255); + $arg = array ($params['name'], $params['courseid'], $params['repeatid'], $params['modulename'], $params['timestart'], $params['timeduration'], $params['description']); + $result = $DB->record_exists_sql($sql, $arg); + if (empty($result)) { + $newitemid = $DB->insert_record('event', $params); + $this->set_mapping('event_description', $oldid, $newitemid, $restorefiles); + } + + } + protected function after_execute() { + // Add related files + $this->add_related_files('calendar', 'event_description', 'event_description'); + } +} + class restore_course_completion_structure_step extends restore_structure_step { /** diff --git a/lang/en/backup.php b/lang/en/backup.php index 0af62aa3162..e8c2a707018 100644 --- a/lang/en/backup.php +++ b/lang/en/backup.php @@ -203,6 +203,7 @@ $string['rootsettingactivities'] = 'Include activities'; $string['rootsettingblocks'] = 'Include blocks'; $string['rootsettingfilters'] = 'Include filters'; $string['rootsettingcomments'] = 'Include comments'; +$string['rootsettingcalendarevents'] = 'Include calendar events'; $string['rootsettinguserscompletion'] = 'Include user completion details'; $string['rootsettinglogs'] = 'Include course logs'; $string['rootsettinggradehistories'] = 'Include grade history';