2 //This php script contains all the stuff to backup/restore
5 //This is the "graphical" structure of the scorm mod:
8 // (CL,pk->id)-------------------------------------
12 // scorm_scoes scorm_scoes_data |
13 // (UL,pk->id, fk->scorm)-------(UL,pk->id, fk->scoid) |
17 // scorm_scoes_track |
18 // (UL,k->id, fk->scormid, fk->scoid, k->element)-------------------
20 // Meaning: pk->primary key field of the table
21 // fk->foreign key to link with parent
22 // nt->nested field (recursive data)
23 // CL->course level info
24 // UL->user level info
25 // files->table may have files)
27 //-----------------------------------------------------------
29 function scorm_backup_mods($bf,$preferences) {
35 //Iterate over scorm table
36 $scorms = get_records ('scorm','course',$preferences->backup_course
,'id');
38 foreach ($scorms as $scorm) {
39 if (backup_mod_selected($preferences,'scorm',$scorm->id
)) {
40 $status = scorm_backup_one_mod($bf,$preferences,$scorm);
47 function scorm_backup_one_mod($bf,$preferences,$scorm) {
50 if (is_numeric($scorm)) {
51 $scorm = get_record('scorm','id',$scorm);
55 fwrite ($bf,start_tag('MOD',3,true));
57 fwrite ($bf,full_tag('ID',4,false,$scorm->id
));
58 fwrite ($bf,full_tag('MODTYPE',4,false,'scorm'));
59 fwrite ($bf,full_tag('NAME',4,false,$scorm->name
));
60 fwrite ($bf,full_tag('REFERENCE',4,false,$scorm->reference
));
61 fwrite ($bf,full_tag('VERSION',4,false,$scorm->version
));
62 fwrite ($bf,full_tag('MAXGRADE',4,false,$scorm->maxgrade
));
63 fwrite ($bf,full_tag('GRADEMETHOD',4,false,$scorm->grademethod
));
64 fwrite ($bf,full_tag('LAUNCH',4,false,$scorm->launch
));
65 fwrite ($bf,full_tag('SKIPVIEW',4,false,$scorm->skipview
));
66 fwrite ($bf,full_tag('SUMMARY',4,false,$scorm->summary
));
67 fwrite ($bf,full_tag('HIDEBROWSE',4,false,$scorm->hidebrowse
));
68 fwrite ($bf,full_tag('HIDETOC',4,false,$scorm->hidetoc
));
69 fwrite ($bf,full_tag('HIDENAV',4,false,$scorm->hidenav
));
70 fwrite ($bf,full_tag('AUTO',4,false,$scorm->auto
));
71 fwrite ($bf,full_tag('POPUP',4,false,$scorm->popup
));
72 fwrite ($bf,full_tag('OPTIONS',4,false,$scorm->options
));
73 fwrite ($bf,full_tag('WIDTH',4,false,$scorm->width
));
74 fwrite ($bf,full_tag('HEIGHT',4,false,$scorm->height
));
75 fwrite ($bf,full_tag('MD5HASH',4,false,$scorm->md5hash
));
76 fwrite ($bf,full_tag("MAXATTEMPT",4,false,$scorm->maxattempt
));
77 fwrite ($bf,full_tag("UPDATEFREQ",4,false,$scorm->updatefreq
));
78 fwrite ($bf,full_tag('TIMEMODIFIED',4,false,$scorm->timemodified
));
79 $status = backup_scorm_scoes($bf,$preferences,$scorm->id
);
81 //if we've selected to backup users info, then execute backup_scorm_scoes_track
83 if (backup_userdata_selected($preferences,'scorm',$scorm->id
)) {
84 $status = backup_scorm_scoes_track($bf,$preferences,$scorm->id
);
86 $status = backup_scorm_files_instance($bf,$preferences,$scorm->id
);
90 $status =fwrite ($bf,end_tag('MOD',3,true));
94 //Backup scorm_scoes contents (executed from scorm_backup_mods)
95 function backup_scorm_scoes ($bf,$preferences,$scorm) {
101 $scorm_scoes = get_records('scorm_scoes','scorm',$scorm,'id');
105 $status =fwrite ($bf,start_tag('SCOES',4,true));
106 //Iterate over each sco
107 foreach ($scorm_scoes as $sco) {
109 $status =fwrite ($bf,start_tag('SCO',5,true));
110 //Print submission contents
111 fwrite ($bf,full_tag('ID',6,false,$sco->id
));
112 fwrite ($bf,full_tag('MANIFEST',6,false,$sco->manifest
));
113 fwrite ($bf,full_tag('ORGANIZATION',6,false,$sco->organization
));
114 fwrite ($bf,full_tag('PARENT',6,false,$sco->parent
));
115 fwrite ($bf,full_tag('IDENTIFIER',6,false,$sco->identifier
));
116 fwrite ($bf,full_tag('LAUNCH',6,false,$sco->launch
));
117 fwrite ($bf,full_tag('SCORMTYPE',6,false,$sco->scormtype
));
118 fwrite ($bf,full_tag('TITLE',6,false,$sco->title
));
119 $status = backup_scorm_scoes_data($bf,$preferences,$sco->id
);
120 $status = backup_scorm_seq_ruleconds($bf,$preferences,$sco->id
);
121 $status = backup_scorm_seq_rolluprule($bf,$preferences,$sco->id
);
122 $status = backup_scorm_seq_objective($bf,$preferences,$sco->id
);
124 $status =fwrite ($bf,end_tag('SCO',5,true));
127 $status =fwrite ($bf,end_tag('SCOES',4,true));
132 //Backup scorm_scoes_data contents (executed from scorm_backup_scorm_scoes)
133 function backup_scorm_scoes_data ($bf,$preferences,$sco) {
139 $scorm_sco_datas = get_records('scorm_scoes_data','scoid',$sco,'id');
141 if ($scorm_sco_datas) {
143 $status =fwrite ($bf,start_tag('SCO_DATAS',4,true));
144 //Iterate over each sco
145 foreach ($scorm_sco_datas as $sco_data) {
147 $status =fwrite ($bf,start_tag('SCO_DATA',5,true));
148 //Print track contents
149 fwrite ($bf,full_tag('ID',6,false,$sco_data->id
));
150 fwrite ($bf,full_tag('SCOID',6,false,$sco_data->scoid
));
151 fwrite ($bf,full_tag('NAME',6,false,$sco_data->name
));
152 fwrite ($bf,full_tag('VALUE',6,false,$sco_data->value
));
154 $status =fwrite ($bf,end_tag('SCO_DATA',5,true));
157 $status =fwrite ($bf,end_tag('SCO_DATAS',4,true));
162 //Backup scorm_scoes_track contents (executed from scorm_backup_mods)
163 function backup_scorm_scoes_track ($bf,$preferences,$scorm) {
169 $scorm_scoes_track = get_records('scorm_scoes_track','scormid',$scorm,'id');
171 if ($scorm_scoes_track) {
173 $status =fwrite ($bf,start_tag('SCO_TRACKS',4,true));
174 //Iterate over each sco
175 foreach ($scorm_scoes_track as $sco_track) {
177 $status =fwrite ($bf,start_tag('SCO_TRACK',5,true));
178 //Print track contents
179 fwrite ($bf,full_tag('ID',6,false,$sco_track->id
));
180 fwrite ($bf,full_tag('USERID',6,false,$sco_track->userid
));
181 fwrite ($bf,full_tag('SCOID',6,false,$sco_track->scoid
));
182 fwrite ($bf,full_tag('ELEMENT',6,false,$sco_track->element
));
183 fwrite ($bf,full_tag('VALUE',6,false,$sco_track->value
));
184 fwrite ($bf,full_tag('ATTEMPT',6,false,$sco_track->attempt
));
185 fwrite ($bf,full_tag('TIMEMODIFIED',6,false,$sco_track->timemodified
));
187 $status =fwrite ($bf,end_tag('SCO_TRACK',5,true));
190 $status =fwrite ($bf,end_tag('SCO_TRACKS',4,true));
196 function backup_scorm_seq_ruleconds ($bf,$preferences,$sco) {
202 $scorm_seq_ruleconditions = get_records('scorm_seq_ruleconds','scoid',$sco,'id');
203 //If there is rulecondition
204 if ($scorm_seq_ruleconditions) {
206 $status =fwrite ($bf,start_tag('SEQ_RULECONDS',4,true));
207 //Iterate over each sco
208 foreach ($scorm_seq_ruleconditions as $seq_rulecondition) {
210 $status =fwrite ($bf,start_tag('SEQ_RULECOND',5,true));
211 //Print track contents
212 fwrite ($bf,full_tag('ID',6,false,$seq_rulecondition->id
));
213 fwrite ($bf,full_tag('SCOID',6,false,$seq_rulecondition->scoid
));
214 fwrite ($bf,full_tag('CONDITIONCOMBINATION',6,false,$seq_rulecondition->conditioncombination
));
215 fwrite ($bf,full_tag('RULETYPE',6,false,$seq_rulecondition->ruletype
));
216 fwrite ($bf,full_tag('ACTION',6,false,$seq_rulecondition->action
));
218 $status = backup_scorm_seq_rulecond($bf,$preferences,$seq_rulecondition->id
);
220 $status =fwrite ($bf,end_tag('SEQ_RULECOND',5,true));
223 $status =fwrite ($bf,end_tag('SEQ_RULECOND',4,true));
229 function backup_scorm_seq_rulecond ($bf,$preferences,$ruleconditions) {
235 $scorm_seq_ruleconditions = get_records('scorm_seq_rulecond','ruleconditionsid',$ruleconditions,'id');
236 //If there is rulecondition
237 if ($scorm_seq_ruleconditions) {
239 $status =fwrite ($bf,start_tag('SEQ_RULECOND_DATAS',4,true));
240 //Iterate over each sco
241 foreach ($scorm_seq_ruleconditions as $seq_rulecondition) {
243 $status =fwrite ($bf,start_tag('SEQ_RULECOND_DATA',5,true));
244 //Print track contents
245 fwrite ($bf,full_tag('ID',6,false,$seq_rulecondition->id
));
246 fwrite ($bf,full_tag('SCOID',6,false,$seq_rulecondition->scoid
));
247 fwrite ($bf,full_tag('RULECONDITIONSID',6,false,$seq_rulecondition->ruleconditionsid
));
248 fwrite ($bf,full_tag('REFRENCEDOBJECTIVE',6,false,$seq_rulecondition->refrencedobjective
));
249 fwrite ($bf,full_tag('MEASURETHRESHOLD',6,false,$seq_rulecondition->measurethreshold
));
250 fwrite ($bf,full_tag('OPERATOR',6,false,$seq_rulecondition->operator
));
251 fwrite ($bf,full_tag('COND',6,false,$seq_rulecondition->cond
));
253 $status =fwrite ($bf,end_tag('SEQ_RULECOND_DATA',5,true));
256 $status =fwrite ($bf,end_tag('SEQ_RULECOND_DATAS',4,true));
261 function backup_scorm_seq_rolluprule ($bf,$preferences,$sco) {
267 $scorm_seq_rolluprules = get_records('scorm_seq_rolluprule','scoid',$sco,'id');
268 //If there is rulecondition
269 if ($scorm_seq_rolluprules) {
271 $status =fwrite ($bf,start_tag('SEQ_ROLLUPRULES',4,true));
272 //Iterate over each sco
273 foreach ($scorm_seq_rolluprules as $seq_rolluprule) {
275 $status =fwrite ($bf,start_tag('SEQ_ROLLUPRULE',5,true));
276 //Print track contents
277 fwrite ($bf,full_tag('ID',6,false,$seq_rolluprule->id
));
278 fwrite ($bf,full_tag('SCOID',6,false,$seq_rolluprule->scoid
));
279 fwrite ($bf,full_tag('CHILDACTIVITYSET',6,false,$seq_rolluprule->childactivityset
));
280 fwrite ($bf,full_tag('MINIMUMCOUNT',6,false,$seq_rolluprule->minimumcount
));
281 fwrite ($bf,full_tag('MINIMUMPERCENT',6,false,$seq_rolluprule->minimumpercent
));
282 fwrite ($bf,full_tag('CONDITIONCOMBINATION',6,false,$seq_rolluprule->conditioncomnination
));
283 fwrite ($bf,full_tag('ACTION',6,false,$seq_rolluprule->action
));
284 $status = backup_scorm_seq_rolluprulecond($bf,$preferences,$seq_rolluprule->id
);
286 $status =fwrite ($bf,end_tag('SEQ_ROLLUPRULE',5,true));
289 $status =fwrite ($bf,end_tag('SEQ_ROLLUPRULES',4,true));
295 function backup_scorm_seq_rolluprulecond ($bf,$preferences,$rolluprule) {
301 $scorm_seq_rollupruleconditions = get_records('scorm_seq_rolluprulecond','rollupruleid',$rolluprule,'id');
302 //If there is rulecondition
303 if ($scorm_seq_rollupruleconditions) {
305 $status =fwrite ($bf,start_tag('SEQ_ROLLUPRULECONDS',4,true));
306 //Iterate over each sco
307 foreach ($scorm_seq_rollupruleconditions as $seq_rolluprulecondition) {
309 $status =fwrite ($bf,start_tag('SEQ_ROLLUPRULECOND',5,true));
310 //Print track contents
311 fwrite ($bf,full_tag('ID',6,false,$seq_rolluprulecondition->id
));
312 fwrite ($bf,full_tag('SCOID',6,false,$seq_rolluprulecondition->scoid
));
313 fwrite ($bf,full_tag('ROLLUPRULEID',6,false,$seq_rolluprulecondition->rollupruleid
));
314 fwrite ($bf,full_tag('COND',6,false,$seq_rolluprulecondition->condition
));
315 fwrite ($bf,full_tag('OPERATOR',6,false,$seq_rolluprulecondition->operator
));
318 $status =fwrite ($bf,end_tag('SEQ_ROLLUPRULECOND',5,true));
321 $status =fwrite ($bf,end_tag('SEQ_ROLLUPRULECONDS',4,true));
327 function backup_scorm_seq_objective ($bf,$preferences,$sco) {
333 $scorm_seq_objectives = get_records('scorm_seq_objective','scoid',$sco,'id');
334 //If there is rulecondition
335 if ($scorm_seq_objectives) {
337 $status =fwrite ($bf,start_tag('SEQ_OBJECTIVES',4,true));
338 //Iterate over each sco
339 foreach ($scorm_seq_objectives as $seq_objective) {
341 $status =fwrite ($bf,start_tag('SEQ_OBJECTIVE',5,true));
342 //Print track contents
343 fwrite ($bf,full_tag('ID',6,false,$seq_objective->id
));
344 fwrite ($bf,full_tag('SCOID',6,false,$seq_objective->scoid
));
345 fwrite ($bf,full_tag('PRIMARYOBJ',6,false,$seq_objective->primaryobj
));
346 fwrite ($bf,full_tag('OBJECTIVEID',6,false,$seq_objective->objectiveid
));
347 fwrite ($bf,full_tag('MINNORMALIZEDMEASURE',6,false,$seq_objective->minnormalizedmeasure
));
348 fwrite ($bf,full_tag('SATISFIEDBYMEASURE',6,false,$seq_objective->objectivemeasureweight
));
350 $status = backup_scorm_seq_mapinfo($bf,$preferences,$seq_objective->id
);
352 $status =fwrite ($bf,end_tag('SEQ_OBJECTIVE',5,true));
355 $status =fwrite ($bf,end_tag('SEQ_OBJECTIVES',4,true));
360 function backup_scorm_seq_mapinfo ($bf,$preferences,$objectives) {
366 $scorm_seq_objectives = get_records('scorm_seq_mapinfo','objectiveid',$objectives,'id');
367 //If there is rulecondition
368 if ($scorm_seq_objectives) {
370 $status =fwrite ($bf,start_tag('SEQ_MAPINFO',4,true));
371 //Iterate over each sco
372 foreach ($scorm_seq_objectives as $seq_objective) {
374 $status =fwrite ($bf,start_tag('SEQ_MAPINF',5,true));
375 //Print track contents
376 fwrite ($bf,full_tag('ID',6,false,$seq_objective->id
));
377 fwrite ($bf,full_tag('SCOID',6,false,$seq_objective->scoid
));
378 fwrite ($bf,full_tag('OBJECTIVEID',6,false,$seq_objective->objectiveid
));
379 fwrite ($bf,full_tag('TARGETOBJECTIVEID',6,false,$seq_objective->targetobjectiveid
));
380 fwrite ($bf,full_tag('READSATISFIEDSTATUS',6,false,$seq_objective->readsatisfiedstatus
));
381 fwrite ($bf,full_tag('READNORMALIZEDMEASURE',6,false,$seq_objective->readnormalizedmeasure
));
382 fwrite ($bf,full_tag('WRITESATISFIEDSTATUS',6,false,$seq_objective->writesatisfiedstatus
));
383 fwrite ($bf,full_tag('WRITENORMALIZEDMEASURE',6,false,$seq_objective->writenormalizedmeasure
));
385 $status =fwrite ($bf,end_tag('SEQ_MAPINF',5,true));
388 $status =fwrite ($bf,end_tag('SEQ_MAPINFO',4,true));
393 ////Return an array of info (name,value)
394 function scorm_check_backup_mods($course,$user_data=false,$backup_unique_code,$instances=null) {
395 if (!empty($instances) && is_array($instances) && count($instances)) {
397 foreach ($instances as $id => $instance) {
398 $info +
= scorm_check_backup_mods_instances($instance,$backup_unique_code);
402 //First the course data
403 $info[0][0] = get_string('modulenameplural','scorm');
404 if ($ids = scorm_ids ($course)) {
405 $info[0][1] = count($ids);
410 //Now, if requested, the user_data
412 $info[1][0] = get_string('scoes','scorm');
413 if ($ids = scorm_scoes_track_ids_by_course ($course)) {
414 $info[1][1] = count($ids);
422 function scorm_check_backup_mods_instances($instance,$backup_unique_code) {
423 $info[$instance->id
.'0'][0] = $instance->name
;
424 $info[$instance->id
.'0'][1] = '';
425 if (!empty($instance->userdata
)) {
426 $info[$instance->id
.'1'][0] = get_string('scoes','scorm');
427 if ($ids = scorm_scoes_track_ids_by_instance ($instance->id
)) {
428 $info[$instance->id
.'1'][1] = count($ids);
430 $info[$instance->id
.'1'][1] = 0;
438 function backup_scorm_files_instance($bf,$preferences,$instanceid) {
443 //First we check to moddata exists and create it as necessary
444 //in temp/backup/$backup_code dir
445 $status = check_and_create_moddata_dir($preferences->backup_unique_code
);
446 $status = check_dir_exists($CFG->dataroot
.'/temp/backup/'.$preferences->backup_unique_code
.'/moddata/scorm/',true);
448 //Only if it exists !! Thanks to Daniel Miksik.
449 if (is_dir($CFG->dataroot
.'/'.$preferences->backup_course
.'/'.$CFG->moddata
.'/scorm/'.$instanceid)) {
450 $status = backup_copy_file($CFG->dataroot
.'/'.$preferences->backup_course
.'/'.$CFG->moddata
.'/scorm/'.$instanceid,
451 $CFG->dataroot
.'/temp/backup/'.$preferences->backup_unique_code
.'/moddata/scorm/'.$instanceid);
459 //Backup scorm package files
460 function backup_scorm_files($bf,$preferences) {
466 //First we check to moddata exists and create it as necessary
467 //in temp/backup/$backup_code dir
468 $status = check_and_create_moddata_dir($preferences->backup_unique_code
);
469 //Now copy the scorm dir
471 if (is_dir($CFG->dataroot
.'/'.$preferences->backup_course
.'/'.$CFG->moddata
.'/scorm')) {
472 $handle = opendir($CFG->dataroot
.'/'.$preferences->backup_course
.'/'.$CFG->moddata
.'/scorm');
473 while (false!==($item = readdir($handle))) {
474 if ($item != '.' && $item != '..' && is_dir($CFG->dataroot
.'/'.$preferences->backup_course
.'/'.$CFG->moddata
.'/scorm/'.$item)
475 && array_key_exists($item,$preferences->mods
['scorm']->instances
)
476 && !empty($preferences->mods
['scorm']->instances
[$item]->backup
)) {
477 $status = backup_copy_file($CFG->dataroot
.'/'.$preferences->backup_course
.'/'.$CFG->moddata
.'/scorm/'.$item,
478 $CFG->dataroot
.'/temp/backup/'.$preferences->backup_unique_code
.'/moddata/scorm/',$item);
488 //Return a content encoded to support interactivities linking. Every module
489 //should have its own. They are called automatically from the backup procedure.
490 function scorm_encode_content_links ($content,$preferences) {
494 $base = preg_quote($CFG->wwwroot
,"/");
496 //Link to the list of scorms
497 $buscar="/(".$base."\/mod\/scorm\/index.php\?id\=)([0-9]+)/";
498 $result= preg_replace($buscar,'$@SCORMINDEX*$2@$',$content);
500 //Link to scorm view by moduleid
501 $buscar="/(".$base."\/mod\/scorm\/view.php\?id\=)([0-9]+)/";
502 $result= preg_replace($buscar,'$@SCORMVIEWBYID*$2@$',$result);
507 // INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE
509 //Returns an array of scorms id
510 function scorm_ids ($course) {
514 return get_records_sql ("SELECT a.id, a.course
515 FROM {$CFG->prefix}scorm a
516 WHERE a.course = '$course'");
519 //Returns an array of scorm_scoes id
520 function scorm_scoes_track_ids_by_course ($course) {
524 return get_records_sql ("SELECT s.id , s.scormid
525 FROM {$CFG->prefix}scorm_scoes_track s,
526 {$CFG->prefix}scorm a
527 WHERE a.course = '$course' AND
531 //Returns an array of scorm_scoes id
532 function scorm_scoes_track_ids_by_instance ($instanceid) {
536 return get_records_sql ("SELECT s.id , s.scormid
537 FROM {$CFG->prefix}scorm_scoes_track s
538 WHERE s.scormid = $instanceid");