2888a132be848b739850ad669f5cc9738fe7ac1a
[moodle.git] / mod / scorm / api1_2.php
1 // 
2 // SCORM API 1.2 Implementation
3 //
5 function SCORMapi() {
6     var cmi= new Object();
7     var nav = new Object();
9     var errorCode = "0";
10     
11     var Initialized = false;
13     function LMSInitialize (param) {
14         if (param != "") {
15             errorCode = "201";
16             return "false";
17         }
18         if (!Initialized) {
19             Initialized = true;
20             errorCode = "0";
21             
22             //
23             // CMI Initialization SCORM 1.2
24             //
25             cmi.core = new Object();
26             cmi.core._children = "student_id,student_name,lesson_location,credit,lesson_status,exit,entry,session_time,total_time,lesson_mode,score,suspend_data,launch_data";
27             cmi.core.student_id = "<?php echo $USER->username; ?>";
28             cmi.core.student_name = "<?php echo $USER->lastname.", ".$USER->firstname; ?>";
29             cmi.core.lesson_location = "<?php echo $sco_user->cmi_core_lesson_location; ?>";
30             cmi.core.credit = "<?php if ($mode != 'normal') {
31                                          echo "no-credit";
32                                      } else {
33                                          echo "credit";
34                                      }?>";
35             cmi.core.lesson_status = "<?php echo $sco_user->cmi_core_lesson_status; ?>";
36             cmi.core.exit = "<?php echo $sco_user->cmi_core_exit ?>";
37             cmi.core.entry = "<?php if ($sco_user->cmi_core_lesson_status == 'not attempted') {
38                                         echo 'ab-initio'; 
39                                     } else {
40                                         if ($sco_user->cmi_core_lesson_status != 'completed') {
41                                             echo 'resume'; 
42                                         } else {
43                                             echo '';
44                                         }
45                                     }?>";
46             cmi.core.session_time = "00:00:00";
47             cmi.core.total_time = "<?php echo $sco_user->cmi_core_total_time; ?>";
48             cmi.core.lesson_mode = "<?php echo $mode; ?>";
49             cmi.core.score = new Object();
50             cmi.core.score._children = "raw,min,max";
51             cmi.core.score.raw = "<?php echo $sco_user->cmi_core_score_raw; ?>";
52             cmi.core.score.min = "";
53             cmi.core.score.max = "";
54             cmi.suspend_data = "<?php echo $sco_user->cmi_suspend_data; ?>";
55             cmi.launch_data = "<?php echo $sco->datafromlms; ?>";
56             cmi.comments = "";
57             cmi.comments_from_lms = "";
58             //
59             // end CMI Initialization
60             //
61             
62             // Navigation Object
63             <?php 
64                 if ($scorm->auto) {
65                     echo 'nav.event = "continue";'."\n";
66                 } else {
67                     echo 'nav.event = "";'."\n";
68                 }
69             ?>
71             return "true";
72         } else {
73             errorCode = "101";
74             return "false";
75         }
76     }
77     
78     function LMSGetValue (param) {
79         if (Initialized) {
80             //top.alert("GET "+param);
81             switch (param) {
82                 case "cmi.core._children":
83                 case "cmi.core.student_id":
84                 case "cmi.core.student_name":
85                 case "cmi.core.lesson_location":
86                 case "cmi.core.credit":
87                 case "cmi.core.lesson_status":
88                 case "cmi.core.entry":
89                 case "cmi.core.total_time":
90                 case "cmi.core.lesson_mode":
91                 case "cmi.core.score._children":
92                 case "cmi.core.score.raw":
93                 case "cmi.core.score.min":
94                 case "cmi.core.score.max":
95                 case "cmi.launch_data":
96                 case "cmi.suspend_data":
97                 case "cmi.comments":
98                 case "cmi.comments_from_lms":
99                     errorCode = "0";
100                     return eval(param);
101                 break;
102                 case "cmi.core.exit":
103                 case "cmi.core.session_time":
104                     errorCode = "404";
105                     return "";
106                 break;
107                 default:
108                     errorCode = "401";
109                     param = param.replace(/.(\d+)./g,"[$1].");
110                     
111                     children = param.match(/._children$/);
112                     if (children != null) {
113                         objType = typeof eval(children[1]);
114                         //alert (param+" :"+objType);
115                         if (objType  != "undefined") {
116                             
117                             errorCode = "202";
118                         }
119                     }
120                     
121                     counted = param.match(/._count$/);
122                     if (counted != null) {
123                         objType = typeof eval(counted[1]);
124                         //alert (param+" :"+objType);
125                         if (objType != "undefined") {
126                             errorCode = "203";
127                         }
128                     }
129                     //alert(param+": "+errorCode);
130                     return "";  
131                 break;
132             }
133         } else {
134             errorCode = "301";
135             return "";
136         }
137     }
138     
139     function LMSSetValue (param,value) {
140         if (Initialized) {
141             //top.alert("SET "+param+" = "+value);
142             switch (param) {
143                 case "cmi.core.session_time":
144                     if (typeof(value) == "string") {
145                         var parsedtime = value.match(/^([0-9]{2,4}):([0-9]{2}):([0-9]{2})(\.[0-9]{1,2})?$/);
146                         if (parsedtime != null) {
147                             //top.alert(parsedtime);
148                             if (((parsedtime.length == 4) || (parsedtime.length == 5)) && (parsedtime[3]>=0) && (parsedtime[3]<=59)) {
149                                 eval(param+'="'+value+'";');
150                                 errorCode = "0";
151                                 return "true";
152                             } else {
153                                 errorCode = "405";
154                                 return "false";
155                             }
156                         } else {
157                             errorCode = "405";
158                             return "false";
159                         }
160                     } else {
161                         errorCode = "405";
162                         return "false";
163                     }
164                 break;
165                 case "cmi.core.lesson_status":
166                     if ((value!="passed")&&(value!="completed")&&(value!="failed")&&(value!="incomplete")&&(value!="browsed")) {
167                         errorCode = "405";
168                         return "false";
169                     }
170                     eval(param+'="'+value+'";');
171                     errorCode = "0";
172                     return "true";
173                 break;
174                 case "cmi.core.score.raw":
175                 case "cmi.core.score.min":
176                 case "cmi.core.score.max":
177                     if (value != "") {
178                         if ((parseFloat(value,10)).toString() != value) {
179                             errorCode = "405";
180                             return "false";
181                         } else {
182                             rawvalue = parseFloat(value,10);
183                             if ((rawvalue<0) || (rawvalue>100)) {
184                                 errorCode = "405";
185                                 return "false";
186                             }
187                         }
188                     }
189                     eval(param+'="'+value+'";');
190                     errorCode = "0";
191                     return "true";
192                 break;
193                 case "cmi.core.exit":
194                     if ((value!="time-out")&&(value!="suspend")&&(value!="logout")&&(value!="")) {
195                         errorCode = "405";
196                         return "false";
197                     }
198                     eval(param+'="'+value+'";');
199                     errorCode = "0";
200                     return "true";
201                 break;
202                 case "cmi.core.lesson_location":
203                     if (value.length > 255) {
204                         errorCode = "405";
205                         return "false";
206                     }
207                     eval(param+'="'+value+'";');
208                     errorCode = "0";
209                     return "true";
210                 break;
211                 case "cmi.suspend_data":
212                 case "cmi.comments":
213                     if (value.length > 4096) {
214                         errorCode = "405";
215                         return "false";
216                     }
217                     eval(param+'="'+value+'";');
218                     errorCode = "0";
219                     return "true";
220                 break;
221                 case "cmi.core._children":
222                 case "cmi.core.score._children":
223                     errorCode = "402";
224                     return "false";
225                 break;
226                 case "cmi.core.student_id":
227                 case "cmi.core.student_name":
228                 case "cmi.core.credit":
229                 case "cmi.core.entry":
230                 case "cmi.core.total_time":
231                 case "cmi.core.lesson_mode":
232                 case "cmi.launch_data":
233                 case "cmi.comments_from_lms":
234                     errorCode = "403";
235                     return "false";
236                 break;
237                 case "nav.event":
238                     if ((value == "previous") || (value == "continue")) {
239                         eval(param+'="'+value+'";');
240                         errorCode = "0";
241                         return "true";
242                     } else {
243                         erroCode = "405";
244                         return "false";
245                     }
246                 break;  
247                 default:
248                     errorCode = "401";  //This is more correct but may have problem with some SCOes
249                     //errorCode = "0"; // With this disable any possible SCO errors alert
250                     return "false";
251                 break;
252             }
253         } else {
254             errorCode = "301";
255             return "false";
256         }
257     }
259     function LMSCommit (param) {
260         if (param != "") {
261             errorCode = "201";
262             return "false";
263         }
264         if (Initialized) {
265             if (<?php echo $navObj ?>cmi.document.theform) {
266                 cmiform = <?php echo $navObj ?>cmi.document.forms[0];
267                 cmiform.scoid.value = "<?php echo $sco->id; ?>";
268                 cmiform.cmi_core_lesson_location.value = cmi.core.lesson_location;
269                 cmiform.cmi_core_lesson_status.value = cmi.core.lesson_status;
270                 cmiform.cmi_core_exit.value = cmi.core.exit;
271                 cmiform.cmi_core_score_raw.value = cmi.core.score.raw;
272                 cmiform.cmi_suspend_data.value = cmi.suspend_data;
273                 cmiform.submit();
274             }
275             errorCode = "0";
276             return "true";
277         } else {
278             errorCode = "301";
279             return "false";
280         }
281     }
282     
283     function LMSFinish (param) {
284         if (param != "") {
285             errorCode = "201";
286             return "false";
287         }
288         if (!Initialized) {
289             errorCode = "301";
290             return "false";
291         } else {
292             Initialized = false;
293             errorCode = "0";
294            
295             if (nav.event != "") {
296             <?php
297                 if ($sco != $last) {
298                     echo "setTimeout('top.changeSco(nav.event);',500);\n";
299                 } else {
300                     echo "exitloc = '".$CFG->wwwroot."/mod/scorm/view.php?id=".$cm->id."';\n";
301                     echo "setTimeout('top.location = exitloc;',500);\n";
302                 } 
303             ?>
304             }
305             return "true";
306         }    
307     }
308     
309     function LMSGetLastError () {
310         return errorCode;
311     }
312     
313     function LMSGetErrorString (param) {
314         var errorString = new Array();
315         errorString["0"] = "No error";
316         errorString["101"] = "General exception";
317         errorString["201"] = "Invalid argument error";
318         errorString["202"] = "Element cannot have children";
319         errorString["203"] = "Element not an array - cannot have count";
320         errorString["301"] = "Not initialized";
321         errorString["401"] = "Not implemented error";
322         errorString["402"] = "Invalid set value, element is a keyword";
323         errorString["403"] = "Element is read only";
324         errorString["404"] = "Element is write only";
325         errorString["405"] = "Incorrect data type";
326         return errorString[param];
327     }
328     
329     function LMSGetDiagnostic (param) {
330         return param;
331     }
332         
333     function AddTime (first, second) {
334         var sFirst = first.split(":");
335         var sSecond = second.split(":");
336         var change = 0;
337         
338         var secs = (Math.round((parseFloat(sFirst[2],10)+parseFloat(sSecond[2],10))*100))/100;  //Seconds
339         change = Math.floor(secs / 60);
340         secs = secs - (change * 60);
341         if (Math.floor(secs) < 10) secs = "0" + secs.toString();
342         
343         mins = parseInt(sFirst[1],10)+parseInt(sSecond[1],10)+change;   //Minutes
344         change = Math.floor(mins / 60);
345         mins = mins - (change * 60);
346         if (mins < 10) mins = "0" + mins.toString();
347             
348         hours = parseInt(sFirst[0],10)+parseInt(sSecond[0],10)+change;  //Hours
349         if (hours < 10) hours = "0" + hours.toString();
350         
351         return hours + ":" + mins + ":" + secs;
352     }
353     
354     function SaveTotalTime() {
355         cmi.core.total_time = AddTime(cmi.core.total_time, cmi.core.session_time);
356         //top.alert(cmi.core.total_time);
357         if (<?php echo $navObj ?>cmi.document.forms[0]) {
358             cmiform = <?php echo $navObj ?>cmi.document.forms[0];
359             cmiform.reset();
360             cmiform.scoid.value = "<?php echo $sco->id; ?>";
361             cmiform.cmi_core_total_time.value = cmi.core.total_time;
362             cmiform.submit();
363             //top.alert(cmi.core.total_time);
364         }
365     }
366     
367     this.SaveTotalTime = SaveTotalTime;
368     
369     this.LMSInitialize = LMSInitialize;
370     this.LMSGetValue = LMSGetValue;
371     this.LMSSetValue = LMSSetValue;
372     this.LMSCommit = LMSCommit;
373     this.LMSFinish = LMSFinish;
374     this.LMSGetLastError = LMSGetLastError;
375     this.LMSGetErrorString = LMSGetErrorString;
376     this.LMSGetDiagnostic = LMSGetDiagnostic;
379 var API = new SCORMapi();