diff --git a/admin/settings/courses.php b/admin/settings/courses.php index d69b8e2719a..f9afd0a382c 100644 --- a/admin/settings/courses.php +++ b/admin/settings/courses.php @@ -26,7 +26,8 @@ $capabilities = array( 'moodle/backup:backupcourse', 'moodle/category:manage', 'moodle/course:create', - 'moodle/site:approvecourse' + 'moodle/site:approvecourse', + 'moodle/restore:restorecourse' ); if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) { // Speedup for non-admins, add all caps used on this page. @@ -42,6 +43,12 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) { array('moodle/category:manage') ) ); + $ADMIN->add('courses', + new admin_externalpage('restorecourse', new lang_string('restorecourse', 'admin'), + new moodle_url('/backup/restorefile.php', array('contextid' => context_system::instance()->id)), + array('moodle/course:create') + ) + ); // Course Default Settings Page. // NOTE: these settings must be applied after all other settings because they depend on them. diff --git a/backup/restore.php b/backup/restore.php index 6e19ef903c2..96121639d19 100644 --- a/backup/restore.php +++ b/backup/restore.php @@ -17,9 +17,17 @@ $PAGE->set_pagelayout('standard'); require_login($course, null, $cm); require_capability('moodle/restore:restorecourse', $context); +if (is_null($course)) { + $coursefullname = $SITE->fullname; + $courseshortname = $SITE->shortname; +} else { + $coursefullname = $course->fullname; + $courseshortname = $course->shortname; +} + // Show page header. -$PAGE->set_title($course->shortname . ': ' . get_string('restore')); -$PAGE->set_heading($course->fullname); +$PAGE->set_title($courseshortname . ': ' . get_string('restore')); +$PAGE->set_heading($coursefullname); $renderer = $PAGE->get_renderer('core','backup'); echo $OUTPUT->header(); diff --git a/backup/restorefile.php b/backup/restorefile.php index 1d12d0dd18a..411aeb607d7 100644 --- a/backup/restorefile.php +++ b/backup/restorefile.php @@ -61,6 +61,14 @@ switch ($context->contextlevel) { require_login($course, false, $cm); require_capability('moodle/restore:restorecourse', $context); +if (is_null($course)) { + $courseid = 0; + $coursefullname = $SITE->fullname; +} else { + $courseid = $course->id; + $coursefullname = $course->fullname; +} + $browser = get_file_browser(); // check if tmp dir exists @@ -83,7 +91,7 @@ if ($action == 'choosebackupfile') { 'pathnamehash' => $file->get_pathnamehash(), 'contenthash' => $file->get_contenthash())); } else { // If it's some weird other kind of file then use old code. - $filename = restore_controller::get_tempdir_name($course->id, $USER->id); + $filename = restore_controller::get_tempdir_name($courseid, $USER->id); $pathname = $tmpdir . '/' . $filename; $fileinfo->copy_to_pathname($pathname); $restore_url = new moodle_url('/backup/restore.php', array( @@ -98,14 +106,14 @@ if ($action == 'choosebackupfile') { $PAGE->set_url($url); $PAGE->set_context($context); -$PAGE->set_title(get_string('course') . ': ' . $course->fullname); +$PAGE->set_title(get_string('course') . ': ' . $coursefullname); $PAGE->set_heading($heading); $PAGE->set_pagelayout('admin'); $form = new course_restore_form(null, array('contextid'=>$contextid)); $data = $form->get_data(); if ($data && has_capability('moodle/restore:uploadfile', $context)) { - $filename = restore_controller::get_tempdir_name($course->id, $USER->id); + $filename = restore_controller::get_tempdir_name($courseid, $USER->id); $pathname = $tmpdir . '/' . $filename; $form->save_file('backupfile', $pathname); $restore_url = new moodle_url('/backup/restore.php', array('contextid'=>$contextid, 'filename'=>$filename)); diff --git a/course/classes/management/helper.php b/course/classes/management/helper.php index a26144ddc40..9a02d19c835 100644 --- a/course/classes/management/helper.php +++ b/course/classes/management/helper.php @@ -278,6 +278,14 @@ class helper { ); } + if ($category->can_restore_courses_into()) { + $actions['restore'] = array( + 'url' => new \moodle_url('/backup/restorefile.php', array('contextid' => $category->get_context()->id)), + 'icon' => new \pix_icon('i/restore', new \lang_string('restorecourse', 'admin')), + 'string' => new \lang_string('restorecourse', 'admin') + ); + } + return $actions; } diff --git a/lang/en/admin.php b/lang/en/admin.php index 45f45273304..7975646d88e 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -920,6 +920,7 @@ $string['purgecaches']= 'Purge all caches'; $string['purgecachesconfirm']= 'Moodle can cache themes, javascript, language strings, filtered text, rss feeds and many other pieces of calculated data. Purging these caches will delete that data from the server and force browsers to refetch data, so that you can be sure you are seeing the most up-to-date values produced by the current code. There is no danger in purging caches, but your site may appear slower for a while until the server and clients calculate new information and cache it.'; $string['purgecachesfinished']= 'All caches were purged.'; $string['requestcategoryselection'] = 'Enable category selection'; +$string['restorecourse'] = 'Restore course'; $string['restorernewroleid'] = 'Restorers\' role in courses'; $string['restorernewroleid_help'] = 'If the user does not already have the permission to manage the newly restored course, the user is automatically assigned this role and enrolled if necessary. Select "None" if you do not want restorers to be able to manage every restored course.'; $string['reverseproxy'] = 'Reverse proxy'; diff --git a/lib/coursecatlib.php b/lib/coursecatlib.php index 9323ea57f16..078659a0b93 100644 --- a/lib/coursecatlib.php +++ b/lib/coursecatlib.php @@ -2395,6 +2395,14 @@ class coursecat implements renderable, cacheable_object, IteratorAggregate { return $this->has_manage_capability(); } + /** + * Returns true if the user is able to restore a course into this category as a new course. + * @return bool + */ + public function can_restore_courses_into() { + return has_capability('moodle/course:create', $this->get_context()); + } + /** * Resorts the sub categories of this category by the given field. *