e770dcd1c747b1e13481de3687ab6165f45bc868
[moodle.git] / backup / restorelib.php
1 <?php
2     //This function iterates over all modules in backup file, searching for a
3     //MODNAME_refresh_events() to execute. Perhaps it should ve moved to central Moodle...
4     function restore_refresh_events($restore) {
6         global $CFG;
7         $status = true;
9         //Take all modules in backup
10         $modules = $restore->mods;
11         //Iterate
12         foreach($modules as $name => $module) {
13             //Only if the module is being restored
14             if (isset($module->restore) && $module->restore == 1) {
15                 //Include module library
16                 include_once("$CFG->dirroot/mod/$name/lib.php");
17                 //If module_refresh_events exists
18                 $function_name = $name."_refresh_events";
19                 if (function_exists($function_name)) {
20                     $status = $function_name($restore->course_id);
21                 }
22             }
23         }
24         return $status;
25     }
27     //Called to set up any course-format specific data that may be in the file
28     function restore_set_format_data($restore,$xml_file) {
29         global $CFG, $DB;
31         $status = true;
32         //Check it exists
33         if (!file_exists($xml_file)) {
34             return false;
35         }
36         //Load data from XML to info
37         if(!($info = restore_read_xml_formatdata($xml_file))) {
38                 return false;
39         }
41         //Process format data if there is any
42         if (isset($info->format_data)) {
43                 if(!$format=$DB->get_field('course','format', array('id'=>$restore->course_id))) {
44                     return false;
45                 }
46                 // If there was any data then it must have a restore method
47                 $file=$CFG->dirroot."/course/format/$format/restorelib.php";
48                 if(!file_exists($file)) {
49                     return false;
50                 }
51                 require_once($file);
52                 $function=$format.'_restore_format_data';
53                 if(!function_exists($function)) {
54                     return false;
55                 }
56                 return $function($restore,$info->format_data);
57         }
59         // If we got here then there's no data, but that's cool
60         return true;
61     }
63     //This function creates all the structures messages and contacts
64     function restore_create_messages($restore,$xml_file) {
65         global $CFG, $DB;
67         $status = true;
68         //Check it exists
69         if (!file_exists($xml_file)) {
70             $status = false;
71         }
72         //Get info from xml
73         if ($status) {
74             //info will contain the id and name of every table
75             //(message, message_read and message_contacts)
76             //in backup_ids->info will be the real info (serialized)
77             $info = restore_read_xml_messages($restore,$xml_file);
79             //If we have info, then process messages & contacts
80             if ($info > 0) {
81                 //Count how many we have
82                 $unreadcount  = $DB->count_records ('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'message'));
83                 $readcount    = $DB->count_records ('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'message_read'));
84                 $contactcount = $DB->count_records ('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'message_contacts'));
85                 if ($unreadcount || $readcount || $contactcount) {
86                     //Start ul
87                     if (!defined('RESTORE_SILENTLY')) {
88                         echo '<ul>';
89                     }
90                     //Number of records to get in every chunk
91                     $recordset_size = 4;
93                     //Process unread
94                     if ($unreadcount) {
95                         if (!defined('RESTORE_SILENTLY')) {
96                             echo '<li>'.get_string('unreadmessages','message').'</li>';
97                         }
98                         $counter = 0;
99                         while ($counter < $unreadcount) {
100                             //Fetch recordset_size records in each iteration
101                             $recs = $DB->get_records("backup_ids", array('table_name'=>'message', 'backup_code'=>$restore->backup_unique_code),"old_id","old_id",$counter,$recordset_size);
102                             if ($recs) {
103                                 foreach ($recs as $rec) {
104                                     //Get the full record from backup_ids
105                                     $data = backup_getid($restore->backup_unique_code,"message",$rec->old_id);
106                                     if ($data) {
107                                         //Now get completed xmlized object
108                                         $info = $data->info;
109                                         //traverse_xmlize($info);                            //Debug
110                                         //print_object ($GLOBALS['traverse_array']);         //Debug
111                                         //$GLOBALS['traverse_array']="";                     //Debug
112                                         //Now build the MESSAGE record structure
113                                         $dbrec = new stdClass();
114                                         $dbrec->useridfrom = backup_todb($info['MESSAGE']['#']['USERIDFROM']['0']['#']);
115                                         $dbrec->useridto = backup_todb($info['MESSAGE']['#']['USERIDTO']['0']['#']);
116                                         $dbrec->message = backup_todb($info['MESSAGE']['#']['MESSAGE']['0']['#']);
117                                         $dbrec->format = backup_todb($info['MESSAGE']['#']['FORMAT']['0']['#']);
118                                         $dbrec->timecreated = backup_todb($info['MESSAGE']['#']['TIMECREATED']['0']['#']);
119                                         $dbrec->messagetype = backup_todb($info['MESSAGE']['#']['MESSAGETYPE']['0']['#']);
120                                         //We have to recode the useridfrom field
121                                         $user = backup_getid($restore->backup_unique_code,"user",$dbrec->useridfrom);
122                                         if ($user) {
123                                             //echo "User ".$dbrec->useridfrom." to user ".$user->new_id."<br />";   //Debug
124                                             $dbrec->useridfrom = $user->new_id;
125                                         }
126                                         //We have to recode the useridto field
127                                         $user = backup_getid($restore->backup_unique_code,"user",$dbrec->useridto);
128                                         if ($user) {
129                                             //echo "User ".$dbrec->useridto." to user ".$user->new_id."<br />";   //Debug
130                                             $dbrec->useridto = $user->new_id;
131                                         }
132                                         //Check if the record doesn't exist in DB!
133                                         $exist = $DB->get_record('message', array('useridfrom'=>$dbrec->useridfrom,
134                                                                                   'useridto'=>$dbrec->useridto,
135                                                                                   'timecreated'=>$dbrec->timecreated));
136                                         if (!$exist) {
137                                             //Not exist. Insert
138                                             $status = $DB->insert_record('message',$dbrec);
139                                         } else {
140                                             //Duplicate. Do nothing
141                                         }
142                                     }
143                                     //Do some output
144                                     $counter++;
145                                     if ($counter % 10 == 0) {
146                                         if (!defined('RESTORE_SILENTLY')) {
147                                             echo ".";
148                                             if ($counter % 200 == 0) {
149                                                 echo "<br />";
150                                             }
151                                         }
152                                         backup_flush(300);
153                                     }
154                                 }
155                             }
156                         }
157                     }
159                     //Process read
160                     if ($readcount) {
161                         if (!defined('RESTORE_SILENTLY')) {
162                             echo '<li>'.get_string('readmessages','message').'</li>';
163                         }
164                         $counter = 0;
165                         while ($counter < $readcount) {
166                             //Fetch recordset_size records in each iteration
167                             $recs = $DB->get_records("backup_ids", array('table_name'=>'message_read', 'backup_code'=>$restore->backup_unique_code),"old_id","old_id",$counter,$recordset_size);
168                             if ($recs) {
169                                 foreach ($recs as $rec) {
170                                     //Get the full record from backup_ids
171                                     $data = backup_getid($restore->backup_unique_code,"message_read",$rec->old_id);
172                                     if ($data) {
173                                         //Now get completed xmlized object
174                                         $info = $data->info;
175                                         //traverse_xmlize($info);                            //Debug
176                                         //print_object ($GLOBALS['traverse_array']);         //Debug
177                                         //$GLOBALS['traverse_array']="";                     //Debug
178                                         //Now build the MESSAGE_READ record structure
179                                         $dbrec->useridfrom = backup_todb($info['MESSAGE']['#']['USERIDFROM']['0']['#']);
180                                         $dbrec->useridto = backup_todb($info['MESSAGE']['#']['USERIDTO']['0']['#']);
181                                         $dbrec->message = backup_todb($info['MESSAGE']['#']['MESSAGE']['0']['#']);
182                                         $dbrec->format = backup_todb($info['MESSAGE']['#']['FORMAT']['0']['#']);
183                                         $dbrec->timecreated = backup_todb($info['MESSAGE']['#']['TIMECREATED']['0']['#']);
184                                         $dbrec->messagetype = backup_todb($info['MESSAGE']['#']['MESSAGETYPE']['0']['#']);
185                                         $dbrec->timeread = backup_todb($info['MESSAGE']['#']['TIMEREAD']['0']['#']);
186                                         $dbrec->mailed = backup_todb($info['MESSAGE']['#']['MAILED']['0']['#']);
187                                         //We have to recode the useridfrom field
188                                         $user = backup_getid($restore->backup_unique_code,"user",$dbrec->useridfrom);
189                                         if ($user) {
190                                             //echo "User ".$dbrec->useridfrom." to user ".$user->new_id."<br />";   //Debug
191                                             $dbrec->useridfrom = $user->new_id;
192                                         }
193                                         //We have to recode the useridto field
194                                         $user = backup_getid($restore->backup_unique_code,"user",$dbrec->useridto);
195                                         if ($user) {
196                                             //echo "User ".$dbrec->useridto." to user ".$user->new_id."<br />";   //Debug
197                                             $dbrec->useridto = $user->new_id;
198                                         }
199                                         //Check if the record doesn't exist in DB!
200                                         $exist = $DB->get_record('message_read', array('useridfrom'=>$dbrec->useridfrom,
201                                                                                        'useridto'=>$dbrec->useridto,
202                                                                                        'timecreated'=>$dbrec->timecreated));
203                                         if (!$exist) {
204                                             //Not exist. Insert
205                                             $status = $DB->insert_record('message_read',$dbrec);
206                                         } else {
207                                             //Duplicate. Do nothing
208                                         }
209                                     }
210                                     //Do some output
211                                     $counter++;
212                                     if ($counter % 10 == 0) {
213                                         if (!defined('RESTORE_SILENTLY')) {
214                                             echo ".";
215                                             if ($counter % 200 == 0) {
216                                                 echo "<br />";
217                                             }
218                                         }
219                                         backup_flush(300);
220                                     }
221                                 }
222                             }
223                         }
224                     }
226                     //Process contacts
227                     if ($contactcount) {
228                         if (!defined('RESTORE_SILENTLY')) {
229                             echo '<li>'.moodle_strtolower(get_string('contacts','message')).'</li>';
230                         }
231                         $counter = 0;
232                         while ($counter < $contactcount) {
233                             //Fetch recordset_size records in each iteration
234                             $recs = $DB->get_records("backup_ids", array('table_name'=>'message_contacts', 'backup_code'=>$restore->backup_unique_code),"old_id","old_id",$counter,$recordset_size);
235                             if ($recs) {
236                                 foreach ($recs as $rec) {
237                                     //Get the full record from backup_ids
238                                     $data = backup_getid($restore->backup_unique_code,"message_contacts",$rec->old_id);
239                                     if ($data) {
240                                         //Now get completed xmlized object
241                                         $info = $data->info;
242                                         //traverse_xmlize($info);                            //Debug
243                                         //print_object ($GLOBALS['traverse_array']);         //Debug
244                                         //$GLOBALS['traverse_array']="";                     //Debug
245                                         //Now build the MESSAGE_CONTACTS record structure
246                                         $dbrec->userid = backup_todb($info['CONTACT']['#']['USERID']['0']['#']);
247                                         $dbrec->contactid = backup_todb($info['CONTACT']['#']['CONTACTID']['0']['#']);
248                                         $dbrec->blocked = backup_todb($info['CONTACT']['#']['BLOCKED']['0']['#']);
249                                         //We have to recode the userid field
250                                         $user = backup_getid($restore->backup_unique_code,"user",$dbrec->userid);
251                                         if ($user) {
252                                             //echo "User ".$dbrec->userid." to user ".$user->new_id."<br />";   //Debug
253                                             $dbrec->userid = $user->new_id;
254                                         }
255                                         //We have to recode the contactid field
256                                         $user = backup_getid($restore->backup_unique_code,"user",$dbrec->contactid);
257                                         if ($user) {
258                                             //echo "User ".$dbrec->contactid." to user ".$user->new_id."<br />";   //Debug
259                                             $dbrec->contactid = $user->new_id;
260                                         }
261                                         //Check if the record doesn't exist in DB!
262                                         $exist = $DB->get_record('message_contacts', array('userid'=>$dbrec->userid,
263                                                                                            'contactid'=>$dbrec->contactid));
264                                         if (!$exist) {
265                                             //Not exist. Insert
266                                             $status = $DB->insert_record('message_contacts',$dbrec);
267                                         } else {
268                                             //Duplicate. Do nothing
269                                         }
270                                     }
271                                     //Do some output
272                                     $counter++;
273                                     if ($counter % 10 == 0) {
274                                         if (!defined('RESTORE_SILENTLY')) {
275                                             echo ".";
276                                             if ($counter % 200 == 0) {
277                                                 echo "<br />";
278                                             }
279                                         }
280                                         backup_flush(300);
281                                     }
282                                 }
283                             }
284                         }
285                     }
286                     if (!defined('RESTORE_SILENTLY')) {
287                         //End ul
288                         echo '</ul>';
289                     }
290                 }
291             }
292         }
294        return $status;
295     }
297     //This function creates all the structures for blogs and blog tags
298     function restore_create_blogs($restore,$xml_file) {
299         global $CFG, $DB;
301         $status = true;
302         //Check it exists
303         if (!file_exists($xml_file)) {
304             $status = false;
305         }
306         //Get info from xml
307         if ($status) {
308             //info will contain the number of blogs in the backup file
309             //in backup_ids->info will be the real info (serialized)
310             $info = restore_read_xml_blogs($restore,$xml_file);
312             //If we have info, then process blogs & blog_tags
313             if ($info > 0) {
314                 //Count how many we have
315                 $blogcount = $DB->count_records('backup_ids', array('backup_code'=>$restore->backup_unique_code, 'table_name'=>'blog'));
316                 if ($blogcount) {
317                     //Number of records to get in every chunk
318                     $recordset_size = 4;
320                     //Process blog
321                     if ($blogcount) {
322                         $counter = 0;
323                         while ($counter < $blogcount) {
324                             //Fetch recordset_size records in each iteration
325                             $recs = $DB->get_records("backup_ids", array("table_name"=>'blog', 'backup_code'=>$restore->backup_unique_code),"old_id","old_id",$counter,$recordset_size);
326                             if ($recs) {
327                                 foreach ($recs as $rec) {
328                                     //Get the full record from backup_ids
329                                     $data = backup_getid($restore->backup_unique_code,"blog",$rec->old_id);
330                                     if ($data) {
331                                         //Now get completed xmlized object
332                                         $info = $data->info;
333                                         //traverse_xmlize($info);                            //Debug
334                                         //print_object ($GLOBALS['traverse_array']);         //Debug
335                                         //$GLOBALS['traverse_array']="";                     //Debug
336                                         //Now build the BLOG record structure
337                                         $dbrec = new stdClass();
338                                         $dbrec->module = backup_todb($info['BLOG']['#']['MODULE']['0']['#']);
339                                         $dbrec->userid = backup_todb($info['BLOG']['#']['USERID']['0']['#']);
340                                         $dbrec->courseid = backup_todb($info['BLOG']['#']['COURSEID']['0']['#']);
341                                         $dbrec->groupid = backup_todb($info['BLOG']['#']['GROUPID']['0']['#']);
342                                         $dbrec->moduleid = backup_todb($info['BLOG']['#']['MODULEID']['0']['#']);
343                                         $dbrec->coursemoduleid = backup_todb($info['BLOG']['#']['COURSEMODULEID']['0']['#']);
344                                         $dbrec->subject = backup_todb($info['BLOG']['#']['SUBJECT']['0']['#']);
345                                         $dbrec->summary = backup_todb($info['BLOG']['#']['SUMMARY']['0']['#']);
346                                         $dbrec->content = backup_todb($info['BLOG']['#']['CONTENT']['0']['#']);
347                                         $dbrec->uniquehash = backup_todb($info['BLOG']['#']['UNIQUEHASH']['0']['#']);
348                                         $dbrec->rating = backup_todb($info['BLOG']['#']['RATING']['0']['#']);
349                                         $dbrec->format = backup_todb($info['BLOG']['#']['FORMAT']['0']['#']);
350                                         $dbrec->attachment = backup_todb($info['BLOG']['#']['ATTACHMENT']['0']['#']);
351                                         $dbrec->publishstate = backup_todb($info['BLOG']['#']['PUBLISHSTATE']['0']['#']);
352                                         $dbrec->lastmodified = backup_todb($info['BLOG']['#']['LASTMODIFIED']['0']['#']);
353                                         $dbrec->created = backup_todb($info['BLOG']['#']['CREATED']['0']['#']);
354                                         $dbrec->usermodified = backup_todb($info['BLOG']['#']['USERMODIFIED']['0']['#']);
356                                         //We have to recode the userid field
357                                         $user = backup_getid($restore->backup_unique_code,"user",$dbrec->userid);
358                                         if ($user) {
359                                             //echo "User ".$dbrec->userid." to user ".$user->new_id."<br />";   //Debug
360                                             $dbrec->userid = $user->new_id;
361                                         }
363                                         //Check if the record doesn't exist in DB!
364                                         $exist = $DB->get_record('post', array('userid'=>$dbrec->userid,
365                                                                                'subject'=>$dbrec->subject,
366                                                                                'created'=>$dbrec->created));
367                                         $newblogid = 0;
368                                         if (!$exist) {
369                                             //Not exist. Insert
370                                             $newblogid = $DB->insert_record('post',$dbrec);
371                                         }
373                                         //Going to restore related tags. Check they are enabled and we have inserted a blog
374                                         if ($CFG->usetags && $newblogid) {
375                                             //Look for tags in this blog
376                                             if (isset($info['BLOG']['#']['BLOG_TAGS']['0']['#']['BLOG_TAG'])) {
377                                                 $tagsarr = $info['BLOG']['#']['BLOG_TAGS']['0']['#']['BLOG_TAG'];
378                                                 //Iterate over tags
379                                                 $tags = array();
380                                                 for($i = 0; $i < sizeof($tagsarr); $i++) {
381                                                     $tag_info = $tagsarr[$i];
382                                                     ///traverse_xmlize($tag_info);                        //Debug
383                                                     ///print_object ($GLOBALS['traverse_array']);         //Debug
384                                                     ///$GLOBALS['traverse_array']="";                     //Debug
386                                                     $name = backup_todb($tag_info['#']['NAME']['0']['#']);
387                                                     $rawname = backup_todb($tag_info['#']['RAWNAME']['0']['#']);
389                                                     $tags[] = $rawname;  //Rawname is all we need
390                                                 }
391                                                 tag_set('post', $newblogid, $tags); //Add all the tags in one API call
392                                             }
393                                         }
394                                     }
395                                     //Do some output
396                                     $counter++;
397                                     if ($counter % 10 == 0) {
398                                         if (!defined('RESTORE_SILENTLY')) {
399                                             echo ".";
400                                             if ($counter % 200 == 0) {
401                                                 echo "<br />";
402                                             }
403                                         }
404                                         backup_flush(300);
405                                     }
406                                 }
407                             }
408                         }
409                     }
410                 }
411             }
412         }
414         return $status;
415     }
417     //This function creates all the course events
418     function restore_create_events($restore,$xml_file) {
419         global $DB;
421         global $CFG, $SESSION;
423         $status = true;
424         //Check it exists
425         if (!file_exists($xml_file)) {
426             $status = false;
427         }
428         //Get info from xml
429         if ($status) {
430             //events will contain the old_id of every event
431             //in backup_ids->info will be the real info (serialized)
432             $events = restore_read_xml_events($restore,$xml_file);
433         }
435         //Get admin->id for later use
436         $admin = get_admin();
437         $adminid = $admin->id;
439         //Now, if we have anything in events, we have to restore that
440         //events
441         if ($events) {
442             if ($events !== true) {
443                 //Iterate over each event
444                 foreach ($events as $event) {
445                     //Get record from backup_ids
446                     $data = backup_getid($restore->backup_unique_code,"event",$event->id);
447                     //Init variables
448                     $create_event = false;
450                     if ($data) {
451                         //Now get completed xmlized object
452                         $info = $data->info;
453                         //traverse_xmlize($info);                                                                     //Debug
454                         //print_object ($GLOBALS['traverse_array']);                                                  //Debug
455                         //$GLOBALS['traverse_array']="";                                                              //Debug
457                         //if necessary, write to restorelog and adjust date/time fields
458                         if ($restore->course_startdateoffset) {
459                             restore_log_date_changes('Events', $restore, $info['EVENT']['#'], array('TIMESTART'));
460                         }
462                         //Now build the EVENT record structure
463                         $eve->name = backup_todb($info['EVENT']['#']['NAME']['0']['#']);
464                         $eve->description = backup_todb($info['EVENT']['#']['DESCRIPTION']['0']['#']);
465                         $eve->format = backup_todb($info['EVENT']['#']['FORMAT']['0']['#']);
466                         $eve->courseid = $restore->course_id;
467                         $eve->groupid = backup_todb($info['EVENT']['#']['GROUPID']['0']['#']);
468                         $eve->userid = backup_todb($info['EVENT']['#']['USERID']['0']['#']);
469                         $eve->repeatid = backup_todb($info['EVENT']['#']['REPEATID']['0']['#']);
470                         $eve->modulename = "";
471                         if (!empty($info['EVENT']['#']['MODULENAME'])) {
472                             $eve->modulename = backup_todb($info['EVENT']['#']['MODULENAME']['0']['#']);
473                         }
474                         $eve->instance = 0;
475                         $eve->eventtype = backup_todb($info['EVENT']['#']['EVENTTYPE']['0']['#']);
476                         $eve->timestart = backup_todb($info['EVENT']['#']['TIMESTART']['0']['#']);
477                         $eve->timeduration = backup_todb($info['EVENT']['#']['TIMEDURATION']['0']['#']);
478                         $eve->visible = backup_todb($info['EVENT']['#']['VISIBLE']['0']['#']);
479                         $eve->timemodified = backup_todb($info['EVENT']['#']['TIMEMODIFIED']['0']['#']);
481                         //Now search if that event exists (by name, description, timestart fields) in
482                         //restore->course_id course
483                         //Going to compare LOB columns so, use the cross-db sql_compare_text() in both sides.
484                         $compare_description_clause = $DB->sql_compare_text('description')  . "=" .  $DB->sql_compare_text("'" . $eve->description . "'");
485                         $eve_db = $DB->get_record_select('event',
486                             "courseid = ? AND name = ? AND $compare_description_clause AND timestart = ?",
487                             array($eve->courseid, $eve->name, $eve->timestart));
488                         //If it doesn't exist, create
489                         if (!$eve_db) {
490                             $create_event = true;
491                         }
492                         //If we must create the event
493                         if ($create_event) {
495                             //We must recode the userid
496                             $user = backup_getid($restore->backup_unique_code,"user",$eve->userid);
497                             if ($user) {
498                                 $eve->userid = $user->new_id;
499                             } else {
500                                 //Assign it to admin
501                                 $eve->userid = $adminid;
502                             }
504                             //We have to recode the groupid field
505                             $group = backup_getid($restore->backup_unique_code,"groups",$eve->groupid);
506                             if ($group) {
507                                 $eve->groupid = $group->new_id;
508                             } else {
509                                 //Assign it to group 0
510                                 $eve->groupid = 0;
511                             }
513                             //The structure is equal to the db, so insert the event
514                             $newid = $DB->insert_record ("event",$eve);
516                             //We must recode the repeatid if the event has it
517                             //The repeatid now refers to the id of the original event. (see Bug#5956)
518                             if ($newid && !empty($eve->repeatid)) {
519                                 $repeat_rec = backup_getid($restore->backup_unique_code,"event_repeatid",$eve->repeatid);
520                                 if ($repeat_rec) {    //Exists, so use it...
521                                     $eve->repeatid = $repeat_rec->new_id;
522                                 } else {              //Doesn't exists, calculate the next and save it
523                                     $oldrepeatid = $eve->repeatid;
524                                     $eve->repeatid = $newid;
525                                     backup_putid($restore->backup_unique_code,"event_repeatid", $oldrepeatid, $eve->repeatid);
526                                 }
527                                 $eve->id = $newid;
528                                 // update the record to contain the correct repeatid
529                                 $DB->update_record('event',$eve);
530                             }
531                         } else {
532                             //get current event id
533                             $newid = $eve_db->id;
534                         }
535                         if ($newid) {
536                             //We have the newid, update backup_ids
537                             backup_putid($restore->backup_unique_code,"event",
538                                          $event->id, $newid);
539                         }
540                     }
541                 }
542             }
543         } else {
544             $status = false;
545         }
546         return $status;
547     }
549     //This function creates all the structures for every log in backup file
550     //Depending what has been selected.
551     function restore_create_logs($restore,$xml_file) {
552         global $CFG, $DB;
554         //Number of records to get in every chunk
555         $recordset_size = 4;
556         //Counter, points to current record
557         $counter = 0;
558         //To count all the recods to restore
559         $count_logs = 0;
561         $status = true;
562         //Check it exists
563         if (!file_exists($xml_file)) {
564             $status = false;
565         }
566         //Get info from xml
567         if ($status) {
568             //count_logs will contain the number of logs entries to process
569             //in backup_ids->info will be the real info (serialized)
570             $count_logs = restore_read_xml_logs($restore,$xml_file);
571         }
573         //Now, if we have records in count_logs, we have to restore that logs
574         //from backup_ids. This piece of code makes calls to:
575         // - restore_log_course() if it's a course log
576         // - restore_log_user() if it's a user log
577         // - restore_log_module() if it's a module log.
578         //And all is segmented in chunks to allow large recordsets to be restored !!
579         if ($count_logs > 0) {
580             while ($counter < $count_logs) {
581                 //Get a chunk of records
582                 //Take old_id twice to avoid adodb limitation
583                 $logs = $DB->get_records("backup_ids", array("table_name"=>'log', 'backup_code'=>$restore->backup_unique_code),"old_id","old_id",$counter,$recordset_size);
584                 //We have logs
585                 if ($logs) {
586                     //Iterate
587                     foreach ($logs as $log) {
588                         //Get the full record from backup_ids
589                         $data = backup_getid($restore->backup_unique_code,"log",$log->old_id);
590                         if ($data) {
591                             //Now get completed xmlized object
592                             $info = $data->info;
593                             //traverse_xmlize($info);                                                                     //Debug
594                             //print_object ($GLOBALS['traverse_array']);                                                  //Debug
595                             //$GLOBALS['traverse_array']="";                                                              //Debug
596                             //Now build the LOG record structure
597                             $dblog = new stdClass();
598                             $dblog->time = backup_todb($info['LOG']['#']['TIME']['0']['#']);
599                             $dblog->userid = backup_todb($info['LOG']['#']['USERID']['0']['#']);
600                             $dblog->ip = backup_todb($info['LOG']['#']['IP']['0']['#']);
601                             $dblog->course = $restore->course_id;
602                             $dblog->module = backup_todb($info['LOG']['#']['MODULE']['0']['#']);
603                             $dblog->cmid = backup_todb($info['LOG']['#']['CMID']['0']['#']);
604                             $dblog->action = backup_todb($info['LOG']['#']['ACTION']['0']['#']);
605                             $dblog->url = backup_todb($info['LOG']['#']['URL']['0']['#']);
606                             $dblog->info = backup_todb($info['LOG']['#']['INFO']['0']['#']);
607                             //We have to recode the userid field
608                             $user = backup_getid($restore->backup_unique_code,"user",$dblog->userid);
609                             if ($user) {
610                                 //echo "User ".$dblog->userid." to user ".$user->new_id."<br />";                             //Debug
611                                 $dblog->userid = $user->new_id;
612                             }
613                             //We have to recode the cmid field (if module isn't "course" or "user")
614                             if ($dblog->module != "course" and $dblog->module != "user") {
615                                 $cm = backup_getid($restore->backup_unique_code,"course_modules",$dblog->cmid);
616                                 if ($cm) {
617                                     //echo "Module ".$dblog->cmid." to module ".$cm->new_id."<br />";                         //Debug
618                                     $dblog->cmid = $cm->new_id;
619                                 } else {
620                                     $dblog->cmid = 0;
621                                 }
622                             }
623                             //print_object ($dblog);                                                                        //Debug
624                             //Now, we redirect to the needed function to make all the work
625                             if ($dblog->module == "course") {
626                                 //It's a course log,
627                                 $stat = restore_log_course($restore,$dblog);
628                             } elseif ($dblog->module == "user") {
629                                 //It's a user log,
630                                 $stat = restore_log_user($restore,$dblog);
631                             } else {
632                                 //It's a module log,
633                                 $stat = restore_log_module($restore,$dblog);
634                             }
635                         }
637                         //Do some output
638                         $counter++;
639                         if ($counter % 10 == 0) {
640                             if (!defined('RESTORE_SILENTLY')) {
641                                 echo ".";
642                                 if ($counter % 200 == 0) {
643                                     echo "<br />";
644                                 }
645                             }
646                             backup_flush(300);
647                         }
648                     }
649                 } else {
650                     //We never should arrive here
651                     $counter = $count_logs;
652                     $status = false;
653                 }
654             }
655         }
657         return $status;
658     }
660     //This function inserts a course log record, calculating the URL field as necessary
661     function restore_log_course($restore,$log) {
662         global $DB;
664         $status = true;
665         $toinsert = false;
667         //echo "<hr />Before transformations<br />";                                        //Debug
668         //print_object($log);                                                           //Debug
669         //Depending of the action, we recode different things
670         switch ($log->action) {
671         case "view":
672             $log->url = "view.php?id=".$log->course;
673             $log->info = $log->course;
674             $toinsert = true;
675             break;
676         case "guest":
677             $log->url = "view.php?id=".$log->course;
678             $toinsert = true;
679             break;
680         case "user report":
681             //recode the info field (it's the user id)
682             $user = backup_getid($restore->backup_unique_code,"user",$log->info);
683             if ($user) {
684                 $log->info = $user->new_id;
685                 //Now, extract the mode from the url field
686                 $mode = substr(strrchr($log->url,"="),1);
687                 $log->url = "user.php?id=".$log->course."&user=".$log->info."&mode=".$mode;
688                 $toinsert = true;
689             }
690             break;
691         case "add mod":
692             //Extract the course_module from the url field
693             $cmid = substr(strrchr($log->url,"="),1);
694             //recode the course_module to see it it has been restored
695             $cm = backup_getid($restore->backup_unique_code,"course_modules",$cmid);
696             if ($cm) {
697                 $cmid = $cm->new_id;
698                 //Extract the module name and the module id from the info field
699                 $modname = strtok($log->info," ");
700                 $modid = strtok(" ");
701                 //recode the module id to see if it has been restored
702                 $mod = backup_getid($restore->backup_unique_code,$modname,$modid);
703                 if ($mod) {
704                     $modid = $mod->new_id;
705                     //Now I have everything so reconstruct url and info
706                     $log->info = $modname." ".$modid;
707                     $log->url = "../mod/".$modname."/view.php?id=".$cmid;
708                     $toinsert = true;
709                 }
710             }
711             break;
712         case "update mod":
713             //Extract the course_module from the url field
714             $cmid = substr(strrchr($log->url,"="),1);
715             //recode the course_module to see it it has been restored
716             $cm = backup_getid($restore->backup_unique_code,"course_modules",$cmid);
717             if ($cm) {
718                 $cmid = $cm->new_id;
719                 //Extract the module name and the module id from the info field
720                 $modname = strtok($log->info," ");
721                 $modid = strtok(" ");
722                 //recode the module id to see if it has been restored
723                 $mod = backup_getid($restore->backup_unique_code,$modname,$modid);
724                 if ($mod) {
725                     $modid = $mod->new_id;
726                     //Now I have everything so reconstruct url and info
727                     $log->info = $modname." ".$modid;
728                     $log->url = "../mod/".$modname."/view.php?id=".$cmid;
729                     $toinsert = true;
730                 }
731             }
732             break;
733         case "delete mod":
734             $log->url = "view.php?id=".$log->course;
735             $toinsert = true;
736             break;
737         case "update":
738             $log->url = "edit.php?id=".$log->course;
739             $log->info = "";
740             $toinsert = true;
741             break;
742         case "unenrol":
743             //recode the info field (it's the user id)
744             $user = backup_getid($restore->backup_unique_code,"user",$log->info);
745             if ($user) {
746                 $log->info = $user->new_id;
747                 $log->url = "view.php?id=".$log->course;
748                 $toinsert = true;
749             }
750             break;
751         case "enrol":
752             //recode the info field (it's the user id)
753             $user = backup_getid($restore->backup_unique_code,"user",$log->info);
754             if ($user) {
755                 $log->info = $user->new_id;
756                 $log->url = "view.php?id=".$log->course;
757                 $toinsert = true;
758             }
759             break;
760         case "editsection":
761             //Extract the course_section from the url field
762             $secid = substr(strrchr($log->url,"="),1);
763             //recode the course_section to see if it has been restored
764             $sec = backup_getid($restore->backup_unique_code,"course_sections",$secid);
765             if ($sec) {
766                 $secid = $sec->new_id;
767                 //Now I have everything so reconstruct url and info
768                 $log->url = "editsection.php?id=".$secid;
769                 $toinsert = true;
770             }
771             break;
772         case "new":
773             $log->url = "view.php?id=".$log->course;
774             $log->info = "";
775             $toinsert = true;
776             break;
777         case "recent":
778             $log->url = "recent.php?id=".$log->course;
779             $log->info = "";
780             $toinsert = true;
781             break;
782         case "report log":
783             $log->url = "report/log/index.php?id=".$log->course;
784             $log->info = $log->course;
785             $toinsert = true;
786             break;
787         case "report live":
788             $log->url = "report/log/live.php?id=".$log->course;
789             $log->info = $log->course;
790             $toinsert = true;
791             break;
792         case "report outline":
793             $log->url = "report/outline/index.php?id=".$log->course;
794             $log->info = $log->course;
795             $toinsert = true;
796             break;
797         case "report participation":
798             $log->url = "report/participation/index.php?id=".$log->course;
799             $log->info = $log->course;
800             $toinsert = true;
801             break;
802         case "report stats":
803             $log->url = "report/stats/index.php?id=".$log->course;
804             $log->info = $log->course;
805             $toinsert = true;
806             break;
807         default:
808             echo "action (".$log->module."-".$log->action.") unknown. Not restored<br />";                 //Debug
809             break;
810         }
812         //echo "After transformations<br />";                                             //Debug
813         //print_object($log);                                                           //Debug
815         //Now if $toinsert is set, insert the record
816         if ($toinsert) {
817             //echo "Inserting record<br />";                                              //Debug
818             $status = $DB->insert_record("log",$log);
819         }
820         return $status;
821     }
823     //This function inserts a user log record, calculating the URL field as necessary
824     function restore_log_user($restore,$log) {
825         global $DB;
827         $status = true;
828         $toinsert = false;
830         //echo "<hr />Before transformations<br />";                                        //Debug
831         //print_object($log);                                                           //Debug
832         //Depending of the action, we recode different things
833         switch ($log->action) {
834         case "view":
835             //recode the info field (it's the user id)
836             $user = backup_getid($restore->backup_unique_code,"user",$log->info);
837             if ($user) {
838                 $log->info = $user->new_id;
839                 $log->url = "view.php?id=".$log->info."&course=".$log->course;
840                 $toinsert = true;
841             }
842             break;
843         case "change password":
844             //recode the info field (it's the user id)
845             $user = backup_getid($restore->backup_unique_code,"user",$log->info);
846             if ($user) {
847                 $log->info = $user->new_id;
848                 $log->url = "view.php?id=".$log->info."&course=".$log->course;
849                 $toinsert = true;
850             }
851             break;
852         case "login":
853             //recode the info field (it's the user id)
854             $user = backup_getid($restore->backup_unique_code,"user",$log->info);
855             if ($user) {
856                 $log->info = $user->new_id;
857                 $log->url = "view.php?id=".$log->info."&course=".$log->course;
858                 $toinsert = true;
859             }
860             break;
861         case "logout":
862             //recode the info field (it's the user id)
863             $user = backup_getid($restore->backup_unique_code,"user",$log->info);
864             if ($user) {
865                 $log->info = $user->new_id;
866                 $log->url = "view.php?id=".$log->info."&course=".$log->course;
867                 $toinsert = true;
868             }
869             break;
870         case "view all":
871             $log->url = "view.php?id=".$log->course;
872             $log->info = "";
873             $toinsert = true;
874         case "update":
875             //We split the url by ampersand char
876             $first_part = strtok($log->url,"&");
877             //Get data after the = char. It's the user being updated
878             $userid = substr(strrchr($first_part,"="),1);
879             //Recode the user
880             $user = backup_getid($restore->backup_unique_code,"user",$userid);
881             if ($user) {
882                 $log->info = "";
883                 $log->url = "view.php?id=".$user->new_id."&course=".$log->course;
884                 $toinsert = true;
885             }
886             break;
887         default:
888             echo "action (".$log->module."-".$log->action.") unknown. Not restored<br />";                 //Debug
889             break;
890         }
892         //echo "After transformations<br />";                                             //Debug
893         //print_object($log);                                                           //Debug
895         //Now if $toinsert is set, insert the record
896         if ($toinsert) {
897             //echo "Inserting record<br />";                                              //Debug
898             $status = $DB->insert_record("log",$log);
899         }
900         return $status;
901     }
903     //This function inserts a module log record, calculating the URL field as necessary
904     function restore_log_module($restore,$log) {
905         global $DB;
907         $status = true;
908         $toinsert = false;
910         //echo "<hr />Before transformations<br />";                                        //Debug
911         //print_object($log);                                                           //Debug
913         //Now we see if the required function in the module exists
914         $function = $log->module."_restore_logs";
915         if (function_exists($function)) {
916             //Call the function
917             $log = $function($restore,$log);
918             //If everything is ok, mark the insert flag
919             if ($log) {
920                 $toinsert = true;
921             }
922         }
924         //echo "After transformations<br />";                                             //Debug
925         //print_object($log);                                                           //Debug
927         //Now if $toinsert is set, insert the record
928         if ($toinsert) {
929             //echo "Inserting record<br />";                                              //Debug
930             $status = $DB->insert_record("log",$log);
931         }
932         return $status;
933     }
935     function restore_execute(&$restore,$info,$course_header,&$errorstr) {
936         global $CFG, $USER, $DB, $OUTPUT;
938         $status = true;
940         //Now create events as needed
941         if ($status) {
942             if (!defined('RESTORE_SILENTLY')) {
943                 echo "<li>".get_string("creatingevents");
944             }
945             if (!$status = restore_create_events($restore,$xml_file)) {
946                 if (!defined('RESTORE_SILENTLY')) {
947                     echo $OUTPUT->notification("Could not restore course events!");
948                 } else {
949                     $errorstr = "Could not restore course events!";
950                     return false;
951                 }
952             }
953             if (!defined('RESTORE_SILENTLY')) {
954                 echo '</li>';
955             }
956         }
958         if ($status) {
959             //If we are deleting and bringing into a course or making a new course, same situation
960             if ($restore->restoreto == RESTORETO_CURRENT_DELETING ||
961                 $restore->restoreto == RESTORETO_EXISTING_DELETING ||
962                 $restore->restoreto == RESTORETO_NEW_COURSE) {
963                 if (!defined('RESTORE_SILENTLY')) {
964                     echo '<li>'.get_string('courseformatdata');
965                 }
966                 if (!$status = restore_set_format_data($restore, $xml_file)) {
967                         $error = "Error while setting the course format data";
968                     if (!defined('RESTORE_SILENTLY')) {
969                         echo $OUTPUT->notification($error);
970                     } else {
971                         $errorstr=$error;
972                         return false;
973                     }
974                 }
975                 if (!defined('RESTORE_SILENTLY')) {
976                     echo '</li>';
977                 }
978             }
979         }
981         //Now create log entries as needed
982         if ($status and ($info->backup_logs == 'true' && $restore->logs)) {
983             if (!defined('RESTORE_SILENTLY')) {
984                 echo "<li>".get_string("creatinglogentries");
985             }
986             if (!$status = restore_create_logs($restore,$xml_file)) {
987                 if (!defined('RESTORE_SILENTLY')) {
988                     echo $OUTPUT->notification("Could not restore logs!");
989                 } else {
990                     $errorstr = "Could not restore logs!";
991                     return false;
992                 }
993             }
994             if (!defined('RESTORE_SILENTLY')) {
995                 echo '</li>';
996             }
997         }
999         //Now, if all is OK, adjust activity events
1000         if ($status) {
1001             if (!defined('RESTORE_SILENTLY')) {
1002                 echo "<li>".get_string("refreshingevents");
1003             }
1004             if (!$status = restore_refresh_events($restore)) {
1005                 if (!defined('RESTORE_SILENTLY')) {
1006                     echo $OUTPUT->notification("Could not refresh events for activities!");
1007                 } else {
1008                     $errorstr = "Could not refresh events for activities!";
1009                     return false;
1010                 }
1011             }
1012             if (!defined('RESTORE_SILENTLY')) {
1013                 echo '</li>';
1014             }
1015         }
1016     }