Fixed problem with the update of cmi.entry adding conditions in the first php block
[moodle.git] / mod / scorm / datamodels / scorm_13.js.php
1 <?php
2     if (isset($userdata->status)) {
3         if ($userdata->status == ''&& (!(($userdata->{'cmi.exit'} == 'suspend') || ($userdata->{'cmi.exit'} == 'logout'))&& !($userdata->{'adl.nav.request'} == 'suspendAll'))||($userdata->{'cmi.exit'} == 'normal')) {      //antes solo llegaba esta línea hasta el &&
4                 $userdata->entry = 'ab-initio';
5         } else {
6             if ((isset($userdata->{'cmi.exit'}) && (($userdata->{'cmi.exit'} == 'suspend') || ($userdata->{'cmi.exit'} == 'logout')))||(($userdata->{'adl.nav.request'} == 'suspendAll')&& isset($userdata->{'adl.nav.request'}) )) {
7                 $userdata->entry = 'resume';
8             } else {
9                 $userdata->entry = '';
10             }
11         }
12     }
13     $userdata->threshold = '0.8';
14 ?>
15     var cmi = new Object();
17 //
18 // SCORM 1.3 API Implementation
19 //
20 function SCORMapi1_3() {
21     // Standard Data Type Definition
22     CMIString200 = '^.{0,200}$';
23     CMIString250 = '^.{0,250}$';
24     CMILangString250 = '^(\{lang=([a-zA-Z]{2,3}|i|x)(\-[a-zA-Z0-9\-]{2,8})?\})?([^\{].{0,250}$)?';
25     CMIString1000 = '^.{0,1500}$';
26     CMIString4000 = '^.{0,4000}$';
27     CMILangString4000 = '^(\{lang=([a-zA-Z]{2,3}|i|x)(\-[a-zA-Z0-9\-]{2,8})?\})?([^\{].{0,4000}$)?';
28     CMIString64000 = '^.{0,64000}$';
29     CMILang = '^([a-zA-Z]{2,3}|i|x)(\-[a-zA-Z0-9\-]{2,8})?$|^$';
30     CMITime = '^(19[7-9]{1}[0-9]{1}|20[0-2]{1}[0-9]{1}|203[0-8]{1})((-(0[1-9]{1}|1[0-2]{1}))((-(0[1-9]{1}|[1-2]{1}[0-9]{1}|3[0-1]{1}))(T([0-1]{1}[0-9]{1}|2[0-3]{1})((:[0-5]{1}[0-9]{1})((:[0-5]{1}[0-9]{1})((\\.[0-9]{1,2})((Z|([+|-]([0-1]{1}[0-9]{1}|2[0-3]{1})))(:[0-5]{1}[0-9]{1})?)?)?)?)?)?)?)?$';
31     CMITimespan = '^P(\\d+Y)?(\\d+M)?(\\d+D)?(T(((\\d+H)(\\d+M)?(\\d+(\.\\d{1,2})?S)?)|((\\d+M)(\\d+(\.\\d{1,2})?S)?)|((\\d+(\.\\d{1,2})?S))))?$';
32     CMIInteger = '^\\d+$';
33     CMISInteger = '^-?([0-9]+)$';
34     CMIDecimal = '^-?([0-9]{1,4})(\\.[0-9]{1,18})?$';
35     CMIIdentifier = '^\\S{0,200}[a-zA-Z0-9]$';
36     CMILongIdentifier = '^\\S{0,4000}[a-zA-Z0-9]$';
37     CMIFeedback = CMIString200; // This must be redefined
38     CMIIndex = '[._](\\d+).';
39     CMIIndexStore = '.N(\\d+).';
40     // Vocabulary Data Type Definition
41     CMICStatus = '^completed$|^incomplete$|^not attempted$|^unknown$';
42     CMISStatus = '^passed$|^failed$|^unknown$';
43     CMIExit = '^time-out$|^suspend$|^logout$|^normal$|^$';
44     CMIType = '^true-false$|^choice$|^(long-)?fill-in$|^matching$|^performance$|^sequencing$|^likert$|^numeric$|^other$';
45     CMIResult = '^correct$|^incorrect$|^unanticipated$|^neutral$|^-?([0-9]{1,4})(\\.[0-9]{1,18})?$';
46     NAVEvent = '^previous$|^continue$|^exit$|^exitAll$|^abandon$|^abandonAll$|^suspendAll$|^{target=\\S{0,200}[a-zA-Z0-9]}choice$';
47     NAVBoolean = '^unknown$|^true$|^false$';
48     NAVTarget = '^previous$|^continue$|^choice.{target=\\S{0,200}[a-zA-Z0-9]}$'
49     // Children lists
50     cmi_children = '_version, comments_from_learner, comments_from_lms, completion_status, credit, entry, exit, interactions, launch_data, learner_id, learner_name, learner_preference, location, max_time_allowed, mode, objectives, progress_measure, scaled_passing_score, score, session_time, success_status, suspend_data, time_limit_action, total_time';
51     comments_children = 'comment, timestamp, location';
52     score_children = 'max, raw, scaled, min';
53     objectives_children = 'progress_measure, completion_status, success_status, description, score, id';
54     student_data_children = 'mastery_score, max_time_allowed, time_limit_action';
55     student_preference_children = 'audio_level, audio_captioning, delivery_speed, language';
56     interactions_children = 'id, type, objectives, timestamp, correct_responses, weighting, learner_response, result, latency, description';
57     // Data ranges
58     scaled_range = '-1#1';
59     audio_range = '0#*';
60     speed_range = '0#*';
61     text_range = '-1#1';
62     progress_range = '0#1';
63     // The SCORM 1.3 data model
64     var datamodel =  {
65         'cmi._children':{'defaultvalue':cmi_children, 'mod':'r'},
66         'cmi._version':{'defaultvalue':'1.0', 'mod':'r'},
67         'cmi.comments_from_learner._children':{'defaultvalue':comments_children, 'mod':'r'},
68         'cmi.comments_from_learner._count':{'mod':'r', 'defaultvalue':'0'},
69         'cmi.comments_from_learner.n.comment':{'format':CMILangString4000, 'mod':'rw'},
70         'cmi.comments_from_learner.n.location':{'format':CMIString250, 'mod':'rw'},
71         'cmi.comments_from_learner.n.timestamp':{'format':CMITime, 'mod':'rw'},
72         'cmi.comments_from_lms._children':{'defaultvalue':comments_children, 'mod':'r'},
73         'cmi.comments_from_lms._count':{'mod':'r', 'defaultvalue':'0'},
74         'cmi.comments_from_lms.n.comment':{'format':CMILangString4000, 'mod':'r'},
75         'cmi.comments_from_lms.n.location':{'format':CMIString250, 'mod':'r'},
76         'cmi.comments_from_lms.n.timestamp':{'format':CMITime, 'mod':'r'},
77         'cmi.completion_status':{'defaultvalue':'<?php echo isset($userdata->{'cmi.completion_status'})?$userdata->{'cmi.completion_status'}:'unknown' ?>', 'format':CMICStatus, 'mod':'rw'},
78         'cmi.completion_threshold':{'defaultvalue':<?php echo isset($userdata->threshold)?'\''.$userdata->threshold.'\'':'null' ?>, 'mod':'r'},
79         'cmi.credit':{'defaultvalue':'<?php echo isset($userdata->credit)?$userdata->credit:'' ?>', 'mod':'r'},
80         'cmi.entry':{'defaultvalue':'<?php echo $userdata->entry ?>', 'mod':'r'},
81         'cmi.exit':{'defaultvalue':'<?php echo isset($userdata->{'cmi.exit'})?$userdata->{'cmi.exit'}:'' ?>', 'format':CMIExit, 'mod':'w'},
82         'cmi.interactions._children':{'defaultvalue':interactions_children, 'mod':'r'},
83         'cmi.interactions._count':{'mod':'r', 'defaultvalue':'0'},
84         'cmi.interactions.n.id':{'pattern':CMIIndex, 'format':CMILongIdentifier, 'mod':'rw'},
85         'cmi.interactions.n.type':{'pattern':CMIIndex, 'format':CMIType, 'mod':'rw'},
86         'cmi.interactions.n.objectives._count':{'pattern':CMIIndex, 'mod':'r', 'defaultvalue':'0'},
87         'cmi.interactions.n.objectives.n.id':{'pattern':CMIIndex, 'format':CMILongIdentifier, 'mod':'rw'},
88         'cmi.interactions.n.timestamp':{'pattern':CMIIndex, 'format':CMITime, 'mod':'rw'},
89         'cmi.interactions.n.correct_responses._count':{'defaultvalue':'0', 'pattern':CMIIndex, 'mod':'r'},
90         'cmi.interactions.n.correct_responses.n.pattern':{'pattern':CMIIndex, 'format':CMIFeedback, 'mod':'rw'},
91         'cmi.interactions.n.weighting':{'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'},
92         'cmi.interactions.n.learner_response':{'pattern':CMIIndex, 'format':CMIFeedback, 'mod':'rw'},
93         'cmi.interactions.n.result':{'pattern':CMIIndex, 'format':CMIResult, 'mod':'rw'},
94         'cmi.interactions.n.latency':{'pattern':CMIIndex, 'format':CMITimespan, 'mod':'rw'},
95         'cmi.interactions.n.description':{'pattern':CMIIndex, 'format':CMILangString250, 'mod':'rw'},
96         'cmi.launch_data':{'defaultvalue':<?php echo isset($userdata->datafromlms)?'\''.$userdata->datafromlms.'\'':'null' ?>, 'mod':'r'},
97         'cmi.learner_id':{'defaultvalue':'<?php echo $userdata->student_id ?>', 'mod':'r'},
98         'cmi.learner_name':{'defaultvalue':'<?php echo addslashes($userdata->student_name) ?>', 'mod':'r'},
99         'cmi.learner_preference._children':{'defaultvalue':student_preference_children, 'mod':'r'},
100         'cmi.learner_preference.audio_level':{'defaultvalue':'1', 'format':CMIDecimal, 'range':audio_range, 'mod':'rw'},
101         'cmi.learner_preference.language':{'defaultvalue':'', 'format':CMILang, 'mod':'rw'},
102         'cmi.learner_preference.delivery_speed':{'defaultvalue':'1', 'format':CMIDecimal, 'range':speed_range, 'mod':'rw'},
103         'cmi.learner_preference.audio_captioning':{'defaultvalue':'0', 'format':CMISInteger, 'range':text_range, 'mod':'rw'},
104         'cmi.location':{'defaultvalue':<?php echo isset($userdata->{'cmi.location'})?'\''.$userdata->{'cmi.location'}.'\'':'null' ?>, 'format':CMIString1000, 'mod':'rw'},
105         'cmi.max_time_allowed':{'defaultvalue':<?php echo isset($userdata->maxtimeallowed)?'\''.$userdata->maxtimeallowed.'\'':'null' ?>, 'mod':'r'},
106         'cmi.mode':{'defaultvalue':'<?php echo $userdata->mode ?>', 'mod':'r'},
107         'cmi.objectives._children':{'defaultvalue':objectives_children, 'mod':'r'},
108         'cmi.objectives._count':{'mod':'r', 'defaultvalue':'0'},
109         'cmi.objectives.n.id':{'pattern':CMIIndex, 'format':CMILongIdentifier, 'mod':'rw'},
110         'cmi.objectives.n.score._children':{'defaultvalue':score_children, 'pattern':CMIIndex, 'mod':'r'},
111         'cmi.objectives.n.score.scaled':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'range':scaled_range, 'mod':'rw'},
112         'cmi.objectives.n.score.raw':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'},
113         'cmi.objectives.n.score.min':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'},
114         'cmi.objectives.n.score.max':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'},
115         'cmi.objectives.n.success_status':{'defaultvalue':'unknown', 'pattern':CMIIndex, 'format':CMISStatus, 'mod':'rw'},
116         'cmi.objectives.n.completion_status':{'defaultvalue':'unknown', 'pattern':CMIIndex, 'format':CMICStatus, 'mod':'rw'},
117         'cmi.objectives.n.progress_measure':{'defaultvalue':null, 'format':CMIDecimal, 'range':progress_range, 'mod':'rw'},
118         'cmi.objectives.n.description':{'pattern':CMIIndex, 'format':CMILangString250, 'mod':'rw'},
119         'cmi.progress_measure':{'defaultvalue':<?php echo isset($userdata->{'cmi.progess_measure'})?'\''.$userdata->{'cmi.progress_measure'}.'\'':'null' ?>, 'format':CMIDecimal, 'range':progress_range, 'mod':'rw'},
120         'cmi.scaled_passing_score':{'defaultvalue':<?php echo isset($userdata->{'cmi.scaled_passing_score'})?'\''.$userdata->{'cmi.scaled_passing_score'}.'\'':'null' ?>, 'format':CMIDecimal, 'range':scaled_range, 'mod':'r'},
121         'cmi.score._children':{'defaultvalue':score_children, 'mod':'r'},
122         'cmi.score.scaled':{'defaultvalue':<?php echo isset($userdata->{'cmi.score.scaled'})?'\''.$userdata->{'cmi.score.scaled'}.'\'':'null' ?>, 'format':CMIDecimal, 'range':scaled_range, 'mod':'rw'},
123         'cmi.score.raw':{'defaultvalue':<?php echo isset($userdata->{'cmi.score.raw'})?'\''.$userdata->{'cmi.score.raw'}.'\'':'null' ?>, 'format':CMIDecimal, 'mod':'rw'},
124         'cmi.score.min':{'defaultvalue':<?php echo isset($userdata->{'cmi.score.min'})?'\''.$userdata->{'cmi.score.min'}.'\'':'null' ?>, 'format':CMIDecimal, 'mod':'rw'},
125         'cmi.score.max':{'defaultvalue':<?php echo isset($userdata->{'cmi.score.max'})?'\''.$userdata->{'cmi.score.max'}.'\'':'null' ?>, 'format':CMIDecimal, 'mod':'rw'},
126         'cmi.session_time':{'format':CMITimespan, 'mod':'w', 'defaultvalue':'PT0H0M0S'},
127         'cmi.success_status':{'defaultvalue':'<?php echo isset($userdata->{'cmi.success_status'})?$userdata->{'cmi.success_status'}:'unknown' ?>', 'format':CMISStatus, 'mod':'rw'},
128         'cmi.suspend_data':{'defaultvalue':<?php echo isset($userdata->{'cmi.suspend_data'})?'\''.$userdata->{'cmi.suspend_data'}.'\'':'null' ?>, 'format':CMIString64000, 'mod':'rw'},
129         'cmi.time_limit_action':{'defaultvalue':<?php echo isset($userdata->timelimitaction)?'\''.$userdata->timelimitaction.'\'':'null' ?>, 'mod':'r'},
130         'cmi.total_time':{'defaultvalue':'<?php echo isset($userdata->{'cmi.total_time'})?$userdata->{'cmi.total_time'}:'PT0H0M0S' ?>', 'mod':'r'},
131         'adl.nav.request':{'defaultvalue':'_none_', 'format':NAVEvent, 'mod':'rw'}
132     };
133     //
134     // Datamodel inizialization
135     //
136 //    var cmi = new Object();
137         cmi.comments_from_learner = new Object();
138         cmi.comments_from_learner._count = 0;
139         cmi.comments_from_lms = new Object();
140         cmi.comments_from_lms._count = 0;
141         cmi.interactions = new Object();
142         cmi.interactions._count = 0;
143         cmi.learner_preference = new Object();
144         cmi.objectives = new Object();
145         cmi.objectives._count = 0;
146         cmi.score = new Object();
148     // Navigation Object
149     var adl = new Object();
150         adl.nav = new Object();
152     for (element in datamodel) {
153         if (element.match(/\.n\./) == null) {
154             if ((typeof eval('datamodel["'+element+'"].defaultvalue')) != 'undefined') {
155                 eval(element+' = datamodel["'+element+'"].defaultvalue;');
156             } else {
157                 eval(element+' = "";');
158             }
159         }
160     }
162 <?php
163     $count = 0;
164     $objectives = '';
165     foreach($userdata as $element => $value){
166         if (substr($element,0,14) == 'cmi.objectives') {
167             preg_match('/.(\d+)./',$element,$matches);
168             $element = preg_replace('/.(\d+)./',".N\$1.",$element);
169             if ($matches[1] == $count) {
170                 $count++;
171                 $end = strpos($element,$matches[1])+strlen($matches[1]);
172                 $subelement = substr($element,0,$end);
173                 echo '    '.$subelement." = new Object();\n";
174                 echo '    '.$subelement.".score = new Object();\n";
175                 echo '    '.$subelement.".score._children = score_children;\n";
176             }
177             echo '    '.$element.' = \''.$value."';\n";
178         }
179     }
180     if ($count > 0) {
181         echo '    cmi.objectives._count = '.$count.";\n";
182     }
183 ?>
185     if (cmi.completion_status == '') {
186         cmi.completion_status = 'not attempted';
187     } 
188     
189     //
190     // API Methods definition
191     //
192     var Initialized = false;
193     var Terminated = false;
194     var diagnostic = "";
196     function Initialize (param) {
197         errorCode = "0";
198         if (param == "") {
199             if ((!Initialized) && (!Terminated)) {
200                 <?php 
201                     if (debugging('',DEBUG_DEVELOPER)) {
202                         echo 'alert("Initialized SCORM 1.3");';
203                     }
204                 ?>
205                 Initialized = true;
206                 errorCode = "0";
207                 return "true";
208             } else {
209                 if (Initialized) {
210                     errorCode = "103";
211                 } else {
212                     errorCode = "104";
213                 }
214             }
215         } else {
216             errorCode = "201";
217         }
218         <?php 
219             if (debugging('',DEBUG_DEVELOPER)) {
220                 echo 'alert("Initialize: "+GetErrorString(errorCode));';
221             }
222         ?>
223         return "false";
224     }
225     
226     function Terminate (param) {
227         errorCode = "0";
228         if (param == "") {
229             if ((Initialized) && (!Terminated)) {
230                 <?php 
231                     if (debugging('',DEBUG_DEVELOPER)) {
232                         echo 'alert("Terminated SCORM 1.3");';
233                     }
234                 ?>
235                 Initialized = false;
236                 Terminated = true;
237                 result = StoreData(cmi,true);
238                 if (nav.event != '') {
239                     if (nav.event == 'continue') {
240                         setTimeout('top.nextSCO();',500);
241                     } else {
242                         setTimeout('top.prevSCO();',500);
243                     }
244                 } else {
245                     if (<?php echo $scorm->auto ?> == 1) {
246                         setTimeout('top.nextSCO();',500);
247                     }
248                 }    
249                 return "true";
250             } else {
251                 if (Terminated) {
252                     errorCode = "113";
253                 } else {
254                     errorCode = "112";
255                 }
256             }
257         } else {
258             errorCode = "201";
259         }
260         <?php 
261             if (debugging('',DEBUG_DEVELOPER)) {
262                 echo 'alert("Terminate: "+GetErrorString(errorCode));';
263             }
264         ?>
265         return "false";
266     }
267     
268     function GetValue (element) {
269         errorCode = "0";
270         diagnostic = "";
271         if ((Initialized) && (!Terminated)) {
272             if (element !="") {
273                 expression = new RegExp(CMIIndex,'g');
274                 elementmodel = element.replace(expression,'.n.');
275                 if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") {
276                     if (eval('datamodel["'+elementmodel+'"].mod') != 'w') {
277                         element = element.replace(/\.(\d+)\./, ".N$1.");
278                         elementIndexes = element.split('.');
279                         subelement = element.substr(0,3);
280                         i = 1;
281                         while ((i < elementIndexes.length) && (typeof eval(subelement) != "undefined")) {
282                             subelement += '.'+elementIndexes[i++];
283                         }
284                         if (subelement == element) {
285                             if ((typeof eval(subelement) != "undefined") && (eval(subelement) != null)) {
286                                 errorCode = "0";
287                                 <?php 
288                                     if (debugging('',DEBUG_DEVELOPER)) {
289                                         echo 'alert("GetValue("+element+") -> "+eval(element));';
290                                     }
291                                 ?>
292                                 return eval(element);
293                             } else {
294                                 errorCode = "403";
295                             }
296                         } else {
297                             errorCode = "301";
298                         }
299                     } else {
300                         //errorCode = eval('datamodel["'+elementmodel+'"].readerror');
301                         errorCode = "405";
302                     }
303                 } else {
304                     childrenstr = '._children';
305                     countstr = '._count';
306                     if (elementmodel.substr(elementmodel.length-childrenstr.length,elementmodel.length) == childrenstr) {
307                         parentmodel = elementmodel.substr(0,elementmodel.length-childrenstr.length);
308                         if ((typeof eval('datamodel["'+parentmodel+'"]')) != "undefined") {
309                             errorCode = "301";
310                             diagnostic = "Data Model Element Does Not Have Children";
311                         } else {
312                             errorCode = "401";
313                         }
314                     } else if (elementmodel.substr(elementmodel.length-countstr.length,elementmodel.length) == countstr) {
315                         parentmodel = elementmodel.substr(0,elementmodel.length-countstr.length);
316                         if ((typeof eval('datamodel["'+parentmodel+'"]')) != "undefined") {
317                             errorCode = "301";
318                             diagnostic = "Data Model Element Cannot Have Count";
319                         } else {
320                             errorCode = "401";
321                         }
322                     } else {
323                         parentmodel = 'adl.nav.request_valid.';
324                         if (element.substr(0,parentmodel.length) == parentmodel) {
325                             if (element.substr(parentmodel.length).match(NAVTarget) == null) {
326                                 errorCode = "301";
327                             } else {
328                                 if (adl.nav.request == element.substr(parentmodel.length)) {
329                                     return "true";
330                                 } else if (adl.nav.request == '_none_') {
331                                     return "unknown";
332                                 } else {
333                                     return "false";
334                                 }
335                             }
336                         } else {
337                             errorCode = "401";
338                         }
339                     }
340                 }
341             } else {
342                 errorCode = "301";
343             }
344         } else {
345             if (Terminated) {                
346                 errorCode = "123";
347             } else {
348                 errorCode = "122";
349             }
350         }
351         <?php 
352             if (debugging('',DEBUG_DEVELOPER)) {
353                 echo 'alert("GetValue("+element+") -> "+GetErrorString(errorCode));';
354             }
355         ?>
356         return "";
357     }
358     
359     function SetValue (element,value) {
360         errorCode = "0";
361         diagnostic = "";
362         if ((Initialized) && (!Terminated)) {
363             if (element != "") {
364                 expression = new RegExp(CMIIndex,'g');
365                 elementmodel = element.replace(expression,'.n.');
366                 if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") {
367                     if (eval('datamodel["'+elementmodel+'"].mod') != 'r') {
368                         expression = new RegExp(eval('datamodel["'+elementmodel+'"].format'));
369                         value = value+'';
370                         matches = value.match(expression);
371                         if ((matches != null) && ((matches.join('').length > 0) || (value.length == 0))) {
372                             //Create dynamic data model element
373                             if (element != elementmodel) {
374                                 elementIndexes = element.split('.');
375                                 subelement = 'cmi';
376                                 parentelement = 'cmi';
377                                 for (i=1;(i < elementIndexes.length-1) && (errorCode=="0");i++) {
378                                     elementIndex = elementIndexes[i];
379                                     if (elementIndexes[i+1].match(/^\d+$/)) {
380                                         if ((parseInt(elementIndexes[i+1]) > 0) && (elementIndexes[i+1].charAt(0) == 0)) {
381                                             // Index has a leading 0 (zero), this is not a number
382                                             errorCode = "351";
383                                         }
384                                         parentelement = subelement+'.'+elementIndex;
385                                         if (elementIndexes[i+1] > eval(parentelement+'._count')) {
386                                             errorCode = "351";
387                                             diagnostic = "Data Model Element Collection Set Out Of Order";
388                                         }
389                                         subelement = subelement.concat('.'+elementIndex+'.N'+elementIndexes[i+1]);
390                                         i++;
391                                         if (((typeof eval(subelement)) == "undefined") && (i < elementIndexes.length-2)) {
392                                             errorCode="408";
393                                         }
394                                     } else {
395                                         subelement = subelement.concat('.'+elementIndex);
396                                     }
397                                 }
398                                 if (errorCode == "0") {
399                                     element = subelement.concat('.'+elementIndexes[elementIndexes.length-1]);
400                                     elemlen = element.length;
401                                     if (((typeof eval(subelement)) == "undefined") && (errorCode == "0")) {
402                                         parentmodel = 'cmi.objectives';
403                                         maxmodel = 'cmi.objectives.Nxxx.id';
404                                         if (subelement.substr(0,parentmodel.length) == parentmodel) {
405                                              if ((elemlen <= maxmodel.length) && (element.substr(elemlen-2) == 'id') && (errorCode=="0")) { 
406                                                 //This is a parentmodel.n.id element
407                                                 if (!duplicatedID(parentmodel,value)) {
408                                                     if (elementIndexes[elementIndexes.length-2] == eval(parentmodel+'._count')) {
409                                                         eval(parentmodel+'._count++;');
410                                                         eval(subelement+' = new Object();');
411                                                         subobject = eval(subelement);
412                                                         subobject.success_status = datamodel["cmi.objectives.n.success_status"].defaultvalue;
413                                                         subobject.completion_status = datamodel["cmi.objectives.n.completion_status"].defaultvalue;
414                                                         subobject.progress_measure = datamodel["cmi.objectives.n.progress_measure"].defaultvalue;
415                                                         subobject.score = new Object();
416                                                         subobject.score._children = score_children;
417                                                         subobject.score.scaled = datamodel["cmi.objectives.n.score.scaled"].defaultvalue;
418                                                         subobject.score.raw = datamodel["cmi.objectives.n.score.raw"].defaultvalue;
419                                                         subobject.score.min = datamodel["cmi.objectives.n.score.min"].defaultvalue;
420                                                         subobject.score.max = datamodel["cmi.objectives.n.score.max"].defaultvalue;
421                                                     }
422                                                 } else {
423                                                     errorCode="351";
424                                                     diagnostic = "Data Model Element ID Already Exists";
425                                                 }
426                                             } else {
427                                                 if (typeof eval(subelement) == "undefined") {
428                                                     errorCode="408";
429                                                 } else {
430                                                     if (duplicatedID(parentmodel,value)) {
431                                                         errorCode="351";
432                                                         diagnostic = "Data Model Element ID Already Exists";
433                                                     }
434                                                 }
435                                             }
436                                         } else {
437                                             parentmodel = 'cmi.interactions';
438                                             maxmodel = 'cmi.interactions.Nxxx.id';
439                                             if (subelement.substr(0,parentmodel.length) == parentmodel) {
440                                                 if ((elemlen <= maxmodel.length) && (element.substr(elemlen-2) == 'id') && (errorCode=="0")) { 
441                                                     //This is a parentmodel.n.id element
442                                                     if (!duplicatedID(parentmodel,value)) {
443                                                         if (elementIndexes[elementIndexes.length-2] == eval(parentmodel+'._count')) {
444                                                             eval(parentmodel+'._count++;');
445                                                             eval(subelement+' = new Object();');
446                                                             subobject = eval(subelement);
447                                                             subobject.objectives = new Object();
448                                                             subobject.objectives._count = 0;
449                                                                                                                         subobject.correct_responses = new Object();//añadido
450                                                             subobject.correct_responses._count = 0;//añadido
451                                                                                                                         
452                                                             
453                                                         } 
454                                                     } else {
455                                                         errorCode="351";
456                                                         diagnostic = "Data Model Element ID Already Exists";
457                                                     }
458                                                 } else {
459                                                     if (typeof eval(subelement) == "undefined") {
460                                                         errorCode="408";
461                                                     } else {
462                                                         maxmodel = 'cmi.interactions.Nxxx.type';
463                                                         if ((elemlen <= maxmodel.length) && (element.substr(elemlen-4) == 'type') && (errorCode=="0")) { 
464                                                             subobject = eval(subelement);
465                                                            //subobject.correct_responses = new Object();
466                                                            //subobject.correct_responses._count = 0;
467                                                         } 
468                                                     }
469                                                 }
470                                             } else { 
471                                                 if (errorCode == "0") {
472                                                     if (elementIndexes[elementIndexes.length-2] == eval(parentelement+'._count')) {
473                                                         eval(parentelement+'._count++;');
474                                                         eval(subelement+' = new Object();');
475                                                     } 
476                                                 }
477                                             }
478                                         }
479                                      } else {
480                                          parentmodel = 'cmi.objectives';
481                                          maxmodel = 'cmi.objectives.Nxxx.id';
482                                          if (subelement.substr(0,parentmodel.length) == parentmodel) {
483                                              if ((elemlen <= maxmodel.length) && (element.substr(elemlen-2) == 'id') && (errorCode=="0")) { 
484                                                  if (eval(element) != value) {
485                                                      errorCode = "351";
486                                                      diagnostic = "Write Once Violation";
487                                                  }
488                                              }
489                                          } else {
490                                              parentmodel = 'cmi.interactions';
491                                              maxmodel = 'cmi.interactions.Nxxx.id';
492                                              if (subelement.substr(0,parentmodel.length) == parentmodel) {
493                                                  if ((elemlen <= maxmodel.length) && (element.substr(elemlen-2) == 'id') && (errorCode=="0")) { 
494                                                      if (eval(element) != value) {
495                                                          errorCode = "351";
496                                                          diagnostic = "Write Once Violation";
497                                                      }
498                                                  }
499                                              }
500                                          }
501                                      }
502                                 }
503                             }
504                             //Store data
505                             if (errorCode == "0") {
506                                 if ((typeof eval('datamodel["'+elementmodel+'"].range')) != "undefined") {
507                                     range = eval('datamodel["'+elementmodel+'"].range');
508                                     ranges = range.split('#');
509                                     value = value*1.0;
510                                     if (value >= ranges[0]) {
511                                         if ((ranges[1] == '*') || (value <= ranges[1])) {
512                                             eval(element+'="'+value+'";');
513                                             errorCode = "0";
514                                             <?php 
515                                                 if (debugging('',DEBUG_DEVELOPER)) {
516                                                     echo 'alert("SetValue("+element+","+value+") -> OK");';
517                                                 }
518                                             ?>
519                                             return "true";
520                                         } else {
521                                             errorCode = '407';
522                                         }
523                                     } else {
524                                         errorCode = '407';
525                                     }
526                                 } else {
527                                     eval(element+'="'+value+'";');
528                                     errorCode = "0"; 
529                                     <?php 
530                                         if (debugging('',DEBUG_DEVELOPER)) {
531                                             echo 'alert("SetValue("+element+","+value+") -> OK");';
532                                         }
533                                     ?>
534                                     return "true";
535                                 }
536                             }
537                         } else {
538                             //errorCode = eval('datamodel["'+elementmodel+'"].writeerror');
539                             errorCode = "406";
540                         }
541                     } else {
542                         //errorCode = eval('datamodel["'+elementmodel+'"].writeerror');
543                         errorCode = "404";
544                     }
545                 } else {
546                     errorCode = "401"
547                 }
548             } else {
549                 errorCode = "351";
550             }
551         } else {
552             if (Terminated) {
553                 errorCode = "133";
554             } else {
555                 errorCode = "132";
556             }
557         }
558         <?php 
559             if (debugging('',DEBUG_DEVELOPER)) {
560                 echo 'alert("SetValue("+element+","+value+") -> "+GetErrorString(errorCode));';
561             }
562         ?>
563         return "false";
564     }
565     
566     function Commit (param) {
567         errorCode = "0";
568         if (param == "") {
569             if ((Initialized) && (!Terminated)) {
570                 result = StoreData(cmi,false);
571                 <?php 
572                     if (debugging('',DEBUG_DEVELOPER)) {
573                         echo 'alert("Data Commited");';
574                     }
575                 ?>
576                 return "true";
577             } else {
578                 if (Terminated) {
579                     errorCode = "143";
580                 } else {
581                     errorCode = "142";
582                 }
583             }
584         } else {
585             errorCode = "201";
586         }
587         <?php 
588             if (debugging('',DEBUG_DEVELOPER)) {
589                 echo 'alert("Commit: "+GetErrorString(errorCode));';
590             }
591         ?>
592         return "false";
593     }
594     
595     function GetLastError () {
596         return errorCode;
597     }
598     
599     function GetErrorString (param) {
600         if (param != "") {
601             var errorString = "";
602             switch(param) {
603                 case "0":
604                     errorString = "No error";
605                 break;
606                 case "101":
607                     errorString = "General exception";
608                 break;
609                 case "102":
610                     errorString = "General Inizialization Failure";
611                 break;
612                 case "103":
613                     errorString = "Already Initialized";
614                 break;
615                 case "104":
616                     errorString = "Content Instance Terminated";
617                 break;
618                 case "111":
619                     errorString = "General Termination Failure";
620                 break;
621                 case "112":
622                     errorString = "Termination Before Inizialization";
623                 break;
624                 case "113":
625                     errorString = "Termination After Termination";
626                 break;
627                 case "122":
628                     errorString = "Retrieve Data Before Initialization";
629                 break;
630                 case "123":
631                     errorString = "Retrieve Data After Termination";
632                 break;
633                 case "132":
634                     errorString = "Store Data Before Inizialization";
635                 break;
636                 case "133":
637                     errorString = "Store Data After Termination";
638                 break;
639                 case "142":
640                     errorString = "Commit Before Inizialization";
641                 break;
642                 case "143":
643                     errorString = "Commit After Termination";
644                 break;
645                 case "201":
646                     errorString = "General Argument Error";
647                 break;
648                 case "301":
649                     errorString = "General Get Failure";
650                 break;
651                 case "351":
652                     errorString = "General Set Failure";
653                 break;
654                 case "391":
655                     errorString = "General Commit Failure";
656                 break;
657                 case "401":
658                     errorString = "Undefinited Data Model";
659                 break;
660                 case "402":
661                     errorString = "Unimplemented Data Model Element";
662                 break;
663                 case "403":
664                     errorString = "Data Model Element Value Not Initialized";
665                 break;
666                 case "404":
667                     errorString = "Data Model Element Is Read Only";
668                 break;
669                 case "405":
670                     errorString = "Data Model Element Is Write Only";
671                 break;
672                 case "406":
673                     errorString = "Data Model Element Type Mismatch";
674                 break;
675                 case "407":
676                     errorString = "Data Model Element Value Out Of Range";
677                 break;
678                 case "408":
679                     errorString = "Data Model Dependency Not Established";
680                 break;
681             }
682             return errorString;
683         } else {
684            return "";
685         }
686     }
687     
688     function GetDiagnostic (param) {
689         if (diagnostic != "") {
690             return diagnostic;
691         }
692         return param;
693     }
695     function duplicatedID (element, value) {
696         var found = false;
697         var elements = eval(element+'._count');
698         for (n=0;(n<elements) && (!found);n++) {
699             if (eval(element+'.N'+n+'.id') == value) {
700                 found = true;
701             }
702         } 
703         return found;
704     }
706     function getElementModel(element) {
707         if (typeof datamodel[element] != "undefined") {
708             return element;
709         } else {
710             expression = new RegExp(CMIIndex,'g');
711             elementmodel = element.replace(expression,'.n.');
712             if (typeof datamodel[elementmodel] != "undefined") {
713                 return elementmodel;
714             }
715         }
716     }
718     function AddTime (first, second) {
719         <?php 
720             if (debugging('',DEBUG_DEVELOPER)) {
721                 echo 'alert("AddTime: "+first+" + "+second);';
722             }
723         ?>
724         var timestring = 'P';
725         var matchexpr = /^P((\d+)Y)?((\d+)M)?((\d+)D)?(T((\d+)H)?((\d+)M)?((\d+(\.\d{1,2})?)S)?)?$/;
726         var firstarray = first.match(matchexpr);
727         var secondarray = second.match(matchexpr);
728         if ((firstarray != null) && (secondarray != null)) {
729             var secs = parseFloat(firstarray[13],10)+parseFloat(secondarray[13],10);  //Seconds
730             change = Math.floor(secs / 60);
731             secs = secs - (change * 60);
732             mins = parseInt(firstarray[11],10)+parseInt(secondarray[11],10)+change;   //Minutes
733             change = Math.floor(mins / 60);
734             mins = mins - (change * 60);
735             hours = parseInt(firstarray[10],10)+parseInt(secondarray[10],10)+change;  //Hours
736             change = Math.floor(hours / 24);
737             hours = hours - (change * 24);
738             days = parseInt(firstarray[6],10)+parseInt(secondarray[6],10)+change; // Days
739             months = parseInt(firstarray[4],10)+parseInt(secondarray[4],10)
740             years = parseInt(firstarray[2],10)+parseInt(secondarray[2],10)
741         }
742         if (years > 0) {
743             timestring += years + 'Y';
744         }
745         if (months > 0) {
746             timestring += months + 'M';
747         }
748         if (days > 0) {
749             timestring += days + 'D';
750         }
751         if ((hours > 0) || (mins > 0) || (secs > 0)) {
752             timestring += 'T';
753             if (hours > 0) {
754                 timestring += hours + 'H';
755             }
756             if (mins > 0) {
757                 timestring += mins + 'M';
758             }
759             if (secs > 0) {
760                 timestring += secs + 'S';
761             }
762         }
763         return timestring;
764     }
766     function TotalTime() {
767         total_time = AddTime(cmi.total_time, cmi.session_time);
768         return '&'+underscore('cmi.total_time')+'='+escape(total_time);
769     }
771     function CollectData(data,parent) {
772         var datastring = '';
773         for (property in data) {
774             if (typeof data[property] == 'object') {
775                 datastring += CollectData(data[property],parent+'.'+property);
776             } else {
777                 element = parent+'.'+property;
778                 expression = new RegExp(CMIIndexStore,'g');
779                 elementmodel = element.replace(expression,'.n.');
780                 if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") {
781                     if (eval('datamodel["'+elementmodel+'"].mod') != 'r') {
782                         elementstring = '&'+underscore(element)+'='+escape(data[property]);
783                         if ((typeof eval('datamodel["'+elementmodel+'"].defaultvalue')) != "undefined") {
784                             if (eval('datamodel["'+elementmodel+'"].defaultvalue') != data[property]) {
785                                 datastring += elementstring;
786                             }
787                         } else {
788                             datastring += elementstring;
789                         }
790                     }
791                 }
792             }
793         }
794         return datastring;
795     }
797     function StoreData(data,storetotaltime) {
798         if (storetotaltime) {
799             if (cmi.mode == 'normal') {
800                 if (cmi.credit == 'credit') {
801                     if ((cmi.completion_threshold != null) && (cmi.progress_measure != null)) {
802                         if (cmi.progress_measure >= cmi.completion_threshold) {
803                             cmi.completion_status = 'completed';
804                         } else {
805                             cmi.completion_status = 'incomplete';
806                         }
807                     }
808                     if ((cmi.scaled_passed_score != null) && (cmi.score.scaled != '')) {
809                         if (cmi.score.scaled >= cmi.scaled_passed_score) {
810                             cmi.success_status = 'passed';
811                         } else {
812                             cmi.success_status = 'failed';
813                         }
814                     }
815                 }
816             }
817             datastring = CollectData(data,'cmi');
818             datastring += TotalTime();
819         } else {
820             datastring = CollectData(data,'cmi');
821         }
822         datastring += '&attempt=<?php echo $attempt ?>';
823         datastring += '&scoid=<?php echo $sco->id ?>';
824         <?php
825             if (debugging('',DEBUG_DEVELOPER)) {
826                 echo 'popupwin(datastring);';
827             }
828         ?>
829         var myRequest = NewHttpReq();
830         result = DoRequest(myRequest,"<?php p($CFG->wwwroot) ?>/mod/scorm/datamodel.php","id=<?php p($id) ?>&sesskey=<?php p($USER->sesskey) ?>"+datastring);
831         results = result.split('\n');
832         errorCode = results[1];
833         return results[0];
834     }
835     
836     this.Initialize = Initialize;
837     this.Terminate = Terminate;
838     this.GetValue = GetValue;
839     this.SetValue = SetValue;
840     this.Commit = Commit;
841     this.GetLastError = GetLastError;
842     this.GetErrorString = GetErrorString;
843     this.GetDiagnostic = GetDiagnostic;
844     this.version = '1.0';
847 var API_1484_11 = new SCORMapi1_3();