2 //This page prints the restore form to select everything yo want
3 //to restore. Form is dinamically buid, depending of "info" object
4 //that contains the backup contents and depending of every mod
7 //Get objects from session
8 if (!($info = $SESSION->info
)) {
9 error( 'info object missing from session' );
11 if (!($course_header = $SESSION->course_header
)) {
12 error( 'course_header object missing from session' );
15 $restore_gradebook_history = optional_param('restore_gradebook_history', 0, PARAM_INT
);
17 //Check that we have all we need
19 $backup_unique_code = required_param( 'backup_unique_code' );
21 $file = required_param( 'file' );
28 if (!has_capability('moodle/site:restore', get_context_instance(CONTEXT_COURSE
, $id))) {
29 error("You need to be a teacher or admin user to use this page.", "$CFG->wwwroot/login/index.php");
32 if (!has_capability('moodle/site:restore', get_context_instance(CONTEXT_SYSTEM
, SITEID
))) {
33 error("You need to be an admin user to use this page.", "$CFG->wwwroot/login/index.php");
38 if (!$site = get_site()) {
39 error("Site not found!");
42 //Checks for the required files/functions to restore every mod
44 if ($allmods = get_records("modules") ) {
45 foreach ($allmods as $mod) {
46 $modname = $mod->name
;
47 $modfile = "$CFG->dirroot/mod/$modname/restorelib.php";
48 $modrestore = $modname."_restore_mods";
49 if (file_exists($modfile)) {
50 include_once($modfile);
51 if (function_exists($modrestore)) {
52 $var = "exists_".$modname;
59 $var = "restore_".$modname;
63 //Check include user info
64 $var = "restore_user_info_".$modname;
71 //Check other parameters
72 if (!isset($restore_metacourse)) {
73 $restore_metacourse = 1;
76 if (!isset($restore_users)) {
80 if (!isset($restore_logs)) {
84 if (!isset($restore_user_files)) {
85 $restore_user_files = 1;
88 if (!isset($restore_course_files)) {
89 $restore_course_files = 1;
92 if (!isset($restore_site_files)) {
93 $restore_site_files = 1;
96 if (!isset($restore_messages)) {
97 $restore_messages = 1;
100 if (!isset($restore_restoreto)) {
101 if (!user_can_create_courses()) {
102 $restore_restoreto = 1;
104 $restore_restoreto = 2;
108 if (!isset($course_header->category
->id
)) {
109 $course_header->category
->id
= 0;
112 if(!isset($form1->startdate
)) {
113 $form1->startdate
= $course_header->course_startdate
; //$course_header->course_startdate;
116 if (empty($form1->shortname
)) {
117 $form1->shortname
= $course_header->course_shortname
; //'_shortname'; //$course_header->course_shortname;
120 if (empty($form1->fullname
)) {
121 $form1->fullname
= $course_header->course_fullname
; // '_fullname'; //$course_header->course_fullname;
125 notice("No restorable modules are installed!");
130 <script type=
"text/javascript">
132 function selectItemInMenuByName(formId
, menuName
, selectIndex
) {
133 myForm
= document
.getElementById(formId
)
134 for (i
=0,n
=myForm
.elements
.length
;i
<n
;i
++) {
135 myLen
= menuName
.length
;
136 myName
= myForm
.elements
[i
].name
;
137 myType
= myForm
.elements
[i
].type
;
138 if (myName
.substring(0,myLen
) == menuName
&& myType
== "select-one") {
139 myForm
.elements
[i
].options
[selectIndex
].selected
= true;
144 function selectItemInRadioByName(formId
, radioName
, selectIndex
) {
145 myForm
= document
.getElementById(formId
)
146 for (i
=0,n
=myForm
.elements
.length
;i
<n
;i
++) {
147 myLen
= radioName
.length
;
148 myName
= myForm
.elements
[i
].name
;
149 myType
= myForm
.elements
[i
].type
;
150 if (myName
.substring(0,myLen
) == radioName
&& myType
== "radio") {
151 myRadioGroup
= myForm
.elements
[myName
];
152 myRadioGroup
[selectIndex
].checked
= true;
157 function selectItemInCheckboxByName(formId
, checkName
, checked
) {
158 myForm
= document
.getElementById(formId
)
159 for (i
=0,n
=myForm
.elements
.length
;i
<n
;i
++) {
160 myLen
= checkName
.length
;
161 myName
= myForm
.elements
[i
].name
;
162 myType
= myForm
.elements
[i
].type
;
163 if (myName
.substring(0,myLen
) == checkName
&& myType
== "checkbox") {
164 myForm
.elements
[i
].checked
= checked
;
171 <form id=
"form1" method=
"post" action=
"restore.php">
173 <table cellpadding=
"5" class=
"boxaligncenter">
176 //First, course destination
179 echo "<td align=\"right\"><b>";
180 echo get_string("restoreto").":</b>";
181 echo "</td><td colspan=\"3\">";
184 // permission should have been checked already
187 * if user has manageactivities in any course, we show
188 * existingcoursedeleting
189 * existingcourseadding
191 * currentcoursedeleting
193 * if user has course:create in any category, we show
197 // Non-cached - get accessinfo
198 if (isset($USER->access
)) {
199 $accessinfo = $USER->access
;
201 $accessinfo = get_user_access_sitewide($USER->id
);
204 $mycourses = get_user_courses_bycap($USER->id
, 'moodle/site:restore', $accessinfo, true);
205 // if the user can manage 2 or more courses,
206 // or if the only course the user can manage is not the current course
207 // we show options for existing courses
209 if (count($mycourses) > 1) {
210 // if user can manage more than 1 course, or if user can restore to a single different course
211 $restore_restoreto_options[0] = get_string("existingcoursedeleting");
212 $restore_restoreto_options[1] = get_string("existingcourseadding");
213 // else if the user can write to current course
214 } else if (has_capability('moodle/site:restore', get_context_instance(CONTEXT_COURSE
, $id))){
215 $restore_restoreto_options[0] = get_string("currentcoursedeleting");
216 $restore_restoreto_options[1] = get_string("currentcourseadding");
219 // if user can create any course at all, give the option
220 if (user_can_create_courses()) {
221 $restore_restoreto_options[2] = get_string("newcourse");
224 choose_from_menu($restore_restoreto_options, "restore_restoreto", $restore_restoreto, "");
226 if (user_can_create_courses()) { //display these fields conditionally
228 // find the list of cates user can edit
229 echo "<tr valign=\"top\" >";
230 echo "<td align=\"right\">";
231 print_string('category');
234 choose_from_menu(get_creatable_categories(), "restore_restorecatto", $course_header->category
->id
, "");
238 echo "<tr valign=\"top\" >";
239 echo "<td align=\"right\">";
240 print_string("shortname");
242 echo "<td><input type=\"text\" name=\"shortname\" maxlength=\"100\" size=\"20\" value=\"$form1->shortname\" alt=\"".get_string("shortname")."\" />" ;
243 helpbutton("courseshortname", get_string("shortname")) ;
244 if (isset($err["shortname"])) formerr($err["shortname"]);
247 echo "<tr valign=\"top\" >";
248 echo "<td align=\"right\">";
249 print_string("fullname");
251 echo "<td><input type=\"text\" name=\"fullname\" maxlength=\"254\" size=\"50\" value=\"$form1->fullname\" alt=\" ".get_string("fullname")."\" />" ;
252 helpbutton("coursefullname", get_string("fullname")) ;
253 if (isset($err["fullname"])) formerr($err["fullname"]);
255 echo "<tr valign=\"top\"> ";
256 echo "<td align=\"right\"> ";
257 print_string("startdate");
259 /// Show the roll dates option only if the backup course has a start date
260 /// (some formats like main page, social..., haven't it and rolling dates
261 /// from 0 produces crazy dates. MDL-10125
262 if ($form1->startdate
) {
263 print_date_selector("startday", "startmonth", "startyear", $form1->startdate
);
265 print_string('notavailable');
266 echo '<input type="hidden" name="startyear" value="0" />';
267 echo '<input type="hidden" name="startmonth" value="0" />';
268 echo '<input type="hidden" name="startday" value="0" />';
270 helpbutton("coursestartdate", get_string("startdate"));
274 echo "<tr><td colspan=\"4\"><hr /></td></tr>";
275 //Now, check modules and info and show posibilities
276 if ($allmods = get_records("modules") ) {
277 //Print option to select/deselect everything with 1 click.
279 echo "<td align=\"right\">";
280 echo '<b>'.get_string("include").":</b>";
282 echo "<a href=\"javascript:void(0);\" onclick=\"selectItemInCheckboxByName('form1', 'restore_', true);\">".
283 get_string("all")."</a>/";
284 echo "<a href=\"javascript:void(0);\" onclick=\"selectItemInCheckboxByName('form1', 'restore_', false);\">".
285 get_string("none")."</a>";
287 echo "<td align=\"right\">";
288 echo '<b> </b>';
290 echo "<a href=\"javascript:void(0);\" onclick=\"selectItemInCheckboxByName('form1', 'restore_user_info_', true);\">".
291 get_string("all")."</a>/";
292 echo "<a href=\"javascript:void(0);\" onclick=\"selectItemInCheckboxByName('form1', 'restore_user_info_', false);\">".
293 get_string("none")."</a>";
296 echo "<tr><td colspan=\"4\"><hr /></td></tr>";
299 foreach ($allmods as $mod) {
300 $modname = $mod->name
;
301 $modrestore = $modname."_restore_mods";
302 //If exists the lib & function
303 $exist = "exists_".$modname;
304 $restore_var = "restore_".$modname;
305 $user_info_var = "restore_user_info_".$modname;
306 if (isset($
$exist)) {
308 //Now check that we have that module info in the backup file
309 if (isset($info->mods
[$modname]) && $info->mods
[$modname]->backup
== "true") {
311 echo "<tr class=\"r".$currentrow."\">";
312 echo "<td align=\"right\"> ";
314 $restore_options[1] = get_string("yes");
315 $restore_options[0] = get_string("no");
316 //choose_from_menu($restore_options, $restore_var, $$restore_var, "");
317 //choose_from_radio($restore_options, $restore_var, $$restore_var);
319 print_checkbox($restore_var, $
$restore_var, $
$restore_var, get_string("modulenameplural",$modname),'','selectItemInCheckboxByName(\'form1\',\'restore_'.$modname.'\',this.checked)');
320 //If backup contains user data, then show menu, else fix it to
322 echo "</td><td align=\"right\"> ";
324 if ($info->mods
[$modname]->userinfo
== "true") {
325 $restore_user_options[1] = get_string("yes");
326 $restore_user_options[0] = get_string("no");
327 //choose_from_menu($restore_user_options, $user_info_var, $$user_info_var, "");
328 //choose_from_radio($restore_user_options, $user_info_var, $$user_info_var);
329 print_checkbox($user_info_var, $
$user_info_var, $
$user_info_var, get_string("userdata"),'','selectItemInCheckboxByName(\'form1\',\'restore_user_info_'.$modname.'\',this.checked)');
331 //Module haven't userdata
332 echo get_string("withoutuserdata");
333 echo "<input type=\"hidden\" name=\"$user_info_var\" value=\"0\" />";
336 if (isset($info->mods
[$modname]->instances
)) {
337 $instances = $info->mods
[$modname]->instances
;
339 if (!empty($instances) && is_array($instances)) {
340 echo '<tr><td></td><td colspan="3"><table class="restore-form-instances">';
341 foreach ($instances as $instance) {
343 $var = 'restore_'.$modname.'_instance_'.$instance->id
;
344 $
$var = optional_param($var,1);
345 print_checkbox($var,$
$var,$
$var,$instance->name
,$instance->name
,'this.form.elements[\'restore_'.$modname.'\'].checked=1;');
346 echo '</td><td align="right"> ';
347 $var = 'restore_user_info_'.$modname.'_instance_'.$instance->id
;
348 $
$var = optional_param($var,1);
349 if ($info->mods
[$modname]->instances
[$instance->id
]->userinfo
== 'true') {
350 print_checkbox($var,$
$var,$
$var,get_string('userdata'),'','this.form.elements[\'restore_user_info_'.$modname.'\'].checked=1;');
352 echo '<input type="hidden" name="'.$var.'" value="0" />';
356 echo '</table></td></tr>';
359 //Module isn't restorable
360 $nonrestmod .= "<input type=\"hidden\" name=\"$restore_var\" value=\"0\" />";
361 $nonrestmod .= "<input type=\"hidden\" name=\"$user_info_var\" value=\"0\" />";
364 //Module isn't restorable
365 $nonrestmod .= "<input type=\"hidden\" name=\"$restore_var\" value=\"0\" />";
366 $nonrestmod .= "<input type=\"hidden\" name=\"$user_info_var\" value=\"0\" />";
369 //Module isn't restorable
370 $nonrestmod .= "<input type=\"hidden\" name=\"$restore_var\" value=\"0\" />";
371 $nonrestmod .= "<input type=\"hidden\" name=\"$user_info_var\" value=\"0\" />";
373 $currentrow = ($currentrow +
1) %
2;
376 echo "<tr><td colspan=\"4\">$nonrestmod<hr /></td></tr>";
378 //Now print the Metacourse tr
380 echo "<td align=\"right\" colspan=\"2\"><b>";
381 echo get_string("metacourse").":";
382 echo "</b></td><td colspan=\"2\">";
383 //If metacourse are in the backup file, show menu, else fixed to no
384 if ($info->backup_metacourse
== "true") {
385 $metacourse_options[0] = get_string("no");
386 $metacourse_options[1] = get_string("yes");
387 choose_from_menu($metacourse_options, "restore_metacourse", $restore_metacourse, "");
389 echo get_string("no");
390 echo "<input type=\"hidden\" name=\"restore_metacourse\" value=\"0\" />";
393 //Now print the Users tr
395 echo "<td align=\"right\" colspan=\"2\"><b>";
396 echo get_string("users").":";
397 echo "</b></td><td colspan=\"2\">";
398 //If some user is present in the backup file
399 if ($info->backup_users
== "all" or $info->backup_users
== "course") {
400 //If all users are in the backup file
401 if ($info->backup_users
== "all") {
402 $user_options[0] = get_string("all");
404 $user_options[1] = get_string("course");
405 $user_options[2] = get_string("none");
406 choose_from_menu($user_options, "restore_users", $restore_users, "");
408 echo get_string("none");
409 echo "<input type=\"hidden\" name=\"restore_users\" value=\"2\" />";
414 //Now print the Logs tr
416 echo "<td align=\"right\" colspan=\"2\"><b>";
417 echo get_string("logs").":";
418 echo "</b></td><td colspan=\"2\">";
419 //If logs are in the backup file, show menu, else fixed to no
420 if ($info->backup_logs
== "true") {
421 $log_options[0] = get_string("no");
422 $log_options[1] = get_string("yes");
423 choose_from_menu($log_options, "restore_logs", $restore_logs, "");
425 echo get_string("no");
426 echo "<input type=\"hidden\" name=\"restore_logs\" value=\"0\" />";
430 //Now print the User Files tr
432 echo "<td align=\"right\" colspan=\"2\"><b>";
433 echo get_string ("userfiles").":";
434 echo "</b></td><td colspan=\"2\">";
435 //If user files are in the backup file, show menu, else fixed to no
436 if ($info->backup_user_files
== "true") {
437 $user_file_options[0] = get_string("no");
438 $user_file_options[1] = get_string("yes");
439 choose_from_menu($user_file_options, "restore_user_files", $restore_user_files, "");
441 echo get_string("no");
442 echo "<input type=\"hidden\" name=\"restore_user_files\" value=\"0\" />";
446 //Now print the Course Files tr
448 echo "<td align=\"right\" colspan=\"2\"><b>";
449 echo get_string ("coursefiles").":";
450 echo "</b></td><td colspan=\"2\">";
451 echo "<input type=\"hidden\" name=\"backup_unique_code\" value=\"$backup_unique_code\" />";
452 echo "<input type=\"hidden\" name=\"file\" value=\"$file\" />";
453 //If course files are in the backup file, show menu, else fixed to no
454 if ($info->backup_course_files
== "true") {
455 $course_file_options[0] = get_string("no");
456 $course_file_options[1] = get_string("yes");
457 choose_from_menu($course_file_options, "restore_course_files", $restore_course_files, "");
459 echo get_string("no");
460 echo "<input type=\"hidden\" name=\"restore_course_files\" value=\"0\" />";
465 //Now print the Site Files tr
467 echo "<td align=\"right\" colspan=\"2\"><b>";
468 echo get_string ("sitefiles").":";
469 echo "</b></td><td colspan=\"2\">";
470 //If site files are in the backup file, show menu, else fixed to no
471 if (isset($info->backup_site_files
) && $info->backup_site_files
== "true") {
472 $site_file_options[0] = get_string("no");
473 $site_file_options[1] = get_string("yes");
474 choose_from_menu($site_file_options, "restore_site_files", $restore_site_files, "");
476 echo get_string("no");
477 echo "<input type=\"hidden\" name=\"restore_site_files\" value=\"0\" />";
481 // do you want grade histories to be restored?
483 echo "<td align=\"right\" colspan=\"2\"><b>";
484 echo get_string ('gradebookhistories', 'grades').":";
485 echo "</b></td><td colspan=\"2\">";
486 $gradebook_history_options[0] = get_string("no");
487 $gradebook_history_options[1] = get_string("yes");
488 choose_from_menu($gradebook_history_options, "restore_gradebook_history", $restore_gradebook_history, "");
491 //Now print the Messages tr
493 echo "<td align=\"right\" colspan=\"2\"><b>";
495 //This tr is slighty different. Everything becomes hidden if
496 //we haven't messages is the backup, to avoid confusions to users.
497 //If messages are in the backup file, show menu, else fixed to no and show nothing
498 if ($info->backup_messages
== "true") {
499 echo get_string ('messages','message').":";
500 echo "</b></td><td colspan=\"2\">";
501 $message_options[0] = get_string("no");
502 $message_options[1] = get_string("yes");
503 choose_from_menu($message_options, "restore_messages", $restore_messages, "");
505 echo " </b></td><td colspan=\"2\">";
506 echo "<input type=\"hidden\" name=\"restore_messages\" value=\"0\" />";
518 print_heading(get_string('rolemappings'));
519 $xml_file = $CFG->dataroot
."/temp/backup/".$backup_unique_code."/moodle.xml";
521 $info = restore_read_xml_info($xml_file);
523 // fix for MDL-9068, front page course is just a normal course
524 $siterolesarray = get_assignable_roles (get_context_instance(CONTEXT_COURSE
, $course->id
), "shortname");
525 $siterolesnamearray = get_assignable_roles (get_context_instance(CONTEXT_COURSE
, $course->id
), "name");
526 $allroles = get_records('role');
528 echo ('<table width="100%" class="restore-form-instances">');
529 echo ('<tr><td align="right" style="width:50%"><b>'.get_string('sourcerole').'</b></td><td align="left" style="width:50%"><b>'.get_string('targetrole').'</b></td></tr>');
531 if ($info->backup_moodle_version
< 2006092801) {
532 // 1.6 and below backup
535 echo ('<tr><td align="right">');
536 print_string('defaultcourseteacher');
537 echo ('</td><td algin="left">');
539 // get the first teacheredit legacy
540 $roles = get_roles_with_capability('moodle/legacy:editingteacher', CAP_ALLOW
, get_context_instance(CONTEXT_SYSTEM
, SITEID
));
542 $editteacher = array_shift($roles);
543 choose_from_menu ($siterolesarray, "defaultteacheredit", $editteacher->id
, 'new role', '', '0');
546 /// Non-editting teacher
547 echo ('<tr><td align="right">');
548 print_string('noneditingteacher');
549 echo ('</td><td algin="left">');
551 // get the first teacheredit legacy
552 $roles = get_roles_with_capability('moodle/legacy:teacher', CAP_ALLOW
, get_context_instance(CONTEXT_SYSTEM
, SITEID
));
553 $teacher = array_shift($roles);
555 choose_from_menu ($siterolesarray, "defaultteacher", $teacher->id
, 'new role', '', '0');
560 echo ('<tr><td align="right">');
561 print_string('defaultcoursestudent');
562 echo ('</td><td algin="left">');
564 // get the first teacheredit legacy
565 $roles = get_roles_with_capability('moodle/legacy:student', CAP_ALLOW
, get_context_instance(CONTEXT_SYSTEM
, SITEID
));
566 $studentrole = array_shift($roles);
568 choose_from_menu ($siterolesarray, "defaultstudent", $studentrole->id
, 'new role', '', '0');
572 // 1.7 and above backup
573 $roles = restore_read_xml_roles($xml_file);
575 if (!empty($roles->roles
)) { // possible to have course with no roles
576 foreach ($siterolesarray as $siteroleid=>$siteroleshortname) {
577 $siteroleschoicearray[$siteroleid] = $siterolesnamearray[$siteroleid]." (". $siterolesarray[$siteroleid].")";
580 foreach ($roles->roles
as $roleid=>$role) {
582 $mappableroles = $siteroleschoicearray;
584 echo ('<tr><td align="right">');
585 echo $role->name
." (".($role->shortname
).")";
586 echo ('</td><td align="left">');
588 /// first, we see if any exact role definition is found
589 /// if found, that is the only option of restoring to
591 if ($samerole = restore_samerole($roleid, $role)) {
592 $matchrole = $samerole->id
;
593 // if an exact role is found, it does not matter whether this user can assign this role or not,
594 // this will be presented as a valid option regardless
595 $mappableroles[$samerole->id
] = $allroles[$samerole->id
]->name
." (". $allroles[$samerole->id
]->shortname
.")";
597 // no exact role found, let's try to match shortname
598 // this is useful in situations where basic roles differ slightly in definition
600 foreach ($siterolesarray as $siteroleid=>$siteroleshortname) {
601 if ($siteroleshortname == $role->shortname
) {
602 $matchrole = $siteroleid;
607 choose_from_menu ($mappableroles, "roles_".$roleid, $matchrole, 'new role', '', '0');
614 echo ('</table>'); // end of role mappings table
618 <div style=
"text-align:center">
619 <input type=
"hidden" name=
"id" value=
"<?php p($id) ?>" />
620 <input type
="hidden" name
="launch" value
="check" />
621 <input type
="hidden" name
="fromform" value
="1" />
622 <input type
="submit" value
="<?php print_string("continue") ?>" />
623 <input type
="submit" name
="cancel" value
="<?php print_string("cancel
") ?>" />
631 * Look for a role in the database with exactly the same definition as the one in the backup file.
633 * @param integer $roleid the id that the role in the backup files had on the old server.
634 * @param object $role the rest of the definition of the role from the backup file.
636 function restore_samerole($roleid, $rolefromxml) {
639 // First we try some intelligent guesses, then, if none of those work, we do a more extensive
642 // First guess, try let's use the id
643 if (restore_is_samerole($roleid, $rolefromxml)) {
644 return get_record('role', 'id', $roleid);
647 // Second guess, try the shortname
648 $testroleid = get_field('role', 'id', 'shortname', $rolefromxml->shortname
);
649 if ($testroleid && restore_is_samerole($testroleid, $rolefromxml)) {
650 return get_record('role', 'id', $testroleid);
653 // Finally, search all other roles. In orter to speed things up, we exclude the ones we have
654 // already tested, and we only search roles with the same number of capabilities set in their
656 $extracondition = '';
658 $extracondition = "AND roleid <> $testroleid";
660 $candidateroleids = get_records_sql("SELECT roleid
661 FROM {$CFG->prefix}role_capabilities
662 WHERE roleid <> $roleid $extracondition
664 HAVING COUNT(capability) = ".count($rolefromxml->capabilities
));
665 if (!empty($candidateroleids)) {
666 foreach ($candidateroleids as $testroleid => $notused) {
667 if (restore_is_samerole($testroleid, $rolefromxml)) {
668 return get_record('role', 'id', $testroleid);
677 * Compare a role in the database with one loaded from the backup file, and determine whether
678 * they have identical permissions for each capability.
679 * @param integer $testroleid the id of the role from the database to test against.
680 * @param object $rolefromxml the role definition loaded from the backup file.
681 * @return boolean true if the two roles are identical.
683 function restore_is_samerole($testroleid, $rolefromxml) {
684 // Load the role definition from the databse.
685 $rolefromdb = get_records('role_capabilities', 'roleid', $testroleid, '', 'capability,permission');
690 // Quick check, do they have the permissions on the same number of capabilities?
691 if (count($rolefromdb) != count($rolefromxml->capabilities
)) {
695 // If they do, check each one.
696 foreach ($rolefromdb as $capability => $permissions) {
697 if (!isset($rolefromxml->capabilities
[$capability]) ||
698 $permissions->permission
!= $rolefromxml->capabilities
[$capability]->permission
) {