MDL-11082 Improved groups upgrade performance 1.8x -> 1.9; thanks Eloy for telling...
[moodle-pu.git] / mod / lesson / backuplib.php
bloba7259d840f94436832ab74b7a6a472987ad003af
1 <?php //$Id$
2 /**
3 * Lesson's backup routine
5 * @version $Id$
6 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
7 * @package lesson
8 **/
9 //This is the "graphical" structure of the lesson mod:
11 // lesson_default lesson ----------------------------|--------------------------|--------------------------|
12 // (UL, pk->id,fk->courseid) (CL,pk->id) | | |
13 // | | | |
14 // | lesson_grades lesson_high_scores lesson_timer
15 // | (UL, pk->id,fk->lessonid) (UL, pk->id,fk->lessonid) (UL, pk->id,fk->lessonid)
16 // |
17 // |
18 // lesson_pages---------------------------|
19 // (CL,pk->id,fk->lessonid) |
20 // | |
21 // | lesson_branch
22 // | (UL, pk->id,fk->pageid)
23 // lesson_answers
24 // (CL,pk->id,fk->pageid)
25 // |
26 // |
27 // |
28 // lesson_attempts
29 // (UL,pk->id,fk->answerid)
31 // Meaning: pk->primary key field of the table
32 // fk->foreign key to link with parent
33 // nt->nested field (recursive data)
34 // CL->course level info
35 // UL->user level info
36 // files->table may have files)
38 //-----------------------------------------------------------
40 //This function executes all the backup procedure about this mod
41 function lesson_backup_mods($bf, $preferences) {
43 global $CFG;
45 $status = true;
47 //Iterate over lesson table
48 $lessons = get_records("lesson", "course", $preferences->backup_course, "id");
49 if ($lessons) {
50 foreach ($lessons as $lesson) {
51 if (backup_mod_selected($preferences,'lesson',$lesson->id)) {
52 $status = lesson_backup_one_mod($bf,$preferences,$lesson);
56 return $status;
59 function lesson_backup_one_mod($bf,$preferences,$lesson) {
61 global $CFG;
63 if (is_numeric($lesson)) {
64 $lesson = get_record('lesson','id',$lesson);
67 $status = true;
69 //Start mod
70 fwrite ($bf,start_tag("MOD",3,true));
71 //Print lesson data
72 fwrite ($bf,full_tag("ID",4,false,$lesson->id));
73 fwrite ($bf,full_tag("MODTYPE",4,false,"lesson"));
74 fwrite ($bf,full_tag("NAME",4,false,$lesson->name));
75 fwrite ($bf,full_tag("PRACTICE",4,false,$lesson->practice));
76 fwrite ($bf,full_tag("MODATTEMPTS",4,false,$lesson->modattempts));
77 fwrite ($bf,full_tag("USEPASSWORD",4,false,$lesson->usepassword));
78 fwrite ($bf,full_tag("PASSWORD",4,false,$lesson->password));
79 fwrite ($bf,full_tag("DEPENDENCY",4,false,$lesson->dependency));
80 fwrite ($bf,full_tag("CONDITIONS",4,false,$lesson->conditions));
81 fwrite ($bf,full_tag("GRADE",4,false,$lesson->grade));
82 fwrite ($bf,full_tag("CUSTOM",4,false,$lesson->custom));
83 fwrite ($bf,full_tag("ONGOING",4,false,$lesson->ongoing));
84 fwrite ($bf,full_tag("USEMAXGRADE",4,false,$lesson->usemaxgrade));
85 fwrite ($bf,full_tag("MAXANSWERS",4,false,$lesson->maxanswers));
86 fwrite ($bf,full_tag("MAXATTEMPTS",4,false,$lesson->maxattempts));
87 fwrite ($bf,full_tag("REVIEW",4,false,$lesson->review));
88 fwrite ($bf,full_tag("NEXTPAGEDEFAULT",4,false,$lesson->nextpagedefault));
89 fwrite ($bf,full_tag("FEEDBACK",4,false,$lesson->feedback));
90 fwrite ($bf,full_tag("MINQUESTIONS",4,false,$lesson->minquestions));
91 fwrite ($bf,full_tag("MAXPAGES",4,false,$lesson->maxpages));
92 fwrite ($bf,full_tag("TIMED",4,false,$lesson->timed));
93 fwrite ($bf,full_tag("MAXTIME",4,false,$lesson->maxtime));
94 fwrite ($bf,full_tag("RETAKE",4,false,$lesson->retake));
95 fwrite ($bf,full_tag("ACTIVITYLINK",4,false,$lesson->activitylink));
96 fwrite ($bf,full_tag("MEDIAFILE",4,false,$lesson->mediafile));
97 fwrite ($bf,full_tag("MEDIAHEIGHT",4,false,$lesson->mediaheight));
98 fwrite ($bf,full_tag("MEDIAWIDTH",4,false,$lesson->mediawidth));
99 fwrite ($bf,full_tag("MEDIACLOSE",4,false,$lesson->mediaclose));
100 fwrite ($bf,full_tag("SLIDESHOW",4,false,$lesson->slideshow));
101 fwrite ($bf,full_tag("WIDTH",4,false,$lesson->width));
102 fwrite ($bf,full_tag("HEIGHT",4,false,$lesson->height));
103 fwrite ($bf,full_tag("BGCOLOR",4,false,$lesson->bgcolor));
104 fwrite ($bf,full_tag("DISPLAYLEFT",4,false,$lesson->displayleft));
105 fwrite ($bf,full_tag("DISPLAYLEFTIF",4,false,$lesson->displayleftif));
106 fwrite ($bf,full_tag("PROGRESSBAR",4,false,$lesson->progressbar));
107 fwrite ($bf,full_tag("SHOWHIGHSCORES",4,false,$lesson->highscores));
108 fwrite ($bf,full_tag("MAXHIGHSCORES",4,false,$lesson->maxhighscores));
109 fwrite ($bf,full_tag("AVAILABLE",4,false,$lesson->available));
110 fwrite ($bf,full_tag("DEADLINE",4,false,$lesson->deadline));
111 fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$lesson->timemodified));
113 //Now we backup lesson pages
114 $status = backup_lesson_pages($bf,$preferences,$lesson->id);
115 //if we've selected to backup users info, then backup grades, high scores, and timer info
116 if ($status) {
117 if (backup_userdata_selected($preferences,'lesson',$lesson->id)) {
118 if(!backup_lesson_grades($bf, $preferences, $lesson->id)) {
119 return false;
121 if (!backup_lesson_high_scores($bf, $preferences, $lesson->id)) {
122 return false;
124 if (!backup_lesson_timer($bf, $preferences, $lesson->id)) {
125 return false;
128 // back up the default for the course. There might not be one, but if there
129 // is, there will only be one.
130 $status = backup_lesson_default($bf,$preferences);
131 //End mod
132 if ($status) {
133 $status =fwrite ($bf,end_tag("MOD",3,true));
137 return $status;
140 //Backup lesson_pages contents (executed from lesson_backup_mods)
141 function backup_lesson_pages ($bf, $preferences, $lessonid) {
143 global $CFG;
145 $status = true;
147 // run through the pages in their logical order, get the first page
148 if ($page = get_record_select("lesson_pages", "lessonid = $lessonid AND prevpageid = 0")) {
149 //Write start tag
150 $status =fwrite ($bf,start_tag("PAGES",4,true));
151 //Iterate over each page
152 while (true) {
153 //Start of page
154 $status =fwrite ($bf,start_tag("PAGE",5,true));
155 //Print page contents (prevpageid and nextpageid not needed)
156 fwrite ($bf,full_tag("PAGEID",6,false,$page->id)); // needed to fix (absolute) jumps
157 fwrite ($bf,full_tag("QTYPE",6,false,$page->qtype));
158 fwrite ($bf,full_tag("QOPTION",6,false,$page->qoption));
159 fwrite ($bf,full_tag("LAYOUT",6,false,$page->layout));
160 fwrite ($bf,full_tag("DISPLAY",6,false,$page->display));
161 fwrite ($bf,full_tag("TIMECREATED",6,false,$page->timecreated));
162 fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$page->timemodified));
163 fwrite ($bf,full_tag("TITLE",6,false,$page->title));
164 fwrite ($bf,full_tag("CONTENTS",6,false,$page->contents));
165 //Now we backup lesson answers for this page
166 $status = backup_lesson_answers($bf, $preferences, $page->id);
167 // backup branch table info for branch tables.
168 if ($status && backup_userdata_selected($preferences,'lesson',$lessonid)) {
169 if (!backup_lesson_branch($bf, $preferences, $page->id)) {
170 return false;
173 //End of page
174 $status =fwrite ($bf,end_tag("PAGE",5,true));
175 // move to the next (logical) page
176 if ($page->nextpageid) {
177 if (!$page = get_record("lesson_pages", "id", $page->nextpageid)) {
178 error("Lesson Backup: Next page not found!");
180 } else {
181 // last page reached
182 break;
186 //Write end tag
187 $status =fwrite ($bf,end_tag("PAGES",4,true));
189 return $status;
192 //Backup lesson_answers contents (executed from backup_lesson_pages)
193 function backup_lesson_answers($bf,$preferences,$pageno) {
195 global $CFG;
197 $status = true;
199 // get the answers in a set order, the id order
200 $lesson_answers = get_records("lesson_answers", "pageid", $pageno, "id");
202 //If there is lesson_answers
203 if ($lesson_answers) {
204 //Write start tag
205 $status =fwrite ($bf,start_tag("ANSWERS",6,true));
206 //Iterate over each element
207 foreach ($lesson_answers as $answer) {
208 //Start answer
209 $status =fwrite ($bf,start_tag("ANSWER",7,true));
210 //Print answer contents
211 fwrite ($bf,full_tag("ID",8,false,$answer->id));
212 fwrite ($bf,full_tag("JUMPTO",8,false,$answer->jumpto));
213 fwrite ($bf,full_tag("GRADE",8,false,$answer->grade));
214 fwrite ($bf,full_tag("SCORE",8,false,$answer->score));
215 fwrite ($bf,full_tag("FLAGS",8,false,$answer->flags));
216 fwrite ($bf,full_tag("TIMECREATED",8,false,$answer->timecreated));
217 fwrite ($bf,full_tag("TIMEMODIFIED",8,false,$answer->timemodified));
218 fwrite ($bf,full_tag("ANSWERTEXT",8,false,$answer->answer));
219 fwrite ($bf,full_tag("RESPONSE",8,false,$answer->response));
220 //Now we backup any lesson attempts (if student data required)
221 if (backup_userdata_selected($preferences,'lesson',$answer->lessonid)) {
222 $status = backup_lesson_attempts($bf,$preferences,$answer->id);
224 //End rubric
225 $status =fwrite ($bf,end_tag("ANSWER",7,true));
227 //Write end tag
228 $status =fwrite ($bf,end_tag("ANSWERS",6,true));
230 return $status;
233 //Backup lesson_attempts contents (executed from lesson_backup_answers)
234 function backup_lesson_attempts ($bf,$preferences,$answerid) {
236 global $CFG;
238 $status = true;
240 $lesson_attempts = get_records("lesson_attempts","answerid", $answerid);
241 //If there are attempts
242 if ($lesson_attempts) {
243 //Write start tag
244 $status =fwrite ($bf,start_tag("ATTEMPTS",8,true));
245 //Iterate over each attempt
246 foreach ($lesson_attempts as $attempt) {
247 //Start Attempt
248 $status =fwrite ($bf,start_tag("ATTEMPT",9,true));
249 //Print attempt contents
250 fwrite ($bf,full_tag("USERID",10,false,$attempt->userid));
251 fwrite ($bf,full_tag("RETRY",10,false,$attempt->retry));
252 fwrite ($bf,full_tag("CORRECT",10,false,$attempt->correct));
253 fwrite ($bf,full_tag("USERANSWER",10,false,$attempt->useranswer));
254 fwrite ($bf,full_tag("TIMESEEN",10,false,$attempt->timeseen));
255 //End attempt
256 $status =fwrite ($bf,end_tag("ATTEMPT",9,true));
258 //Write end tag
259 $status =fwrite ($bf,end_tag("ATTEMPTS",8,true));
261 return $status;
265 //Backup lesson_grades contents (executed from backup_lesson_mods)
266 function backup_lesson_grades ($bf,$preferences,$lessonid) {
268 global $CFG;
270 $status = true;
272 $grades = get_records("lesson_grades", "lessonid", $lessonid);
274 //If there is grades
275 if ($grades) {
276 //Write start tag
277 $status =fwrite ($bf,start_tag("GRADES",4,true));
278 //Iterate over each grade
279 foreach ($grades as $grade) {
280 //Start grade
281 $status =fwrite ($bf,start_tag("GRADE",5,true));
282 //Print grade contents
283 fwrite ($bf,full_tag("USERID",6,false,$grade->userid));
284 fwrite ($bf,full_tag("GRADE_VALUE",6,false,$grade->grade));
285 fwrite ($bf,full_tag("LATE",6,false,$grade->late));
286 fwrite ($bf,full_tag("COMPLETED",6,false,$grade->completed));
287 //End grade
288 $status =fwrite ($bf,end_tag("GRADE",5,true));
290 //Write end tag
291 $status =fwrite ($bf,end_tag("GRADES",4,true));
293 return $status;
296 //Backup lesson_branch contents (executed from backup_lesson_pages)
297 function backup_lesson_branch($bf,$preferences,$pageno) {
299 global $CFG;
301 $status = true;
303 // get the branches in a set order, the id order
304 $lesson_branch = get_records("lesson_branch", "pageid", $pageno, "id");
306 //If there is lesson_branch
307 if ($lesson_branch) {
308 //Write start tag
309 $status =fwrite ($bf,start_tag("BRANCHES",6,true));
310 //Iterate over each element
311 foreach ($lesson_branch as $branch) {
312 //Start branch
313 $status =fwrite ($bf,start_tag("BRANCH",7,true));
314 //Print branch contents
315 fwrite ($bf,full_tag("USERID",8,false,$branch->userid));
316 fwrite ($bf,full_tag("RETRY",8,false,$branch->retry));
317 fwrite ($bf,full_tag("FLAG",8,false,$branch->flag));
318 fwrite ($bf,full_tag("TIMESEEN",8,false,$branch->timeseen));
319 // END BRANCH
320 $status =fwrite ($bf,end_tag("BRANCH",7,true));
322 //Write end tag
323 $status =fwrite ($bf,end_tag("BRANCHES",6,true));
325 return $status;
328 //Backup lesson_timer contents (executed from backup_lesson_mods)
329 function backup_lesson_timer ($bf,$preferences,$lessonid) {
331 global $CFG;
333 $status = true;
335 $times = get_records("lesson_timer", "lessonid", $lessonid);
337 //If there is times
338 if ($times) {
339 //Write start tag
340 $status =fwrite ($bf,start_tag("TIMES",4,true));
341 //Iterate over each time
342 foreach ($times as $time) {
343 //Start time
344 $status =fwrite ($bf,start_tag("TIME",5,true));
345 //Print time contents
346 fwrite ($bf,full_tag("USERID",6,false,$time->userid));
347 fwrite ($bf,full_tag("STARTTIME",6,false,$time->starttime));
348 fwrite ($bf,full_tag("LESSONTIME",6,false,$time->lessontime));
349 //End time
350 $status =fwrite ($bf,end_tag("TIME",5,true));
352 //Write end tag
353 $status =fwrite ($bf,end_tag("TIMES",4,true));
355 return $status;
358 // backup lesson_high_score contents (executed from backup_lesson_mods)
359 function backup_lesson_high_scores($bf, $preferences, $lessonid) {
360 global $CFG;
362 $status = true;
364 $highscores = get_records("lesson_high_scores", "lessonid", $lessonid);
366 //If there is highscores
367 if ($highscores) {
368 //Write start tag
369 $status =fwrite ($bf,start_tag("HIGHSCORES",4,true));
370 //Iterate over each highscore
371 foreach ($highscores as $highscore) {
372 //Start highscore
373 $status =fwrite ($bf,start_tag("HIGHSCORE",5,true));
374 //Print highscore contents
375 fwrite ($bf,full_tag("USERID",6,false,$highscore->userid));
376 fwrite ($bf,full_tag("GRADEID",6,false,$highscore->gradeid));
377 fwrite ($bf,full_tag("NICKNAME",6,false,$highscore->nickname));
378 //End highscore
379 $status =fwrite ($bf,end_tag("HIGHSCORE",5,true));
381 //Write end tag
382 $status =fwrite ($bf,end_tag("HIGHSCORES",4,true));
384 return $status;
387 // backup lesson_default contents (executed from backup_lesson_mods)
388 function backup_lesson_default ($bf,$preferences) {
389 global $CFG;
391 $status = true;
393 //only one default record per course
394 $default = get_record("lesson_default", "course", $preferences->backup_course);
395 if ($default) {
396 //Start mod
397 $status =fwrite ($bf,start_tag("DEFAULTS",4,true));
398 //Print default data
399 fwrite ($bf,full_tag("PRACTICE",5,false,$default->practice));
400 fwrite ($bf,full_tag("MODATTEMPTS",5,false,$default->modattempts));
401 fwrite ($bf,full_tag("USEPASSWORD",5,false,$default->usepassword));
402 fwrite ($bf,full_tag("PASSWORD",5,false,$default->password));
403 fwrite ($bf,full_tag("CONDITIONS",5,false,$default->conditions));
404 fwrite ($bf,full_tag("GRADE",5,false,$default->grade));
405 fwrite ($bf,full_tag("CUSTOM",5,false,$default->custom));
406 fwrite ($bf,full_tag("ONGOING",5,false,$default->ongoing));
407 fwrite ($bf,full_tag("USEMAXGRADE",5,false,$default->usemaxgrade));
408 fwrite ($bf,full_tag("MAXANSWERS",5,false,$default->maxanswers));
409 fwrite ($bf,full_tag("MAXATTEMPTS",5,false,$default->maxattempts));
410 fwrite ($bf,full_tag("REVIEW",5,false,$default->review));
411 fwrite ($bf,full_tag("NEXTPAGEDEFAULT",5,false,$default->nextpagedefault));
412 fwrite ($bf,full_tag("FEEDBACK",5,false,$default->feedback));
413 fwrite ($bf,full_tag("MINQUESTIONS",5,false,$default->minquestions));
414 fwrite ($bf,full_tag("MAXPAGES",5,false,$default->maxpages));
415 fwrite ($bf,full_tag("TIMED",5,false,$default->timed));
416 fwrite ($bf,full_tag("MAXTIME",5,false,$default->maxtime));
417 fwrite ($bf,full_tag("RETAKE",5,false,$default->retake));
418 fwrite ($bf,full_tag("MEDIAHEIGHT",5,false,$default->mediaheight));
419 fwrite ($bf,full_tag("MEDIAWIDTH",5,false,$default->mediawidth));
420 fwrite ($bf,full_tag("MEDIACLOSE",5,false,$default->mediaclose));
421 fwrite ($bf,full_tag("SLIDESHOW",5,false,$default->slideshow));
422 fwrite ($bf,full_tag("WIDTH",5,false,$default->width));
423 fwrite ($bf,full_tag("HEIGHT",5,false,$default->height));
424 fwrite ($bf,full_tag("BGCOLOR",5,false,$default->bgcolor));
425 fwrite ($bf,full_tag("DISPLAYLEFT",5,false,$default->displayleft));
426 fwrite ($bf,full_tag("DISPLAYLEFTIF",5,false,$default->displayleftif));
427 fwrite ($bf,full_tag("PROGRESSBAR",5,false,$default->progressbar));
428 fwrite ($bf,full_tag("HIGHSCORES",5,false,$default->highscores));
429 fwrite ($bf,full_tag("MAXHIGHSCORES",5,false,$default->maxhighscores));
430 $status =fwrite ($bf,end_tag("DEFAULTS",4,true));
432 return $status;
435 //Return an array of info (name,value)
436 function lesson_check_backup_mods($course,$user_data=false,$backup_unique_code,$instances=null) {
437 if (!empty($instances) && is_array($instances) && count($instances)) {
438 $info = array();
439 foreach ($instances as $id => $instance) {
440 $info += lesson_check_backup_mods_instances($instance,$backup_unique_code);
442 return $info;
444 //First the course data
445 $info[0][0] = get_string("modulenameplural","lesson");
446 if ($ids = lesson_ids($course)) {
447 $info[0][1] = count($ids);
448 } else {
449 $info[0][1] = 0;
452 //Now, if requested, the user_data
453 if ($user_data) {
454 $info[1][0] = get_string("attempts","lesson");
455 if ($ids = lesson_attempts_ids_by_course ($course)) {
456 $info[1][1] = count($ids);
457 } else {
458 $info[1][1] = 0;
461 return $info;
464 //Return an array of info (name,value)
465 function lesson_check_backup_mods_instances($instance,$backup_unique_code) {
466 //First the course data
467 $info[$instance->id.'0'][0] = '<b>'.$instance->name.'</b>';
468 $info[$instance->id.'0'][1] = '';
470 //Now, if requested, the user_data
471 if (!empty($instance->userdata)) {
472 $info[$instance->id.'1'][0] = get_string("attempts","lesson");
473 if ($ids = lesson_attempts_ids_by_instance ($instance->id)) {
474 $info[$instance->id.'1'][1] = count($ids);
475 } else {
476 $info[$instance->id.'1'][1] = 0;
479 return $info;
482 //Return a content encoded to support interactivities linking. Every module
483 //should have its own. They are called automatically from the backup procedure.
484 function lesson_encode_content_links ($content,$preferences) {
486 global $CFG;
488 $base = preg_quote($CFG->wwwroot,"/");
490 //Link to the list of lessons
491 $buscar="/(".$base."\/mod\/lesson\/index.php\?id\=)([0-9]+)/";
492 $result= preg_replace($buscar,'$@LESSONINDEX*$2@$',$content);
494 //Link to lesson view by moduleid
495 $buscar="/(".$base."\/mod\/lesson\/view.php\?id\=)([0-9]+)/";
496 $result= preg_replace($buscar,'$@LESSONVIEWBYID*$2@$',$result);
498 return $result;
501 // INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE
503 //Returns an array of lesson id
504 function lesson_ids ($course) {
506 global $CFG;
508 return get_records_sql ("SELECT l.id, l.course
509 FROM {$CFG->prefix}lesson l
510 WHERE l.course = '$course'");
513 //Returns an array of lesson_submissions id
514 function lesson_attempts_ids_by_course ($course) {
516 global $CFG;
518 return get_records_sql ("SELECT a.id , a.lessonid
519 FROM {$CFG->prefix}lesson_attempts a,
520 {$CFG->prefix}lesson l
521 WHERE l.course = '$course' AND
522 a.lessonid = l.id");
525 //Returns an array of lesson_submissions id
526 function lesson_attempts_ids_by_instance ($instanceid) {
528 global $CFG;
530 return get_records_sql ("SELECT a.id , a.lessonid
531 FROM {$CFG->prefix}lesson_attempts a
532 WHERE a.lessonid = $instanceid");