diff --git a/backup/import.php b/backup/import.php new file mode 100644 index 00000000000..35e77847baf --- /dev/null +++ b/backup/import.php @@ -0,0 +1,159 @@ +dirroot . '/backup/util/includes/backup_includes.php'); +require_once($CFG->dirroot . '/backup/moodle2/backup_plan_builder.class.php'); +require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php'); +require_once($CFG->dirroot . '/backup/util/ui/import_extensions.php'); + +// The courseid we are importing to +$courseid = required_param('id', PARAM_INT); +// The id of the course we are importing FROM (will only be set if past first stage +$importcourseid = optional_param('importid', false, PARAM_INT); +// The target method for the restore (adding or deleting) +$restoretarget = optional_param('target', backup::TARGET_CURRENT_ADDING, PARAM_INT); + +// Load the course and context +$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST); +$context = get_context_instance(CONTEXT_COURSE, $courseid); + +// Must pass login +require_login($course); +// Must hold restoretargetimport in the current course +require_capability('moodle/restore:restoretargetimport', $context); + +$heading = get_string('import'); + +// Set up the page +$PAGE->set_title($heading); +$PAGE->set_heading($heading); +$PAGE->set_url(new moodle_url('/backup/import.php', array('id'=>$courseid))); +$PAGE->set_context($context); +$PAGE->set_pagelayout('incourse'); + +// Prepare the backup renderer +$renderer = $PAGE->get_renderer('core','backup'); + +// Check if we already have a import course id +if ($importcourseid === false) { + // Obviously not... show the selector so one can be chosen + $url = new moodle_url('/backup/import.php', array('id'=>$courseid)); + $search = new import_course_search(array('url'=>$url)); + + // show the course selector + echo $OUTPUT->header(); + echo $renderer->import_course_selector($url, $search); + echo $OUTPUT->footer(); + die(); +} + +// Load the course +context to import from +$importcourse = $DB->get_record('course', array('id'=>$importcourseid), '*', MUST_EXIST); +$importcontext = get_context_instance(CONTEXT_COURSE, $importcourseid); + +// Make sure the user can backup from that course +require_capability('moodle/backup:backuptargetimport', $importcontext); + +// Attempt to load the existing backup controller (backupid will be false if there isn't one) +$backupid = optional_param('backup', false, PARAM_ALPHANUM); +if (!($bc = backup_ui::load_controller($backupid))) { + $bc = new backup_controller(backup::TYPE_1COURSE, $importcourse->id, backup::FORMAT_MOODLE, + backup::INTERACTIVE_YES, backup::MODE_GENERAL, $USER->id); + $bc->get_plan()->get_setting('users')->set_status(backup_setting::LOCKED_BY_CONFIG); + $settings = $bc->get_plan()->get_settings(); + + // For the initial stage we want to hide all locked settings and if there are + // no visible settings move to the next stage + $visiblesettings = false; + foreach ($settings as $setting) { + if ($setting->get_status() !== backup_setting::NOT_LOCKED) { + $setting->set_visibility(backup_setting::HIDDEN); + } else { + $visiblesettings = true; + } + } + import_ui::skip_current_stage(!$visiblesettings); +} + +// Prepare the import UI +$backup = new import_ui($bc, array('importid'=>$importcourse->id, 'target'=>$restoretarget)); +// Process the current stage +$backup->process(); + +// If this is the confirmation stage remove the filename setting +if ($backup->get_stage() == backup_ui::STAGE_CONFIRMATION) { + $backup->get_setting('filename')->set_visibility(backup_setting::HIDDEN); +} + +// If it's the final stage process the import +if ($backup->get_stage() == backup_ui::STAGE_FINAL) { + // First execute the backup + $backup->execute(); + + // Check whether the backup directory still exists and if it doesn't extract the + // backup file so that we have it + $tempdestination = $CFG->dataroot . '/temp/backup/' . $backupid; + if (!file_exists($tempdestination) || !is_dir($tempdestination)) { + $results = $backup->get_controller()->get_results(); + $file = $results['backup_destination']; + $file->extract_to_pathname(get_file_packer($file->get_mimetype()), $tempdestination); + } + // Delete the backup file, we only want the directory + $results['backup_destination']->delete(); + + // Prepare the restore controller. We don't need a UI here as we will just use what + // ever the restore has (the user has just chosen). + $rc = new restore_controller($backupid, $course->id, backup::INTERACTIVE_YES, backup::MODE_GENERAL, $USER->id, $restoretarget); + // Convert the backup if required.... it should NEVER happed + if ($rc->get_status() == backup::STATUS_REQUIRE_CONV) { + $rc->convert(); + } + // Mark the UI finished. + $rc->finish_ui(); + // Execute prechecks + if (!$rc->execute_precheck()) { + $precheckresults = $rc->get_precheck_results(); + if (is_array($precheckresults) && !empty($precheckresults['errors'])) { + fulldelete($tempdestination); + + echo $OUTPUT->header(); + echo $renderer->precheck_notices($precheckresults); + echo $OUTPUT->continue_button(new moodle_url('/course/view.php', array('id'=>$course->id))); + echo $OUTPUT->footer(); + die(); + } + } else { + // Execute the restore + $rc->execute_plan(); + } + + // Delete the temp directory now + fulldelete($tempdestination); + + // Display a notification and a continue button + echo $OUTPUT->header(); + echo $OUTPUT->notification(get_string('importsuccess', 'backup'),'notifysuccess'); + echo $OUTPUT->continue_button(new moodle_url('/course/view.php', array('id'=>$course->id))); + echo $OUTPUT->footer(); + + die(); + +} else { + // Otherwise save the controller and progress + $backup->save_controller(); +} + +// Adjust the page for the stage +$PAGE->set_title($heading.': '.$backup->get_stage_name()); +$PAGE->set_heading($heading.': '.$backup->get_stage_name()); +$PAGE->navbar->add($backup->get_stage_name()); + +// Display the current stage +echo $OUTPUT->header(); +if ($backup->enforce_changed_dependencies()) { + echo $renderer->dependency_notification(get_string('dependenciesenforced','backup')); +} +echo $renderer->progress_bar($backup->get_progress_bar()); +echo $backup->display(); +echo $OUTPUT->footer(); \ No newline at end of file diff --git a/backup/restore.php b/backup/restore.php index 313e6b2bbdc..084ab1f05c6 100644 --- a/backup/restore.php +++ b/backup/restore.php @@ -17,8 +17,6 @@ $PAGE->set_pagelayout('standard'); require_login($course, null, $cm); require_capability('moodle/restore:restorecourse', $context); -$isfrontpage = ($course->id == SITEID); - if ($stage & restore_ui::STAGE_CONFIRM + restore_ui::STAGE_DESTINATION) { $restore = restore_ui::engage_independent_stage($stage, $contextid); } else { diff --git a/backup/util/ui/backup_ui.class.php b/backup/util/ui/backup_ui.class.php index 01435dffbb9..70c7166785e 100644 --- a/backup/util/ui/backup_ui.class.php +++ b/backup/util/ui/backup_ui.class.php @@ -42,6 +42,12 @@ class backup_ui extends base_ui { const STAGE_FINAL = 8; const STAGE_COMPLETE = 16; + /** + * If set to true the current stage is skipped. + * @var bool + */ + protected static $skipcurrentstage = false; + /** * Intialises what ever stage is requested. If none are requested we check * params for 'stage' and default to initial @@ -53,6 +59,9 @@ class backup_ui extends base_ui { if ($stage == null) { $stage = optional_param('stage', self::STAGE_INITIAL, PARAM_INT); } + if (self::$skipcurrentstage) { + $stage *= 2; + } switch ($stage) { case backup_ui::STAGE_INITIAL: $stage = new backup_ui_stage_initial($this, $params); @@ -72,6 +81,10 @@ class backup_ui extends base_ui { } return $stage; } + /** + * Returns the backup id + * @return string + */ public function get_uniqueid() { return $this->get_backupid(); } @@ -150,22 +163,40 @@ class backup_ui extends base_ui { $classes[] = 'backup_stage_complete'; } $item = array('text' => strlen(decbin($stage)).'. '.get_string('currentstage'.$stage, 'backup'),'class' => join(' ', $classes)); - if ($stage < $currentstage && $currentstage < self::STAGE_COMPLETE) { - $item['link'] = new moodle_url($PAGE->url, array('backup'=>$this->get_backupid(), 'stage'=>$stage)); + if ($stage < $currentstage && $currentstage < self::STAGE_COMPLETE && (!self::$skipcurrentstage || ($stage*2) != $currentstage)) { + $params = $this->stage->get_params(); + if (empty($params)) { + $params = array(); + } + $params = array_merge($params, array('backup'=>$this->get_backupid(), 'stage'=>$stage)); + $item['link'] = new moodle_url($PAGE->url, $params); } array_unshift($items, $item); $stage = floor($stage/2); } return $items; } - + /** + * Gets the name related to the operation of this UI + * @return string + */ public function get_name() { return 'backup'; } - + /** + * Gets the id of the first stage this UI is reponsible for + * @return int + */ public function get_first_stage_id() { return self::STAGE_INITIAL; } + /** + * If called with default arg the current stage gets skipped. + * @static + */ + public static function skip_current_stage($setting=true) { + self::$skipcurrentstage = $setting; + } } /** diff --git a/backup/util/ui/base_moodleform.class.php b/backup/util/ui/base_moodleform.class.php index d483f488853..3b88377bd2e 100644 --- a/backup/util/ui/base_moodleform.class.php +++ b/backup/util/ui/base_moodleform.class.php @@ -257,4 +257,49 @@ abstract class base_moodleform extends moodleform { public function is_cancelled() { return (optional_param('cancel', false, PARAM_BOOL) || parent::is_cancelled()); } + + /** + * Removes an element from the form if it exists + * @param string $elementName + * @return bool + */ + public function remove_element($elementName) { + if ($this->_form->elementExists($elementname)) { + return $this->_form->removeElement($elementName); + } else { + return false; + } + } + + /** + * Gets an element from the form if it exists + * + * @param string $elementname + * @return HTML_QuickForm_input|MoodleQuickForm_group + */ + public function get_element($elementname) { + if ($this->_form->elementExists($elementname)) { + return $this->_form->getElement($elementname); + } else { + return false; + } + } + + /** + * Displays the form + */ + public function display() { + $this->require_definition_after_data(); + parent::display(); + } + + /** + * Ensures the the definition after data is loaded + */ + public function require_definition_after_data() { + if (!$this->_definition_finalized) { + $this->_definition_finalized = true; + $this->definition_after_data(); + } + } } \ No newline at end of file diff --git a/backup/util/ui/import_extensions.php b/backup/util/ui/import_extensions.php new file mode 100644 index 00000000000..b4f9068dc49 --- /dev/null +++ b/backup/util/ui/import_extensions.php @@ -0,0 +1,161 @@ +. + +/** + * This file contains extension of the backup classes that override some methods + * and functionality in order to customise the backup UI for the purposes of + * import. + * + * @package moodlecore + * @copyright 2010 Sam Hemelryk + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * Import UI class + */ +class import_ui extends backup_ui { + /** + * Customises the backup progress bar + * + * @global moodle_page $PAGE + * @return array + */ + public function get_progress_bar() { + global $PAGE; + $stage = self::STAGE_COMPLETE; + $currentstage = $this->stage->get_stage(); + $items = array(); + while ($stage > 0) { + $classes = array('backup_stage'); + if (floor($stage/2) == $currentstage) { + $classes[] = 'backup_stage_next'; + } else if ($stage == $currentstage) { + $classes[] = 'backup_stage_current'; + } else if ($stage < $currentstage) { + $classes[] = 'backup_stage_complete'; + } + $item = array('text' => strlen(decbin($stage*2)).'. '.get_string('importcurrentstage'.$stage, 'backup'),'class' => join(' ', $classes)); + if ($stage < $currentstage && $currentstage < self::STAGE_COMPLETE && (!self::$skipcurrentstage || $stage*2 != $currentstage)) { + $item['link'] = new moodle_url($PAGE->url, $this->stage->get_params() + array('backup'=>$this->get_backupid(), 'stage'=>$stage)); + } + array_unshift($items, $item); + $stage = floor($stage/2); + } + $selectorlink = new moodle_url($PAGE->url, $this->stage->get_params()); + $selectorlink->remove_params('importid'); + array_unshift($items, array( + 'text' => '1. '.get_string('importcurrentstage0', 'backup'), + 'class' => join(' ', $classes), + 'link' => $selectorlink)); + return $items; + } + + /** + * Intialises what ever stage is requested. If none are requested we check + * params for 'stage' and default to initial + * + * @param int|null $stage The desired stage to intialise or null for the default + * @return backup_ui_stage_initial|backup_ui_stage_schema|backup_ui_stage_confirmation|backup_ui_stage_final + */ + protected function initialise_stage($stage = null, array $params=null) { + if ($stage == null) { + $stage = optional_param('stage', self::STAGE_INITIAL, PARAM_INT); + } + if (self::$skipcurrentstage) { + $stage *= 2; + } + switch ($stage) { + case backup_ui::STAGE_INITIAL: + $stage = new import_ui_stage_inital($this, $params); + break; + case backup_ui::STAGE_SCHEMA: + $stage = new import_ui_stage_schema($this, $params); + break; + case backup_ui::STAGE_CONFIRMATION: + $stage = new import_ui_stage_confirmation($this, $params); + break; + case backup_ui::STAGE_FINAL: + $stage = new import_ui_stage_final($this, $params); + break; + default: + $stage = false; + break; + } + return $stage; + } +} + +/** + * Extends the initial stage + */ +class import_ui_stage_inital extends backup_ui_stage_initial {} + +/** + * Extends the schema stage + */ +class import_ui_stage_schema extends backup_ui_stage_schema {} + +/** + * Extends the confirmation stage. + * + * This overides the initialise stage form to remove the filenamesetting heading + * as it is always hidden. + */ +class import_ui_stage_confirmation extends backup_ui_stage_confirmation { + + /** + * Initialises the stages moodleform + * @return moodleform + */ + protected function initialise_stage_form() { + $form = parent::initialise_stage_form(); + $form->remove_element('filenamesetting'); + return $form; + } + + /** + * Displays the stage + * + * This function is overriden so that we can manipulate the strings on the + * buttons. + */ + public function display() { + $form = $this->initialise_stage_form(); + $form->require_definition_after_data(); + if ($e = $form->get_element('submitbutton')) { + $e->setLabel(get_string('import'.$this->get_ui()->get_name().'stage'.$this->get_stage().'action', 'backup')); + } else { + $elements = $form->get_element('buttonar')->getElements(); + foreach ($elements as &$element) { + if ($element->getName()=='submitbutton') { + $element->setValue(get_string('import'.$this->get_ui()->get_name().'stage'.$this->get_stage().'action', 'backup')); + } + } + } + $form->display(); + } +} +/** + * Overrides the final stage. + */ +class import_ui_stage_final extends backup_ui_stage_final {} + +/** + * Extends the restore course search to search for import courses. + */ +class import_course_search extends restore_course_search {} \ No newline at end of file diff --git a/backup/util/ui/renderer.php b/backup/util/ui/renderer.php index 65a89505def..47995eb37ac 100644 --- a/backup/util/ui/renderer.php +++ b/backup/util/ui/renderer.php @@ -64,6 +64,13 @@ class core_backup_renderer extends plugin_renderer_base { return html_writer::tag('div', $message, array('class'=>'notification dependencies_enforced')); } + /** + * Displays the details of a backup file + * + * @param stdClass $details + * @param moodle_url $nextstageurl + * @return string + */ public function backup_details($details, $nextstageurl) { $yestick = $this->output->pix_icon('i/tick_green_big', get_string('yes')); $notick = $this->output->pix_icon('i/cross_red_big', get_string('no')); @@ -146,7 +153,17 @@ class core_backup_renderer extends plugin_renderer_base { return $html; } - public function course_selector(moodle_url $nextstageurl, $details, $categories, restore_course_search $courses=null, $currentcourse = null) { + /** + * Displays a course selector for restore + * + * @param moodle_url $nextstageurl + * @param stdClass $details + * @param restore_category_search $categories + * @param restore_course_search $courses + * @param int $currentcourse + * @return string + */ + public function course_selector(moodle_url $nextstageurl, $details, restore_category_search $categories = null, restore_course_search $courses=null, $currentcourse = null) { global $CFG; require_once($CFG->dirroot.'/course/lib.php'); @@ -172,7 +189,7 @@ class core_backup_renderer extends plugin_renderer_base { $html .= html_writer::end_tag('form'); } - if ($categories->get_resultscount() > 0 || $categories->get_search() == '') { + if (!empty($categories) && ($categories->get_resultscount() > 0 || $categories->get_search() == '')) { // New course $html .= $form; $html .= html_writer::start_tag('div', array('class'=>'bcs-new-course backup-section')); @@ -185,7 +202,7 @@ class core_backup_renderer extends plugin_renderer_base { $html .= html_writer::end_tag('form'); } - if ($courses->get_resultscount() > 0 || $courses->get_search() == '') { + if (!empty($courses) && ($courses->get_resultscount() > 0 || $courses->get_search() == '')) { // Existing course $html .= $form; $html .= html_writer::start_tag('div', array('class'=>'bcs-existing-course backup-section')); @@ -202,6 +219,39 @@ class core_backup_renderer extends plugin_renderer_base { return $html; } + /** + * Displays the import course selector + * + * @param moodle_url $nextstageurl + * @param import_course_search $courses + * @return string + */ + public function import_course_selector(moodle_url $nextstageurl, import_course_search $courses=null) { + $html = html_writer::start_tag('div', array('class'=>'import-course-selector backup-restore')); + $html .= html_writer::start_tag('form', array('method'=>'post', 'action'=>$nextstageurl->out_omit_querystring())); + foreach ($nextstageurl->params() as $key=>$value) { + $html .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>$key, 'value'=>$value)); + } + $html .= html_writer::start_tag('div', array('class'=>'ics-existing-course backup-section')); + $html .= $this->output->heading(get_string('importdatafrom'), 2, array('class'=>'header')); + $html .= $this->backup_detail_input(get_string('importadding', 'backup'), 'radio', 'target', backup::TARGET_CURRENT_ADDING, array('checked'=>'checked'), get_string('importaddingdesc', 'backup')); + $html .= $this->backup_detail_input(get_string('importdeleting', 'backup'), 'radio', 'target', backup::TARGET_CURRENT_DELETING, array(), get_string('importdeletingdesc', 'backup')); + $html .= $this->backup_detail_pair(get_string('selectacourse', 'backup'), $this->render($courses)); + $html .= $this->backup_detail_pair('', html_writer::empty_tag('input', array('type'=>'submit', 'value'=>get_string('continue')))); + $html .= html_writer::end_tag('div'); + $html .= html_writer::end_tag('form'); + $html .= html_writer::end_tag('div'); + return $html; + } + + /** + * Creates a detailed pairing (key + value) + * + * @staticvar int $count + * @param string $label + * @param string $value + * @return string + */ protected function backup_detail_pair($label, $value) { static $count= 0; $count++; @@ -212,6 +262,17 @@ class core_backup_renderer extends plugin_renderer_base { return $html; } + /** + * Created a detailed pairing with an input + * + * @param string $label + * @param string $type + * @param string $name + * @param string $value + * @param array $attributes + * @param string|null $description + * @return string + */ protected function backup_detail_input($label, $type, $name, $value, array $attributes=array(), $description=null) { if (!empty ($description)) { $description = html_writer::tag('span', $description, array('class'=>'description')); @@ -221,6 +282,18 @@ class core_backup_renderer extends plugin_renderer_base { return $this->backup_detail_pair($label, html_writer::empty_tag('input', $attributes+array('name'=>$name, 'type'=>$type, 'value'=>$value)).$description); } + /** + * Creates a detailed pairing with a select + * + * @param string $label + * @param string $name + * @param array $options + * @param string $selected + * @param bool $nothing + * @param array $attributes + * @param string|null $description + * @return string + */ protected function backup_detail_select($label, $name, $options, $selected='', $nothing=false, array $attributes=array(), $description=null) { if (!empty ($description)) { $description = html_writer::tag('span', $description, array('class'=>'description')); @@ -230,6 +303,12 @@ class core_backup_renderer extends plugin_renderer_base { return $this->backup_detail_pair($label, html_writer::select($options, $name, $selected, false, $attributes).$description); } + /** + * Displays precheck notices + * + * @param array $results + * @return string + */ public function precheck_notices($results) { $output = html_writer::start_tag('div', array('class'=>'restore-precheck-notices')); if (array_key_exists('errors', $results)) { @@ -245,6 +324,12 @@ class core_backup_renderer extends plugin_renderer_base { return $output.html_writer::end_tag('div'); } + /** + * Displays substage buttons + * + * @param bool $haserrors + * @return string + */ public function substage_buttons($haserrors) { $output = html_writer::start_tag('div', array('continuebutton')); if (!$haserrors) { @@ -255,6 +340,13 @@ class core_backup_renderer extends plugin_renderer_base { return $output; } + /** + * Displays a role mapping interface + * + * @param array $rolemappings + * @param array $roles + * @return string + */ public function role_mappings($rolemappings, $roles) { $roles[0] = get_string('none'); $output = html_writer::start_tag('div', array('class'=>'restore-rolemappings')); @@ -269,6 +361,13 @@ class core_backup_renderer extends plugin_renderer_base { return $output; } + /** + * Displays a continue button + * + * @param string|moodle_url $url + * @param string $method + * @return string + */ public function continue_button($url, $method='post') { if (!($url instanceof moodle_url)) { $url = new moodle_url($url); @@ -291,6 +390,13 @@ class core_backup_renderer extends plugin_renderer_base { return $this->render($tree); } + /** + * Displays a backup files viewer + * + * @global stdClass $USER + * @param backup_files_viewer $tree + * @return string + */ public function render_backup_files_viewer(backup_files_viewer $tree) { global $USER; $user_context = get_context_instance(CONTEXT_USER, $USER->id); @@ -337,6 +443,12 @@ class core_backup_renderer extends plugin_renderer_base { return $html; } + /** + * Renders a restore course search object + * + * @param restore_course_search $component + * @return string + */ public function render_restore_course_search(restore_course_search $component) { $url = $component->get_url(); @@ -386,6 +498,67 @@ class core_backup_renderer extends plugin_renderer_base { return $output; } + /** + * Renders an import course search object + * + * @param import_course_search $component + * @return string + */ + public function render_import_course_search(import_course_search $component) { + $url = $component->get_url(); + + $output = html_writer::start_tag('div', array('class' => 'import-course-search')); + if ($component->get_totalcount() === 0) { + $output .= $this->output->notification(get_string('nomatchingcourses', 'backup')); + $output .= html_writer::end_tag('div'); + return $output; + } + + $output .= html_writer::tag('div', get_string('totalcoursesearchresults', 'backup', $component->get_totalcount()), array('class'=>'ics-totalresults')); + + $output .= html_writer::start_tag('div', array('class' => 'ics-results')); + if ($component->get_totalpages()>1) { + $pagingbar = new paging_bar($component->get_totalcount(), $component->get_page(), $component->get_pagelimit(), new moodle_url($url, array('searchcourses'=>1)), restore_course_search::$VAR_PAGE); + $output .= $this->output->render($pagingbar); + } + + $table = new html_table(); + $table->head = array('', get_string('shortname'), get_string('fullname')); + $table->data = array(); + foreach ($component->get_results() as $course) { + $row = new html_table_row(); + $row->attributes['class'] = 'ics-course'; + if (!$course->visible) { + $row->attributes['class'] .= ' dimmed'; + } + $row->cells = array( + html_writer::empty_tag('input', array('type'=>'radio', 'name'=>'importid', 'value'=>$course->id)), + $course->shortname, + $course->fullname + ); + $table->data[] = $row; + } + $output .= html_writer::table($table); + if (isset($pagingbar)) { + $output .= $this->output->render($pagingbar); + } + $output .= html_writer::end_tag('div'); + + $output .= html_writer::start_tag('div', array('class'=>'ics-search')); + $output .= html_writer::empty_tag('input', array('type'=>'text', 'name'=>restore_course_search::$VAR_SEARCH, 'value'=>$component->get_search())); + $output .= html_writer::empty_tag('input', array('type'=>'submit', 'name'=>'searchcourses', 'value'=>get_string('search'))); + $output .= html_writer::end_tag('div'); + + $output .= html_writer::end_tag('div'); + return $output; + } + + /** + * Renders a restore category search object + * + * @param restore_category_search $component + * @return string + */ public function render_restore_category_search(restore_category_search $component) { $url = $component->get_url(); diff --git a/lang/en/backup.php b/lang/en/backup.php index 73d9209f855..08f7f3fd0b3 100644 --- a/lang/en/backup.php +++ b/lang/en/backup.php @@ -88,6 +88,22 @@ $string['generaluserscompletion'] = 'Include user completion information'; $string['generaluserfiles'] = 'Include user files'; $string['generalusers'] = 'Include users'; $string['importfile'] = 'Import a backup file'; +$string['importadding'] = 'Import adding'; +$string['importaddingdesc'] = 'Merge the selected course into this course'; +$string['importbackupstage1action'] = 'Next'; +$string['importbackupstage2action'] = 'Next'; +$string['importbackupstage4action'] = 'Perform import'; +$string['importbackupstage8action'] = 'Continue'; +$string['importbackupstage16action'] = 'Continue'; +$string['importcurrentstage0'] = 'Course selection'; +$string['importcurrentstage1'] = 'Initial settings'; +$string['importcurrentstage2'] = 'Schema settings'; +$string['importcurrentstage4'] = 'Confirmation and review'; +$string['importcurrentstage8'] = 'Perform import'; +$string['importcurrentstage16'] = 'Complete'; +$string['importdeleting'] = 'Import deleting'; +$string['importdeletingdesc'] = 'Delete the contents of this course and then import the selected course'; +$string['importsuccess'] = 'Import complete. Click continue to return to the course.'; $string['includeactivities'] = 'Choose activities to include'; $string['includesection'] = 'Include section {$a}'; $string['includeuserinfo'] = 'Include user information'; diff --git a/lib/navigationlib.php b/lib/navigationlib.php index 98778114535..d09f7a08a6d 100644 --- a/lib/navigationlib.php +++ b/lib/navigationlib.php @@ -1516,13 +1516,15 @@ class global_navigation extends navigation_node { if (!$issitecourse) { // Not the current user so add it to the participants node for the current course $usersnode = $coursenode->get('participants', navigation_node::TYPE_CONTAINER); + $userviewurl = new moodle_url('/user/view.php', $baseargs); } else { // This is the site so add a users node to the root branch $usersnode = $this->rootnodes['users']; $usersnode->action = new moodle_url('/user/index.php', array('id'=>$course->id)); + $userviewurl = new moodle_url('/user/profile.php', $baseargs); } // Add a branch for the current user - $usernode = $usersnode->add(fullname($user, true), null, self::TYPE_USER, null, $user->id); + $usernode = $usersnode->add(fullname($user, true), $userviewurl, self::TYPE_USER, null, $user->id); if ($this->page->context->contextlevel == CONTEXT_USER && $user->id == $this->page->context->instanceid) { $usernode->make_active(); @@ -2855,8 +2857,7 @@ class settings_navigation extends navigation_node { // Import data from other courses if (has_capability('moodle/restore:restoretargetimport', $coursecontext)) { - $url = new moodle_url('/course/import.php', array('id'=>$course->id)); - $url = null; // Disabled until restore is implemented. MDL-21432 + $url = new moodle_url('/backup/import.php', array('id'=>$course->id)); $coursenode->add(get_string('import'), $url, self::TYPE_SETTING, null, 'import', new pix_icon('i/restore', '')); }