From 03c39daad8e52515cff616b59dfc7dc64f22eafd Mon Sep 17 00:00:00 2001 From: David Monllao Date: Thu, 13 Nov 2014 10:45:15 +0800 Subject: [PATCH] MDL-31500 backup: Allow front page backup/restore Removes restore on front page restrictions and allows front page modules duplication. --- backup/moodle2/backup_stepslib.php | 61 ++++++++++++++++++- backup/moodle2/restore_stepslib.php | 45 ++++++++++++++ .../dbops/backup_controller_dbops.class.php | 2 +- .../helper/backup_general_helper.class.php | 5 ++ .../helper/restore_prechecks_helper.class.php | 22 +++++-- backup/util/ui/renderer.php | 5 +- backup/util/ui/restore_ui_components.php | 6 +- course/lib.php | 3 +- lang/en/backup.php | 2 +- 9 files changed, 135 insertions(+), 16 deletions(-) diff --git a/backup/moodle2/backup_stepslib.php b/backup/moodle2/backup_stepslib.php index 84cf4de3161af..de35cc37cfbfb 100644 --- a/backup/moodle2/backup_stepslib.php +++ b/backup/moodle2/backup_stepslib.php @@ -503,6 +503,14 @@ protected function define_structure() { */ class backup_enrolments_structure_step extends backup_structure_step { + /** + * Skip enrolments on the front page. + * @return bool + */ + protected function execute_condition() { + return ($this->get_courseid() != SITEID); + } + protected function define_structure() { // To know if we are including users @@ -921,7 +929,12 @@ class backup_gradebook_structure_step extends backup_structure_step { * the module gradeitems have been already included in backup */ protected function execute_condition() { - return backup_plan_dbops::require_gradebook_backup($this->get_courseid(), $this->get_backupid()); + $courseid = $this->get_courseid(); + if ($courseid == SITEID) { + return false; + } + + return backup_plan_dbops::require_gradebook_backup($courseid, $this->get_backupid()); } protected function define_structure() { @@ -1035,7 +1048,12 @@ class backup_grade_history_structure_step extends backup_structure_step { * because we do not want to save the history of items which are not backed up. At least for now. */ protected function execute_condition() { - return backup_plan_dbops::require_gradebook_backup($this->get_courseid(), $this->get_backupid()); + $courseid = $this->get_courseid(); + if ($courseid == SITEID) { + return false; + } + + return backup_plan_dbops::require_gradebook_backup($courseid, $this->get_backupid()); } protected function define_structure() { @@ -1088,6 +1106,14 @@ protected function define_structure() { */ class backup_userscompletion_structure_step extends backup_structure_step { + /** + * Skip completion on the front page. + * @return bool + */ + protected function execute_condition() { + return ($this->get_courseid() != SITEID); + } + protected function define_structure() { // Define each element separated @@ -1617,6 +1643,7 @@ protected function define_structure() { $info['original_site_identifier_hash'] = md5(get_site_identifier()); $info['original_course_id'] = $this->get_courseid(); $originalcourseinfo = backup_controller_dbops::backup_get_original_course_info($this->get_courseid()); + $info['original_course_format'] = $originalcourseinfo->format; $info['original_course_fullname'] = $originalcourseinfo->fullname; $info['original_course_shortname'] = $originalcourseinfo->shortname; $info['original_course_startdate'] = $originalcourseinfo->startdate; @@ -1634,7 +1661,7 @@ protected function define_structure() { $information = new backup_nested_element('information', null, array( 'name', 'moodle_version', 'moodle_release', 'backup_version', 'backup_release', 'backup_date', 'mnet_remoteusers', 'include_files', 'include_file_references_to_external_content', 'original_wwwroot', - 'original_site_identifier_hash', 'original_course_id', + 'original_site_identifier_hash', 'original_course_id', 'original_course_format', 'original_course_fullname', 'original_course_shortname', 'original_course_startdate', 'original_course_contextid', 'original_system_contextid')); @@ -2102,6 +2129,12 @@ class backup_activity_grading_structure_step extends backup_structure_step { * Include the grading.xml only if the module supports advanced grading */ protected function execute_condition() { + + // No grades on the front page. + if ($this->get_courseid() == SITEID) { + return false; + } + return plugin_supports('mod', $this->get_task()->get_modulename(), FEATURE_ADVANCED_GRADING, false); } @@ -2175,6 +2208,14 @@ protected function define_structure() { */ class backup_activity_grades_structure_step extends backup_structure_step { + /** + * No grades on the front page. + * @return bool + */ + protected function execute_condition() { + return ($this->get_courseid() != SITEID); + } + protected function define_structure() { // To know if we are including userinfo @@ -2259,6 +2300,14 @@ protected function define_structure() { */ class backup_activity_grade_history_structure_step extends backup_structure_step { + /** + * No grades on the front page. + * @return bool + */ + protected function execute_condition() { + return ($this->get_courseid() != SITEID); + } + protected function define_structure() { // Settings to use. @@ -2306,6 +2355,12 @@ protected function define_structure() { class backup_course_completion_structure_step extends backup_structure_step { protected function execute_condition() { + + // No completion on front page. + if ($this->get_courseid() == SITEID) { + return false; + } + // Check that all activities have been included if ($this->task->is_excluding_activities()) { return false; diff --git a/backup/moodle2/restore_stepslib.php b/backup/moodle2/restore_stepslib.php index fc4fe154ca6a6..ee4fa9d2c83f5 100644 --- a/backup/moodle2/restore_stepslib.php +++ b/backup/moodle2/restore_stepslib.php @@ -89,6 +89,10 @@ class restore_gradebook_structure_step extends restore_structure_step { protected function execute_condition() { global $CFG, $DB; + if ($this->get_courseid() == SITEID) { + return false; + } + // No gradebook info found, don't execute $fullpath = $this->task->get_taskbasepath(); $fullpath = rtrim($fullpath, '/') . '/' . $this->filename; @@ -464,6 +468,10 @@ class restore_grade_history_structure_step extends restore_structure_step { protected function execute_condition() { global $CFG, $DB; + if ($this->get_courseid() == SITEID) { + return false; + } + // No gradebook info found, don't execute. $fullpath = $this->task->get_taskbasepath(); $fullpath = rtrim($fullpath, '/') . '/' . $this->filename; @@ -1814,9 +1822,15 @@ public function process_override($data) { * If no instances yet add default enrol methods the same way as when creating new course in UI. */ class restore_default_enrolments_step extends restore_execution_step { + public function define_execution() { global $DB; + // No enrolments in front page. + if ($this->get_courseid() == SITEID) { + return; + } + $course = $DB->get_record('course', array('id'=>$this->get_courseid()), '*', MUST_EXIST); if ($DB->record_exists('enrol', array('courseid'=>$this->get_courseid(), 'enrol'=>'manual'))) { @@ -1853,6 +1867,10 @@ class restore_enrolments_structure_step extends restore_structure_step { */ protected function execute_condition() { + if ($this->get_courseid() == SITEID) { + return false; + } + // Check it is included in the backup $fullpath = $this->task->get_taskbasepath(); $fullpath = rtrim($fullpath, '/') . '/' . $this->filename; @@ -2444,6 +2462,11 @@ protected function execute_condition() { return false; } + // No course completion on the front page. + if ($this->get_courseid() == SITEID) { + return false; + } + // Check it is included in the backup $fullpath = $this->task->get_taskbasepath(); $fullpath = rtrim($fullpath, '/') . '/' . $this->filename; @@ -2791,6 +2814,10 @@ class restore_activity_grading_structure_step extends restore_structure_step { */ protected function execute_condition() { + if ($this->get_courseid() == SITEID) { + return false; + } + $fullpath = $this->task->get_taskbasepath(); $fullpath = rtrim($fullpath, '/') . '/' . $this->filename; if (!file_exists($fullpath)) { @@ -2925,6 +2952,14 @@ protected function after_execute() { */ class restore_activity_grades_structure_step extends restore_structure_step { + /** + * No grades in front page. + * @return bool + */ + protected function execute_condition() { + return ($this->get_courseid() != SITEID); + } + protected function define_structure() { $paths = array(); @@ -3061,6 +3096,11 @@ class restore_activity_grade_history_structure_step extends restore_structure_st * This step is executed only if the grade history file is present. */ protected function execute_condition() { + + if ($this->get_courseid() == SITEID) { + return false; + } + $fullpath = $this->task->get_taskbasepath(); $fullpath = rtrim($fullpath, '/') . '/' . $this->filename; if (!file_exists($fullpath)) { @@ -3447,6 +3487,11 @@ protected function execute_condition() { return false; } + // No completion on the front page. + if ($this->get_courseid() == SITEID) { + return false; + } + // No user completion info found, don't execute $fullpath = $this->task->get_taskbasepath(); $fullpath = rtrim($fullpath, '/') . '/' . $this->filename; diff --git a/backup/util/dbops/backup_controller_dbops.class.php b/backup/util/dbops/backup_controller_dbops.class.php index 41ff9d394bdb9..e7456ce466302 100644 --- a/backup/util/dbops/backup_controller_dbops.class.php +++ b/backup/util/dbops/backup_controller_dbops.class.php @@ -524,7 +524,7 @@ public static function backup_includes_file_references($backupid) { */ public static function backup_get_original_course_info($courseid) { global $DB; - return $DB->get_record('course', array('id' => $courseid), 'fullname, shortname, startdate'); + return $DB->get_record('course', array('id' => $courseid), 'fullname, shortname, startdate, format'); } /** diff --git a/backup/util/helper/backup_general_helper.class.php b/backup/util/helper/backup_general_helper.class.php index d9ad80d5b28e5..b0425a33094b4 100644 --- a/backup/util/helper/backup_general_helper.class.php +++ b/backup/util/helper/backup_general_helper.class.php @@ -155,6 +155,11 @@ public static function get_backup_information($tempdir) { } else { $info->include_file_references_to_external_content = 0; } + // Introduced in Moodle 2.9. + $info->original_course_format = ''; + if (!empty($infoarr['original_course_format'])) { + $info->original_course_format = $infoarr['original_course_format']; + } // include_files is a new setting in 2.6. if (isset($infoarr['include_files'])) { $info->include_files = $infoarr['include_files']; diff --git a/backup/util/helper/restore_prechecks_helper.class.php b/backup/util/helper/restore_prechecks_helper.class.php index a80a80b30553f..803cd77903df5 100644 --- a/backup/util/helper/restore_prechecks_helper.class.php +++ b/backup/util/helper/restore_prechecks_helper.class.php @@ -105,10 +105,24 @@ public static function execute_prechecks(restore_controller $controller, $dropte $warnings[] = get_string('noticenewerbackup','',$message); } - // Error if restoring over frontpage - // TODO: Review the whole restore process in order to transform this into one warning (see 1.9) - if ($controller->get_courseid() == SITEID) { - $errors[] = get_string('errorrestorefrontpage', 'backup'); + // The original_course_format var was introduced in Moodle 2.9. + $originalcourseformat = null; + if (!empty($controller->get_info()->original_course_format)) { + $originalcourseformat = $controller->get_info()->original_course_format; + } + + // We can't restore other course's backups on the front page. + if ($controller->get_courseid() == SITEID && + $originalcourseformat != 'site' && + $controller->get_type() == backup::TYPE_1COURSE) { + $errors[] = get_string('errorrestorefrontpagebackup', 'backup'); + } + + // We can't restore front pages over other courses. + if ($controller->get_courseid() != SITEID && + $originalcourseformat == 'site' && + $controller->get_type() == backup::TYPE_1COURSE) { + $errors[] = get_string('errorrestorefrontpagebackup', 'backup'); } // If restoring to different site and restoring users and backup has mnet users warn/error diff --git a/backup/util/ui/renderer.php b/backup/util/ui/renderer.php index 0560c4eb49c2f..82bcf8f4fc134 100644 --- a/backup/util/ui/renderer.php +++ b/backup/util/ui/renderer.php @@ -265,7 +265,8 @@ public function course_selector(moodle_url $nextstageurl, $wholecourse = true, r $hasrestoreoption = false; $html = html_writer::start_tag('div', array('class'=>'backup-course-selector backup-restore')); - if ($wholecourse && !empty($categories) && ($categories->get_count() > 0 || $categories->get_search())) { + if ($wholecourse && !empty($categories) && ($categories->get_count() > 0 || $categories->get_search()) && + $currentcourse != SITEID) { // New course $hasrestoreoption = true; @@ -302,7 +303,7 @@ public function course_selector(moodle_url $nextstageurl, $wholecourse = true, r $html .= html_writer::end_tag('form'); } - if (!empty($courses) && ($courses->get_count() > 0 || $courses->get_search())) { + if (!empty($courses) && ($courses->get_count() > 0 || $courses->get_search()) && $currentcourse != SITEID) { // Existing course $hasrestoreoption = true; $html .= $form; diff --git a/backup/util/ui/restore_ui_components.php b/backup/util/ui/restore_ui_components.php index f892b8cf1088c..cbd4c7041f87e 100644 --- a/backup/util/ui/restore_ui_components.php +++ b/backup/util/ui/restore_ui_components.php @@ -280,13 +280,13 @@ protected function get_searchsql() { $params = array( 'contextlevel' => CONTEXT_COURSE, 'fullnamesearch' => '%'.$this->get_search().'%', - 'shortnamesearch' => '%'.$this->get_search().'%', - 'siteid' => SITEID + 'shortnamesearch' => '%'.$this->get_search().'%' ); $select = " SELECT c.id,c.fullname,c.shortname,c.visible,c.sortorder "; $from = " FROM {course} c "; - $where = " WHERE (".$DB->sql_like('c.fullname', ':fullnamesearch', false)." OR ".$DB->sql_like('c.shortname', ':shortnamesearch', false).") AND c.id <> :siteid"; + $where = " WHERE (".$DB->sql_like('c.fullname', ':fullnamesearch', false)." OR ". + $DB->sql_like('c.shortname', ':shortnamesearch', false).")"; $orderby = " ORDER BY c.sortorder"; if ($this->currentcourseid !== null && !$this->includecurrentcourse) { diff --git a/course/lib.php b/course/lib.php index cd83b66a4b902..07cd6ed218da3 100644 --- a/course/lib.php +++ b/course/lib.php @@ -2054,8 +2054,7 @@ function course_get_cm_edit_actions(cm_info $mod, $indent = -1, $sr = null) { } // Duplicate (require both target import caps to be able to duplicate and backup2 support, see modduplicate.php) - // Note that restoring on front page is never allowed. - if ($mod->course != SITEID && has_all_capabilities($dupecaps, $coursecontext) && + if (has_all_capabilities($dupecaps, $coursecontext) && plugin_supports('mod', $mod->modname, FEATURE_BACKUP_MOODLE2)) { $actions['duplicate'] = new action_menu_link_secondary( new moodle_url($baseurl, array('duplicate' => $mod->id)), diff --git a/lang/en/backup.php b/lang/en/backup.php index f2173e382893b..a449f120dfb8d 100644 --- a/lang/en/backup.php +++ b/lang/en/backup.php @@ -114,9 +114,9 @@ $string['errorfilenamerequired'] = 'You must enter a valid filename for this backup'; $string['errorfilenamemustbezip'] = 'The filename you enter must be a ZIP file and have the .mbz extension'; $string['errorminbackup20version'] = 'This backup file has been created with one development version of Moodle backup ({$a->backup}). Minimum required is {$a->min}. Cannot be restored.'; -$string['errorrestorefrontpage'] = 'Restoring over front page is not allowed.'; $string['errorinvalidformat'] = 'Unknown backup format'; $string['errorinvalidformatinfo'] = 'The selected file is not a valid Moodle backup file and can\'t be restored.'; +$string['errorrestorefrontpagebackup'] = 'You can only restore front page backups on the front page'; $string['executionsuccess'] = 'The backup file was successfully created.'; $string['filename'] = 'Filename'; $string['filealiasesrestorefailures'] = 'Aliases restore failures';