MDL-22164 backup - clean important parts of old code. Leaving rest for reference
[moodle.git] / backup / restore_check.html
1 <?php
3     //This page receive all the restore_form data. Then, if existing course
4     //has been selected, shows a list of courses to select one.
5     //It cheks that the parammeter from restore_form are coherent.
6     //It puts all the restore info in the session.
7     //Finally, it calls restore_execute to do the hard work
8     //Get objects from session
10     global $DB, $OUTPUT;
12     if ($SESSION) {
13         $info = $SESSION->info;
14         $course_header = $SESSION->course_header;
15         if (isset($SESSION->restore)) {
16             $restore = $SESSION->restore;
17         }
18     }
20     //Detect if we are coming from the restore form
21     $fromform = optional_param ('fromform', 0, PARAM_INT);
23     ///Enforce SESSION->course_header rewrite (PHP 4.x needed because assigns are by value) MDL-8298
24     $SESSION->course_header = $course_header;
26     //If restore session info exists, but we are coming from the form
27     //it has prioriry
28     if (isset($restore) and !empty($fromform)) {
29         unset($restore);
30     }
32     // check for session objects
33     if (empty($info) or empty($course_header)) {
34       print_error('sessionmissing', 'debug', '',
35               'info and course_header');
36     }
39     //If the restore object doesn't exist, we are going
40     //to check every variable individually and create it
42     if (!isset($restore)) {
43         //Check that we have all we need
44         //backup_unique_code
45         $backup_unique_code = required_param('backup_unique_code', PARAM_INT);
46         //file
47         $file = required_param('file', PARAM_PATH);
48         //Checks for the required restoremod parameters
49         if ($allmods = $DB->get_records("modules")) {
50             foreach ($allmods as $mod) {
51                 $modname = $mod->name;
52                 $var = "restore_".$modname;
53                 $$var = optional_param( $var,0, PARAM_CLEAN);
54                 $var = "restore_user_info_".$modname;
55                 $$var = optional_param( $var,0, PARAM_CLEAN);
56                 $instances = !empty($info->mods[$mod->name]->instances) ? $info->mods[$mod->name]->instances : NULL;
57                 if ($instances === NULL) {
58                     continue;
59                 }
60                 foreach ($instances as $instance) {
61                     $var = 'restore_'.$modname.'_instance_'.$instance->id;
62                     $$var = optional_param($var,0,PARAM_INT);
63                     $var = 'restore_user_info_'.$modname.'_instance_'.$instance->id;
64                     $$var = optional_param($var,0,PARAM_INT);
65                 }
66             }
67         }
68         //restoreto
69         $restore_restoreto = required_param('restore_restoreto', PARAM_INT);
70         //restore_users
71         $restore_users = required_param('restore_users', PARAM_INT);
73         $restore_groups = required_param('restore_groups', PARAM_INT);
74         //restore_logs
75         $restore_logs = required_param('restore_logs', PARAM_INT);
76         //restore_user_files
77         $restore_user_files = required_param('restore_user_files', PARAM_INT);
78         //restore_course_files
79         $restore_course_files = required_param('restore_course_files', PARAM_INT);
80         //restore_site_files
81         $restore_site_files = required_param('restore_site_files', PARAM_INT);
82         //restore_gradebook_history
83         $restore_gradebook_history = required_param('restore_gradebook_history', PARAM_INT);
84         //restore_messages
85         $restore_messages = required_param('restore_messages', PARAM_INT);
86         //restore_blogs
87         $restore_blogs = required_param('restore_blogs', PARAM_INT);
89         //Check we've selected a course to restore to
90         $course_id = optional_param('course_id', 0, PARAM_INT);
92         //We are here, having all we need !!
93         //Create the restore object and put it in the session
94         $restore->backup_unique_code = $backup_unique_code;
95         $restore->file = $file;
96         if ($allmods = $DB->get_records("modules")) {
97             foreach ($allmods as $mod) {
98                 $modname = $mod->name;
99                 $var = "restore_".$modname;
100                 $restore->mods[$modname]->restore=$$var;
101                 $var = "restore_user_info_".$modname;
102                 $restore->mods[$modname]->userinfo=$$var;
103                 $instances = !empty($info->mods[$mod->name]->instances) ? $info->mods[$mod->name]->instances : NULL;
104                 if ($instances === NULL) {
105                     continue;
106                 }
107                 foreach ($instances as $instance) {
108                     $var = 'restore_'.$modname.'_instance_'.$instance->id;
109                     $restore->mods[$modname]->instances[$instance->id]->restore = $$var;
110                     $var = 'restore_user_info_'.$modname.'_instance_'.$instance->id;
111                     $restore->mods[$modname]->instances[$instance->id]->userinfo = $$var;
112                 }
113             }
114         }
115         $restore->restoreto=$restore_restoreto;
116         $restore->users=$restore_users;
117         $restore->groups=$restore_groups;
118         $restore->logs=$restore_logs;
119         $restore->user_files=$restore_user_files;
120         $restore->course_files=$restore_course_files;
121         $restore->site_files=$restore_site_files;
122         $restore->messages=$restore_messages;
123         $restore->blogs=$restore_blogs;
124         $restore->restore_gradebook_history=$restore_gradebook_history;
125         $restore->course_id=$course_id;
126         //add new vars to restore object
127         $restore->course_startdateoffset = $coursestartdatedateoffset;
128         $restore->course_shortname = $currentcourseshortname;
130         // create role mappings, not sure all should be here
131         if ($data2 = data_submitted()) {
132             foreach ($data2 as $tempname=>$tempdata) {
133                 if (strstr($tempname, 'roles_')) {
134                     $temprole = explode('_', $tempname);
135                     $oldroleid = $temprole[1];
136                     $newroleid = $tempdata;
137                     $restore->rolesmapping[$oldroleid] = $newroleid;
138                 }
139             }
140         }
142         // default role mapping for moodle < 1.7
143         if ($defaultteacheredit = optional_param('defaultteacheredit', 0, PARAM_INT)) {
144             $restore->rolesmapping['defaultteacheredit'] = $defaultteacheredit;
145         }
146         if ($defaultteacher = optional_param('defaultteacher', 0, PARAM_INT)) {
147             $restore->rolesmapping['defaultteacher'] = $defaultteacher;
148         }
149         if ($defaultstudent = optional_param('defaultstudent', 0, PARAM_INT)) {
150             $restore->rolesmapping['defaultstudent'] = $defaultstudent;
151         }
153     } else {
154         //We have the object, so check if we have a new course_id
155         //passed as parammeter
156         $course_id = optional_param('course_id', 0, PARAM_INT);
157         if ($course_id) {
158             $restore->course_id=$course_id;
159         }
160     }
162     // pass in the course category param
163     $restore->restore_restorecatto = optional_param('restore_restorecatto', 0, PARAM_INT);
165     //We have the object with data, put it in the session
166     $SESSION->restore = $restore;
168     //From here to the end of the script, only use the $restore object
170     //Check login
171     require_login();
173     $loginurl = get_login_url();
175     //Init restoreuserinfo
176     $restoreuserinfo = false;
179     //Check admin
180     if (!empty($id)) {
181         if (!has_capability('moodle/restore:restorecourse', get_context_instance(CONTEXT_COURSE, $id))) {
182             print_error("cannotuseadminadminorteacher", '', $loginurl);
183         }
184         $restoreuserinfo = has_capability('moodle/restore:userinfo', get_context_instance(CONTEXT_COURSE, $id));
185     } else {
186         if (!has_capability('moodle/restore:restorecourse', get_context_instance(CONTEXT_SYSTEM))) {
187             print_error("cannotuseadmin", '', $loginurl);
188         }
189         $restoreuserinfo = has_capability('moodle/restore:userinfo', get_context_instance(CONTEXT_SYSTEM));
190     }
192     //Check site
193     $site = get_site();
195     // Get all the courses the user is able to restore to
196     //TODO: use better function which includes all courses for admins
197     $mycourses = get_user_courses_bycap($USER->id, 'moodle/restore:restorecourse');
199     // Calculate if the user can create courses
200     $cancreatecourses = user_can_create_courses();
202     if (empty($restore->course_id) && ($restore->restoreto == RESTORETO_CURRENT_DELETING || $restore->restoreto == RESTORETO_CURRENT_ADDING)) {
203         $restore->course_id = $id; /// Force restore to current course, disabling pick course from list
204     }
206     //Set restore->deleting as needed
207     if ($restore->restoreto == RESTORETO_CURRENT_DELETING || $restore->restoreto == RESTORETO_EXISTING_DELETING) {
208         $restore->deleting = true;
209     } else {
210         $restore->deleting = false;
211     }
213     //Now, select the course if needed
214     if (empty($restore->course_id) && ($restore->restoreto == RESTORETO_EXISTING_DELETING || $restore->restoreto == RESTORETO_EXISTING_ADDING)) {
216         if ($courses = $mycourses) {
217             echo $OUTPUT->heading(get_string("choosecourse"));
218             echo $OUTPUT->box_start();
219             foreach ($courses as $course) {
220                 if (!has_capability('moodle/restore:restorecourse', get_context_instance(CONTEXT_COURSE, $course->id))) {
221                     continue;
222                 }
223                 if (empty($course->visible)) {
224                     $optdimmed = ' class="dimmed" ';
225                 } else {
226                     $optdimmed = '';
227                 }
228                 echo "<a $optdimmed href=\"restore.php?course_id=$course->id&amp;launch=check&amp;id=$id&amp;file=$file\">".format_string($course->fullname).' ('.format_string($course->shortname).')</a><br />'."\n";
229             }
230             echo $OUTPUT->box_end();
231         } else {
232             echo $OUTPUT->heading(get_string("nocoursesyet"));
233             echo $OUTPUT->continue_button("$CFG->wwwroot/$CFG->admin/index.php");
234         }
235     //Checks everything and execute restore
236     } else if (($restore->restoreto != RESTORETO_NEW_COURSE and !empty($restore->course_id)) or ($restore->restoreto == RESTORETO_NEW_COURSE)) {
237         //Final access control check
238         if (empty($restore->course_id) and !$cancreatecourses) {
239             print_error("cannotrestoreadminorcreator");
240         } else if (!empty($restore->course_id) and !has_capability('moodle/restore:restorecourse', get_context_instance(CONTEXT_COURSE, $restore->course_id))) {
241             print_error("cannotrestoreadminoredit");
242         }
243         $show_continue_button = true;
244         $messages = array();
246         //Check and warn if we are restoring over frontpage (SITEID) course. MDL-19163
247         if ($restore->course_id == SITEID) {
248             if ($restore->restoreto == RESTORETO_CURRENT_DELETING) {
249                 $messages[] = get_string ('restoretositedeleting');
250             } else if ($restore->restoreto == RESTORETO_CURRENT_ADDING) {
251                 $messages[] = get_string ('restoretositeadding');
252             }
253         }
255         //Check if we've selected any mod's user info and restore->users
256         //is set to none. Change it to course and inform.
257         if ($restore->users == 2) {
258             $changed = false;
259             $mods = $restore->mods;
260             foreach ($mods as $mod) {
261                 if ($mod->userinfo) {
262                     $changed = true;
263                 }
264             }
265             //If we have selected user files or messages or blogs, then users must be restored too
266             if ($restore->user_files || $restore->messages || $restore->blogs) {
267                 $changed = 1;
268             }
269             if ($changed) {
270                 $messages[] = get_string ("noteuserschangednonetocourse");
271                 $restore->users = 1;
272             }
273         }
275         // Re-enforce 'moodle/restore:restorecourse' at system context to be able to restore all users
276         if ($restore->users == 0 and !has_capability('moodle/restore:restorecourse', get_context_instance(CONTEXT_SYSTEM))) {
277             $restore->users = 1; // users => course
278         }
280         // Re-enforce moodle/restore:userinfo capability
281         if (!$restoreuserinfo) {
282             $userinfocheck = true;
283             // Confirm that all the settings are properly set to no users
284             // if anything is wrong, message and stop
285             // First global settings
286             if ($restore->users != 2 or $restore->user_files or $restore->messages or $restore->blogs) {
287                 $userinfocheck = false;
289             // Now all modules userinfo flag
290             } else {
291                 $mods = $restore->mods;
292                 foreach ($mods as $mod) {
293                     if ($mod->userinfo) {
294                         $userinfocheck = false;
295                     }
296                 }
297             }
299             if (!$userinfocheck) { // Something was wrong
300                 $messages[] = get_string('restoreuserinfofailed');
301                 $show_continue_button = false;
302             }
303         }
305         // Re-check all the roles creation/mapping stuff
306         if (!empty($restore->course_id)) {
307             $contexttosearch = get_context_instance(CONTEXT_COURSE, $restore->course_id);
308         // if we know the target category, check capability on it
309         } else if (!empty($restore->restore_restorecatto)) {
310             $contexttosearch = get_context_instance(CONTEXT_COURSECAT, $restore->restore_restorecatto);
311         } else {
312             $contexttosearch = get_context_instance(CONTEXT_SYSTEM);
313         }
314         $cancreateroles = has_capability('moodle/role:manage', get_context_instance(CONTEXT_SYSTEM));
315         $canassignroles = has_capability('moodle/role:assign', $contexttosearch);
316         $canoverridecaps= has_capability('moodle/role:override', $contexttosearch) || has_capability('moodle/role:safeoverride', $contexttosearch);
317         if (!empty($restore->rolesmapping)) {
318             foreach ($restore->rolesmapping as $originalrole => $targetrole) {
319                 // First, if new role is selected, check used really can do that
320                 if (empty($targetrole) && !$cancreateroles) {
321                     $messages[] = get_string('restorecannotcreateorassignroles');
322                     $show_continue_button = false;
323                     break;
324                 }
325                 // Now, check that the target role is available for role assignments
326                 if (!empty($targetrole) && !$canassignroles) {
327                     $messages[] = get_string('restorecannotassignroles');
328                     $show_continue_button = false;
329                     break;
330                 }
331                 // Now, check that the target role is available for capability overrides
332                 if (!empty($targetrole) && !$canoverridecaps) {
333                     $messages[] = get_string('restorecannotoverrideperms');
334                     $show_continue_button = false;
335                     break;
336                 }
337             }
338         }
340     /// If restoring users and backup has mnet remote users and we are restoring to different site, forbid restore to non-admins. MDL-17009
341         if ($restore->users != 2 &&                                                   /// If restoring users
342             !empty($info->mnet_remoteusers) && $info->mnet_remoteusers === 'true'  && /// and backup contains remote users
343             !backup_is_same_site($info)) {                              /// and backup is being restored to different site
345         /// If user is admin (by 'moodle/user:create' cap), warn about conversion to local auth if missing mnet hosts and continue restore
346             if (has_capability('moodle/user:create', get_context_instance(CONTEXT_SYSTEM))) {
347                 $messages[] = get_string('mnetrestore_extusers_admin', 'admin');
348                 $show_continue_button = true;
350         /// else, notify about the thing (suggesting to ask admin) and stop restore
351             } else {
352                 $messages[] = get_string('mnetrestore_extusers_noadmin', 'admin');
353                 $show_continue_button = false;
354             }
355         }
357         //Save the restore session object
358         $SESSION->restore = $restore;
360         // Calculate all session objects checksum and store them in session too
361         // so restore_execute.html (used by manual restore and import) will be
362         // able to detect any problem in session info.
363         restore_save_session_object_checksums($restore, $info, $course_header);
365         echo "<div style='text-align:center'>";
367     /// Printout messages
368         foreach ($messages as $message) {
369             echo '<p>' . $message . '</p>';
370         }
372     /// Warning and button
373         if ($show_continue_button) {
374             //Print the continue button to execute the restore NOW !!!!
375             //All is prepared !!!
376             $hidden["launch"]             = "execute";
377             $hidden["file"]               =  $file;
378             $hidden["id"]                 =  $id;
379             $hidden["sesskey"]            =  sesskey();
380             print_string('longtimewarning','admin');
383         /// Restore button
384             echo $OUTPUT->single_button(new moodle_url("restore.php", $hidden), get_string("restorecoursenow"));
385         }
386         echo "</div>";
388     //If we are here. Something must be wrong. Debug !!!
389     } else {
390         print_object($restore);
391         print_object($info);
392         print_object($course_header);
393         print_error('error');
394     }