Commit | Line | Data |
---|---|---|
dc383b6f | 1 | <?php |
f7b5c6aa DM |
2 | // This file is part of Moodle - http://moodle.org/ |
3 | // | |
4 | // Moodle is free software: you can redistribute it and/or modify | |
5 | // it under the terms of the GNU General Public License as published by | |
6 | // the Free Software Foundation, either version 3 of the License, or | |
7 | // (at your option) any later version. | |
8 | // | |
9 | // Moodle is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | // | |
14 | // You should have received a copy of the GNU General Public License | |
15 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
faa0e875 | 16 | |
f7b5c6aa DM |
17 | require_once($CFG->dirroot.'/mod/scorm/locallib.php'); |
18 | ||
19 | if (isset($userdata->status)) { | |
20 | if (!isset($userdata->{'cmi.exit'}) || (($userdata->{'cmi.exit'} == 'time-out') || ($userdata->{'cmi.exit'} == 'normal'))) { | |
21 | $userdata->entry = 'ab-initio'; | |
22 | } else { | |
23 | if (isset($userdata->{'cmi.exit'}) && (($userdata->{'cmi.exit'} == 'suspend') || ($userdata->{'cmi.exit'} == 'logout'))) { | |
24 | $userdata->entry = 'resume'; | |
dc383b6f | 25 | } else { |
f7b5c6aa | 26 | $userdata->entry = ''; |
dc383b6f | 27 | } |
28 | } | |
f7b5c6aa DM |
29 | } |
30 | if (!isset($currentorg)) { | |
31 | $currentorg = ''; | |
32 | } | |
dc383b6f | 33 | ?> |
d5f9eb42 | 34 | |
35 | // Used need to debug cmi content (if you uncomment this, you must comment the definition inside SCORMapi1_3) | |
faa0e875 | 36 | //var cmi = new Object(); |
d11b69ff | 37 | |
dc383b6f | 38 | // |
39 | // SCORM 1.3 API Implementation | |
40 | // | |
41 | function SCORMapi1_3() { | |
42 | // Standard Data Type Definition | |
faa0e875 | 43 | |
f7c9304b | 44 | // language key has to be checked for language dependent strings |
faa0e875 | 45 | var validLanguages = {'aa':'aa', 'ab':'ab', 'ae':'ae', 'af':'af', 'ak':'ak', 'am':'am', 'an':'an', 'ar':'ar', 'as':'as', 'av':'av', 'ay':'ay', 'az':'az', |
f7c9304b | 46 | 'ba':'ba', 'be':'be', 'bg':'bg', 'bh':'bh', 'bi':'bi', 'bm':'bm', 'bn':'bn', 'bo':'bo', 'br':'br', 'bs':'bs', |
faa0e875 | 47 | 'ca':'ca', 'ce':'ce', 'ch':'ch', 'co':'co', 'cr':'cr', 'cs':'cs', 'cu':'cu', 'cv':'cv', 'cy':'cy', |
f7c9304b | 48 | 'da':'da', 'de':'de', 'dv':'dv', 'dz':'dz', 'ee':'ee', 'el':'el', 'en':'en', 'eo':'eo', 'es':'es', 'et':'et', 'eu':'eu', |
49 | 'fa':'fa', 'ff':'ff', 'fi':'fi', 'fj':'fj', 'fo':'fo', 'fr':'fr', 'fy':'fy', 'ga':'ga', 'gd':'gd', 'gl':'gl', 'gn':'gn', 'gu':'gu', 'gv':'gv', | |
50 | 'ha':'ha', 'he':'he', 'hi':'hi', 'ho':'ho', 'hr':'hr', 'ht':'ht', 'hu':'hu', 'hy':'hy', 'hz':'hz', | |
51 | 'ia':'ia', 'id':'id', 'ie':'ie', 'ig':'ig', 'ii':'ii', 'ik':'ik', 'io':'io', 'is':'is', 'it':'it', 'iu':'iu', | |
52 | 'ja':'ja', 'jv':'jv', 'ka':'ka', 'kg':'kg', 'ki':'ki', 'kj':'kj', 'kk':'kk', 'kl':'kl', 'km':'km', 'kn':'kn', 'ko':'ko', 'kr':'kr', 'ks':'ks', 'ku':'ku', 'kv':'kv', 'kw':'kw', 'ky':'ky', | |
53 | 'la':'la', 'lb':'lb', 'lg':'lg', 'li':'li', 'ln':'ln', 'lo':'lo', 'lt':'lt', 'lu':'lu', 'lv':'lv', | |
54 | 'mg':'mg', 'mh':'mh', 'mi':'mi', 'mk':'mk', 'ml':'ml', 'mn':'mn', 'mo':'mo', 'mr':'mr', 'ms':'ms', 'mt':'mt', 'my':'my', | |
55 | 'na':'na', 'nb':'nb', 'nd':'nd', 'ne':'ne', 'ng':'ng', 'nl':'nl', 'nn':'nn', 'no':'no', 'nr':'nr', 'nv':'nv', 'ny':'ny', | |
56 | 'oc':'oc', 'oj':'oj', 'om':'om', 'or':'or', 'os':'os', 'pa':'pa', 'pi':'pi', 'pl':'pl', 'ps':'ps', 'pt':'pt', | |
57 | 'qu':'qu', 'rm':'rm', 'rn':'rn', 'ro':'ro', 'ru':'ru', 'rw':'rw', | |
58 | 'sa':'sa', 'sc':'sc', 'sd':'sd', 'se':'se', 'sg':'sg', 'sh':'sh', 'si':'si', 'sk':'sk', 'sl':'sl', 'sm':'sm', 'sn':'sn', 'so':'so', 'sq':'sq', 'sr':'sr', 'ss':'ss', 'st':'st', 'su':'su', 'sv':'sv', 'sw':'sw', | |
59 | 'ta':'ta', 'te':'te', 'tg':'tg', 'th':'th', 'ti':'ti', 'tk':'tk', 'tl':'tl', 'tn':'tn', 'to':'to', 'tr':'tr', 'ts':'ts', 'tt':'tt', 'tw':'tw', 'ty':'ty', | |
60 | 'ug':'ug', 'uk':'uk', 'ur':'ur', 'uz':'uz', 've':'ve', 'vi':'vi', 'vo':'vo', | |
61 | 'wa':'wa', 'wo':'wo', 'xh':'xh', 'yi':'yi', 'yo':'yo', 'za':'za', 'zh':'zh', 'zu':'zu', | |
62 | 'aar':'aar', 'abk':'abk', 'ave':'ave', 'afr':'afr', 'aka':'aka', 'amh':'amh', 'arg':'arg', 'ara':'ara', 'asm':'asm', 'ava':'ava', 'aym':'aym', 'aze':'aze', | |
63 | 'bak':'bak', 'bel':'bel', 'bul':'bul', 'bih':'bih', 'bis':'bis', 'bam':'bam', 'ben':'ben', 'tib':'tib', 'bod':'bod', 'bre':'bre', 'bos':'bos', | |
64 | 'cat':'cat', 'che':'che', 'cha':'cha', 'cos':'cos', 'cre':'cre', 'cze':'cze', 'ces':'ces', 'chu':'chu', 'chv':'chv', 'wel':'wel', 'cym':'cym', | |
65 | 'dan':'dan', 'ger':'ger', 'deu':'deu', 'div':'div', 'dzo':'dzo', 'ewe':'ewe', 'gre':'gre', 'ell':'ell', 'eng':'eng', 'epo':'epo', 'spa':'spa', 'est':'est', 'baq':'baq', 'eus':'eus', 'per':'per', | |
66 | 'fas':'fas', 'ful':'ful', 'fin':'fin', 'fij':'fij', 'fao':'fao', 'fre':'fre', 'fra':'fra', 'fry':'fry', 'gle':'gle', 'gla':'gla', 'glg':'glg', 'grn':'grn', 'guj':'guj', 'glv':'glv', | |
67 | 'hau':'hau', 'heb':'heb', 'hin':'hin', 'hmo':'hmo', 'hrv':'hrv', 'hat':'hat', 'hun':'hun', 'arm':'arm', 'hye':'hye', 'her':'her', | |
68 | 'ina':'ina', 'ind':'ind', 'ile':'ile', 'ibo':'ibo', 'iii':'iii', 'ipk':'ipk', 'ido':'ido', 'ice':'ice', 'isl':'isl', 'ita':'ita', 'iku':'iku', | |
69 | 'jpn':'jpn', 'jav':'jav', 'geo':'geo', 'kat':'kat', 'kon':'kon', 'kik':'kik', 'kua':'kua', 'kaz':'kaz', 'kal':'kal', 'khm':'khm', 'kan':'kan', 'kor':'kor', 'kau':'kau', 'kas':'kas', 'kur':'kur', 'kom':'kom', 'cor':'cor', 'kir':'kir', | |
70 | 'lat':'lat', 'ltz':'ltz', 'lug':'lug', 'lim':'lim', 'lin':'lin', 'lao':'lao', 'lit':'lit', 'lub':'lub', 'lav':'lav', | |
71 | 'mlg':'mlg', 'mah':'mah', 'mao':'mao', 'mri':'mri', 'mac':'mac', 'mkd':'mkd', 'mal':'mal', 'mon':'mon', 'mol':'mol', 'mar':'mar', 'may':'may', 'msa':'msa', 'mlt':'mlt', 'bur':'bur', 'mya':'mya', | |
72 | 'nau':'nau', 'nob':'nob', 'nde':'nde', 'nep':'nep', 'ndo':'ndo', 'dut':'dut', 'nld':'nld', 'nno':'nno', 'nor':'nor', 'nbl':'nbl', 'nav':'nav', 'nya':'nya', | |
73 | 'oci':'oci', 'oji':'oji', 'orm':'orm', 'ori':'ori', 'oss':'oss', 'pan':'pan', 'pli':'pli', 'pol':'pol', 'pus':'pus', 'por':'por', 'que':'que', | |
74 | 'roh':'roh', 'run':'run', 'rum':'rum', 'ron':'ron', 'rus':'rus', 'kin':'kin', 'san':'san', 'srd':'srd', 'snd':'snd', 'sme':'sme', 'sag':'sag', 'slo':'slo', 'sin':'sin', 'slk':'slk', 'slv':'slv', 'smo':'smo', 'sna':'sna', 'som':'som', 'alb':'alb', 'sqi':'sqi', 'srp':'srp', 'ssw':'ssw', 'sot':'sot', 'sun':'sun', 'swe':'swe', 'swa':'swa', | |
75 | 'tam':'tam', 'tel':'tel', 'tgk':'tgk', 'tha':'tha', 'tir':'tir', 'tuk':'tuk', 'tgl':'tgl', 'tsn':'tsn', 'ton':'ton', 'tur':'tur', 'tso':'tso', 'tat':'tat', 'twi':'twi', 'tah':'tah', | |
76 | 'uig':'uig', 'ukr':'ukr', 'urd':'urd', 'uzb':'uzb', 'ven':'ven', 'vie':'vie', 'vol':'vol', 'wln':'wln', 'wol':'wol', 'xho':'xho', 'yid':'yid', 'yor':'yor', 'zha':'zha', 'chi':'chi', 'zho':'zho', 'zul':'zul'}; | |
77 | ||
67859ce6 | 78 | var CMIString200 = '^[\\u0000-\\uFFFF]{0,200}$'; |
faa0e875 | 79 | var CMIString250 = '^[\\u0000-\\uFFFF]{0,250}$'; |
80 | var CMIString1000 = '^[\\u0000-\\uFFFF]{0,1000}$'; | |
81 | var CMIString4000 = '^[\\u0000-\\uFFFF]{0,4000}$'; | |
82 | var CMIString64000 = '^[\\u0000-\\uFFFF]{0,64000}$'; | |
d5f9eb42 | 83 | var CMILang = '^([a-zA-Z]{2,3}|i|x)(\-[a-zA-Z0-9\-]{2,8})?$|^$'; |
84 | var CMILangString250 = '^(\{lang=([a-zA-Z]{2,3}|i|x)(\-[a-zA-Z0-9\-]{2,8})?\})?([^\{].{0,250}$)?'; | |
f7c9304b | 85 | var CMILangcr = '^((\{lang=([a-zA-Z]{2,3}|i|x)?(\-[a-zA-Z0-9\-]{2,8})?\}))(.*?)$'; |
86 | var CMILangString250cr = '^((\{lang=([a-zA-Z]{2,3}|i|x)?(\-[a-zA-Z0-9\-]{2,8})?\})?(.{0,250})?)?$'; | |
d5f9eb42 | 87 | var CMILangString4000 = '^(\{lang=([a-zA-Z]{2,3}|i|x)(\-[a-zA-Z0-9\-]{2,8})?\})?([^\{].{0,4000}$)?'; |
88 | var 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})?)?)?)?)?)?)?)?$'; | |
89 | var 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))))?$'; | |
90 | var CMIInteger = '^\\d+$'; | |
91 | var CMISInteger = '^-?([0-9]+)$'; | |
f7c9304b | 92 | var CMIDecimal = '^-?([0-9]{1,5})(\\.[0-9]{1,18})?$'; |
c9e7d6eb | 93 | var CMIIdentifier = '^\\S{1,250}[a-zA-Z0-9]$'; |
55175138 | 94 | var CMIShortIdentifier = '^[\\w\.]{1,250}$'; |
c9e7d6eb | 95 | var CMILongIdentifier = '^(?:(?!urn:)\\S{1,4000}|urn:[a-z0-9][-a-z-0-9]{1,31}:\\S{1,4000})$'; |
d5f9eb42 | 96 | var CMIFeedback = '^.*$'; // This must be redefined |
97 | var CMIIndex = '[._](\\d+).'; | |
98 | var CMIIndexStore = '.N(\\d+).'; | |
dc383b6f | 99 | // Vocabulary Data Type Definition |
d5f9eb42 | 100 | var CMICStatus = '^completed$|^incomplete$|^not attempted$|^unknown$'; |
101 | var CMISStatus = '^passed$|^failed$|^unknown$'; | |
102 | var CMIExit = '^time-out$|^suspend$|^logout$|^normal$|^$'; | |
103 | var CMIType = '^true-false$|^choice$|^(long-)?fill-in$|^matching$|^performance$|^sequencing$|^likert$|^numeric$|^other$'; | |
104 | var CMIResult = '^correct$|^incorrect$|^unanticipated$|^neutral$|^-?([0-9]{1,4})(\\.[0-9]{1,18})?$'; | |
105 | var NAVEvent = '^previous$|^continue$|^exit$|^exitAll$|^abandon$|^abandonAll$|^suspendAll$|^{target=\\S{0,200}[a-zA-Z0-9]}choice$'; | |
106 | var NAVBoolean = '^unknown$|^true$|^false$'; | |
107 | var NAVTarget = '^previous$|^continue$|^choice.{target=\\S{0,200}[a-zA-Z0-9]}$' | |
dc383b6f | 108 | // Children lists |
1ed0a96c DM |
109 | var 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'; |
110 | var comments_children = 'comment,timestamp,location'; | |
111 | var score_children = 'max,raw,scaled,min'; | |
112 | var objectives_children = 'progress_measure,completion_status,success_status,description,score,id'; | |
bf34ac0f | 113 | var correct_responses_children = 'pattern'; |
1ed0a96c DM |
114 | var student_data_children = 'mastery_score,max_time_allowed,time_limit_action'; |
115 | var student_preference_children = 'audio_level,audio_captioning,delivery_speed,language'; | |
116 | var interactions_children = 'id,type,objectives,timestamp,correct_responses,weighting,learner_response,result,latency,description'; | |
dc383b6f | 117 | // Data ranges |
d5f9eb42 | 118 | var scaled_range = '-1#1'; |
119 | var audio_range = '0#*'; | |
120 | var speed_range = '0#*'; | |
121 | var text_range = '-1#1'; | |
122 | var progress_range = '0#1'; | |
123 | var learner_response = { | |
55175138 | 124 | 'true-false':{'format':'^true$|^false$', 'max':1, 'delimiter':'', 'unique':false}, |
f7c9304b | 125 | 'choice':{'format':CMIShortIdentifier, 'max':36, 'delimiter':'[,]', 'unique':true}, |
55175138 | 126 | 'fill-in':{'format':CMILangString250, 'max':10, 'delimiter':'[,]', 'unique':false}, |
127 | 'long-fill-in':{'format':CMILangString4000, 'max':1, 'delimiter':'', 'unique':false}, | |
f8c950b3 | 128 | 'matching':{'format':CMIShortIdentifier, 'format2':CMIShortIdentifier, 'max':36, 'delimiter':'[,]', 'delimiter2':'[.]', 'unique':false}, |
129 | 'performance':{'format':'^$|'+CMIShortIdentifier, 'format2':CMIDecimal+'|^$|'+CMIShortIdentifier, 'max':250, 'delimiter':'[,]', 'delimiter2':'[.]', 'unique':false}, | |
130 | 'sequencing':{'format':CMIShortIdentifier, 'max':36, 'delimiter':'[,]', 'unique':false}, | |
55175138 | 131 | 'likert':{'format':CMIShortIdentifier, 'max':1, 'delimiter':'', 'unique':false}, |
132 | 'numeric':{'format':CMIDecimal, 'max':1, 'delimiter':'', 'unique':false}, | |
133 | 'other':{'format':CMIString4000, 'max':1, 'delimiter':'', 'unique':false} | |
d5f9eb42 | 134 | } |
faa0e875 | 135 | |
d5f9eb42 | 136 | var correct_responses = { |
7e17f5a2 | 137 | 'true-false':{'pre':'', 'max':1, 'delimiter':'', 'unique':false, 'duplicate':false, |
faa0e875 | 138 | 'format':'^true$|^false$', |
7e17f5a2 | 139 | 'limit':1}, |
140 | 'choice':{'pre':'', 'max':36, 'delimiter':'[,]', 'unique':true, 'duplicate':false, | |
f7c9304b | 141 | 'format':CMIShortIdentifier}, |
142 | // 'fill-in':{'pre':'^(((\{case_matters=(true|false)\})(\{order_matters=(true|false)\})?)|((\{order_matters=(true|false)\})(\{case_matters=(true|false)\})?))(.*?)$', | |
143 | 'fill-in':{'pre':'', | |
7e17f5a2 | 144 | 'max':10, 'delimiter':'[,]', 'unique':false, 'duplicate':false, |
f7c9304b | 145 | 'format':CMILangString250cr}, |
7e17f5a2 | 146 | 'long-fill-in':{'pre':'^(\{case_matters=(true|false)\})?', 'max':1, 'delimiter':'', 'unique':false, 'duplicate':true, |
147 | 'format':CMILangString4000}, | |
f7c9304b | 148 | 'matching':{'pre':'', 'max':36, 'delimiter':'[,]', 'delimiter2':'[.]', 'unique':false, 'duplicate':false, |
7e17f5a2 | 149 | 'format':CMIShortIdentifier, 'format2':CMIShortIdentifier}, |
150 | 'performance':{'pre':'^(\{order_matters=(true|false)\})?', | |
f7c9304b | 151 | 'max':250, 'delimiter':'[,]', 'delimiter2':'[.]', 'unique':false, 'duplicate':false, |
7e17f5a2 | 152 | 'format':'^$|'+CMIShortIdentifier, 'format2':CMIDecimal+'|^$|'+CMIShortIdentifier}, |
153 | 'sequencing':{'pre':'', 'max':36, 'delimiter':'[,]', 'unique':false, 'duplicate':false, | |
154 | 'format':CMIShortIdentifier}, | |
155 | 'likert':{'pre':'', 'max':1, 'delimiter':'', 'unique':false, 'duplicate':false, | |
156 | 'format':CMIShortIdentifier, | |
157 | 'limit':1}, | |
f7c9304b | 158 | 'numeric':{'pre':'', 'max':2, 'delimiter':'[:]', 'unique':false, 'duplicate':false, |
7e17f5a2 | 159 | 'format':CMIDecimal, |
160 | 'limit':1}, | |
161 | 'other':{'pre':'', 'max':1, 'delimiter':'', 'unique':false, 'duplicate':false, | |
162 | 'format':CMIString4000, | |
163 | 'limit':1} | |
d5f9eb42 | 164 | } |
7e17f5a2 | 165 | |
dc383b6f | 166 | // The SCORM 1.3 data model |
167 | var datamodel = { | |
168 | 'cmi._children':{'defaultvalue':cmi_children, 'mod':'r'}, | |
172ec29f | 169 | 'cmi._version':{'defaultvalue':'1.0', 'mod':'r'}, |
dc383b6f | 170 | 'cmi.comments_from_learner._children':{'defaultvalue':comments_children, 'mod':'r'}, |
171 | 'cmi.comments_from_learner._count':{'mod':'r', 'defaultvalue':'0'}, | |
89656c61 | 172 | 'cmi.comments_from_learner.n.comment':{'format':CMILangString4000, 'mod':'rw'}, |
dc383b6f | 173 | 'cmi.comments_from_learner.n.location':{'format':CMIString250, 'mod':'rw'}, |
acba841b | 174 | 'cmi.comments_from_learner.n.timestamp':{'format':CMITime, 'mod':'rw'}, |
dc383b6f | 175 | 'cmi.comments_from_lms._children':{'defaultvalue':comments_children, 'mod':'r'}, |
176 | 'cmi.comments_from_lms._count':{'mod':'r', 'defaultvalue':'0'}, | |
89656c61 | 177 | 'cmi.comments_from_lms.n.comment':{'format':CMILangString4000, 'mod':'r'}, |
dc383b6f | 178 | 'cmi.comments_from_lms.n.location':{'format':CMIString250, 'mod':'r'}, |
89656c61 | 179 | 'cmi.comments_from_lms.n.timestamp':{'format':CMITime, 'mod':'r'}, |
75638e0a MG |
180 | 'cmi.completion_status':{'defaultvalue':'<?php echo !empty($userdata->{'cmi.completion_status'})?$userdata->{'cmi.completion_status'}:'unknown' ?>', 'format':CMICStatus, 'mod':'rw'}, |
181 | 'cmi.completion_threshold':{'defaultvalue':<?php echo !empty($userdata->threshold)?'\''.$userdata->threshold.'\'':'null' ?>, 'mod':'r'}, | |
182 | 'cmi.credit':{'defaultvalue':'<?php echo !empty($userdata->credit)?$userdata->credit:'' ?>', 'mod':'r'}, | |
dc383b6f | 183 | 'cmi.entry':{'defaultvalue':'<?php echo $userdata->entry ?>', 'mod':'r'}, |
75638e0a | 184 | 'cmi.exit':{'defaultvalue':'<?php echo !empty($userdata->{'cmi.exit'})?$userdata->{'cmi.exit'}:'' ?>', 'format':CMIExit, 'mod':'w'}, |
dc383b6f | 185 | 'cmi.interactions._children':{'defaultvalue':interactions_children, 'mod':'r'}, |
186 | 'cmi.interactions._count':{'mod':'r', 'defaultvalue':'0'}, | |
187 | 'cmi.interactions.n.id':{'pattern':CMIIndex, 'format':CMILongIdentifier, 'mod':'rw'}, | |
188 | 'cmi.interactions.n.type':{'pattern':CMIIndex, 'format':CMIType, 'mod':'rw'}, | |
189 | 'cmi.interactions.n.objectives._count':{'pattern':CMIIndex, 'mod':'r', 'defaultvalue':'0'}, | |
190 | 'cmi.interactions.n.objectives.n.id':{'pattern':CMIIndex, 'format':CMILongIdentifier, 'mod':'rw'}, | |
191 | 'cmi.interactions.n.timestamp':{'pattern':CMIIndex, 'format':CMITime, 'mod':'rw'}, | |
192 | 'cmi.interactions.n.correct_responses._count':{'defaultvalue':'0', 'pattern':CMIIndex, 'mod':'r'}, | |
27a46315 | 193 | 'cmi.interactions.n.correct_responses.n.pattern':{'pattern':CMIIndex, 'format':'CMIFeedback', 'mod':'rw'}, |
dc383b6f | 194 | 'cmi.interactions.n.weighting':{'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'}, |
27a46315 | 195 | 'cmi.interactions.n.learner_response':{'pattern':CMIIndex, 'format':'CMIFeedback', 'mod':'rw'}, |
dc383b6f | 196 | 'cmi.interactions.n.result':{'pattern':CMIIndex, 'format':CMIResult, 'mod':'rw'}, |
197 | 'cmi.interactions.n.latency':{'pattern':CMIIndex, 'format':CMITimespan, 'mod':'rw'}, | |
89656c61 | 198 | 'cmi.interactions.n.description':{'pattern':CMIIndex, 'format':CMILangString250, 'mod':'rw'}, |
75638e0a | 199 | 'cmi.launch_data':{'defaultvalue':<?php echo !empty($userdata->datafromlms)?'\''.$userdata->datafromlms.'\'':'null' ?>, 'mod':'r'}, |
dc383b6f | 200 | 'cmi.learner_id':{'defaultvalue':'<?php echo $userdata->student_id ?>', 'mod':'r'}, |
dac958fc | 201 | 'cmi.learner_name':{'defaultvalue':'<?php echo $userdata->student_name ?>', 'mod':'r'}, |
dc383b6f | 202 | 'cmi.learner_preference._children':{'defaultvalue':student_preference_children, 'mod':'r'}, |
a16abd53 MG |
203 | 'cmi.learner_preference.audio_level':{'defaultvalue':<?php echo !empty($userdata->{'cmi.learner_preference.audio_level'})?'\''.$userdata->{'cmi.learner_preference.audio_level'}.'\'':'\'1\'' ?>, 'format':CMIDecimal, 'range':audio_range, 'mod':'rw'}, |
204 | 'cmi.learner_preference.language':{'defaultvalue':<?php echo !empty($userdata->{'cmi.learner_preference.language'})?'\''.$userdata->{'cmi.learner_preference.language'}.'\'':'\'\'' ?>, 'format':CMILang, 'mod':'rw'}, | |
205 | 'cmi.learner_preference.delivery_speed':{'defaultvalue':<?php echo !empty($userdata->{'cmi.learner_preference.delivery_speed'})?'\''.$userdata->{'cmi.learner_preference.delivery_speed'}.'\'':'\'1\'' ?>, 'format':CMIDecimal, 'range':speed_range, 'mod':'rw'}, | |
206 | 'cmi.learner_preference.audio_captioning':{'defaultvalue':<?php echo !empty($userdata->{'cmi.learner_preference.audio_captioning'})?'\''.$userdata->{'cmi.learner_preference.audio_captioning'}.'\'':'\'0\'' ?>, 'format':CMISInteger, 'range':text_range, 'mod':'rw'}, | |
75638e0a MG |
207 | 'cmi.location':{'defaultvalue':<?php echo !empty($userdata->{'cmi.location'})?'\''.$userdata->{'cmi.location'}.'\'':'null' ?>, 'format':CMIString1000, 'mod':'rw'}, |
208 | 'cmi.max_time_allowed':{'defaultvalue':<?php echo !empty($userdata->attemptAbsoluteDurationLimit)?'\''.$userdata->attemptAbsoluteDurationLimit.'\'':'null' ?>, 'mod':'r'}, | |
dc383b6f | 209 | 'cmi.mode':{'defaultvalue':'<?php echo $userdata->mode ?>', 'mod':'r'}, |
210 | 'cmi.objectives._children':{'defaultvalue':objectives_children, 'mod':'r'}, | |
211 | 'cmi.objectives._count':{'mod':'r', 'defaultvalue':'0'}, | |
212 | 'cmi.objectives.n.id':{'pattern':CMIIndex, 'format':CMILongIdentifier, 'mod':'rw'}, | |
d11b69ff | 213 | 'cmi.objectives.n.score._children':{'defaultvalue':score_children, 'pattern':CMIIndex, 'mod':'r'}, |
214 | 'cmi.objectives.n.score.scaled':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'range':scaled_range, 'mod':'rw'}, | |
215 | 'cmi.objectives.n.score.raw':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'}, | |
216 | 'cmi.objectives.n.score.min':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'}, | |
217 | 'cmi.objectives.n.score.max':{'defaultvalue':null, 'pattern':CMIIndex, 'format':CMIDecimal, 'mod':'rw'}, | |
dc383b6f | 218 | 'cmi.objectives.n.success_status':{'defaultvalue':'unknown', 'pattern':CMIIndex, 'format':CMISStatus, 'mod':'rw'}, |
2aaf134c | 219 | 'cmi.objectives.n.completion_status':{'defaultvalue':'unknown', 'pattern':CMIIndex, 'format':CMICStatus, 'mod':'rw'}, |
220 | 'cmi.objectives.n.progress_measure':{'defaultvalue':null, 'format':CMIDecimal, 'range':progress_range, 'mod':'rw'}, | |
89656c61 | 221 | 'cmi.objectives.n.description':{'pattern':CMIIndex, 'format':CMILangString250, 'mod':'rw'}, |
a16abd53 | 222 | 'cmi.progress_measure':{'defaultvalue':<?php echo !empty($userdata->{'cmi.progress_measure'})?'\''.$userdata->{'cmi.progress_measure'}.'\'':'null' ?>, 'format':CMIDecimal, 'range':progress_range, 'mod':'rw'}, |
75638e0a | 223 | 'cmi.scaled_passing_score':{'defaultvalue':<?php echo !empty($userdata->{'cmi.scaled_passing_score'})?'\''.$userdata->{'cmi.scaled_passing_score'}.'\'':'null' ?>, 'format':CMIDecimal, 'range':scaled_range, 'mod':'r'}, |
d11b69ff | 224 | 'cmi.score._children':{'defaultvalue':score_children, 'mod':'r'}, |
75638e0a MG |
225 | 'cmi.score.scaled':{'defaultvalue':<?php echo !empty($userdata->{'cmi.score.scaled'})?'\''.$userdata->{'cmi.score.scaled'}.'\'':'null' ?>, 'format':CMIDecimal, 'range':scaled_range, 'mod':'rw'}, |
226 | 'cmi.score.raw':{'defaultvalue':<?php echo !empty($userdata->{'cmi.score.raw'})?'\''.$userdata->{'cmi.score.raw'}.'\'':'null' ?>, 'format':CMIDecimal, 'mod':'rw'}, | |
227 | 'cmi.score.min':{'defaultvalue':<?php echo !empty($userdata->{'cmi.score.min'})?'\''.$userdata->{'cmi.score.min'}.'\'':'null' ?>, 'format':CMIDecimal, 'mod':'rw'}, | |
228 | 'cmi.score.max':{'defaultvalue':<?php echo !empty($userdata->{'cmi.score.max'})?'\''.$userdata->{'cmi.score.max'}.'\'':'null' ?>, 'format':CMIDecimal, 'mod':'rw'}, | |
dc383b6f | 229 | 'cmi.session_time':{'format':CMITimespan, 'mod':'w', 'defaultvalue':'PT0H0M0S'}, |
75638e0a MG |
230 | 'cmi.success_status':{'defaultvalue':'<?php echo !empty($userdata->{'cmi.success_status'})?$userdata->{'cmi.success_status'}:'unknown' ?>', 'format':CMISStatus, 'mod':'rw'}, |
231 | 'cmi.suspend_data':{'defaultvalue':<?php echo !empty($userdata->{'cmi.suspend_data'})?'\''.$userdata->{'cmi.suspend_data'}.'\'':'null' ?>, 'format':CMIString64000, 'mod':'rw'}, | |
232 | 'cmi.time_limit_action':{'defaultvalue':<?php echo !empty($userdata->timelimitaction)?'\''.$userdata->timelimitaction.'\'':'null' ?>, 'mod':'r'}, | |
233 | 'cmi.total_time':{'defaultvalue':'<?php echo !empty($userdata->{'cmi.total_time'})?$userdata->{'cmi.total_time'}:'PT0H0M0S' ?>', 'mod':'r'}, | |
4c2095de | 234 | 'adl.nav.request':{'defaultvalue':'_none_', 'format':NAVEvent, 'mod':'rw'} |
dc383b6f | 235 | }; |
236 | // | |
237 | // Datamodel inizialization | |
238 | // | |
d5f9eb42 | 239 | var cmi = new Object(); |
dc383b6f | 240 | cmi.comments_from_learner = new Object(); |
d11b69ff | 241 | cmi.comments_from_learner._count = 0; |
dc383b6f | 242 | cmi.comments_from_lms = new Object(); |
d11b69ff | 243 | cmi.comments_from_lms._count = 0; |
dc383b6f | 244 | cmi.interactions = new Object(); |
d11b69ff | 245 | cmi.interactions._count = 0; |
dc383b6f | 246 | cmi.learner_preference = new Object(); |
247 | cmi.objectives = new Object(); | |
d11b69ff | 248 | cmi.objectives._count = 0; |
dc383b6f | 249 | cmi.score = new Object(); |
250 | ||
251 | // Navigation Object | |
4c2095de | 252 | var adl = new Object(); |
253 | adl.nav = new Object(); | |
667a2166 | 254 | adl.nav.request_valid = new Array(); |
dc383b6f | 255 | |
256 | for (element in datamodel) { | |
257 | if (element.match(/\.n\./) == null) { | |
258 | if ((typeof eval('datamodel["'+element+'"].defaultvalue')) != 'undefined') { | |
259 | eval(element+' = datamodel["'+element+'"].defaultvalue;'); | |
260 | } else { | |
261 | eval(element+' = "";'); | |
262 | } | |
263 | } | |
264 | } | |
265 | ||
266 | <?php | |
527af457 | 267 | // reconstitute objectives, comments_from_learner and comments_from_lms |
268 | scorm_reconstitute_array_element($scorm->version, $userdata, 'cmi.objectives', array('score')); | |
bf34ac0f | 269 | scorm_reconstitute_array_element($scorm->version, $userdata, 'cmi.interactions', array('objectives', 'correct_responses')); |
527af457 | 270 | scorm_reconstitute_array_element($scorm->version, $userdata, 'cmi.comments_from_learner', array()); |
271 | scorm_reconstitute_array_element($scorm->version, $userdata, 'cmi.comments_from_lms', array()); | |
dc383b6f | 272 | ?> |
273 | ||
274 | if (cmi.completion_status == '') { | |
275 | cmi.completion_status = 'not attempted'; | |
faa0e875 | 276 | } |
277 | ||
dc383b6f | 278 | // |
279 | // API Methods definition | |
280 | // | |
281 | var Initialized = false; | |
282 | var Terminated = false; | |
283 | var diagnostic = ""; | |
0ec0224b | 284 | var errorCode = "0"; |
dc383b6f | 285 | |
286 | function Initialize (param) { | |
287 | errorCode = "0"; | |
288 | if (param == "") { | |
289 | if ((!Initialized) && (!Terminated)) { | |
7bbb7f49 | 290 | Initialized = true; |
291 | errorCode = "0"; | |
faa0e875 | 292 | <?php |
1881df27 | 293 | if (scorm_debugging($scorm)) { |
7bbb7f49 | 294 | echo 'LogAPICall("Initialize", param, "", errorCode);'; |
dc383b6f | 295 | } |
296 | ?> | |
dc383b6f | 297 | return "true"; |
298 | } else { | |
acba841b | 299 | if (Initialized) { |
dc383b6f | 300 | errorCode = "103"; |
301 | } else { | |
302 | errorCode = "104"; | |
303 | } | |
304 | } | |
305 | } else { | |
306 | errorCode = "201"; | |
307 | } | |
faa0e875 | 308 | <?php |
1881df27 | 309 | if (scorm_debugging($scorm)) { |
7bbb7f49 | 310 | echo 'LogAPICall("Initialize", param, "", errorCode);'; |
acba841b | 311 | } |
312 | ?> | |
dc383b6f | 313 | return "false"; |
314 | } | |
faa0e875 | 315 | |
cac50377 | 316 | |
e62c1d22 PH |
317 | <?php |
318 | // pull in the TOC callback | |
319 | include_once($CFG->dirroot.'/mod/scorm/datamodels/callback.js.php'); | |
320 | ?> | |
cac50377 PH |
321 | |
322 | ||
dc383b6f | 323 | function Terminate (param) { |
324 | errorCode = "0"; | |
325 | if (param == "") { | |
326 | if ((Initialized) && (!Terminated)) { | |
0ec0224b | 327 | var AJAXResult = StoreData(cmi,true); |
faa0e875 | 328 | <?php |
1881df27 | 329 | if (scorm_debugging($scorm)) { |
0ec0224b | 330 | echo 'LogAPICall("Terminate", "AJAXResult", AJAXResult, 0);'; |
dc383b6f | 331 | } |
332 | ?> | |
0ec0224b MS |
333 | result = ('true' == AJAXResult) ? 'true' : 'false'; |
334 | errorCode = ('true' == result)? '0' : '101'; // General exception for any AJAX fault | |
335 | <?php | |
336 | if (scorm_debugging($scorm)) { | |
337 | echo 'LogAPICall("Terminate", "result", result, errorCode);'; | |
338 | } | |
339 | ?> | |
340 | if ('true' == result) { | |
341 | Initialized = false; | |
342 | Terminated = true; | |
343 | if (adl.nav.request != '_none_') { | |
344 | switch (adl.nav.request) { | |
345 | case 'continue': | |
346 | setTimeout('scorm_get_next();',500); | |
347 | break; | |
348 | case 'previous': | |
349 | setTimeout('scorm_get_prev();',500); | |
350 | break; | |
351 | case 'choice': | |
352 | break; | |
353 | case 'exit': | |
354 | break; | |
355 | case 'exitAll': | |
356 | break; | |
357 | case 'abandon': | |
358 | break; | |
359 | case 'abandonAll': | |
360 | break; | |
361 | } | |
362 | } else { | |
363 | if (<?php echo $scorm->auto ?> == 1) { | |
baf8b9b7 | 364 | setTimeout('scorm_get_next();',500); |
0ec0224b | 365 | } |
dc383b6f | 366 | } |
0ec0224b MS |
367 | // trigger TOC update |
368 | var sURL = "<?php echo $CFG->wwwroot; ?>" + "/mod/scorm/prereqs.php?a=<?php echo $scorm->id ?>&scoid=<?php echo $scoid ?>&attempt=<?php echo $attempt ?>&mode=<?php echo $mode ?>¤torg=<?php echo $currentorg ?>&sesskey=<?php echo sesskey(); ?>"; | |
369 | YAHOO.util.Connect.asyncRequest('GET', sURL, this.connectPrereqCallback, null); | |
dc383b6f | 370 | } else { |
0ec0224b | 371 | diagnostic = "Failure calling the Terminate remote callback: the server replied with HTTP Status " + AJAXResult; |
faa0e875 | 372 | } |
0ec0224b | 373 | return result; |
dc383b6f | 374 | } else { |
375 | if (Terminated) { | |
376 | errorCode = "113"; | |
377 | } else { | |
378 | errorCode = "112"; | |
379 | } | |
380 | } | |
381 | } else { | |
382 | errorCode = "201"; | |
383 | } | |
faa0e875 | 384 | <?php |
1881df27 | 385 | if (scorm_debugging($scorm)) { |
0ec0224b | 386 | echo 'LogAPICall("Terminate", param, "", errorCode);'; |
acba841b | 387 | } |
388 | ?> | |
dc383b6f | 389 | return "false"; |
390 | } | |
faa0e875 | 391 | |
dc383b6f | 392 | function GetValue (element) { |
393 | errorCode = "0"; | |
394 | diagnostic = ""; | |
25fe9d19 | 395 | if ((Initialized) && (!Terminated)) { |
dc383b6f | 396 | if (element !="") { |
d5f9eb42 | 397 | var expression = new RegExp(CMIIndex,'g'); |
d5f3bdc9 | 398 | var elementmodel = String(element).replace(expression,'.n.'); |
dc383b6f | 399 | if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") { |
25fe9d19 | 400 | if (eval('datamodel["'+elementmodel+'"].mod') != 'w') { |
667a2166 | 401 | |
d5f3bdc9 | 402 | element = String(element).replace(/\.(\d+)\./, ".N$1."); |
4c2095de | 403 | element = element.replace(/\.(\d+)\./, ".N$1."); |
469a8d75 | 404 | |
d5f9eb42 | 405 | var elementIndexes = element.split('.'); |
406 | var subelement = element.substr(0,3); | |
407 | var i = 1; | |
dc383b6f | 408 | while ((i < elementIndexes.length) && (typeof eval(subelement) != "undefined")) { |
409 | subelement += '.'+elementIndexes[i++]; | |
410 | } | |
667a2166 | 411 | |
dc383b6f | 412 | if (subelement == element) { |
469a8d75 | 413 | |
89656c61 | 414 | if ((typeof eval(subelement) != "undefined") && (eval(subelement) != null)) { |
415 | errorCode = "0"; | |
faa0e875 | 416 | <?php |
1881df27 | 417 | if (scorm_debugging($scorm)) { |
7bbb7f49 | 418 | echo 'LogAPICall("GetValue", element, eval(element), 0);'; |
89656c61 | 419 | } |
420 | ?> | |
421 | return eval(element); | |
422 | } else { | |
423 | errorCode = "403"; | |
424 | } | |
dc383b6f | 425 | } else { |
acba841b | 426 | errorCode = "301"; |
dc383b6f | 427 | } |
428 | } else { | |
429 | //errorCode = eval('datamodel["'+elementmodel+'"].readerror'); | |
430 | errorCode = "405"; | |
431 | } | |
432 | } else { | |
d5f9eb42 | 433 | var childrenstr = '._children'; |
434 | var countstr = '._count'; | |
435 | var parentmodel = ''; | |
dc383b6f | 436 | if (elementmodel.substr(elementmodel.length-childrenstr.length,elementmodel.length) == childrenstr) { |
437 | parentmodel = elementmodel.substr(0,elementmodel.length-childrenstr.length); | |
438 | if ((typeof eval('datamodel["'+parentmodel+'"]')) != "undefined") { | |
439 | errorCode = "301"; | |
440 | diagnostic = "Data Model Element Does Not Have Children"; | |
441 | } else { | |
442 | errorCode = "401"; | |
443 | } | |
444 | } else if (elementmodel.substr(elementmodel.length-countstr.length,elementmodel.length) == countstr) { | |
445 | parentmodel = elementmodel.substr(0,elementmodel.length-countstr.length); | |
446 | if ((typeof eval('datamodel["'+parentmodel+'"]')) != "undefined") { | |
447 | errorCode = "301"; | |
448 | diagnostic = "Data Model Element Cannot Have Count"; | |
449 | } else { | |
450 | errorCode = "401"; | |
451 | } | |
452 | } else { | |
4c2095de | 453 | parentmodel = 'adl.nav.request_valid.'; |
454 | if (element.substr(0,parentmodel.length) == parentmodel) { | |
455 | if (element.substr(parentmodel.length).match(NAVTarget) == null) { | |
456 | errorCode = "301"; | |
457 | } else { | |
458 | if (adl.nav.request == element.substr(parentmodel.length)) { | |
459 | return "true"; | |
460 | } else if (adl.nav.request == '_none_') { | |
461 | return "unknown"; | |
462 | } else { | |
463 | return "false"; | |
464 | } | |
465 | } | |
466 | } else { | |
467 | errorCode = "401"; | |
468 | } | |
dc383b6f | 469 | } |
470 | } | |
471 | } else { | |
472 | errorCode = "301"; | |
473 | } | |
474 | } else { | |
faa0e875 | 475 | if (Terminated) { |
dc383b6f | 476 | errorCode = "123"; |
477 | } else { | |
478 | errorCode = "122"; | |
479 | } | |
480 | } | |
faa0e875 | 481 | <?php |
1881df27 | 482 | if (scorm_debugging($scorm)) { |
7bbb7f49 | 483 | echo 'LogAPICall("GetValue", element, "", errorCode);'; |
acba841b | 484 | } |
485 | ?> | |
dc383b6f | 486 | return ""; |
487 | } | |
faa0e875 | 488 | |
dc383b6f | 489 | function SetValue (element,value) { |
490 | errorCode = "0"; | |
491 | diagnostic = ""; | |
25fe9d19 | 492 | if ((Initialized) && (!Terminated)) { |
493 | if (element != "") { | |
d5f9eb42 | 494 | var expression = new RegExp(CMIIndex,'g'); |
d5f3bdc9 | 495 | var elementmodel = String(element).replace(expression,'.n.'); |
25fe9d19 | 496 | if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") { |
497 | if (eval('datamodel["'+elementmodel+'"].mod') != 'r') { | |
416050aa | 498 | if (eval('datamodel["'+elementmodel+'"].format') != 'CMIFeedback') { |
27a46315 | 499 | expression = new RegExp(eval('datamodel["'+elementmodel+'"].format')); |
500 | } else { | |
501 | // cmi.interactions.n.type depending format accept everything at this stage | |
502 | expression = new RegExp(CMIFeedback); | |
503 | } | |
dc383b6f | 504 | value = value+''; |
d5f9eb42 | 505 | var matches = value.match(expression); |
d11b69ff | 506 | if ((matches != null) && ((matches.join('').length > 0) || (value.length == 0))) { |
d5f9eb42 | 507 | // Value match dataelement format |
25fe9d19 | 508 | |
dc383b6f | 509 | if (element != elementmodel) { |
d5f9eb42 | 510 | //This is a dynamic datamodel element |
511 | ||
512 | var elementIndexes = element.split('.'); | |
513 | var subelement = 'cmi'; | |
514 | var parentelement = 'cmi'; | |
515 | for (var i=1;(i < elementIndexes.length-1) && (errorCode=="0");i++) { | |
516 | var elementIndex = elementIndexes[i]; | |
25fe9d19 | 517 | if (elementIndexes[i+1].match(/^\d+$/)) { |
518 | if ((parseInt(elementIndexes[i+1]) > 0) && (elementIndexes[i+1].charAt(0) == 0)) { | |
2aaf134c | 519 | // Index has a leading 0 (zero), this is not a number |
520 | errorCode = "351"; | |
521 | } | |
d11b69ff | 522 | parentelement = subelement+'.'+elementIndex; |
91e7b2b1 | 523 | if ((typeof eval(parentelement) == "undefined") || (typeof eval(parentelement+'._count') == "undefined")) { |
524 | errorCode="408"; | |
525 | } else { | |
526 | if (elementIndexes[i+1] > eval(parentelement+'._count')) { | |
91e7b2b1 | 527 | errorCode = "351"; |
528 | diagnostic = "Data Model Element Collection Set Out Of Order"; | |
529 | } | |
530 | subelement = subelement.concat('.'+elementIndex+'.N'+elementIndexes[i+1]); | |
531 | i++; | |
667a2166 | 532 | |
91e7b2b1 | 533 | if (((typeof eval(subelement)) == "undefined") && (i < elementIndexes.length-2)) { |
534 | errorCode="408"; | |
535 | } | |
2aaf134c | 536 | } |
25fe9d19 | 537 | } else { |
2aaf134c | 538 | subelement = subelement.concat('.'+elementIndex); |
539 | } | |
540 | } | |
25fe9d19 | 541 | |
25fe9d19 | 542 | if (errorCode == "0") { |
d5f9eb42 | 543 | // Till now it's a real datamodel element |
667a2166 | 544 | |
2aaf134c | 545 | element = subelement.concat('.'+elementIndexes[elementIndexes.length-1]); |
667a2166 | 546 | |
d5f9eb42 | 547 | if ((typeof eval(subelement)) == "undefined") { |
548 | switch (elementmodel) { | |
faa0e875 | 549 | case 'cmi.objectives.n.id': |
d5f9eb42 | 550 | if (!duplicatedID(element,parentelement,value)) { |
551 | if (elementIndexes[elementIndexes.length-2] == eval(parentelement+'._count')) { | |
552 | eval(parentelement+'._count++;'); | |
4c2095de | 553 | eval(subelement+' = new Object();'); |
d5f9eb42 | 554 | var subobject = eval(subelement); |
4c2095de | 555 | subobject.success_status = datamodel["cmi.objectives.n.success_status"].defaultvalue; |
556 | subobject.completion_status = datamodel["cmi.objectives.n.completion_status"].defaultvalue; | |
557 | subobject.progress_measure = datamodel["cmi.objectives.n.progress_measure"].defaultvalue; | |
558 | subobject.score = new Object(); | |
559 | subobject.score._children = score_children; | |
560 | subobject.score.scaled = datamodel["cmi.objectives.n.score.scaled"].defaultvalue; | |
561 | subobject.score.raw = datamodel["cmi.objectives.n.score.raw"].defaultvalue; | |
562 | subobject.score.min = datamodel["cmi.objectives.n.score.min"].defaultvalue; | |
563 | subobject.score.max = datamodel["cmi.objectives.n.score.max"].defaultvalue; | |
564 | } | |
565 | } else { | |
566 | errorCode="351"; | |
567 | diagnostic = "Data Model Element ID Already Exists"; | |
568 | } | |
d5f9eb42 | 569 | break; |
570 | case 'cmi.interactions.n.id': | |
7e17f5a2 | 571 | if (elementIndexes[elementIndexes.length-2] == eval(parentelement+'._count')) { |
572 | eval(parentelement+'._count++;'); | |
573 | eval(subelement+' = new Object();'); | |
574 | var subobject = eval(subelement); | |
575 | subobject.objectives = new Object(); | |
576 | subobject.objectives._count = 0; | |
faa0e875 | 577 | } |
d5f9eb42 | 578 | break; |
579 | case 'cmi.interactions.n.objectives.n.id': | |
580 | if (typeof eval(parentelement) != "undefined") { | |
581 | if (!duplicatedID(element,parentelement,value)) { | |
582 | if (elementIndexes[elementIndexes.length-2] == eval(parentelement+'._count')) { | |
583 | eval(parentelement+'._count++;'); | |
d11b69ff | 584 | eval(subelement+' = new Object();'); |
d5f9eb42 | 585 | } |
d11b69ff | 586 | } else { |
587 | errorCode="351"; | |
588 | diagnostic = "Data Model Element ID Already Exists"; | |
589 | } | |
590 | } else { | |
d5f9eb42 | 591 | errorCode="408"; |
592 | } | |
593 | break; | |
594 | case 'cmi.interactions.n.correct_responses.n.pattern': | |
595 | if (typeof eval(parentelement) != "undefined") { | |
596 | // Use cmi.interactions.n.type value to check the right dataelement format | |
d5f9eb42 | 597 | if (elementIndexes[elementIndexes.length-2] == eval(parentelement+'._count')) { |
d5f3bdc9 | 598 | var interactiontype = eval(String(parentelement).replace('correct_responses','type')); |
f7c9304b | 599 | var interactioncount = eval(parentelement+'._count'); |
600 | // trap duplicate values, which is not allowed for type choice | |
601 | if (interactiontype == 'choice') { | |
602 | for (var i=0; (i < interactioncount) && (errorCode=="0"); i++) { | |
603 | if (eval(parentelement+'.N'+i+'.pattern') == value) { | |
604 | errorCode = "351"; | |
605 | } | |
606 | } | |
607 | } | |
d5f9eb42 | 608 | if ((typeof correct_responses[interactiontype].limit == 'undefined') || |
609 | (eval(parentelement+'._count') < correct_responses[interactiontype].limit)) { | |
7e17f5a2 | 610 | var nodes = new Array(); |
611 | if (correct_responses[interactiontype].delimiter != '') { | |
612 | nodes = value.split(correct_responses[interactiontype].delimiter); | |
613 | } else { | |
614 | nodes[0] = value; | |
615 | } | |
616 | if ((nodes.length > 0) && (nodes.length <= correct_responses[interactiontype].max)) { | |
f7c9304b | 617 | errorCode = CRcheckValueNodes (element, interactiontype, nodes, value, errorCode); |
7e17f5a2 | 618 | } else if (nodes.length > correct_responses[interactiontype].max) { |
619 | errorCode = "351"; | |
620 | diagnostic = "Data Model Element Pattern Too Long"; | |
621 | } | |
faa0e875 | 622 | if ((errorCode == "0") && ((correct_responses[interactiontype].duplicate == false) || |
f7c9304b | 623 | (!duplicatedPA(element,parentelement,value))) || (errorCode == "0" && value == "")) { |
7e17f5a2 | 624 | eval(parentelement+'._count++;'); |
625 | eval(subelement+' = new Object();'); | |
d5f9eb42 | 626 | } else { |
f7c9304b | 627 | if (errorCode == "0") { |
628 | errorCode="351"; | |
629 | diagnostic = "Data Model Element Pattern Already Exists"; | |
630 | } | |
91e7b2b1 | 631 | } |
92733802 | 632 | } else { |
d5f9eb42 | 633 | errorCode="351"; |
634 | diagnostic = "Data Model Element Collection Limit Reached"; | |
92733802 | 635 | } |
d11b69ff | 636 | } else { |
d5f9eb42 | 637 | errorCode="351"; |
638 | diagnostic = "Data Model Element Collection Set Out Of Order"; | |
d11b69ff | 639 | } |
d5f9eb42 | 640 | } else { |
641 | errorCode="408"; | |
d11b69ff | 642 | } |
d5f9eb42 | 643 | break; |
644 | default: | |
645 | if ((parentelement != 'cmi.objectives') && (parentelement != 'cmi.interactions') && (typeof eval(parentelement) != "undefined")) { | |
4c2095de | 646 | if (elementIndexes[elementIndexes.length-2] == eval(parentelement+'._count')) { |
647 | eval(parentelement+'._count++;'); | |
648 | eval(subelement+' = new Object();'); | |
d5f9eb42 | 649 | } else { |
650 | errorCode="351"; | |
651 | diagnostic = "Data Model Element Collection Set Out Of Order"; | |
faa0e875 | 652 | } |
d5f9eb42 | 653 | } else { |
654 | errorCode="408"; | |
4c2095de | 655 | } |
d5f9eb42 | 656 | break; |
4c2095de | 657 | } |
d5f9eb42 | 658 | } else { |
659 | switch (elementmodel) { | |
660 | case 'cmi.objectives.n.id': | |
661 | if (eval(element) != value) { | |
662 | errorCode = "351"; | |
663 | diagnostic = "Write Once Violation"; | |
664 | } | |
faa0e875 | 665 | break; |
d5f9eb42 | 666 | case 'cmi.interactions.n.objectives.n.id': |
667 | if (duplicatedID(element,parentelement,value)) { | |
668 | errorCode = "351"; | |
669 | diagnostic = "Data Model Element ID Already Exists"; | |
670 | } | |
671 | break; | |
672 | case 'cmi.interactions.n.type': | |
673 | var subobject = eval(subelement); | |
674 | subobject.correct_responses = new Object(); | |
675 | subobject.correct_responses._count = 0; | |
676 | break; | |
677 | case 'cmi.interactions.n.learner_response': | |
678 | if (typeof eval(subelement+'.type') == "undefined") { | |
679 | errorCode="408"; | |
680 | } else { | |
681 | // Use cmi.interactions.n.type value to check the right dataelement format | |
682 | interactiontype = eval(subelement+'.type'); | |
77f62720 | 683 | var nodes = new Array(); |
684 | if (learner_response[interactiontype].delimiter != '') { | |
685 | nodes = value.split(learner_response[interactiontype].delimiter); | |
686 | } else { | |
687 | nodes[0] = value; | |
688 | } | |
689 | if ((nodes.length > 0) && (nodes.length <= learner_response[interactiontype].max)) { | |
690 | expression = new RegExp(learner_response[interactiontype].format); | |
2f60a9cb | 691 | for (var i=0; (i < nodes.length) && (errorCode=="0"); i++) { |
f8c950b3 | 692 | if (typeof learner_response[interactiontype].delimiter2 != 'undefined') { |
693 | values = nodes[i].split(learner_response[interactiontype].delimiter2); | |
694 | if (values.length == 2) { | |
695 | matches = values[0].match(expression); | |
696 | if (matches == null) { | |
697 | errorCode = "406"; | |
698 | } else { | |
699 | var expression2 = new RegExp(learner_response[interactiontype].format2); | |
700 | matches = values[1].match(expression2); | |
701 | if (matches == null) { | |
55175138 | 702 | errorCode = "406"; |
703 | } | |
77f62720 | 704 | } |
f8c950b3 | 705 | } else { |
706 | errorCode = "406"; | |
707 | } | |
708 | } else { | |
709 | matches = nodes[i].match(expression); | |
f8c950b3 | 710 | if (matches == null) { |
711 | errorCode = "406"; | |
712 | } else { | |
713 | if ((nodes[i] != '') && (learner_response[interactiontype].unique)) { | |
714 | for (var j=0; (j<i) && (errorCode=="0"); j++) { | |
715 | if (nodes[i] == nodes[j]) { | |
716 | errorCode = "406"; | |
717 | } | |
718 | } | |
719 | } | |
77f62720 | 720 | } |
721 | } | |
722 | } | |
723 | } else if (nodes.length > learner_response[interactiontype].max) { | |
724 | errorCode = "351"; | |
725 | diagnostic = "Data Model Element Pattern Too Long"; | |
726 | } | |
8e4838ff | 727 | } |
d5f9eb42 | 728 | break; |
f7c9304b | 729 | case 'cmi.interactions.n.correct_responses.n.pattern': |
4454447d PS |
730 | subel= subelement.split('.'); |
731 | subel1= 'cmi.interactions.'+subel[2]; | |
50ccd872 | 732 | |
f7c9304b | 733 | if (typeof eval(subel1+'.type') == "undefined") { |
50ccd872 | 734 | errorCode="408"; |
735 | } else { | |
50ccd872 | 736 | // Use cmi.interactions.n.type value to check the right //dataelement format |
f7c9304b | 737 | var interactiontype = eval(subel1+'.type'); |
738 | var interactioncount = eval(parentelement+'._count'); | |
739 | // trap duplicate values, which is not allowed for type choice | |
740 | if (interactiontype == 'choice') { | |
741 | for (var i=0; (i < interactioncount) && (errorCode=="0"); i++) { | |
742 | if (eval(parentelement+'.N'+i+'.pattern') == value) { | |
743 | errorCode = "351"; | |
744 | } | |
745 | } | |
746 | } | |
50ccd872 | 747 | var nodes = new Array(); |
748 | if (correct_responses[interactiontype].delimiter != '') { | |
749 | nodes = value.split(correct_responses[interactiontype].delimiter); | |
750 | } else { | |
751 | nodes[0] = value; | |
752 | } | |
faa0e875 | 753 | |
50ccd872 | 754 | if ((nodes.length > 0) && (nodes.length <= correct_responses[interactiontype].max)) { |
f7c9304b | 755 | errorCode = CRcheckValueNodes (element, interactiontype, nodes, value, errorCode); |
50ccd872 | 756 | } else if (nodes.length > correct_responses[interactiontype].max) { |
50ccd872 | 757 | errorCode = "351"; |
758 | diagnostic = "Data Model Element Pattern Too Long"; | |
759 | } | |
50ccd872 | 760 | } |
d5f9eb42 | 761 | break; |
faa0e875 | 762 | } |
d5f9eb42 | 763 | } |
89656c61 | 764 | } |
dc383b6f | 765 | } |
766 | //Store data | |
767 | if (errorCode == "0") { | |
667a2166 | 768 | |
dc383b6f | 769 | if ((typeof eval('datamodel["'+elementmodel+'"].range')) != "undefined") { |
770 | range = eval('datamodel["'+elementmodel+'"].range'); | |
771 | ranges = range.split('#'); | |
772 | value = value*1.0; | |
773 | if (value >= ranges[0]) { | |
774 | if ((ranges[1] == '*') || (value <= ranges[1])) { | |
021d903e | 775 | eval(element+'=value;'); |
dc383b6f | 776 | errorCode = "0"; |
faa0e875 | 777 | <?php |
1881df27 | 778 | if (scorm_debugging($scorm)) { |
7bbb7f49 | 779 | echo 'LogAPICall("SetValue", element, value, errorCode);'; |
dc383b6f | 780 | } |
781 | ?> | |
782 | return "true"; | |
783 | } else { | |
784 | errorCode = '407'; | |
785 | } | |
786 | } else { | |
787 | errorCode = '407'; | |
788 | } | |
789 | } else { | |
021d903e | 790 | eval(element+'=value;'); |
faa0e875 | 791 | errorCode = "0"; |
792 | <?php | |
1881df27 | 793 | if (scorm_debugging($scorm)) { |
7bbb7f49 | 794 | echo 'LogAPICall("SetValue", element, value, errorCode);'; |
dc383b6f | 795 | } |
796 | ?> | |
797 | return "true"; | |
798 | } | |
799 | } | |
800 | } else { | |
dc383b6f | 801 | errorCode = "406"; |
802 | } | |
803 | } else { | |
dc383b6f | 804 | errorCode = "404"; |
805 | } | |
806 | } else { | |
807 | errorCode = "401" | |
808 | } | |
809 | } else { | |
810 | errorCode = "351"; | |
811 | } | |
667a2166 | 812 | } else { |
dc383b6f | 813 | if (Terminated) { |
814 | errorCode = "133"; | |
815 | } else { | |
816 | errorCode = "132"; | |
817 | } | |
818 | } | |
faa0e875 | 819 | <?php |
1881df27 | 820 | if (scorm_debugging($scorm)) { |
7bbb7f49 | 821 | echo 'LogAPICall("SetValue", element, value, errorCode);'; |
acba841b | 822 | } |
823 | ?> | |
dc383b6f | 824 | return "false"; |
825 | } | |
f7c9304b | 826 | |
827 | ||
828 | function CRremovePrefixes (node) { | |
829 | // check for prefixes lang, case, order | |
faa0e875 | 830 | // case and then order |
f7c9304b | 831 | var seenOrder = false; |
832 | var seenCase = false; | |
833 | var seenLang = false; | |
834 | var errorCode = "0"; | |
835 | while (matches = node.match('^(\{(lang|case_matters|order_matters)=([^\}]+)\})')) { | |
836 | switch (matches[2]) { | |
837 | case 'lang': | |
838 | // check for language prefix on each node | |
839 | langmatches = node.match(CMILangcr); | |
840 | if (langmatches != null) { | |
841 | lang = langmatches[3]; | |
842 | // check that language string definition is valid | |
843 | if (lang.length > 0 && lang != undefined) { | |
844 | if (validLanguages[lang.toLowerCase()] == undefined) { | |
845 | errorCode = "406"; | |
846 | } | |
847 | } | |
848 | } | |
849 | seenLang = true; | |
850 | break; | |
faa0e875 | 851 | |
f7c9304b | 852 | case 'case_matters': |
853 | // check for correct case answer | |
854 | if (! seenLang && ! seenOrder && ! seenCase) { | |
855 | if (matches[3] != 'true' && matches[3] != 'false') { | |
856 | errorCode = "406"; | |
857 | } | |
858 | } | |
859 | seenCase = true; | |
860 | break; | |
faa0e875 | 861 | |
f7c9304b | 862 | case 'order_matters': |
863 | // check for correct case answer | |
864 | if (! seenCase && ! seenLang && ! seenOrder) { | |
865 | if (matches[3] != 'true' && matches[3] != 'false') { | |
866 | errorCode = "406"; | |
867 | } | |
868 | } | |
869 | seenOrder = true; | |
870 | break; | |
faa0e875 | 871 | |
f7c9304b | 872 | default: |
873 | break; | |
874 | } | |
875 | node = node.substr(matches[1].length); | |
876 | } | |
877 | return {'errorCode': errorCode, 'node': node}; | |
878 | } | |
879 | ||
880 | ||
881 | function CRcheckValueNodes(element, interactiontype, nodes, value, errorCode) { | |
882 | expression = new RegExp(correct_responses[interactiontype].format); | |
883 | for (var i=0; (i < nodes.length) && (errorCode=="0"); i++) { | |
884 | if (interactiontype.match('^(fill-in|long-fill-in|matching|performance|sequencing)$')) { | |
885 | result = CRremovePrefixes(nodes[i]); | |
886 | errorCode = result.errorCode; | |
887 | nodes[i] = result.node; | |
888 | } | |
faa0e875 | 889 | |
f7c9304b | 890 | // check for prefix on each node |
891 | if (correct_responses[interactiontype].pre != '') { | |
892 | matches = nodes[i].match(correct_responses[interactiontype].pre); | |
893 | if (matches != null) { | |
894 | nodes[i] = nodes[i].substr(matches[1].length); | |
895 | } | |
896 | } | |
faa0e875 | 897 | |
f7c9304b | 898 | if (correct_responses[interactiontype].delimiter2 != undefined) { |
899 | values = nodes[i].split(correct_responses[interactiontype].delimiter2); | |
900 | if (values.length == 2) { | |
901 | matches = values[0].match(expression); | |
902 | if (matches == null) { | |
903 | errorCode = "406"; | |
904 | } else { | |
905 | var expression2 = new RegExp(correct_responses[interactiontype].format2); | |
906 | matches = values[1].match(expression2); | |
907 | if (matches == null) { | |
908 | errorCode = "406"; | |
909 | } | |
910 | } | |
911 | } else { | |
912 | errorCode = "406"; | |
913 | } | |
914 | } else { | |
915 | matches = nodes[i].match(expression); | |
916 | //if ((matches == null) || (matches.join('').length == 0)) { | |
917 | if ((matches == null && value != "")||(matches == null && interactiontype=="true-false")){ | |
918 | errorCode = "406"; | |
919 | } else { | |
920 | // numeric range - left must be <= right | |
921 | if (interactiontype == 'numeric' && nodes.length > 1) { | |
922 | if (parseFloat(nodes[0]) > parseFloat(nodes[1])) { | |
923 | errorCode = "406"; | |
924 | } | |
925 | } else { | |
926 | if ((nodes[i] != '') && (correct_responses[interactiontype].unique)) { | |
927 | for (var j=0; (j < i) && (errorCode=="0"); j++) { | |
928 | if (nodes[i] == nodes[j]) { | |
929 | errorCode = "406"; | |
930 | } | |
931 | } | |
932 | } | |
933 | } | |
934 | } | |
935 | } | |
936 | } // end of for each nodes | |
937 | return errorCode; | |
938 | } | |
939 | ||
faa0e875 | 940 | |
dc383b6f | 941 | function Commit (param) { |
942 | errorCode = "0"; | |
943 | if (param == "") { | |
944 | if ((Initialized) && (!Terminated)) { | |
0ec0224b | 945 | var AJAXResult = StoreData(cmi,false); |
faa0e875 | 946 | <?php |
1881df27 | 947 | if (scorm_debugging($scorm)) { |
0ec0224b | 948 | echo 'LogAPICall("Commit", "AJAXResult", AJAXResult, 0);'; |
dc383b6f | 949 | } |
950 | ?> | |
0ec0224b MS |
951 | var result = ('true' == AJAXResult) ? 'true' : 'false'; |
952 | errorCode = ('true' == result)? '0' : '101'; // General exception for any AJAX fault | |
953 | <?php | |
954 | if (scorm_debugging($scorm)) { | |
955 | echo 'LogAPICall("Commit", "result", result, errorCode);'; | |
956 | } | |
957 | ?> | |
958 | if ('false' == result) { | |
959 | diagnostic = "Failure calling the Commit remote callback: the server replied with HTTP Status " + AJAXResult; | |
960 | } | |
961 | return result; | |
dc383b6f | 962 | } else { |
963 | if (Terminated) { | |
964 | errorCode = "143"; | |
965 | } else { | |
966 | errorCode = "142"; | |
967 | } | |
968 | } | |
969 | } else { | |
970 | errorCode = "201"; | |
971 | } | |
faa0e875 | 972 | <?php |
1881df27 | 973 | if (scorm_debugging($scorm)) { |
0ec0224b | 974 | echo 'LogAPICall("Commit", param, "", errorCode);'; |
acba841b | 975 | } |
976 | ?> | |
dc383b6f | 977 | return "false"; |
978 | } | |
faa0e875 | 979 | |
dc383b6f | 980 | function GetLastError () { |
0ec0224b | 981 | <?php |
1881df27 | 982 | if (scorm_debugging($scorm)) { |
7bbb7f49 | 983 | echo 'LogAPICall("GetLastError", "", "", errorCode);'; |
984 | } | |
985 | ?> | |
dc383b6f | 986 | return errorCode; |
987 | } | |
faa0e875 | 988 | |
dc383b6f | 989 | function GetErrorString (param) { |
990 | if (param != "") { | |
acba841b | 991 | var errorString = ""; |
992 | switch(param) { | |
993 | case "0": | |
994 | errorString = "No error"; | |
995 | break; | |
996 | case "101": | |
997 | errorString = "General exception"; | |
998 | break; | |
999 | case "102": | |
1000 | errorString = "General Inizialization Failure"; | |
1001 | break; | |
1002 | case "103": | |
1003 | errorString = "Already Initialized"; | |
1004 | break; | |
1005 | case "104": | |
1006 | errorString = "Content Instance Terminated"; | |
1007 | break; | |
1008 | case "111": | |
1009 | errorString = "General Termination Failure"; | |
1010 | break; | |
1011 | case "112": | |
1012 | errorString = "Termination Before Inizialization"; | |
1013 | break; | |
1014 | case "113": | |
1015 | errorString = "Termination After Termination"; | |
1016 | break; | |
1017 | case "122": | |
1018 | errorString = "Retrieve Data Before Initialization"; | |
1019 | break; | |
1020 | case "123": | |
1021 | errorString = "Retrieve Data After Termination"; | |
1022 | break; | |
1023 | case "132": | |
1024 | errorString = "Store Data Before Inizialization"; | |
1025 | break; | |
1026 | case "133": | |
1027 | errorString = "Store Data After Termination"; | |
1028 | break; | |
1029 | case "142": | |
1030 | errorString = "Commit Before Inizialization"; | |
1031 | break; | |
1032 | case "143": | |
1033 | errorString = "Commit After Termination"; | |
1034 | break; | |
1035 | case "201": | |
1036 | errorString = "General Argument Error"; | |
1037 | break; | |
1038 | case "301": | |
1039 | errorString = "General Get Failure"; | |
1040 | break; | |
1041 | case "351": | |
1042 | errorString = "General Set Failure"; | |
1043 | break; | |
1044 | case "391": | |
1045 | errorString = "General Commit Failure"; | |
1046 | break; | |
1047 | case "401": | |
1048 | errorString = "Undefinited Data Model"; | |
1049 | break; | |
1050 | case "402": | |
1051 | errorString = "Unimplemented Data Model Element"; | |
1052 | break; | |
1053 | case "403": | |
1054 | errorString = "Data Model Element Value Not Initialized"; | |
1055 | break; | |
1056 | case "404": | |
1057 | errorString = "Data Model Element Is Read Only"; | |
1058 | break; | |
1059 | case "405": | |
1060 | errorString = "Data Model Element Is Write Only"; | |
1061 | break; | |
1062 | case "406": | |
1063 | errorString = "Data Model Element Type Mismatch"; | |
1064 | break; | |
1065 | case "407": | |
1066 | errorString = "Data Model Element Value Out Of Range"; | |
1067 | break; | |
1068 | case "408": | |
1069 | errorString = "Data Model Dependency Not Established"; | |
1070 | break; | |
1071 | } | |
faa0e875 | 1072 | <?php |
1881df27 | 1073 | if (scorm_debugging($scorm)) { |
7bbb7f49 | 1074 | echo 'LogAPICall("GetErrorString", param, errorString, 0);'; |
1075 | } | |
1076 | ?> | |
acba841b | 1077 | return errorString; |
dc383b6f | 1078 | } else { |
faa0e875 | 1079 | <?php |
1881df27 | 1080 | if (scorm_debugging($scorm)) { |
7bbb7f49 | 1081 | echo 'LogAPICall("GetErrorString", param, "No error string found!", 0);'; |
1082 | } | |
1083 | ?> | |
1084 | return ""; | |
dc383b6f | 1085 | } |
1086 | } | |
faa0e875 | 1087 | |
dc383b6f | 1088 | function GetDiagnostic (param) { |
d11b69ff | 1089 | if (diagnostic != "") { |
faa0e875 | 1090 | <?php |
1881df27 | 1091 | if (scorm_debugging($scorm)) { |
7bbb7f49 | 1092 | echo 'LogAPICall("GetDiagnostic", param, diagnostic, 0);'; |
1093 | } | |
1094 | ?> | |
dc383b6f | 1095 | return diagnostic; |
1096 | } | |
faa0e875 | 1097 | <?php |
1881df27 | 1098 | if (scorm_debugging($scorm)) { |
7bbb7f49 | 1099 | echo 'LogAPICall("GetDiagnostic", param, param, 0);'; |
1100 | } | |
1101 | ?> | |
dc383b6f | 1102 | return param; |
1103 | } | |
1104 | ||
d5f9eb42 | 1105 | function duplicatedID (element, parent, value) { |
d11b69ff | 1106 | var found = false; |
d5f9eb42 | 1107 | var elements = eval(parent+'._count'); |
2f60a9cb | 1108 | for (var n=0;(n < elements) && (!found);n++) { |
d5f9eb42 | 1109 | if ((parent+'.N'+n+'.id' != element) && (eval(parent+'.N'+n+'.id') == value)) { |
1110 | found = true; | |
1111 | } | |
faa0e875 | 1112 | } |
d5f9eb42 | 1113 | return found; |
1114 | } | |
1115 | ||
1116 | function duplicatedPA (element, parent, value) { | |
1117 | var found = false; | |
1118 | var elements = eval(parent+'._count'); | |
2f60a9cb | 1119 | for (var n=0;(n < elements) && (!found);n++) { |
d5f9eb42 | 1120 | if ((parent+'.N'+n+'.pattern' != element) && (eval(parent+'.N'+n+'.pattern') == value)) { |
d11b69ff | 1121 | found = true; |
1122 | } | |
faa0e875 | 1123 | } |
d11b69ff | 1124 | return found; |
1125 | } | |
1126 | ||
4c2095de | 1127 | function getElementModel(element) { |
1128 | if (typeof datamodel[element] != "undefined") { | |
1129 | return element; | |
1130 | } else { | |
d5f9eb42 | 1131 | var expression = new RegExp(CMIIndex,'g'); |
d5f3bdc9 | 1132 | var elementmodel = String(element).replace(expression,'.n.'); |
4c2095de | 1133 | if (typeof datamodel[elementmodel] != "undefined") { |
1134 | return elementmodel; | |
1135 | } | |
1136 | } | |
d5f9eb42 | 1137 | return false; |
4c2095de | 1138 | } |
1139 | ||
dc383b6f | 1140 | function AddTime (first, second) { |
faa0e875 | 1141 | <?php |
1881df27 | 1142 | // if (scorm_debugging($scorm)) { |
7bbb7f49 | 1143 | // echo 'alert("AddTime: "+first+" + "+second);'; |
1144 | // } | |
acba841b | 1145 | ?> |
dc383b6f | 1146 | var timestring = 'P'; |
1147 | var matchexpr = /^P((\d+)Y)?((\d+)M)?((\d+)D)?(T((\d+)H)?((\d+)M)?((\d+(\.\d{1,2})?)S)?)?$/; | |
1148 | var firstarray = first.match(matchexpr); | |
1149 | var secondarray = second.match(matchexpr); | |
1150 | if ((firstarray != null) && (secondarray != null)) { | |
d6d1f9b3 | 1151 | var firstsecs=0; |
1152 | if(parseFloat(firstarray[13],10)>0){ firstsecs=parseFloat(firstarray[13],10); } | |
1153 | var secondsecs=0; | |
1154 | if(parseFloat(secondarray[13],10)>0){ secondsecs=parseFloat(secondarray[13],10); } | |
1155 | var secs = firstsecs+secondsecs; //Seconds | |
1156 | var change = Math.floor(secs/60); | |
1157 | secs = Math.round((secs-(change*60))*100)/100; | |
1158 | var firstmins=0; | |
1159 | if(parseInt(firstarray[11],10)>0){ firstmins=parseInt(firstarray[11],10); } | |
1160 | var secondmins=0; | |
1161 | if(parseInt(secondarray[11],10)>0){ secondmins=parseInt(secondarray[11],10); } | |
1162 | var mins = firstmins+secondmins+change; //Minutes | |
dc383b6f | 1163 | change = Math.floor(mins / 60); |
d6d1f9b3 | 1164 | mins = Math.round(mins-(change*60)); |
1165 | var firsthours=0; | |
1166 | if(parseInt(firstarray[9],10)>0){ firsthours=parseInt(firstarray[9],10); } | |
1167 | var secondhours=0; | |
1168 | if(parseInt(secondarray[9],10)>0){ secondhours=parseInt(secondarray[9],10); } | |
faa0e875 | 1169 | var hours = firsthours+secondhours+change; //Hours |
d6d1f9b3 | 1170 | change = Math.floor(hours/24); |
1171 | hours = Math.round(hours-(change*24)); | |
1172 | var firstdays=0; | |
1173 | if(parseInt(firstarray[6],10)>0){ firstdays=parseInt(firstarray[6],10); } | |
1174 | var seconddays=0; | |
1175 | if(parseInt(secondarray[6],10)>0){ firstdays=parseInt(secondarray[6],10); } | |
1176 | var days = Math.round(firstdays+seconddays+change); // Days | |
1177 | var firstmonths=0; | |
1178 | if(parseInt(firstarray[4],10)>0){ firstmonths=parseInt(firstarray[4],10); } | |
1179 | var secondmonths=0; | |
1180 | if(parseInt(secondarray[4],10)>0){ secondmonths=parseInt(secondarray[4],10); } | |
1181 | var months = Math.round(firstmonths+secondmonths); | |
1182 | var firstyears=0; | |
1183 | if(parseInt(firstarray[2],10)>0){ firstyears=parseInt(firstarray[2],10); } | |
1184 | var secondyears=0; | |
1185 | if(parseInt(secondarray[2],10)>0){ secondyears=parseInt(secondarray[2],10); } | |
1186 | var years = Math.round(firstyears+secondyears); | |
dc383b6f | 1187 | } |
1188 | if (years > 0) { | |
1189 | timestring += years + 'Y'; | |
1190 | } | |
1191 | if (months > 0) { | |
1192 | timestring += months + 'M'; | |
1193 | } | |
1194 | if (days > 0) { | |
1195 | timestring += days + 'D'; | |
1196 | } | |
1197 | if ((hours > 0) || (mins > 0) || (secs > 0)) { | |
1198 | timestring += 'T'; | |
1199 | if (hours > 0) { | |
1200 | timestring += hours + 'H'; | |
1201 | } | |
1202 | if (mins > 0) { | |
1203 | timestring += mins + 'M'; | |
1204 | } | |
1205 | if (secs > 0) { | |
1206 | timestring += secs + 'S'; | |
1207 | } | |
1208 | } | |
1209 | return timestring; | |
1210 | } | |
1211 | ||
1212 | function TotalTime() { | |
d5f9eb42 | 1213 | var total_time = AddTime(cmi.total_time, cmi.session_time); |
021d903e | 1214 | return '&'+underscore('cmi.total_time')+'='+encodeURIComponent(total_time); |
dc383b6f | 1215 | } |
1216 | ||
1217 | function CollectData(data,parent) { | |
1218 | var datastring = ''; | |
1219 | for (property in data) { | |
1220 | if (typeof data[property] == 'object') { | |
1221 | datastring += CollectData(data[property],parent+'.'+property); | |
1222 | } else { | |
d5f9eb42 | 1223 | var element = parent+'.'+property; |
1224 | var expression = new RegExp(CMIIndexStore,'g'); | |
d5f3bdc9 | 1225 | var elementmodel = String(element).replace(expression,'.n.'); |
dc383b6f | 1226 | if ((typeof eval('datamodel["'+elementmodel+'"]')) != "undefined") { |
1227 | if (eval('datamodel["'+elementmodel+'"].mod') != 'r') { | |
d5f9eb42 | 1228 | var elementstring = '&'+underscore(element)+'='+encodeURIComponent(data[property]); |
dc383b6f | 1229 | if ((typeof eval('datamodel["'+elementmodel+'"].defaultvalue')) != "undefined") { |
67859ce6 | 1230 | if (eval('datamodel["'+elementmodel+'"].defaultvalue') != data[property] || eval('typeof(datamodel["'+elementmodel+'"].defaultvalue)') != typeof(data[property])) { |
dc383b6f | 1231 | datastring += elementstring; |
1232 | } | |
1233 | } else { | |
1234 | datastring += elementstring; | |
1235 | } | |
1236 | } | |
1237 | } | |
1238 | } | |
1239 | } | |
1240 | return datastring; | |
1241 | } | |
1242 | ||
1243 | function StoreData(data,storetotaltime) { | |
d5f9eb42 | 1244 | var datastring = ''; |
dc383b6f | 1245 | if (storetotaltime) { |
1246 | if (cmi.mode == 'normal') { | |
1247 | if (cmi.credit == 'credit') { | |
4c2095de | 1248 | if ((cmi.completion_threshold != null) && (cmi.progress_measure != null)) { |
dc383b6f | 1249 | if (cmi.progress_measure >= cmi.completion_threshold) { |
1250 | cmi.completion_status = 'completed'; | |
1251 | } else { | |
1252 | cmi.completion_status = 'incomplete'; | |
1253 | } | |
1254 | } | |
1255 | if ((cmi.scaled_passed_score != null) && (cmi.score.scaled != '')) { | |
1256 | if (cmi.score.scaled >= cmi.scaled_passed_score) { | |
1257 | cmi.success_status = 'passed'; | |
1258 | } else { | |
1259 | cmi.success_status = 'failed'; | |
1260 | } | |
1261 | } | |
1262 | } | |
1263 | } | |
dc383b6f | 1264 | datastring += TotalTime(); |
dc383b6f | 1265 | } |
667a2166 | 1266 | datastring += CollectData(data,'cmi'); |
d5f9eb42 | 1267 | var element = 'adl.nav.request'; |
1268 | var navrequest = eval(element) != datamodel[element].defaultvalue ? '&'+underscore(element)+'='+encodeURIComponent(eval(element)) : ''; | |
667a2166 | 1269 | datastring += navrequest; |
dc383b6f | 1270 | datastring += '&attempt=<?php echo $attempt ?>'; |
667a2166 | 1271 | datastring += '&scoid=<?php echo $scoid ?>'; |
dc383b6f | 1272 | var myRequest = NewHttpReq(); |
0ec0224b | 1273 | var result = DoRequest(myRequest,"<?php p($CFG->wwwroot) ?>/mod/scorm/datamodel.php","id=<?php p($id) ?>&a=<?php p($a) ?>&sesskey=<?php echo sesskey() ?>"+datastring); |
45e94d82 | 1274 | var results = String(result).split('\n'); |
667a2166 | 1275 | if ((results.length > 2) && (navrequest != '')) { |
1276 | eval(results[2]); | |
1277 | } | |
dc383b6f | 1278 | errorCode = results[1]; |
1279 | return results[0]; | |
1280 | } | |
faa0e875 | 1281 | |
dc383b6f | 1282 | this.Initialize = Initialize; |
1283 | this.Terminate = Terminate; | |
1284 | this.GetValue = GetValue; | |
1285 | this.SetValue = SetValue; | |
1286 | this.Commit = Commit; | |
1287 | this.GetLastError = GetLastError; | |
1288 | this.GetErrorString = GetErrorString; | |
1289 | this.GetDiagnostic = GetDiagnostic; | |
acba841b | 1290 | this.version = '1.0'; |
dc383b6f | 1291 | } |
1292 | ||
1293 | var API_1484_11 = new SCORMapi1_3(); | |
7bbb7f49 | 1294 | |
1295 | <?php | |
1296 | // pull in the debugging utilities | |
1881df27 | 1297 | if (scorm_debugging($scorm)) { |
7bbb7f49 | 1298 | include_once($CFG->dirroot.'/mod/scorm/datamodels/debug.js.php'); |
77e889a0 | 1299 | echo 'AppendToLog("Moodle SCORM 1.3 API Loaded, Activity: '.$scorm->name.', SCO: '.$sco->identifier.'", 0);'; |
7bbb7f49 | 1300 | } |