diff --git a/admin/settings/courses.php b/admin/settings/courses.php index 9e379a4c83c..05e64edbb07 100644 --- a/admin/settings/courses.php +++ b/admin/settings/courses.php @@ -196,6 +196,8 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) { $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_logs', new lang_string('generallogs','backup'), new lang_string('configgenerallogs','backup'), array('value'=>0, 'locked'=>0))); $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_histories', new lang_string('generalhistories','backup'), new lang_string('configgeneralhistories','backup'), array('value'=>0, 'locked'=>0))); $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_questionbank', new lang_string('generalquestionbank','backup'), new lang_string('configgeneralquestionbank','backup'), array('value'=>1, 'locked'=>0))); + $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_groups', new lang_string('generalgroups','backup'), new lang_string('configgeneralgroups','backup'), array('value'=>1, 'locked'=>0))); + $ADMIN->add('backups', $temp); // Create a page for general import configuration and defaults. @@ -271,6 +273,7 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) { $temp->add(new admin_setting_configcheckbox('backup/backup_auto_logs', new lang_string('generallogs', 'backup'), new lang_string('configgenerallogs', 'backup'), 0)); $temp->add(new admin_setting_configcheckbox('backup/backup_auto_histories', new lang_string('generalhistories','backup'), new lang_string('configgeneralhistories','backup'), 0)); $temp->add(new admin_setting_configcheckbox('backup/backup_auto_questionbank', new lang_string('generalquestionbank','backup'), new lang_string('configgeneralquestionbank','backup'), 1)); + $temp->add(new admin_setting_configcheckbox('backup/backup_auto_groups', new lang_string('generalgroups','backup'), new lang_string('configgeneralgroups','backup'), 1)); //$temp->add(new admin_setting_configcheckbox('backup/backup_auto_messages', new lang_string('messages', 'message'), new lang_string('backupmessageshelp','message'), 0)); //$temp->add(new admin_setting_configcheckbox('backup/backup_auto_blogs', new lang_string('blogs', 'blog'), new lang_string('backupblogshelp','blog'), 0)); diff --git a/backup/moodle2/backup_activity_task.class.php b/backup/moodle2/backup_activity_task.class.php index e39c858bee7..8eac1691d29 100644 --- a/backup/moodle2/backup_activity_task.class.php +++ b/backup/moodle2/backup_activity_task.class.php @@ -137,8 +137,10 @@ abstract class backup_activity_task extends backup_task { // activity and from its related course_modules record and availability $this->add_step(new backup_module_structure_step('module_info', 'module.xml')); - // Annotate the groups used in already annotated groupings - $this->add_step(new backup_annotate_groups_from_groupings('annotate_groups')); + // Annotate the groups used in already annotated groupings if groups are to be backed up. + if ($this->get_setting_value('groups')) { + $this->add_step(new backup_annotate_groups_from_groupings('annotate_groups')); + } // Here we add all the common steps for any activity and, in the point of interest // we call to define_my_steps() is order to get the particular ones inserted in place. diff --git a/backup/moodle2/backup_course_task.class.php b/backup/moodle2/backup_course_task.class.php index 5ed54e91cfc..c7b64b4c287 100644 --- a/backup/moodle2/backup_course_task.class.php +++ b/backup/moodle2/backup_course_task.class.php @@ -83,15 +83,18 @@ class backup_course_task extends backup_task { // Annotate enrolment custom fields. $this->add_step(new backup_enrolments_execution_step('annotate_enrol_custom_fields')); - // Annotate all the groups and groupings belonging to the course - $this->add_step(new backup_annotate_course_groups_and_groupings('annotate_course_groups')); + // Annotate all the groups and groupings belonging to the course. This can be optional. + if ($this->get_setting_value('groups')) { + $this->add_step(new backup_annotate_course_groups_and_groupings('annotate_course_groups')); + } // Annotate the groups used in already annotated groupings (note this may be // unnecessary now that we are annotating all the course groups and groupings in the - // step above. But we keep it working in case we decide, someday, to introduce one - // setting to transform the step above into an optional one. This is here to support - // course->defaultgroupingid - $this->add_step(new backup_annotate_groups_from_groupings('annotate_groups_from_groupings')); + // step above). This is here to support course->defaultgroupingid. + // This may not be required to annotate if groups are not being backed up. + if ($this->get_setting_value('groups')) { + $this->add_step(new backup_annotate_groups_from_groupings('annotate_groups_from_groupings')); + } // Annotate the question_categories belonging to the course context (conditionally). if ($this->get_setting_value('questionbank')) { diff --git a/backup/moodle2/backup_root_task.class.php b/backup/moodle2/backup_root_task.class.php index 0a2df8a6c45..45e792d0980 100644 --- a/backup/moodle2/backup_root_task.class.php +++ b/backup/moodle2/backup_root_task.class.php @@ -159,5 +159,9 @@ class backup_root_task extends backup_task { $questionbank = new backup_generic_setting('questionbank', base_setting::IS_BOOLEAN, true); $questionbank->set_ui(new backup_setting_ui_checkbox($questionbank, get_string('rootsettingquestionbank', 'backup'))); $this->add_setting($questionbank); + + $groups = new backup_groups_setting('groups', base_setting::IS_BOOLEAN, true); + $groups->set_ui(new backup_setting_ui_checkbox($groups, get_string('rootsettinggroups', 'backup'))); + $this->add_setting($groups); } } diff --git a/backup/moodle2/backup_settingslib.php b/backup/moodle2/backup_settingslib.php index b3704ab1aa5..af2b70c5242 100644 --- a/backup/moodle2/backup_settingslib.php +++ b/backup/moodle2/backup_settingslib.php @@ -65,6 +65,12 @@ class backup_filename_setting extends backup_generic_setting { */ class backup_users_setting extends backup_generic_setting {} +/** + * root setting to control if backup will include group information + * depends on @backup_users_setting + */ +class backup_groups_setting extends backup_generic_setting {} + /** * root setting to control if backup will include activities or no. * A lot of other settings (_included at activity levels) diff --git a/backup/moodle2/backup_stepslib.php b/backup/moodle2/backup_stepslib.php index 78507d22d99..0b171c0a447 100644 --- a/backup/moodle2/backup_stepslib.php +++ b/backup/moodle2/backup_stepslib.php @@ -1149,8 +1149,11 @@ class backup_groups_structure_step extends backup_structure_step { protected function define_structure() { - // To know if we are including users - $users = $this->get_setting_value('users'); + // To know if we are including users. + $userinfo = $this->get_setting_value('users'); + // To know if we are including groups and groupings. + $groupinfo = $this->get_setting_value('groups'); + // Define each element separated @@ -1190,27 +1193,29 @@ class backup_groups_structure_step extends backup_structure_step { // Define sources - $group->set_source_sql(" - SELECT g.* - FROM {groups} g - JOIN {backup_ids_temp} bi ON g.id = bi.itemid - WHERE bi.backupid = ? - AND bi.itemname = 'groupfinal'", array(backup::VAR_BACKUPID)); + // This only happens if we are including groups/groupings. + if ($groupinfo) { + $group->set_source_sql(" + SELECT g.* + FROM {groups} g + JOIN {backup_ids_temp} bi ON g.id = bi.itemid + WHERE bi.backupid = ? + AND bi.itemname = 'groupfinal'", array(backup::VAR_BACKUPID)); - // This only happens if we are including users - if ($users) { - $member->set_source_table('groups_members', array('groupid' => backup::VAR_PARENTID)); + $grouping->set_source_sql(" + SELECT g.* + FROM {groupings} g + JOIN {backup_ids_temp} bi ON g.id = bi.itemid + WHERE bi.backupid = ? + AND bi.itemname = 'groupingfinal'", array(backup::VAR_BACKUPID)); + $groupinggroup->set_source_table('groupings_groups', array('groupingid' => backup::VAR_PARENTID)); + + // This only happens if we are including users + if ($userinfo) { + $member->set_source_table('groups_members', array('groupid' => backup::VAR_PARENTID)); + } } - $grouping->set_source_sql(" - SELECT g.* - FROM {groupings} g - JOIN {backup_ids_temp} bi ON g.id = bi.itemid - WHERE bi.backupid = ? - AND bi.itemname = 'groupingfinal'", array(backup::VAR_BACKUPID)); - - $groupinggroup->set_source_table('groupings_groups', array('groupingid' => backup::VAR_PARENTID)); - // Define id annotations (as final) $member->annotate_ids('userfinal', 'userid'); @@ -1241,7 +1246,7 @@ class backup_users_structure_step extends backup_structure_step { // To know if we are including role assignments $roleassignments = $this->get_setting_value('role_assignments'); - // Define each element separated + // Define each element separate. $users = new backup_nested_element('users'); diff --git a/backup/moodle2/restore_root_task.class.php b/backup/moodle2/restore_root_task.class.php index 73384df6f16..922e20394f6 100644 --- a/backup/moodle2/restore_root_task.class.php +++ b/backup/moodle2/restore_root_task.class.php @@ -249,5 +249,22 @@ class restore_root_task extends restore_task { // The restore does not process the grade histories when some activities are ignored. // So let's define a dependency to prevent false expectations from our users. $activities->add_dependency($gradehistories); + + // Define groups and groupings. + $defaultvalue = false; + $changeable = false; + if (isset($rootsettings['groups']) && $rootsettings['groups']) { // Only enabled when available. + $defaultvalue = true; + $changeable = true; + } else if (!isset($rootsettings['groups'])) { + // It is likely this is an older backup that does not contain information on the group setting, + // in which case groups should be restored and this setting can be changed. + $defaultvalue = true; + $changeable = true; + } + $groups = new restore_groups_setting('groups', base_setting::IS_BOOLEAN, $defaultvalue); + $groups->set_ui(new backup_setting_ui_checkbox($groups, get_string('rootsettinggroups', 'backup'))); + $groups->get_ui()->set_changeable($changeable); + $this->add_setting($groups); } } diff --git a/backup/moodle2/restore_settingslib.php b/backup/moodle2/restore_settingslib.php index 9568637f6fe..9c5a51c12de 100644 --- a/backup/moodle2/restore_settingslib.php +++ b/backup/moodle2/restore_settingslib.php @@ -43,6 +43,12 @@ class restore_generic_setting extends root_backup_setting {} */ class restore_users_setting extends restore_generic_setting {} +/** + * root setting to control if restore will create groups/grouping information. + * depends on @restore_users_setting + */ +class restore_groups_setting extends restore_generic_setting {} + /** * root setting to control if restore will create role assignments * or no (any level), depends of @restore_users_setting diff --git a/backup/moodle2/restore_stepslib.php b/backup/moodle2/restore_stepslib.php index d0b9a3a29d1..c8dcaa9c25e 100644 --- a/backup/moodle2/restore_stepslib.php +++ b/backup/moodle2/restore_stepslib.php @@ -937,10 +937,13 @@ class restore_groups_structure_step extends restore_structure_step { $paths = array(); // Add paths here - $paths[] = new restore_path_element('group', '/groups/group'); - $paths[] = new restore_path_element('grouping', '/groups/groupings/grouping'); - $paths[] = new restore_path_element('grouping_group', '/groups/groupings/grouping/grouping_groups/grouping_group'); - + // Do not include group/groupings information if not requested. + $groupinfo = $this->get_setting_value('groups'); + if ($groupinfo) { + $paths[] = new restore_path_element('group', '/groups/group'); + $paths[] = new restore_path_element('grouping', '/groups/groupings/grouping'); + $paths[] = new restore_path_element('grouping_group', '/groups/groupings/grouping/grouping_groups/grouping_group'); + } return $paths; } @@ -1069,7 +1072,7 @@ class restore_groups_members_structure_step extends restore_structure_step { $paths = array(); // Add paths here - if ($this->get_setting_value('users')) { + if ($this->get_setting_value('groups') && $this->get_setting_value('users')) { $paths[] = new restore_path_element('group', '/groups/group'); $paths[] = new restore_path_element('member', '/groups/group/group_members/group_member'); } diff --git a/backup/util/dbops/backup_controller_dbops.class.php b/backup/util/dbops/backup_controller_dbops.class.php index e7456ce4663..06aa4230761 100644 --- a/backup/util/dbops/backup_controller_dbops.class.php +++ b/backup/util/dbops/backup_controller_dbops.class.php @@ -574,7 +574,8 @@ abstract class backup_controller_dbops extends backup_dbops { 'backup_auto_userscompletion' => 'userscompletion', 'backup_auto_logs' => 'logs', 'backup_auto_histories' => 'grade_histories', - 'backup_auto_questionbank' => 'questionbank' + 'backup_auto_questionbank' => 'questionbank', + 'backup_auto_groups' => 'groups' ); $plan = $controller->get_plan(); foreach ($settings as $config => $settingname) { @@ -612,7 +613,8 @@ abstract class backup_controller_dbops extends backup_dbops { 'backup_general_userscompletion' => 'userscompletion', 'backup_general_logs' => 'logs', 'backup_general_histories' => 'grade_histories', - 'backup_general_questionbank' => 'questionbank' + 'backup_general_questionbank' => 'questionbank', + 'backup_general_groups' => 'groups' ); $plan = $controller->get_plan(); foreach ($settings as $config=>$settingname) { diff --git a/lang/en/backup.php b/lang/en/backup.php index 6e68819a1fc..d8fd6473ec9 100644 --- a/lang/en/backup.php +++ b/lang/en/backup.php @@ -87,6 +87,7 @@ $string['configgeneralfilters'] = 'Sets the default for including filters in a b $string['configgeneralhistories'] = 'Sets the default for including user history within a backup.'; $string['configgenerallogs'] = 'If enabled logs will be included in backups by default.'; $string['configgeneralquestionbank'] = 'If enabled the question bank will be included in backups by default. PLEASE NOTE: Disabling this setting will disable the backup of activities which use the question bank, such as the quiz.'; +$string['configgeneralgroups'] = 'Sets the default for including groups and groupings in a backup.'; $string['configgeneralroleassignments'] = 'If enabled by default roles assignments will also be backed up.'; $string['configgeneraluserscompletion'] = 'If enabled user completion information will be included in backups by default.'; $string['configgeneralusers'] = 'Sets the default for whether to include users in backups.'; @@ -138,6 +139,7 @@ $string['generalhistories'] = 'Include histories'; $string['generalgradehistories'] = 'Include histories'; $string['generallogs'] = 'Include logs'; $string['generalquestionbank'] = 'Include question bank'; +$string['generalgroups'] = 'Include groups and groupings'; $string['generalroleassignments'] = 'Include role assignments'; $string['generalsettings'] = 'General backup settings'; $string['generaluserscompletion'] = 'Include user completion information'; @@ -235,6 +237,7 @@ $string['rootsettinguserscompletion'] = 'Include user completion details'; $string['rootsettingquestionbank'] = 'Include question bank'; $string['rootsettinglogs'] = 'Include course logs'; $string['rootsettinggradehistories'] = 'Include grade history'; +$string['rootsettinggroups'] = 'Include groups and groupings'; $string['rootsettingimscc1'] = 'Convert to IMS Common Cartridge 1.0'; $string['rootsettingimscc11'] = 'Convert to IMS Common Cartridge 1.1'; $string['sitecourseformatwarning'] = 'This is a front page backup, note that they can only be restored on the front page'; diff --git a/mod/assign/backup/moodle2/restore_assign_stepslib.php b/mod/assign/backup/moodle2/restore_assign_stepslib.php index b603b49e6db..9f0e5e67827 100644 --- a/mod/assign/backup/moodle2/restore_assign_stepslib.php +++ b/mod/assign/backup/moodle2/restore_assign_stepslib.php @@ -33,6 +33,10 @@ defined('MOODLE_INTERNAL') || die(); */ class restore_assign_activity_structure_step extends restore_activity_structure_step { + // Store whether submission details should be included. Details may not be included if the + // this is a team submission, but groups/grouping information was not included in the backup. + protected $includesubmission = true; + /** * Define the structure of the restore workflow. * @@ -80,6 +84,14 @@ class restore_assign_activity_structure_step extends restore_activity_structure_ $data->timemodified = $this->apply_date_offset($data->timemodified); $data->allowsubmissionsfromdate = $this->apply_date_offset($data->allowsubmissionsfromdate); $data->duedate = $this->apply_date_offset($data->duedate); + + // If this is a team submission, but there is no group info we need to flag that the submission + // information should not be included. It should not be restored. + $groupinfo = $this->task->get_setting_value('groups'); + if ($data->teamsubmission && !$groupinfo) { + $this->includesubmission = false; + } + if (!empty($data->teamsubmissiongroupingid)) { $data->teamsubmissiongroupingid = $this->get_mappingid('grouping', $data->teamsubmissiongroupingid); @@ -120,6 +132,10 @@ class restore_assign_activity_structure_step extends restore_activity_structure_ protected function process_assign_submission($data) { global $DB; + if (!$this->includesubmission) { + return; + } + $data = (object)$data; $oldid = $data->id;