forked from moodle/moodle
-
Notifications
You must be signed in to change notification settings - Fork 0
/
import.php
214 lines (179 loc) · 8.35 KB
/
import.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
<?php
// Require both the backup and restore libs
require_once('../config.php');
require_once($CFG->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);
// We just want to check if a search has been run. True if anything is there.
$searchcourses = optional_param('searchcourses', false, PARAM_BOOL);
// 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 = context_course::instance($courseid);
// Must pass login
require_login($course);
// Must hold restoretargetimport in the current course
require_capability('moodle/restore:restoretargetimport', $context);
// Set up the page
$PAGE->set_title($course->shortname . ': ' . get_string('import'));
$PAGE->set_heading($course->fullname);
$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 || $searchcourses) {
// 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 = context_course::instance($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_IMPORT, $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) {
echo $OUTPUT->header();
// Display an extra progress bar so that we can show the current stage.
echo html_writer::start_div('', array('id' => 'executionprogress'));
echo $renderer->progress_bar($backup->get_progress_bar());
// Start the progress display - we split into 2 chunks for backup and restore.
$progress = new \core\progress\display();
$progress->start_progress('', 2);
$backup->get_controller()->set_progress($progress);
// Prepare logger for backup.
$logger = new core_backup_html_logger($CFG->debugdeveloper ? backup::LOG_DEBUG : backup::LOG_INFO);
$backup->get_controller()->add_logger($logger);
// First execute the backup
$backup->execute();
$backup->destroy();
unset($backup);
// Note that we've done that progress.
$progress->progress(1);
// Check whether the backup directory still exists. If missing, something
// went really wrong in backup, throw error. Note that backup::MODE_IMPORT
// backups don't store resulting files ever
$tempdestination = $CFG->tempdir . '/backup/' . $backupid;
if (!file_exists($tempdestination) || !is_dir($tempdestination)) {
print_error('unknownbackupexporterror'); // shouldn't happen ever
}
// 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_IMPORT, $USER->id, $restoretarget);
// Start a progress section for the restore, which will consist of 2 steps
// (the precheck and then the actual restore).
$progress->start_progress('Restore process', 2);
$rc->set_progress($progress);
// Set logger for restore.
$rc->add_logger($logger);
// 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
$warnings = false;
if (!$rc->execute_precheck()) {
$precheckresults = $rc->get_precheck_results();
if (is_array($precheckresults)) {
if (!empty($precheckresults['errors'])) { // If errors are found, terminate the import.
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();
}
if (!empty($precheckresults['warnings'])) { // If warnings are found, go ahead but display warnings later.
$warnings = $precheckresults['warnings'];
}
}
}
if ($restoretarget == backup::TARGET_CURRENT_DELETING || $restoretarget == backup::TARGET_EXISTING_DELETING) {
restore_dbops::delete_course_content($course->id);
}
// Execute the restore.
$rc->execute_plan();
// Delete the temp directory now
fulldelete($tempdestination);
// End restore section of progress tracking (restore/precheck).
$progress->end_progress();
// All progress complete. Hide progress area.
$progress->end_progress();
echo html_writer::end_div();
echo html_writer::script('document.getElementById("executionprogress").style.display = "none";');
// Display a notification and a continue button
if ($warnings) {
echo $OUTPUT->box_start();
echo $OUTPUT->notification(get_string('warning'), 'notifyproblem');
echo html_writer::start_tag('ul', array('class'=>'list'));
foreach ($warnings as $warning) {
echo html_writer::tag('li', $warning);
}
echo html_writer::end_tag('ul');
echo $OUTPUT->box_end();
}
echo $OUTPUT->notification(get_string('importsuccess', 'backup'), 'notifysuccess');
echo $OUTPUT->continue_button(new moodle_url('/course/view.php', array('id'=>$course->id)));
// Get and display log data if there was any.
$loghtml = $logger->get_html();
if ($loghtml != '') {
echo $renderer->log_display($loghtml);
}
echo $OUTPUT->footer();
die();
} else {
// Otherwise save the controller and progress
$backup->save_controller();
}
// Display the current stage
echo $OUTPUT->header();
if ($backup->enforce_changed_dependencies()) {
debugging('Your settings have been altered due to unmet dependencies', DEBUG_DEVELOPER);
}
echo $renderer->progress_bar($backup->get_progress_bar());
echo $backup->display($renderer);
$backup->destroy();
unset($backup);
echo $OUTPUT->footer();