69674171e91fa3a2f93bcfe6b9871b4834de2fa4
[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)) {//si está inicializado y no terminado
272             if (element !="") {
273                 expression = new RegExp(CMIIndex,'g');
274                 elementmodel = element.replace(expression,'.n.');//creamos su elementmodel
276                                 if (element=='cmi.interactions.0.objectives.0.id'){
277                                         alert("Estamos aquí, con el elemntmodel "+elementmodel);
278                                 }
279                                 
280                 if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") {
281                     if (eval('datamodel["'+elementmodel+'"].mod') != 'w') {//compruebo que está definido el modelo
282                                         //y compruebo que no es de solo escritura
283                                                 if (element=='cmi.interactions.0.objectives.0.id'){
284                                                         alert("Entro");
285                                                 }
286                         element = element.replace(/\.(\d+)\./, ".N$1.");
287                                                 element = element.replace(/\.(\d+)\./, ".N$1.");
289                         elementIndexes = element.split('.');
290                         subelement = element.substr(0,3);
291                         i = 1;
292                                                 
293                                                 if (elementmodel=='cmi.interactions.n.objectives.n.id'){
294                                                         alert ("el element vale "+element+"y el subelement vale"+subelement);
295                                                 }
296                                                 
297                         while ((i < elementIndexes.length) && (typeof eval(subelement) != "undefined")) {
298                             subelement += '.'+elementIndexes[i++];
299         
300                                                         if (elementmodel=='cmi.interactions.n.objectives.n.id'){
301                                                                 alert ("el element vale "+element+"y el subelement vale"+subelement);
302                                                                         if((typeof eval(subelement) != "undefined")){
303                                                                                 alert("está definido");
304                                                                         }
305                                                                         else {
306                                                                                 alert("no definido");
307                                                                         }
309                                                         }
310                                                 
311                         }
312                                                 if (elementmodel=='cmi.interactions.n.objectives.n.id'){
313                                                                 alert ("Tras el bucle el element vale "+element+"y el subelement vale"+subelement);
314                                                         }
315                         if (subelement == element) {
317                                                         if (elementmodel=='cmi.interactions.n.objectives.n.id'){
318                                                                 alert ("Tras el bucle, si element y sub son iguales el element vale "+element+"y el subelement vale"+subelement);
319                                                         }
321                             if ((typeof eval(subelement) != "undefined") && (eval(subelement) != null)) {
322                                 errorCode = "0";
323                                 <?php 
324                                     if (debugging('',DEBUG_DEVELOPER)) {
325                                         echo 'alert("GetValue("+element+") -> "+eval(element));';
326                                     }
327                                 ?>
328                                 return eval(element);
329                             } else {
330                                 errorCode = "403";
331                             }
332                         } else {
334                                                         if (elementmodel=='cmi.interactions.n.objectives.n.id'){
335                                                                 alert("element y subelement no son iguales");
336                                                         }
337                             errorCode = "301";
338                         }
339                     } else {
340                         //errorCode = eval('datamodel["'+elementmodel+'"].readerror');
341                         errorCode = "405";
342                     }
343                 } else {
344                     childrenstr = '._children';
345                     countstr = '._count';
346                     if (elementmodel.substr(elementmodel.length-childrenstr.length,elementmodel.length) == childrenstr) {
347                         parentmodel = elementmodel.substr(0,elementmodel.length-childrenstr.length);
348                         if ((typeof eval('datamodel["'+parentmodel+'"]')) != "undefined") {
349                             errorCode = "301";
350                             diagnostic = "Data Model Element Does Not Have Children";
351                         } else {
352                             errorCode = "401";
353                         }
354                     } else if (elementmodel.substr(elementmodel.length-countstr.length,elementmodel.length) == countstr) {
355                         parentmodel = elementmodel.substr(0,elementmodel.length-countstr.length);
356                         if ((typeof eval('datamodel["'+parentmodel+'"]')) != "undefined") {
357                             errorCode = "301";
358                             diagnostic = "Data Model Element Cannot Have Count";
359                         } else {
360                             errorCode = "401";
361                         }
362                     } else {
363                         parentmodel = 'adl.nav.request_valid.';
364                         if (element.substr(0,parentmodel.length) == parentmodel) {
365                             if (element.substr(parentmodel.length).match(NAVTarget) == null) {
366                                 errorCode = "301";
367                             } else {
368                                 if (adl.nav.request == element.substr(parentmodel.length)) {
369                                     return "true";
370                                 } else if (adl.nav.request == '_none_') {
371                                     return "unknown";
372                                 } else {
373                                     return "false";
374                                 }
375                             }
376                         } else {
377                             errorCode = "401";
378                         }
379                     }
380                 }
381             } else {
382                 errorCode = "301";
383             }
384         } else {
385             if (Terminated) {                
386                 errorCode = "123";
387             } else {
388                 errorCode = "122";
389             }
390         }
391         <?php 
392             if (debugging('',DEBUG_DEVELOPER)) {
393                 echo 'alert("GetValue("+element+") -> "+GetErrorString(errorCode));';
394             }
395         ?>
396         return "";
397     }
398     
399     function SetValue (element,value) {
400         errorCode = "0";
401         diagnostic = "";
402                 if (element== 'cmi.interactions.0.learner_response' && value=='Dependency on cmi.interaction.n.type not established'){
403                         //alert("entramos");
404                         errorCode="408";
405                 }
406         if ((Initialized) && (!Terminated)) {//Si está inicializado y no terminado
407             if (element != "") {//Si hay un elemento
408                 expression = new RegExp(CMIIndex,'g');
409                 elementmodel = element.replace(expression,'.n.');//cambio los números por n
410                 if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") {//miro si elementmodel definido
411                     if (eval('datamodel["'+elementmodel+'"].mod') != 'r') {//si no es de sólo lectura
412                         expression = new RegExp(eval('datamodel["'+elementmodel+'"].format'));//ajusto a expReg
413                         value = value+'';
414                         matches = value.match(expression);
415                         if ((matches != null) && ((matches.join('').length > 0) || (value.length == 0))) {
416                                                 //si el valor a asignar se ajusta a la expresión regular
417                             //Create dynamic data model element
418                             if (element != elementmodel) {
419                                 elementIndexes = element.split('.');//divido el elemento en trozos
420                                 subelement = 'cmi';
421                                 parentelement = 'cmi';
422                                 for (i=1;(i < elementIndexes.length-1) && (errorCode=="0");i++) {//recorro trozos
423                                     elementIndex = elementIndexes[i];
424                                     if (elementIndexes[i+1].match(/^\d+$/)) {//si el trozo es un dígito (índice)
425                                         if ((parseInt(elementIndexes[i+1]) > 0) && (elementIndexes[i+1].charAt(0) == 0)) {//si no es un número da error
426                                             // Index has a leading 0 (zero), this is not a number
427                                             errorCode = "351";
428                                         }
429                                         parentelement = subelement+'.'+elementIndex;
430                                         if (elementIndexes[i+1] > eval(parentelement+'._count')) {
431                                                                                 //si el número (índice) es mayor que el count, se desborda
432                                             errorCode = "351";
433                                             diagnostic = "Data Model Element Collection Set Out Of Order";
434                                         }
435                                         subelement = subelement.concat('.'+elementIndex+'.N'+elementIndexes[i+1]);
436                                         i++;
437                                                                                 //formo la cadena y aumento el índice para saltar
438                                         if (((typeof eval(subelement)) == "undefined") && (i < elementIndexes.length-2)) {
439                                                                                 //si el elemento no está definido, salta
440                                             errorCode="408";
441                                         }
442                                     } else {//si no es un dígito, sólo lo concateno a lo que había
443                                         subelement = subelement.concat('.'+elementIndex);
444                                     }
445                                 }
446                                 if (errorCode == "0") {//si no se produce ningún error en los índices
447                                                                         //if (element=='cmi.interactions.0.learner_response'){
448                                                                                 //alert ("Ha llegado con el subelement "+subelement+" y el elementIndexes //"+elementIndexes[elementIndexes.length-1]); 
449                                                                         //}
450                                     element = subelement.concat('.'+elementIndexes[elementIndexes.length-1]);
451                                     elemlen = element.length;
452                                                                         //if (element=='cmi.interactions.N0.learner_response'){
453                                                                                 //alert ("Ha llegado2");
454                                                                         //}
455                                                                         //le añado la terminación (el learner response)
456                                     if (((typeof eval(subelement)) == "undefined") && (errorCode == "0")) {
457                                                                         //si el cmi.interactions.N0 no está definido
458                                                                                 //if (element=='cmi.interactions.N0.learner_response'){
459                                                                                   //            alert ("Ha llegado3");
460                                                                                 //}
462                                                                                 //es porque es un cmi.objectives
463                                         parentmodel = 'cmi.objectives';
464                                         maxmodel = 'cmi.objectives.Nxxx.id';
465                                         if (subelement.substr(0,parentmodel.length) == parentmodel) {
466                                                                                 //si el subelement es un cmi.objectives
467                                              if ((elemlen <= maxmodel.length) && (element.substr(elemlen-2) == 'id') && (errorCode=="0")) { 
468                                                                                          /*if (element=='cmi.interactions.N0.learner_response'){
469                                                                                               alert ("Ha llegado32");
470                                                                                         }*/
471                                                 //This is a parentmodel.n.id element
472                                                 if (!duplicatedID(parentmodel,value)) {
473                                                     if (elementIndexes[elementIndexes.length-2] == eval(parentmodel+'._count')) {
474                                                         eval(parentmodel+'._count++;');
475                                                         eval(subelement+' = new Object();');
476                                                         subobject = eval(subelement);
477                                                         subobject.success_status = datamodel["cmi.objectives.n.success_status"].defaultvalue;
478                                                         subobject.completion_status = datamodel["cmi.objectives.n.completion_status"].defaultvalue;
479                                                         subobject.progress_measure = datamodel["cmi.objectives.n.progress_measure"].defaultvalue;
480                                                         subobject.score = new Object();
481                                                         subobject.score._children = score_children;
482                                                         subobject.score.scaled = datamodel["cmi.objectives.n.score.scaled"].defaultvalue;
483                                                         subobject.score.raw = datamodel["cmi.objectives.n.score.raw"].defaultvalue;
484                                                         subobject.score.min = datamodel["cmi.objectives.n.score.min"].defaultvalue;
485                                                         subobject.score.max = datamodel["cmi.objectives.n.score.max"].defaultvalue;
486                                                     }
487                                                 } else {
488                                                     errorCode="351";
489                                                     diagnostic = "Data Model Element ID Already Exists";
490                                                 }
491                                             } else {
492                                                                                         
493                                                                                         /*if (element=='cmi.interactions.N0.learner_response'){
494                                                                                               alert ("Ha llegado33");
495                                                                                 }*/
496                                                 if (typeof eval(subelement) == "undefined") {
497                                                     errorCode="408";
498                                                 } else {
499                                                     if (duplicatedID(parentmodel,value)) {
500                                                         errorCode="351";
501                                                         diagnostic = "Data Model Element ID Already Exists";
502                                                     }
503                                                 }
504                                             }
505                                         } else {
506                                                                                         //si no es un cmi.objectives es porque hay que construir el interactions
507                                                                                         /*if (element=='cmi.interactions.N0.learner_response'){
508                                                                                               alert ("Ha llegado4");
509                                                                                         }*/
510                                             parentmodel = 'cmi.interactions';
511                                             maxmodel = 'cmi.interactions.Nxxx.id';
512                                                                                         //construyo el interactions
513                                             if (subelement.substr(0,parentmodel.length) == parentmodel) {
514                                                                                         //si el subelement es un interactions
515                                                 if ((elemlen <= maxmodel.length) && (element.substr(elemlen-2) == 'id') && (errorCode=="0")) { 
516                                                                                                         //si es un interactions.id
517                                                     //This is a parentmodel.n.id element
518                                                     if (!duplicatedID(parentmodel,value)) {
519                                                                                                         //si no está duplicado, es porque es uno nuevo
520                                                         if (elementIndexes[elementIndexes.length-2] == eval(parentmodel+'._count')) {
521                                                                                                                 //si es el ultimo elemento que hay hasta ahora
522                                                             eval(parentmodel+'._count++;');
523                                                                                                                         //aumentamos el contador que indica el númElem
524                                                             eval(subelement+' = new Object();');
525                                                                                                                         //creamos el nuevo objeto, el objectives y el corr_resp
526                                                             subobject = eval(subelement);
527                                                             subobject.objectives = new Object();
528                                                             subobject.objectives._count = 0;
529                                                                                                                         subobject.correct_responses = new Object();//añadido
530                                                             subobject.correct_responses._count = 0;//añadido
531                                                                                                                         
532                                                             
533                                                         } 
534                                                     } else {
535                                                                                                         //si esta duplicado da un error
536                                                         errorCode="351";
537                                                         diagnostic = "Data Model Element ID Already Exists";
538                                                     }
539                                                 } else {
540                                                                                                 //si no es un interactions y vemos que no esta definido dicho //elemento
541                                                     if (typeof eval(subelement) == "undefined") {
542                                                         errorCode="408";
543                                                     } else {
544                                                         maxmodel = 'cmi.interactions.Nxxx.type';
545                                                         if ((elemlen <= maxmodel.length) && (element.substr(elemlen-4) == 'type') && (errorCode=="0")) { 
546                                                             subobject = eval(subelement);
547                                                            //subobject.correct_responses = new Object();
548                                                            //subobject.correct_responses._count = 0;
549                                                                                                                   subobject.learner_response = new Object();
550                                                         } 
551                                                     }
552                                                 }
553                                             } else {
554                                                                                         /*if (element=='cmi.interactions.N0.learner_response'){
555                                                                                               alert ("Ha llegado38");
556                                                                                         }*/
557                                                                                         //si no es ni objectives ni interactions lo construyo
558                                                 if (errorCode == "0") {
559                                                     if (elementIndexes[elementIndexes.length-2] == eval(parentelement+'._count')) {
560                                                         eval(parentelement+'._count++;');
561                                                         eval(subelement+' = new Object();');
562                                                     } 
563                                                 }
564                                             }
565                                         }
566                                      } else {
568                                                                          //si ya está definido el subelement
570                                                                         /* if (element=='cmi.interactions.N0.learner_response'){//Aqui entra
571                                                                                               alert ("Ha llegado5");
572                                                                                 }*/
573                                          parentmodel = 'cmi.objectives';
574                                          maxmodel = 'cmi.objectives.Nxxx.id';
575                                          if (subelement.substr(0,parentmodel.length) == parentmodel) {
576                                                                                                         
577                                                                                                         /*if (element=='cmi.interactions.N0.learner_response'){
578                                                                                               alert ("Ha llegado6");
579                                                                                                         }*/
581                                                                                         //si es un objectives
582                                              if ((elemlen <= maxmodel.length) && (element.substr(elemlen-2) == 'id') && (errorCode=="0")) {
583                                                                                                 //si es id y es distinto de value da fallo porque no se cambia
584                                                  if (eval(element) != value) {
585                                                      errorCode = "351";
586                                                      diagnostic = "Write Once Violation";
587                                                  }
588                                              }
589                                          } else {
590                                                                                  
591                                                                                                         /*if (element=='cmi.interactions.N0.learner_response'){//llega 
592                                                                                               alert ("Ha llegado63");
593                                                                                                         }*/
595                                                                                         //si no es objectives miro si es interactions
596                                              parentmodel = 'cmi.interactions';
597                                              maxmodel = 'cmi.interactions.Nxxx.id';
598                                              if (subelement.substr(0,parentmodel.length) == parentmodel) {
599                                                  if ((elemlen <= maxmodel.length) && (element.substr(elemlen-2) == 'id') && (errorCode=="0")) { 
601                                                                                                                 /*if (element=='cmi.interactions.N0.learner_response'){
602                                                                                                                         alert ("Ha llegado64");
603                                                                                                                 }*/
605                                                                                                  //compruebo si intentan modificar su id
606                                                      if (eval(element) != value) {
607                                                          errorCode = "351";
608                                                          diagnostic = "Write Once Violation";
609                                                      }
610                                                  }
611                                              }
612                                          }
613                                      }
614                                 }
615                             }
616                             //Store data
617                             if (errorCode == "0") {
618                                                         //si no ha habido errores                                                               
619                                                                 /*if (element=='cmi.interactions.N0.learner_response'){
620                                                                                               alert ("Ha llegado9");
621                                                                                 }*/
623                                 if ((typeof eval('datamodel["'+elementmodel+'"].range')) != "undefined") {
624                                     range = eval('datamodel["'+elementmodel+'"].range');
625                                     ranges = range.split('#');
626                                     value = value*1.0;
627                                     if (value >= ranges[0]) {
628                                         if ((ranges[1] == '*') || (value <= ranges[1])) {
629                                             eval(element+'="'+value+'";');
630                                             errorCode = "0";
631                                             <?php 
632                                                 if (debugging('',DEBUG_DEVELOPER)) {
633                                                     echo 'alert("SetValue("+element+","+value+") -> OK");';
634                                                 }
635                                             ?>
636                                             return "true";
637                                         } else {
638                                             errorCode = '407';
639                                         }
640                                     } else {
641                                         errorCode = '407';
642                                     }
643                                 } else {
644                                     eval(element+'="'+value+'";');
645                                     errorCode = "0"; 
646                                     <?php 
647                                         if (debugging('',DEBUG_DEVELOPER)) {
648                                             echo 'alert("SetValue("+element+","+value+") -> OK");';
649                                         }
650                                     ?>
651                                     return "true";
652                                 }
653                             }
654                         } else {
655                             //errorCode = eval('datamodel["'+elementmodel+'"].writeerror');
656                             errorCode = "406";
657                         }
658                     } else {
659                         //errorCode = eval('datamodel["'+elementmodel+'"].writeerror');
660                         errorCode = "404";
661                     }
662                 } else {
663                     errorCode = "401"
664                 }
665             } else {
666                 errorCode = "351";
667             }
668         }
669                 //Si está inicializado y no terminado termina aquí 
671                 else {
672             if (Terminated) {
673                 errorCode = "133";
674             } else {
675                 errorCode = "132";
676             }
677         }
678         <?php 
679             if (debugging('',DEBUG_DEVELOPER)) {
680                 echo 'alert("SetValue("+element+","+value+") -> "+GetErrorString(errorCode));';
681             }
682         ?>
683         return "false";
684     }
685     
686     function Commit (param) {
687         errorCode = "0";
688         if (param == "") {
689             if ((Initialized) && (!Terminated)) {
690                 result = StoreData(cmi,false);
691                 <?php 
692                     if (debugging('',DEBUG_DEVELOPER)) {
693                         echo 'alert("Data Commited");';
694                     }
695                 ?>
696                 return "true";
697             } else {
698                 if (Terminated) {
699                     errorCode = "143";
700                 } else {
701                     errorCode = "142";
702                 }
703             }
704         } else {
705             errorCode = "201";
706         }
707         <?php 
708             if (debugging('',DEBUG_DEVELOPER)) {
709                 echo 'alert("Commit: "+GetErrorString(errorCode));';
710             }
711         ?>
712         return "false";
713     }
714     
715     function GetLastError () {
716         return errorCode;
717     }
718     
719     function GetErrorString (param) {
720         if (param != "") {
721             var errorString = "";
722             switch(param) {
723                 case "0":
724                     errorString = "No error";
725                 break;
726                 case "101":
727                     errorString = "General exception";
728                 break;
729                 case "102":
730                     errorString = "General Inizialization Failure";
731                 break;
732                 case "103":
733                     errorString = "Already Initialized";
734                 break;
735                 case "104":
736                     errorString = "Content Instance Terminated";
737                 break;
738                 case "111":
739                     errorString = "General Termination Failure";
740                 break;
741                 case "112":
742                     errorString = "Termination Before Inizialization";
743                 break;
744                 case "113":
745                     errorString = "Termination After Termination";
746                 break;
747                 case "122":
748                     errorString = "Retrieve Data Before Initialization";
749                 break;
750                 case "123":
751                     errorString = "Retrieve Data After Termination";
752                 break;
753                 case "132":
754                     errorString = "Store Data Before Inizialization";
755                 break;
756                 case "133":
757                     errorString = "Store Data After Termination";
758                 break;
759                 case "142":
760                     errorString = "Commit Before Inizialization";
761                 break;
762                 case "143":
763                     errorString = "Commit After Termination";
764                 break;
765                 case "201":
766                     errorString = "General Argument Error";
767                 break;
768                 case "301":
769                     errorString = "General Get Failure";
770                 break;
771                 case "351":
772                     errorString = "General Set Failure";
773                 break;
774                 case "391":
775                     errorString = "General Commit Failure";
776                 break;
777                 case "401":
778                     errorString = "Undefinited Data Model";
779                 break;
780                 case "402":
781                     errorString = "Unimplemented Data Model Element";
782                 break;
783                 case "403":
784                     errorString = "Data Model Element Value Not Initialized";
785                 break;
786                 case "404":
787                     errorString = "Data Model Element Is Read Only";
788                 break;
789                 case "405":
790                     errorString = "Data Model Element Is Write Only";
791                 break;
792                 case "406":
793                     errorString = "Data Model Element Type Mismatch";
794                 break;
795                 case "407":
796                     errorString = "Data Model Element Value Out Of Range";
797                 break;
798                 case "408":
799                     errorString = "Data Model Dependency Not Established";
800                 break;
801             }
802             return errorString;
803         } else {
804            return "";
805         }
806     }
807     
808     function GetDiagnostic (param) {
809         if (diagnostic != "") {
810             return diagnostic;
811         }
812         return param;
813     }
815     function duplicatedID (element, value) {
816         var found = false;
817         var elements = eval(element+'._count');
818         for (n=0;(n<elements) && (!found);n++) {
819             if (eval(element+'.N'+n+'.id') == value) {
820                 found = true;
821             }
822         } 
823         return found;
824     }
826     function getElementModel(element) {
827         if (typeof datamodel[element] != "undefined") {
828             return element;
829         } else {
830             expression = new RegExp(CMIIndex,'g');
831             elementmodel = element.replace(expression,'.n.');
832             if (typeof datamodel[elementmodel] != "undefined") {
833                 return elementmodel;
834             }
835         }
836     }
838     function AddTime (first, second) {
839         <?php 
840             if (debugging('',DEBUG_DEVELOPER)) {
841                 echo 'alert("AddTime: "+first+" + "+second);';
842             }
843         ?>
844         var timestring = 'P';
845         var matchexpr = /^P((\d+)Y)?((\d+)M)?((\d+)D)?(T((\d+)H)?((\d+)M)?((\d+(\.\d{1,2})?)S)?)?$/;
846         var firstarray = first.match(matchexpr);
847         var secondarray = second.match(matchexpr);
848         if ((firstarray != null) && (secondarray != null)) {
849             var secs = parseFloat(firstarray[13],10)+parseFloat(secondarray[13],10);  //Seconds
850             change = Math.floor(secs / 60);
851             secs = secs - (change * 60);
852             mins = parseInt(firstarray[11],10)+parseInt(secondarray[11],10)+change;   //Minutes
853             change = Math.floor(mins / 60);
854             mins = mins - (change * 60);
855             hours = parseInt(firstarray[10],10)+parseInt(secondarray[10],10)+change;  //Hours
856             change = Math.floor(hours / 24);
857             hours = hours - (change * 24);
858             days = parseInt(firstarray[6],10)+parseInt(secondarray[6],10)+change; // Days
859             months = parseInt(firstarray[4],10)+parseInt(secondarray[4],10)
860             years = parseInt(firstarray[2],10)+parseInt(secondarray[2],10)
861         }
862         if (years > 0) {
863             timestring += years + 'Y';
864         }
865         if (months > 0) {
866             timestring += months + 'M';
867         }
868         if (days > 0) {
869             timestring += days + 'D';
870         }
871         if ((hours > 0) || (mins > 0) || (secs > 0)) {
872             timestring += 'T';
873             if (hours > 0) {
874                 timestring += hours + 'H';
875             }
876             if (mins > 0) {
877                 timestring += mins + 'M';
878             }
879             if (secs > 0) {
880                 timestring += secs + 'S';
881             }
882         }
883         return timestring;
884     }
886     function TotalTime() {
887         total_time = AddTime(cmi.total_time, cmi.session_time);
888         return '&'+underscore('cmi.total_time')+'='+escape(total_time);
889     }
891     function CollectData(data,parent) {
892         var datastring = '';
893         for (property in data) {
894             if (typeof data[property] == 'object') {
895                 datastring += CollectData(data[property],parent+'.'+property);
896             } else {
897                 element = parent+'.'+property;
898                 expression = new RegExp(CMIIndexStore,'g');
899                 elementmodel = element.replace(expression,'.n.');
900                 if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") {
901                     if (eval('datamodel["'+elementmodel+'"].mod') != 'r') {
902                         elementstring = '&'+underscore(element)+'='+escape(data[property]);
903                         if ((typeof eval('datamodel["'+elementmodel+'"].defaultvalue')) != "undefined") {
904                             if (eval('datamodel["'+elementmodel+'"].defaultvalue') != data[property]) {
905                                 datastring += elementstring;
906                             }
907                         } else {
908                             datastring += elementstring;
909                         }
910                     }
911                 }
912             }
913         }
914         return datastring;
915     }
917     function StoreData(data,storetotaltime) {
918         if (storetotaltime) {
919             if (cmi.mode == 'normal') {
920                 if (cmi.credit == 'credit') {
921                     if ((cmi.completion_threshold != null) && (cmi.progress_measure != null)) {
922                         if (cmi.progress_measure >= cmi.completion_threshold) {
923                             cmi.completion_status = 'completed';
924                         } else {
925                             cmi.completion_status = 'incomplete';
926                         }
927                     }
928                     if ((cmi.scaled_passed_score != null) && (cmi.score.scaled != '')) {
929                         if (cmi.score.scaled >= cmi.scaled_passed_score) {
930                             cmi.success_status = 'passed';
931                         } else {
932                             cmi.success_status = 'failed';
933                         }
934                     }
935                 }
936             }
937             datastring = CollectData(data,'cmi');
938             datastring += TotalTime();
939         } else {
940             datastring = CollectData(data,'cmi');
941         }
942         datastring += '&attempt=<?php echo $attempt ?>';
943         datastring += '&scoid=<?php echo $sco->id ?>';
944         <?php
945             if (debugging('',DEBUG_DEVELOPER)) {
946                 echo 'popupwin(datastring);';
947             }
948         ?>
949         var myRequest = NewHttpReq();
950         result = DoRequest(myRequest,"<?php p($CFG->wwwroot) ?>/mod/scorm/datamodel.php","id=<?php p($id) ?>&sesskey=<?php p($USER->sesskey) ?>"+datastring);
951         results = result.split('\n');
952         errorCode = results[1];
953         return results[0];
954     }
955     
956     this.Initialize = Initialize;
957     this.Terminate = Terminate;
958     this.GetValue = GetValue;
959     this.SetValue = SetValue;
960     this.Commit = Commit;
961     this.GetLastError = GetLastError;
962     this.GetErrorString = GetErrorString;
963     this.GetDiagnostic = GetDiagnostic;
964     this.version = '1.0';
967 var API_1484_11 = new SCORMapi1_3();