925b449245166e726aed84c7c84c2339f053d1a3
[moodle.git] / mod / lesson / backuplib.php
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
18 /**
19  * Lesson's backup routine
20  *
21  * @package    mod
22  * @subpackage lesson
23  * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
24  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25  **/
27 // This is the "graphical" structure of the lesson mod:
28 //
29 //                  lesson ----------------------------|--------------------------|--------------------------|
30 //               (CL,pk->id)                           |                          |                          |
31 //                     |                               |                          |                          |
32 //                     |                         lesson_grades              lesson_high_scores         lesson_timer
33 //                     |                  (UL, pk->id,fk->lessonid)    (UL, pk->id,fk->lessonid)   (UL, pk->id,fk->lessonid)
34 //                     |
35 //                     |
36 //              lesson_pages---------------------------|
37 //          (CL,pk->id,fk->lessonid)                   |
38 //                     |                               |
39 //                     |                         lesson_branch
40 //                     |                   (UL, pk->id,fk->pageid)
41 //               lesson_answers
42 //            (CL,pk->id,fk->pageid)
43 //                     |
44 //                     |
45 //                     |
46 //               lesson_attempts
47 //          (UL,pk->id,fk->answerid)
48 //
49 // Meaning: pk->primary key field of the table
50 //          fk->foreign key to link with parent
51 //          nt->nested field (recursive data)
52 //          CL->course level info
53 //          UL->user level info
54 //          files->table may have files)
55 //
56 //-----------------------------------------------------------
58 defined('MOODLE_INTERNAL') || die();
60 /**
61  * This function executes all the backup procedure about this mod
62  */
63 function lesson_backup_mods($bf, $preferences) {
65     global $CFG, $DB;
67     $status = true;
69     //Iterate over lesson table
70     $lessons = $DB->get_records("lesson", array ("course" => $preferences->backup_course), "id");
71     if ($lessons) {
72         foreach ($lessons as $lesson) {
73             if (backup_mod_selected($preferences,'lesson',$lesson->id)) {
74                 $status = lesson_backup_one_mod($bf,$preferences,$lesson);
75             }
76         }
77     }
78     return $status;
79 }
81 function lesson_backup_one_mod($bf,$preferences,$lesson) {
83     global $CFG, $DB;
85     if (is_numeric($lesson)) {
86         $lesson = $DB->get_record('lesson',array ('id' => $lesson));
87     }
89     $status = true;
91     //Start mod
92     fwrite ($bf,start_tag("MOD",3,true));
93     //Print lesson data
94     fwrite ($bf,full_tag("ID",4,false,$lesson->id));
95     fwrite ($bf,full_tag("MODTYPE",4,false,"lesson"));
96     fwrite ($bf,full_tag("NAME",4,false,$lesson->name));
97     fwrite ($bf,full_tag("PRACTICE",4,false,$lesson->practice));
98     fwrite ($bf,full_tag("MODATTEMPTS",4,false,$lesson->modattempts));
99     fwrite ($bf,full_tag("USEPASSWORD",4,false,$lesson->usepassword));
100     fwrite ($bf,full_tag("PASSWORD",4,false,$lesson->password));
101     fwrite ($bf,full_tag("DEPENDENCY",4,false,$lesson->dependency));
102     fwrite ($bf,full_tag("CONDITIONS",4,false,$lesson->conditions));
103     fwrite ($bf,full_tag("GRADE",4,false,$lesson->grade));
104     fwrite ($bf,full_tag("CUSTOM",4,false,$lesson->custom));
105     fwrite ($bf,full_tag("ONGOING",4,false,$lesson->ongoing));
106     fwrite ($bf,full_tag("USEMAXGRADE",4,false,$lesson->usemaxgrade));
107     fwrite ($bf,full_tag("MAXANSWERS",4,false,$lesson->maxanswers));
108     fwrite ($bf,full_tag("MAXATTEMPTS",4,false,$lesson->maxattempts));
109     fwrite ($bf,full_tag("REVIEW",4,false,$lesson->review));
110     fwrite ($bf,full_tag("NEXTPAGEDEFAULT",4,false,$lesson->nextpagedefault));
111     fwrite ($bf,full_tag("FEEDBACK",4,false,$lesson->feedback));
112     fwrite ($bf,full_tag("MINQUESTIONS",4,false,$lesson->minquestions));
113     fwrite ($bf,full_tag("MAXPAGES",4,false,$lesson->maxpages));
114     fwrite ($bf,full_tag("TIMED",4,false,$lesson->timed));
115     fwrite ($bf,full_tag("MAXTIME",4,false,$lesson->maxtime));
116     fwrite ($bf,full_tag("RETAKE",4,false,$lesson->retake));
117     fwrite ($bf,full_tag("ACTIVITYLINK",4,false,$lesson->activitylink));
118     fwrite ($bf,full_tag("MEDIAFILE",4,false,$lesson->mediafile));
119     fwrite ($bf,full_tag("MEDIAHEIGHT",4,false,$lesson->mediaheight));
120     fwrite ($bf,full_tag("MEDIAWIDTH",4,false,$lesson->mediawidth));
121     fwrite ($bf,full_tag("MEDIACLOSE",4,false,$lesson->mediaclose));
122     fwrite ($bf,full_tag("SLIDESHOW",4,false,$lesson->slideshow));
123     fwrite ($bf,full_tag("WIDTH",4,false,$lesson->width));
124     fwrite ($bf,full_tag("HEIGHT",4,false,$lesson->height));
125     fwrite ($bf,full_tag("BGCOLOR",4,false,$lesson->bgcolor));
126     fwrite ($bf,full_tag("DISPLAYLEFT",4,false,$lesson->displayleft));
127     fwrite ($bf,full_tag("DISPLAYLEFTIF",4,false,$lesson->displayleftif));
128     fwrite ($bf,full_tag("PROGRESSBAR",4,false,$lesson->progressbar));
129     fwrite ($bf,full_tag("SHOWHIGHSCORES",4,false,$lesson->highscores));
130     fwrite ($bf,full_tag("MAXHIGHSCORES",4,false,$lesson->maxhighscores));
131     fwrite ($bf,full_tag("AVAILABLE",4,false,$lesson->available));
132     fwrite ($bf,full_tag("DEADLINE",4,false,$lesson->deadline));
133     fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$lesson->timemodified));
135     //Now we backup lesson pages
136     $status = backup_lesson_pages($bf,$preferences,$lesson->id);
137     //if we've selected to backup users info, then backup grades, high scores, and timer info
138     if ($status) {
139         if (backup_userdata_selected($preferences,'lesson',$lesson->id)) {
140             if(!backup_lesson_grades($bf, $preferences, $lesson->id)) {
141                 return false;
142             }
143             if (!backup_lesson_high_scores($bf, $preferences, $lesson->id)) {
144                 return false;
145             }
146             if (!backup_lesson_timer($bf, $preferences, $lesson->id)) {
147                 return false;
148             }
149         }
150         //End mod
151         $status =fwrite ($bf,end_tag("MOD",3,true));
152     }
154     return $status;
157 //Backup lesson_pages contents (executed from lesson_backup_mods)
158 function backup_lesson_pages ($bf, $preferences, $lessonid) {
160     global $CFG, $DB;
162     $status = true;
164     // run through the pages in their logical order, get the first page
165     $params = array ("lessonid" => $lessonid, "prevpageid" => 0);
166     if ($page = $DB->get_record_select("lesson_pages", "lessonid = :lessonid AND prevpageid = :prevpageid", $params)) {
167         //Write start tag
168         $status =fwrite ($bf,start_tag("PAGES",4,true));
169         //Iterate over each page
170         while (true) {
171             //Start of page
172             $status =fwrite ($bf,start_tag("PAGE",5,true));
173             //Print page contents (prevpageid and nextpageid not needed)
174             fwrite ($bf,full_tag("PAGEID",6,false,$page->id)); // needed to fix (absolute) jumps
175             fwrite ($bf,full_tag("QTYPE",6,false,$page->qtype));
176             fwrite ($bf,full_tag("QOPTION",6,false,$page->qoption));
177             fwrite ($bf,full_tag("LAYOUT",6,false,$page->layout));
178             fwrite ($bf,full_tag("DISPLAY",6,false,$page->display));
179             fwrite ($bf,full_tag("TIMECREATED",6,false,$page->timecreated));
180             fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$page->timemodified));
181             fwrite ($bf,full_tag("TITLE",6,false,$page->title));
182             fwrite ($bf,full_tag("CONTENTS",6,false,$page->contents));
183             //Now we backup lesson answers for this page
184             $status = backup_lesson_answers($bf, $preferences, $page->id);
185             // backup branch table info for branch tables.
186             if ($status && backup_userdata_selected($preferences,'lesson',$lessonid)) {
187                 if (!backup_lesson_branch($bf, $preferences, $page->id)) {
188                     return false;
189                 }
190             }
191             //End of page
192             $status =fwrite ($bf,end_tag("PAGE",5,true));
193             // move to the next (logical) page
194             if ($page->nextpageid) {
195                 if (!$page = $DB->get_record("lesson_pages", array ("id" => $page->nextpageid))) {
196                     print_error('cannotfindnextpage', 'lesson');
197                 }
198             } else {
199                 // last page reached
200                 break;
201             }
203         }
204         //Write end tag
205         $status =fwrite ($bf,end_tag("PAGES",4,true));
206     }
207     return $status;
210 //Backup lesson_answers contents (executed from backup_lesson_pages)
211 function backup_lesson_answers($bf,$preferences,$pageno) {
213     global $CFG, $DB;
215     $status = true;
217     // get the answers in a set order, the id order
218     $lesson_answers = $DB->get_records("lesson_answers", array("pageid" => $pageno), "id");
220     //If there is lesson_answers
221     if ($lesson_answers) {
222         //Write start tag
223         $status =fwrite ($bf,start_tag("ANSWERS",6,true));
224         //Iterate over each element
225         foreach ($lesson_answers as $answer) {
226             //Start answer
227             $status =fwrite ($bf,start_tag("ANSWER",7,true));
228             //Print answer contents
229             fwrite ($bf,full_tag("ID",8,false,$answer->id));
230             fwrite ($bf,full_tag("JUMPTO",8,false,$answer->jumpto));
231             fwrite ($bf,full_tag("GRADE",8,false,$answer->grade));
232             fwrite ($bf,full_tag("SCORE",8,false,$answer->score));
233             fwrite ($bf,full_tag("FLAGS",8,false,$answer->flags));
234             fwrite ($bf,full_tag("TIMECREATED",8,false,$answer->timecreated));
235             fwrite ($bf,full_tag("TIMEMODIFIED",8,false,$answer->timemodified));
236             fwrite ($bf,full_tag("ANSWERTEXT",8,false,$answer->answer));
237             fwrite ($bf,full_tag("RESPONSE",8,false,$answer->response));
238             //Now we backup any lesson attempts (if student data required)
239             if (backup_userdata_selected($preferences,'lesson',$answer->lessonid)) {
240                 $status = backup_lesson_attempts($bf,$preferences,$answer->id);
241             }
242             //End rubric
243             $status =fwrite ($bf,end_tag("ANSWER",7,true));
244         }
245         //Write end tag
246         $status =fwrite ($bf,end_tag("ANSWERS",6,true));
247     }
248     return $status;
251 //Backup lesson_attempts contents (executed from lesson_backup_answers)
252 function backup_lesson_attempts ($bf,$preferences,$answerid) {
254     global $CFG, $DB;
256     $status = true;
258     $lesson_attempts = $DB->get_records("lesson_attempts", array("answerid" => $answerid));
259     //If there are attempts
260     if ($lesson_attempts) {
261         //Write start tag
262         $status =fwrite ($bf,start_tag("ATTEMPTS",8,true));
263         //Iterate over each attempt
264         foreach ($lesson_attempts as $attempt) {
265             //Start Attempt
266             $status =fwrite ($bf,start_tag("ATTEMPT",9,true));
267             //Print attempt contents
268             fwrite ($bf,full_tag("USERID",10,false,$attempt->userid));
269             fwrite ($bf,full_tag("RETRY",10,false,$attempt->retry));
270             fwrite ($bf,full_tag("CORRECT",10,false,$attempt->correct));
271             fwrite ($bf,full_tag("USERANSWER",10,false,$attempt->useranswer));
272             fwrite ($bf,full_tag("TIMESEEN",10,false,$attempt->timeseen));
273             //End attempt
274             $status =fwrite ($bf,end_tag("ATTEMPT",9,true));
275         }
276         //Write end tag
277         $status =fwrite ($bf,end_tag("ATTEMPTS",8,true));
278     }
279     return $status;
283 //Backup lesson_grades contents (executed from backup_lesson_mods)
284 function backup_lesson_grades ($bf,$preferences,$lessonid) {
286     global $CFG, $DB;
288     $status = true;
290     $grades = $DB->get_records("lesson_grades", array("lessonid" => $lessonid));
292     //If there is grades
293     if ($grades) {
294         //Write start tag
295         $status =fwrite ($bf,start_tag("GRADES",4,true));
296         //Iterate over each grade
297         foreach ($grades as $grade) {
298             //Start grade
299             $status =fwrite ($bf,start_tag("GRADE",5,true));
300             //Print grade contents
301             fwrite ($bf,full_tag("USERID",6,false,$grade->userid));
302             fwrite ($bf,full_tag("GRADE_VALUE",6,false,$grade->grade));
303             fwrite ($bf,full_tag("LATE",6,false,$grade->late));
304             fwrite ($bf,full_tag("COMPLETED",6,false,$grade->completed));
305             //End grade
306             $status =fwrite ($bf,end_tag("GRADE",5,true));
307         }
308         //Write end tag
309         $status =fwrite ($bf,end_tag("GRADES",4,true));
310     }
311     return $status;
314 //Backup lesson_branch contents (executed from backup_lesson_pages)
315 function backup_lesson_branch($bf,$preferences,$pageno) {
317     global $CFG, $DB;
319     $status = true;
321     // get the branches in a set order, the id order
322     $lesson_branch = $DB->get_records("lesson_branch", array("pageid" => $pageno), "id");
324     //If there is lesson_branch
325     if ($lesson_branch) {
326         //Write start tag
327         $status =fwrite ($bf,start_tag("BRANCHES",6,true));
328         //Iterate over each element
329         foreach ($lesson_branch as $branch) {
330             //Start branch
331             $status =fwrite ($bf,start_tag("BRANCH",7,true));
332             //Print branch contents
333             fwrite ($bf,full_tag("USERID",8,false,$branch->userid));
334             fwrite ($bf,full_tag("RETRY",8,false,$branch->retry));
335             fwrite ($bf,full_tag("FLAG",8,false,$branch->flag));
336             fwrite ($bf,full_tag("TIMESEEN",8,false,$branch->timeseen));
337             // END BRANCH
338             $status =fwrite ($bf,end_tag("BRANCH",7,true));
339         }
340         //Write end tag
341         $status =fwrite ($bf,end_tag("BRANCHES",6,true));
342     }
343     return $status;
346 //Backup lesson_timer contents (executed from backup_lesson_mods)
347 function backup_lesson_timer ($bf,$preferences,$lessonid) {
349     global $CFG, $DB;
351     $status = true;
353     $times = $DB->get_records("lesson_timer", array("lessonid" => $lessonid));
355     //If there is times
356     if ($times) {
357         //Write start tag
358         $status =fwrite ($bf,start_tag("TIMES",4,true));
359         //Iterate over each time
360         foreach ($times as $time) {
361             //Start time
362             $status =fwrite ($bf,start_tag("TIME",5,true));
363             //Print time contents
364             fwrite ($bf,full_tag("USERID",6,false,$time->userid));
365             fwrite ($bf,full_tag("STARTTIME",6,false,$time->starttime));
366             fwrite ($bf,full_tag("LESSONTIME",6,false,$time->lessontime));
367             //End time
368             $status =fwrite ($bf,end_tag("TIME",5,true));
369         }
370         //Write end tag
371         $status =fwrite ($bf,end_tag("TIMES",4,true));
372     }
373     return $status;
376 // backup lesson_high_score contents (executed from backup_lesson_mods)
377 function backup_lesson_high_scores($bf, $preferences, $lessonid) {
378     global $CFG, $DB;
380     $status = true;
382     $highscores = $DB->get_records("lesson_high_scores", array("lessonid" => $lessonid));
384     //If there is highscores
385     if ($highscores) {
386         //Write start tag
387         $status =fwrite ($bf,start_tag("HIGHSCORES",4,true));
388         //Iterate over each highscore
389         foreach ($highscores as $highscore) {
390             //Start highscore
391             $status =fwrite ($bf,start_tag("HIGHSCORE",5,true));
392             //Print highscore contents
393             fwrite ($bf,full_tag("USERID",6,false,$highscore->userid));
394             fwrite ($bf,full_tag("GRADEID",6,false,$highscore->gradeid));
395             fwrite ($bf,full_tag("NICKNAME",6,false,$highscore->nickname));
396             //End highscore
397             $status =fwrite ($bf,end_tag("HIGHSCORE",5,true));
398         }
399         //Write end tag
400         $status =fwrite ($bf,end_tag("HIGHSCORES",4,true));
401     }
402     return $status;
405 //Return an array of info (name,value)
406 function lesson_check_backup_mods($course,$user_data=false,$backup_unique_code,$instances=null) {
407     if (!empty($instances) && is_array($instances) && count($instances)) {
408         $info = array();
409         foreach ($instances as $id => $instance) {
410             $info += lesson_check_backup_mods_instances($instance,$backup_unique_code);
411         }
412         return $info;
413     }
414     //First the course data
415     $info[0][0] = get_string("modulenameplural","lesson");
416     if ($ids = lesson_ids($course)) {
417         $info[0][1] = count($ids);
418     } else {
419         $info[0][1] = 0;
420     }
422     //Now, if requested, the user_data
423     if ($user_data) {
424         $info[1][0] = get_string("attempts","lesson");
425         if ($ids = lesson_attempts_ids_by_course ($course)) {
426             $info[1][1] = count($ids);
427         } else {
428             $info[1][1] = 0;
429         }
430     }
431     return $info;
434 //Return an array of info (name,value)
435 function lesson_check_backup_mods_instances($instance,$backup_unique_code) {
436     //First the course data
437     $info[$instance->id.'0'][0] = '<b>'.$instance->name.'</b>';
438     $info[$instance->id.'0'][1] = '';
440     //Now, if requested, the user_data
441     if (!empty($instance->userdata)) {
442         $info[$instance->id.'1'][0] = get_string("attempts","lesson");
443         if ($ids = lesson_attempts_ids_by_instance ($instance->id)) {
444             $info[$instance->id.'1'][1] = count($ids);
445         } else {
446             $info[$instance->id.'1'][1] = 0;
447         }
448     }
449     return $info;
452 //Return a content encoded to support interactivities linking. Every module
453 //should have its own. They are called automatically from the backup procedure.
454 function lesson_encode_content_links ($content,$preferences) {
456     global $CFG;
458     $base = preg_quote($CFG->wwwroot,"/");
460     //Link to the list of lessons
461     $buscar="/(".$base."\/mod\/lesson\/index.php\?id\=)([0-9]+)/";
462     $result= preg_replace($buscar,'$@LESSONINDEX*$2@$',$content);
464     //Link to lesson view by moduleid
465     $buscar="/(".$base."\/mod\/lesson\/view.php\?id\=)([0-9]+)/";
466     $result= preg_replace($buscar,'$@LESSONVIEWBYID*$2@$',$result);
468     return $result;
471 // INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE
473 //Returns an array of lesson id
474 function lesson_ids ($course) {
476     global $CFG, $DB;
478     $params = array ("course" => $course);
479     return $DB->get_records_sql ("SELECT l.id, l.course
480                              FROM {lesson} l
481                              WHERE l.course = :course", $params);
484 //Returns an array of lesson_submissions id
485 function lesson_attempts_ids_by_course ($course) {
487     global $CFG, $DB;
489     $params = array ("course" => $course);
490     return $DB->get_records_sql ("SELECT a.id , a.lessonid
491                              FROM {lesson_attempts} a,
492                                   {lesson} l
493                              WHERE l.course = :course AND
494                                    a.lessonid = l.id", $params);
497 //Returns an array of lesson_submissions id
498 function lesson_attempts_ids_by_instance ($instanceid) {
500     global $CFG, $DB;
502     $params = array ("lessonid" => $instanceid);
503     return $DB->get_records_sql ("SELECT a.id , a.lessonid
504                              FROM {lesson_attempts} a
505                              WHERE a.lessonid = :lessonid", $params);