scorm_api.php 75 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875
  1. <?php
  2. /* For licensing terms, see /license.txt */
  3. /**
  4. * API event handler functions for Scorm 1.1 and 1.2 and 1.3
  5. *
  6. * @author Denes Nagy <darkden@freemail.hu>
  7. * @author Yannick Warnier <ywarnier@beeznest.org>
  8. * @version v 1.0
  9. * @access public
  10. * @package chamilo.learnpath.scorm
  11. */
  12. /**
  13. * This script is divided into three sections.
  14. * The first section (below) is the initialisation part.
  15. * The second section is the SCORM object part
  16. * The third section defines the event handlers for Chamilo's internal messaging
  17. * and frames refresh
  18. */
  19. /* INIT SECTION */
  20. // If you open the imsmanifest.xml via local machine (f.ex.: file://c:/...), then the Apiwrapper.js
  21. // of Maritime Navigation when trying to execute this row
  22. // var result = api.LMSInitialize("");
  23. // get the error response : you are not authorized to call this function
  24. // Flag to allow for anonymous user - needs to be set before global.inc.php.
  25. $use_anonymous = true;
  26. require_once 'back_compat.inc.php';
  27. require_once 'learnpath.class.php';
  28. require_once 'learnpathItem.class.php';
  29. require_once 'scorm.class.php';
  30. // Is this needed? This is probabaly done in the header file
  31. //$_user = $_SESSION['_user'];
  32. $file = (empty($_SESSION['file'])?'':$_SESSION['file']);
  33. $oLP = unserialize($_SESSION['lpobject']);
  34. $oItem = $oLP->items[$oLP->current];
  35. if (!is_object($oItem)) {
  36. error_log('New LP - scorm_api - Could not load oItem item',0);
  37. exit;
  38. }
  39. $autocomplete_when_80pct = 0;
  40. $user = api_get_user_info();
  41. header('Content-type: text/javascript');
  42. /*
  43. * JavaScript Functions
  44. */
  45. ?>var scorm_logs=<?php echo ((empty($oLP->scorm_debug) or !api_is_course_admin())?'0':'3');?>; //debug log level for SCORM. 0 = none, 1=light, 2=a lot, 3=all - displays logs in log frame
  46. var lms_logs=0; //debug log level for LMS actions. 0=none, 1=light, 2=a lot, 3=all
  47. //logit_lms('scormfunctions.php included',0);
  48. // API Object initialization (eases access later on)
  49. function APIobject() {
  50. this.LMSInitialize=LMSInitialize; //for Scorm 1.2
  51. this.Initialize=LMSInitialize; //for Scorm 1.3
  52. this.LMSGetValue=LMSGetValue;
  53. this.GetValue=LMSGetValue;
  54. this.LMSSetValue=LMSSetValue;
  55. this.SetValue=LMSSetValue;
  56. this.LMSCommit=LMSCommit;
  57. this.Commit=LMSCommit;
  58. this.LMSFinish=LMSFinish;
  59. this.Finish=LMSFinish;
  60. this.LMSGetLastError=LMSGetLastError;
  61. this.GetLastError=LMSGetLastError;
  62. this.LMSGetErrorString=LMSGetErrorString;
  63. this.GetErrorString=LMSGetErrorString;
  64. this.LMSGetDiagnostic=LMSGetDiagnostic;
  65. this.GetDiagnostic=LMSGetDiagnostic;
  66. this.Terminate=Terminate; //only in Scorm 1.3
  67. this.save_asset = lms_save_asset;
  68. this.void_save_asset = chamilo_void_save_asset;
  69. }
  70. // it is not sure that the scos use the above declarations. The following
  71. // multiple declarations are to make sure we have an API object for each type of
  72. // SCORM
  73. var API = new APIobject(); //for scorm 1.2
  74. var api = API;
  75. var API_1484_11 = new APIobject(); //for scorm 1.3
  76. var api_1484_11 = API_1484_11;
  77. // SCORM-specific Error codes
  78. var G_NoError = 0;
  79. var G_GeneralException = 101;
  80. var G_ServerBusy = 102; // this is not in the Scorm1.2_Runtime document
  81. var G_InvalidArgumentError = 201;
  82. var G_ElementCannotHaveChildren = 202;
  83. var G_ElementIsNotAnArray = 203;
  84. var G_NotInitialized = 301;
  85. var G_NotImplementedError = 401;
  86. var G_InvalidSetValue = 402;
  87. var G_ElementIsReadOnly = 403;
  88. var G_ElementIsWriteOnly = 404;
  89. var G_IncorrectDataType = 405;
  90. // SCORM-specific Error messages
  91. var G_NoErrorMessage = '';
  92. var G_GeneralExceptionMessage = 'General Exception';
  93. var G_ServerBusyMessage = 'Server busy'; // this is not in the Scorm1.2_Runtime document
  94. var G_InvalidArgumentErrorMessage = 'Invalid argument error';
  95. var G_ElementCannotHaveChildrenMessage = 'Element cannot have children';
  96. var G_ElementIsNotAnArrayMessage = 'Element not an array. Cannot have count';
  97. var G_NotInitializedMessage = 'Not initialized';
  98. var G_NotImplementedErrorMessage = 'Not implemented error';
  99. var G_InvalidSetValueMessage = 'Invalid set value, element is a keyword';
  100. var G_ElementIsReadOnlyMessage = 'Element is read only';
  101. var G_ElementIsWriteOnlyMessage = 'Element is write only';
  102. var G_IncorrectDataTypeMessage = 'Incorrect Data Type';
  103. var olms = new Object();
  104. //the last recorded error message was:
  105. olms.G_LastError = G_NoError ;
  106. olms.G_LastErrorMessage = 'No error';
  107. //this is not necessary and is only provided to make bad Articulate contents shut up (and not trigger useless JS messages)
  108. olms.G_LastErrorString = 'No error';
  109. //these variables are provided for better control of the current status in the
  110. // SCORM exchange
  111. olms.commit = false;
  112. // informative array helping to select variables to save, later on
  113. olms.scorm_variables = new Array(
  114. 'cmi.core.score.raw',
  115. 'cmi.core.score.max',
  116. 'cmi.core.score.min',
  117. 'cmi.core.lesson_location',
  118. 'cmi.core.lesson_status',
  119. 'cmi.completion_status',
  120. 'cmi.core.session_time',
  121. 'cmi.score.scaled',
  122. 'cmi.success_status',
  123. 'cmi.suspend_data',
  124. 'cmi.core.exit',
  125. 'interactions'
  126. );
  127. // manage variables to save or not
  128. olms.variable_to_send=new Array();
  129. // temporary list of variables (gets set to true when set through LMSSetValue)
  130. olms.updatable_vars_list=new Array();
  131. // Strictly scorm variables
  132. olms.score=<?php echo $oItem->get_score();?>;
  133. olms.max='<?php echo $oItem->get_max();?>';
  134. olms.min='<?php echo $oItem->get_min();?>';
  135. olms.lesson_status='<?php echo $oItem->get_status();?>';
  136. olms.session_time='<?php echo $oItem->get_scorm_time('js');?>';
  137. olms.suspend_data = '<?php echo $oItem->get_suspend_data();?>';
  138. olms.lesson_location = '<?php echo $oItem->get_lesson_location();?>';
  139. olms.total_time = '<?php echo $oItem->get_scorm_time('js');?>';
  140. olms.mastery_score = '<?php echo $oItem->get_mastery_score();?>';
  141. olms.launch_data = '<?php echo $oItem->get_launch_data();?>';
  142. olms.max_time_allowed = '<?php echo $oItem->get_max_time_allowed();?>';
  143. olms.interactions = new Array(<?php echo $oItem->get_interactions_js_array();?>);
  144. olms.item_objectives = new Array();
  145. olms.info_lms_item=new Array();
  146. // Chamilo internal variables (not SCORM)
  147. // olms.saved_lesson_status = 'not attempted';
  148. olms.lms_lp_id = <?php echo $oLP->get_id();?>;
  149. olms.lms_item_id = <?php echo $oItem->get_id();?>;
  150. olms.lms_initialized = 0;
  151. //olms.lms_total_lessons = <?php echo $oLP->get_total_items_count(); ?>;
  152. //olms.lms_complete_lessons = <?php echo $oLP->get_complete_items_count();?>;
  153. //olms.lms_progress_bar_mode = '<?php echo $oLP->progress_bar_mode;?>';
  154. //if(lms_progress_bar_mode == ''){lms_progress_bar_mode='%';}
  155. olms.lms_view_id = '<?php echo $oLP->get_view();?>';
  156. if(olms.lms_view_id == ''){ olms.lms_view_id = 1;}
  157. olms.lms_user_id = '<?php echo $_user['user_id'];?>';
  158. olms.lms_next_item = '<?php echo $oLP->get_next_item_id();?>';
  159. olms.lms_previous_item = '<?php echo $oLP->get_previous_item_id();?>';
  160. olms.lms_lp_type = '<?php echo $oLP->get_type();?>';
  161. olms.lms_item_type = '<?php echo $oItem->get_type();?>';
  162. olms.lms_item_credit = '<?php echo $oItem->get_credit();?>';
  163. olms.lms_item_lesson_mode = '<?php echo $oItem->get_lesson_mode();?>';
  164. olms.lms_item_launch_data = '<?php echo $oItem->get_launch_data();?>';
  165. olms.lms_item_core_exit = '<?php echo $oItem->get_core_exit();?>';
  166. <?php echo $oLP->get_items_details_as_js('olms.lms_item_types');?>
  167. olms.asset_timer = 0;
  168. olms.userfname = '<?php echo str_replace("'","\\'",$user['firstname']); ?>';
  169. olms.userlname = '<?php echo str_replace("'","\\'",$user['lastname']); ?>';
  170. //Backup for old values
  171. //var olms.old_score = 0;
  172. //var old_max = 0;
  173. //var old_min = 0;
  174. //var old_lesson_status = '';
  175. //var old_session_time = '';
  176. //var old_suspend_data = '';
  177. //var olms.lms_old_item_id = 0;
  178. olms.execute_stats=false;
  179. // Initialize stuff when the page is loaded
  180. $(document).ready( function() {
  181. olms.info_lms_item[0]='<?php echo $oItem->get_id();?>';
  182. olms.info_lms_item[1]='<?php echo $oItem->get_id();?>';
  183. $("#content_id").load( function() {
  184. // Add a right margin see BT#1607
  185. if (frames['content_name']) {
  186. // See the task #2558: try-catch block has been added for suppressing "Access denied" error that may occur on IE.
  187. try {
  188. frames['content_name'].document.body.style.margin="0 12px 0px 5px";
  189. } catch (ex) { }
  190. }
  191. olms.info_lms_item[0]=olms.info_lms_item[1];
  192. if (olms.lms_item_types['i'+olms.info_lms_item[1]] != 'sco') {
  193. LMSInitialize();
  194. }
  195. });
  196. });
  197. /**
  198. * The following section represents a set of mandatory functions for SCORM
  199. */
  200. /**
  201. * Function called mandatorily by the SCORM content to start the SCORM comm
  202. * @return string 'true' or 'false'. Returning a string is mandatory (SCORM).
  203. */
  204. function LMSInitialize() { //this is the initialize function of all APIobjects
  205. /* load info for this new item by calling the js_api_refresh command in
  206. * the message frame. The message frame will update the JS variables by
  207. * itself, in JS, by doing things like top.lesson_status = 'not attempted'
  208. * and that kind of stuff, so when the content loads in the content frame
  209. * it will have all the correct variables set
  210. */
  211. olms.G_LastError = G_NoError ;
  212. olms.G_LastErrorMessage = 'No error';
  213. olms.lms_initialized=0;
  214. // if there are more parameters than ""
  215. if (arguments.length>1) {
  216. olms.G_LastError = G_InvalidArgumentError;
  217. olms.G_LastErrorMessage = G_InvalidArgumentErrorMessage;
  218. logit_scorm('Error '+ G_InvalidArgumentError + G_InvalidArgumentErrorMessage, 0);
  219. return('false');
  220. } else {
  221. //reinit the list of modified variables
  222. reinit_updatable_vars_list();
  223. // Get LMS values for this item
  224. params = {
  225. 'lid': olms.lms_lp_id,
  226. 'uid': olms.lms_user_id,
  227. 'vid': olms.lms_view_id,
  228. 'iid': olms.lms_item_id
  229. };
  230. $.ajax({
  231. type: "POST",
  232. url: "lp_ajax_initialize.php",
  233. data: params,
  234. dataType: 'script',
  235. async: false
  236. });
  237. // log a more complete object dump when initializing, so we know what data hasn't been cleaned
  238. var log = '<br />item : '+ olms.lms_item_id
  239. + '<br />item_type : '+ olms.lms_item_type
  240. + '<br />score : '+ olms.score
  241. + '<br />max : '+ olms.max
  242. + '<br />min : '+ olms.min
  243. + '<br />lesson_status : '+ olms.lesson_status
  244. + '<br />session_time : '+ olms.session_time
  245. + '<br />lesson_location : '+ olms.lesson_location
  246. + '<br />suspend_data : '+ olms.suspend_data
  247. + '<br />total_time : '+ olms.total_time
  248. + '<br />mastery_score : '+ olms.mastery_score
  249. + '<br />max_time_allowed: '+ olms.max_time_allowed
  250. + '<br />lms_lp_id : '+olms.lms_lp_id
  251. + '<br />lms_user_id: '+olms.lms_user_id
  252. + '<br />lms_view_id: '+olms.lms_view_id
  253. ;
  254. logit_scorm('LMSInitialize()'+log,0);
  255. olms.lms_initialized=1;
  256. <?php if (api_get_setting('show_glossary_in_documents') == 'ismanual') { ?>
  257. if (olms.lms_item_type == 'sco') {
  258. attach_glossary_into_scorm('automatic');
  259. } else {
  260. attach_glossary_into_scorm('manual');
  261. }
  262. <?php } elseif (api_get_setting('show_glossary_in_documents') == 'isautomatic') { ?>
  263. attach_glossary_into_scorm('automatic');
  264. <?php } ?>
  265. return('true');
  266. }
  267. }
  268. /**
  269. * Twin sister of LMSInitialize(). Only provided for backwards compatibility.
  270. */
  271. function Initialize()
  272. { //this is the initialize function of all APIobjects
  273. return LMSInitialize();
  274. }
  275. /**
  276. * Gets a value in the current SCORM context and returns it to the calling SCO
  277. * @param string The name of the value we want
  278. * @return string All return values must be string (see SCORM)
  279. */
  280. function LMSGetValue(param)
  281. {
  282. //logit_scorm("LMSGetValue('"+param+"')",1);
  283. olms.G_LastError = G_NoError ;
  284. olms.G_LastErrorMessage = 'No error';
  285. var result='';
  286. // the LMSInitialize is missing
  287. if (olms.lms_initialized == 0) {
  288. olms.G_LastError = G_NotInitialized;
  289. olms.G_LastErrorMessage = G_NotInitializedMessage;
  290. logit_scorm('LMSGetValue('+param+'):<br />=> Error '+ G_NotInitialized + ' ' +G_NotInitializedMessage, 0);
  291. return '';
  292. }
  293. //Chamilo does not support these SCO object properties
  294. if (param == 'cmi.student_preference.text' ||
  295. param == 'cmi.student_preference.language' ||
  296. param == 'cmi.student_preference.speed' ||
  297. param == 'cmi.student_preference.audio' ||
  298. param == 'cmi.student_preference._children' ||
  299. param == 'cmi.student_data.time_limit_action' ||
  300. param == 'cmi.comments' ||
  301. param == 'cmi.comments_from_lms' ||
  302. /* The following properties were part of SCORM 1.0 or never implemented at all
  303. but seem to react badly to Captivate content producer when not defined */
  304. param == 'cmi.student_demographics._children' ||
  305. param == 'cmi.student_demographics.city' ||
  306. param == 'cmi.student_demographics.class' ||
  307. param == 'cmi.student_demographics.company' ||
  308. param == 'cmi.student_demographics.country' ||
  309. param == 'cmi.student_demographics.experience' ||
  310. param == 'cmi.student_demographics.familiar_name' ||
  311. param == 'cmi.student_demographics.instructor_name' ||
  312. param == 'cmi.student_demographics.title' ||
  313. param == 'cmi.student_demographics.native_language' ||
  314. param == 'cmi.student_demographics.state' ||
  315. param == 'cmi.student_demographics.street_address' ||
  316. param == 'cmi.student_demographics.telephone' ||
  317. param == 'cmi.student_demographics.years_experience' ) {
  318. // the value is not supported
  319. olms.G_LastError = G_NotImplementedError ;
  320. olms.G_LastErrorString = G_NotImplementedErrorMessage;
  321. logit_scorm("LMSGetValue ('"+param+"') Error '"+G_NotImplementedErrorMessage+"'",1);
  322. result = '';
  323. return result;
  324. }
  325. if(param=='cmi.student_demographics.first_name') {
  326. result=olms.userfname;
  327. }else if(param=='cmi.student_demographics.last_name') {
  328. result=olms.userlname;
  329. // ---- cmi.core._children
  330. }else if(param=='cmi.core._children' || param=='cmi.core_children'){
  331. result='entry, exit, lesson_status, student_id, student_name, lesson_location, total_time, credit, lesson_mode, score, session_time';
  332. }else if(param == 'cmi.core.entry'){
  333. // ---- cmi.core.entry
  334. if(olms.lms_item_core_exit=='none') {
  335. result='ab-initio';
  336. } else if(olms.lms_item_core_exit=='suspend') {
  337. result='resume';
  338. } else {
  339. result='';
  340. }
  341. }else if(param == 'cmi.core.exit'){
  342. // ---- cmi.core.exit
  343. result='';
  344. olms.G_LastError = G_ElementIsWriteOnly;
  345. }else if(param == 'cmi.core.session_time'){
  346. result='';
  347. olms.G_LastError = G_ElementIsWriteOnly;
  348. }else if(param == 'cmi.core.lesson_status'){
  349. // ---- cmi.core.lesson_status
  350. if(olms.lesson_status != '') {
  351. result=olms.lesson_status;
  352. } else {
  353. //result='not attempted';
  354. }
  355. }else if(param == 'cmi.core.student_id'){
  356. // ---- cmi.core.student_id
  357. result='<?php echo $_user['user_id']; ?>';
  358. }else if(param == 'cmi.core.student_name'){
  359. // ---- cmi.core.student_name
  360. <?php
  361. $who=addslashes(api_get_person_name($_user['firstName'], $_user['lastName']));
  362. echo "result='$who';";
  363. ?>
  364. }else if(param == 'cmi.core.lesson_location'){
  365. // ---- cmi.core.lesson_location
  366. result=olms.lesson_location;
  367. }else if(param == 'cmi.core.total_time'){
  368. // ---- cmi.core.total_time
  369. result=olms.total_time;
  370. }else if(param == 'cmi.core.score._children'){
  371. // ---- cmi.core.score._children
  372. result='raw,min,max';
  373. }else if(param == 'cmi.core.score.raw'){
  374. // ---- cmi.core.score.raw
  375. result=olms.score;
  376. }else if(param == 'cmi.core.score.max'){
  377. // ---- cmi.core.score.max
  378. result=olms.max;
  379. }else if(param == 'cmi.core.score.min'){
  380. // ---- cmi.core.score.min
  381. result=olms.min;
  382. }else if(param == 'cmi.core.score'){
  383. // ---- cmi.core.score -- non-standard item, provided as cmi.core.score.raw just in case
  384. result=olms.score;
  385. }else if(param == 'cmi.core.credit'){
  386. // ---- cmi.core.credit
  387. result = olms.lms_item_credit;
  388. }else if(param == 'cmi.core.lesson_mode'){
  389. // ---- cmi.core.lesson_mode
  390. result = olms.lms_item_lesson_mode;
  391. }else if(param == 'cmi.suspend_data'){
  392. // ---- cmi.suspend_data
  393. result = olms.suspend_data;
  394. }else if(param == 'cmi.launch_data'){
  395. // ---- cmi.launch_data
  396. result = olms.lms_item_launch_data;
  397. }else if(param == 'cmi.objectives._children'){
  398. // ---- cmi.objectives._children
  399. result = 'id,score,status';
  400. }else if(param == 'cmi.objectives._count'){
  401. // ---- cmi.objectives._count
  402. //result='<?php echo $oItem->get_view_count();?>';
  403. result = olms.item_objectives.length;
  404. }else if(param.substring(0,15)== 'cmi.objectives.'){
  405. var myres = '';
  406. if(myres = param.match(/cmi.objectives.(\d+).(id|score|status|_children)(.*)/))
  407. {
  408. var obj_id = myres[1];
  409. var req_type = myres[2];
  410. if(olms.item_objectives[obj_id]==null)
  411. {
  412. if(req_type == 'id')
  413. {
  414. result = '';
  415. }else if(req_type == '_children'){
  416. result = 'id,score,status';
  417. }else if(req_type == 'score'){
  418. if(myres[3]==null)
  419. {
  420. result = '';
  421. olms.G_LastError = G_NotImplementedError;
  422. olms.G_LastErrorString = 'Not implemented yet';
  423. }else if (myres[3] == '._children'){
  424. result = 'raw,min,max'; //non-standard, added for NetG
  425. }else if (myres[3] == '.raw'){
  426. result = '';
  427. }else if (myres[3] == '.max'){
  428. result = '';
  429. }else if (myres[3] == '.min'){
  430. result = '';
  431. }else{
  432. result = '';
  433. olms.G_LastError = G_NotImplementedError;
  434. olms.G_LastErrorString = 'Not implemented yet';
  435. }
  436. }else if(req_type == 'status'){
  437. result = 'not attempted';
  438. }
  439. }
  440. else
  441. {
  442. //the object is not null
  443. if(req_type == 'id')
  444. {
  445. result = olms.item_objectives[obj_id][0];
  446. }else if(req_type == '_children'){
  447. result = 'id,score,status';
  448. }else if(req_type == 'score'){
  449. if(myres[3]==null)
  450. {
  451. result = '';
  452. olms.G_LastError = G_NotImplementedError;
  453. olms.G_LastErrorString = 'Not implemented yet';
  454. }else if (myres[3] == '._children'){
  455. result = 'raw,min,max'; //non-standard, added for NetG
  456. }else if (myres[3] == '.raw'){
  457. if(olms.item_objectives[obj_id][2] != null)
  458. {
  459. result = olms.item_objectives[obj_id][2];
  460. }else{
  461. result = '';
  462. }
  463. }else if (myres[3] == '.max'){
  464. if(olms.item_objectives[obj_id][3] != null)
  465. {
  466. result = olms.item_objectives[obj_id][3];
  467. }else{
  468. result = '';
  469. }
  470. }else if (myres[3] == '.min'){
  471. if(olms.item_objectives[obj_id][4] != null)
  472. {
  473. result = olms.item_objectives[obj_id][4];
  474. }else{
  475. result = '';
  476. }
  477. }else{
  478. result = '';
  479. olms.G_LastError = G_NotImplementedError;
  480. olms.G_LastErrorString = 'Not implemented yet';
  481. }
  482. }else if(req_type == 'status'){
  483. if(olms.item_objectives[obj_id][1] != null)
  484. {
  485. result = olms.item_objectives[obj_id][1];
  486. }else{
  487. result = 'not attempted';
  488. }
  489. }
  490. }
  491. }
  492. }else if(param == 'cmi.student_data._children'){
  493. // ---- cmi.student_data._children
  494. result = 'mastery_score,max_time_allowed';
  495. }else if(param == 'cmi.student_data.mastery_score'){
  496. // ---- cmi.student_data.mastery_score
  497. result = olms.mastery_score;
  498. }else if(param == 'cmi.student_data.max_time_allowed'){
  499. // ---- cmi.student_data.max_time_allowed
  500. result = olms.max_time_allowed;
  501. }else if(param == 'cmi.interactions._count'){
  502. // ---- cmi.interactions._count
  503. result = olms.interactions.length;
  504. }else if(param == 'cmi.interactions._children'){
  505. // ---- cmi.interactions._children
  506. result = 'id,time,type,correct_responses,weighting,student_response,result,latency';
  507. }else{
  508. // ---- anything else
  509. // Invalid argument error
  510. olms.G_LastError = G_InvalidArgumentError ;
  511. olms.G_LastErrorString = G_InvalidArgumentErrorMessage;
  512. logit_scorm("LMSGetValue ('"+param+"') Error '"+G_InvalidArgumentErrorMessage+"'",1);
  513. result = '';
  514. return result;
  515. }
  516. logit_scorm("LMSGetValue\n\t('"+param+"') returned '"+result+"'",1);
  517. return result;
  518. }
  519. /**
  520. * Twin sister of LMSGetValue(). Only provided for backwards compatibility.
  521. */
  522. function GetValue(param) {
  523. return LMSGetValue(param);
  524. }
  525. /**
  526. * Sets a SCORM variable's value through a call from the SCO.
  527. * @param string The SCORM variable's name
  528. * @param string The SCORM variable's new value
  529. * @param string 'true','false' or an error code
  530. */
  531. function LMSSetValue(param, val) {
  532. logit_scorm("LMSSetValue\n\t('"+param+"','"+val+"')",0);
  533. olms.commit = true; //value has changed, need to re-commit
  534. olms.G_LastError = G_NoError ;
  535. olms.G_LastErrorMessage = 'No error';
  536. return_value = 'false';
  537. if( param == "cmi.core.score.raw" ) {
  538. olms.score= val;
  539. olms.updatable_vars_list['cmi.core.score.raw']=true;
  540. return_value='true';
  541. } else if ( param == "cmi.core.score.max" ) {
  542. olms.max = val;
  543. olms.updatable_vars_list['cmi.core.score.max']=true;
  544. return_value='true';
  545. } else if ( param == "cmi.core.score.min" ) {
  546. olms.min = val;
  547. olms.updatable_vars_list['cmi.core.score.min']=true;
  548. return_value='true';
  549. } else if ( param == "cmi.core.lesson_location" ) {
  550. olms.lesson_location = val;
  551. olms.updatable_vars_list['cmi.core.lesson_location']=true;
  552. return_value='true';
  553. } else if ( param == "cmi.core.lesson_status" ) {
  554. olms.lesson_status = val;
  555. olms.updatable_vars_list['cmi.core.lesson_status']=true;
  556. return_value='true';
  557. } else if ( param == "cmi.completion_status" ) {
  558. olms.lesson_status = val;
  559. olms.updatable_vars_list['cmi.completion_status']=true;
  560. return_value='true'; //1.3
  561. } else if ( param == "cmi.core.session_time" ) {
  562. olms.session_time = val;
  563. olms.updatable_vars_list['cmi.core.session_time']=true;
  564. return_value='true';
  565. } else if ( param == "cmi.score.scaled") { //1.3
  566. if(val<=1 && val>=-1) {
  567. olms.score = val ;
  568. olms.updatable_vars_list['cmi.score.scaled']=true;
  569. return_value='true';
  570. } else {
  571. return_value='false';
  572. }
  573. } else if ( param == "cmi.success_status" ) {
  574. success_status = val;
  575. olms.updatable_vars_list['cmi.success_status']=true;
  576. return_value='true'; //1.3
  577. } else if ( param == "cmi.suspend_data" ) {
  578. olms.suspend_data = val;
  579. olms.updatable_vars_list['cmi.suspend_data']=true;
  580. return_value='true';
  581. } else if ( param == "cmi.core.exit" ) {
  582. olms.lms_item_core_exit = val;
  583. olms.updatable_vars_list['cmi.core.exit']=true;
  584. return_value='true';
  585. } else if ( param == "cmi.core.student_id" ) {
  586. olms.G_LastError = G_ElementIsReadOnly;
  587. } else if ( param == "cmi.core.student_name" ) {
  588. olms.G_LastError = G_ElementIsReadOnly;
  589. } else if ( param == "cmi.core.credit" ) {
  590. olms.G_LastError = G_ElementIsReadOnly;
  591. } else if ( param == "cmi.core.entry" ) {
  592. olms.G_LastError = G_ElementIsReadOnly;
  593. } else if ( param == "cmi.core.total_time" ) {
  594. olms.G_LastError = G_ElementIsReadOnly;
  595. } else if ( param == "cmi.core.lesson_mode" ) {
  596. olms.G_LastError = G_ElementIsReadOnly;
  597. } else if ( param == "cmi.comments_from_lms" ) {
  598. olms.G_LastError = G_ElementIsReadOnly;
  599. } else if ( param == "cmi.student_data.time_limit_action" ) {
  600. olms.G_LastError = G_ElementIsReadOnly;
  601. } else if ( param == "cmi.student_data.mastery_score" ) {
  602. olms.G_LastError = G_ElementIsReadOnly;
  603. } else if ( param == "cmi.student_data.max_time_allowed" ) {
  604. olms.G_LastError = G_ElementIsReadOnly;
  605. } else if ( param == "cmi.student_preference._children" ) {
  606. olms.G_LastError = G_ElementIsReadOnly;
  607. } else if ( param == "cmi.launch_data" ) {
  608. olms.G_LastError = G_ElementIsReadOnly;
  609. } else {
  610. var myres = new Array();
  611. if(myres = param.match(/cmi.interactions.(\d+).(id|time|type|correct_responses|weighting|student_response|result|latency)(.*)/)) {
  612. olms.updatable_vars_list['interactions']=true;
  613. elem_id = myres[1];
  614. if(elem_id > olms.interactions.length) //interactions setting should start at 0
  615. {
  616. /*
  617. olms.G_LastError = G_InvalidArgumentError;
  618. olms.G_LastErrorString = 'Invalid argument (interactions)';
  619. return_value = false;
  620. */
  621. olms.interactions[0] = ['0','','','','','','',''];
  622. }
  623. if(olms.interactions[elem_id] == null){
  624. olms.interactions[elem_id] = ['','','','','','','',''];
  625. //id(0), type(1), time(2), weighting(3),correct_responses(4),student_response(5),result(6),latency(7)
  626. olms.interactions[elem_id][4] = new Array();
  627. }
  628. elem_attrib = myres[2];
  629. switch(elem_attrib) {
  630. case "id":
  631. olms.interactions[elem_id][0] = val;
  632. logit_scorm("Interaction "+elem_id+"'s id updated",2);
  633. return_value='true';
  634. break;
  635. case "time":
  636. olms.interactions[elem_id][2] = val;
  637. logit_scorm("Interaction "+elem_id+"'s time updated",2);
  638. return_value='true';
  639. break;
  640. case "type":
  641. olms.interactions[elem_id][1] = val;
  642. logit_scorm("Interaction "+elem_id+"'s type updated",2);
  643. return_value='true';
  644. break;
  645. case "correct_responses":
  646. //do nothing yet
  647. olms.interactions[elem_id][4].push(val);
  648. logit_scorm("Interaction "+elem_id+"'s correct_responses not updated",2);
  649. return_value='true';
  650. break;
  651. case "weighting":
  652. olms.interactions[elem_id][3] = val;
  653. logit_scorm("Interaction "+elem_id+"'s weighting updated",2);
  654. return_value='true';
  655. break;
  656. case "student_response":
  657. olms.interactions[elem_id][5] = ''+val;
  658. logit_scorm("Interaction "+elem_id+"'s student_response updated",2);
  659. return_value='true';
  660. break;
  661. case "result":
  662. olms.interactions[elem_id][6] = val;
  663. logit_scorm("Interaction "+elem_id+"'s result updated",2);
  664. return_value='true';
  665. break;
  666. case "latency":
  667. olms.interactions[elem_id][7] = val;
  668. logit_scorm("Interaction "+elem_id+"'s latency updated",2);
  669. return_value='true';
  670. break;
  671. default:
  672. olms.G_LastError = G_NotImplementedError;
  673. olms.G_LastErrorString = 'Not implemented yet';
  674. }
  675. }else if(param.substring(0,15)== 'cmi.objectives.'){
  676. var myres = '';
  677. olms.updatable_vars_list['objectives']=true;
  678. if(myres = param.match(/cmi.objectives.(\d+).(id|score|status)(.*)/))
  679. {
  680. obj_id = myres[1];
  681. if(obj_id > olms.item_objectives.length) //objectives setting should start at 0
  682. {
  683. olms.G_LastError = G_InvalidArgumentError;
  684. olms.G_LastErrorString = 'Invalid argument (objectives)';
  685. return_value = false;
  686. }
  687. else
  688. {
  689. req_type = myres[2];
  690. if(obj_id == null || obj_id == '')
  691. {
  692. ;//do nothing
  693. }
  694. else
  695. {
  696. if(olms.item_objectives[obj_id]==null)
  697. {
  698. olms.item_objectives[obj_id] = ['','','','',''];
  699. }
  700. if( req_type == "id" ) {
  701. //olms.item_objectives[obj_id][0] = val.substring(51,57);
  702. olms.item_objectives[obj_id][0] = val;
  703. logit_scorm("Objective "+obj_id+"'s id updated",2);
  704. return_value = 'true';
  705. } else if ( req_type == "score" ) {
  706. if (myres[3] == '._children'){
  707. return_value = '';
  708. olms.G_LastError = G_InvalidSetValue;
  709. olms.G_LastErrorString = 'Invalid set value, element is a keyword';
  710. }else if (myres[3] == '.raw'){
  711. olms.item_objectives[obj_id][2] = val;
  712. logit_scorm("Objective "+obj_id+"'s score raw updated",2);
  713. return_value = 'true';
  714. }else if (myres[3] == '.max'){
  715. olms.item_objectives[obj_id][3] = val;
  716. logit_scorm("Objective "+obj_id+"'s score max updated",2);
  717. return_value = 'true';
  718. }else if (myres[3] == '.min'){
  719. olms.item_objectives[obj_id][4] = val;
  720. logit_scorm("Objective "+obj_id+"'s score min updated",2);
  721. return_value = 'true';
  722. }else{
  723. return_value = '';
  724. olms.G_LastError = G_NotImplementedError;
  725. olms.G_LastErrorString = 'Not implemented yet';
  726. }
  727. } else if ( req_type == "status" ) {
  728. olms.item_objectives[obj_id][1] = val;
  729. logit_scorm("Objective "+obj_id+"'s status updated",2);
  730. return_value = 'true';
  731. } else {
  732. olms.G_LastError = G_NotImplementedError;
  733. olms.G_LastErrorString = 'Not implemented yet';
  734. }
  735. }
  736. }
  737. }
  738. }else{
  739. olms.G_LastError = G_NotImplementedError;
  740. olms.G_LastErrorString = G_NotImplementedErrorMessage;
  741. }
  742. }
  743. <?php
  744. if ($oLP->force_commit == 1){
  745. echo " var mycommit = LMSCommit('force');";
  746. }
  747. ?>
  748. return(return_value);
  749. }
  750. /**
  751. * Twin sister of LMSSetValue(). Only provided for backwards compatibility.
  752. */
  753. function SetValue(param, val) {
  754. return LMSSetValue(param, val);
  755. }
  756. /**
  757. * Saves the current data from JS memory to the LMS database
  758. * @param string The origin of the call to save the data ('commit','finish', 'unload' or 'terminate')
  759. * @note origin actually seems deprecated now
  760. */
  761. function savedata(origin) {
  762. //origin can be 'commit', 'finish' or 'terminate' (depending on the calling function)
  763. if ((olms.lesson_status != 'completed') && (olms.lesson_status != 'passed') && (olms.mastery_score >=0) && (olms.score >= olms.mastery_score)) {
  764. olms.lesson_status = 'passed';
  765. olms.updatable_vars_list['cmi.core.lesson_status']=true;
  766. } else if( (olms.mastery_score < 0) && (olms.lms_lp_type != '2') && ( olms.lesson_status == 'incomplete') && (olms.score >= (0.8*olms.max) ) ) {
  767. //the status cannot be modified automatically by the LMS under SCORM 1.2's rules
  768. <?php if ($autocomplete_when_80pct){ ?>
  769. olms.lesson_status = 'completed';
  770. olms.updatable_vars_list['cmi.core.lesson_status']=true;
  771. <?php }?>
  772. ;
  773. } else {
  774. /* DEPRECATED
  775. * See notes in switch_item for why this has been disabled
  776. if ((origin== 'finish' || origin == 'unload') && olms.lesson_status != 'completed' && olms.lesson_status != 'passed' && olms.lesson_status != 'browsed' && olms.lesson_status != 'failed' && olms.lesson_status != 'incomplete') {
  777. // The SCORM1.2 Runtime object document says for the "cmi.core.lesson_status" variable:
  778. // Upon receiving the LMSFinish() call or the user navigates away,
  779. // the LMS should set the cmi.core.lesson_status for the SCO to 'completed'
  780. logit_lms('the LMS did saving data (status='+olms.lesson_status+' - interactions: '+ olms.interactions.length +')',1);
  781. if (olms.mastery_score && olms.mastery_score!= '' && olms.score && olms.score != '') {
  782. if (olms.score >= olms.mastery_score) {
  783. olms.lesson_status = 'passed';
  784. } else {
  785. olms.lesson_status = 'failed';
  786. }
  787. olms.updatable_vars_list['cmi.core.lesson_status']=true;
  788. } else if (olms.mastery_score && olms.mastery_score!= '') {
  789. olms.lesson_status = 'completed';
  790. olms.updatable_vars_list['cmi.core.lesson_status']=true;
  791. }
  792. }
  793. */
  794. }
  795. logit_lms('saving data (status='+olms.lesson_status+' - interactions: '+ olms.interactions.length +')',1);
  796. old_item_id=olms.info_lms_item[0];
  797. xajax_save_item_scorm(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, old_item_id);
  798. //olms.info_lms_item[0] is old_item_id and olms.info_lms_item[1] is current_item_id
  799. olms.info_lms_item[1]=olms.lms_item_id;
  800. if(olms.item_objectives.length>0) {
  801. xajax_save_objectives(olms.lms_lp_id,olms.lms_user_id,olms.lms_view_id,old_item_id,olms.item_objectives);
  802. }
  803. olms.execute_stats=false;
  804. //clean array
  805. olms.variable_to_send=new Array();
  806. }
  807. /**
  808. * Send the Commit signal to the LMS (save the data for this element without
  809. * closing the current process)
  810. * From SCORM 1.2 RTE: If the API Adapter is caching values received from the
  811. * SCO via an LMSSetValue(), this call requires that any values not yet
  812. * persisted by the LMS be persisted.
  813. * @param string Must be empty string for conformance with SCORM 1.2
  814. */
  815. function LMSCommit(val) {
  816. logit_scorm('LMSCommit()',0);
  817. olms.G_LastError = G_NoError ;
  818. olms.G_LastErrorMessage = 'No error';
  819. savedata('commit');
  820. reinit_updatable_vars_list();
  821. //commit = 'false' ; //now changes have been commited, no need to update until next SetValue()
  822. return('true');
  823. }
  824. /**
  825. * Twin sister of LMSCommit(). Only provided for backwards compatibility.
  826. */
  827. function Commit(val) {
  828. return LMSCommit(val);
  829. }
  830. /**
  831. * Send the closure signal to the LMS. This saves the data and closes the current SCO.
  832. * From SCORM 1.2 RTE: The SCO must call this when it has determined that it no
  833. * longer needs to communicate with the LMS, if it successfully called
  834. * LMSInitialize at any previous point. This call signifies two things:
  835. * 1.The SCO can be assured that any data set using LMSSetValue() calls has been persisted by the LMS.
  836. * 2.The SCO has finished communicating with the LMS.
  837. * @param string
  838. */
  839. function LMSFinish(val) {
  840. olms.G_LastError = G_NoError ;
  841. olms.G_LastErrorMessage = 'No error';
  842. // if olms.commit == false, then the SCORM didn't ask for a commit, so we
  843. // should at least report that
  844. if ( !olms.commit ) {
  845. logit_scorm('LMSFinish() (no LMSCommit())',1);
  846. }
  847. //if ( olms.commit ) {
  848. logit_scorm('LMSFinish() called',1);
  849. savedata('finish');
  850. olms.commit = false;
  851. //}
  852. //reinit the list of modified variables
  853. reinit_updatable_vars_list()
  854. return('true');
  855. }
  856. /**
  857. * Twin sister of LMSFinish(). Only provided for backwards compatibility.
  858. */
  859. function Finish(val) {
  860. return LMSFinish(val);
  861. }
  862. /**
  863. * Returns the last error code as a string
  864. * @return string Error code
  865. */
  866. function LMSGetLastError() {
  867. logit_scorm('LMSGetLastError()',1);
  868. return(olms.G_LastError.toString());
  869. }
  870. /**
  871. * Twin sister of LMSGetLastError(). Only provided for backwards compatibility.
  872. */
  873. function GetLastError() {
  874. return LMSGetLastError();
  875. }
  876. /**
  877. * Returns the last error code literal for a given error code
  878. * @param int Error code
  879. * @return string Last error
  880. */
  881. function LMSGetErrorString(errCode){
  882. logit_scorm('LMSGetErrorString()',1);
  883. return(olms.G_LastErrorString);
  884. }
  885. /**
  886. * Twin sister of LMSGetErrorString(). Only provided for backwards compatibility.
  887. */
  888. function GetErrorString(errCode){
  889. return LMSGetErrorString(errCode);
  890. }
  891. /**
  892. * Returns a more explanatory, full English, error message
  893. * @param int Error code
  894. * @return string Diagnostic
  895. */
  896. function LMSGetDiagnostic(errCode){
  897. logit_scorm('LMSGetDiagnostic()',1);
  898. return(API.LMSGetLastError());
  899. }
  900. /**
  901. * Twin sister of LMSGetDiagnostic(). Only provided for backwards compatibility.
  902. */
  903. function GetDiagnostic(errCode){
  904. return LMSGetDiagnostic(errCode);
  905. }
  906. /**
  907. * Acts as a "commit"
  908. * This function is not standard SCORM 1.2 and is probably deprecated in all
  909. * meanings of the term.
  910. * @return string 'true' or 'false', depening on whether the LMS has initialized the SCORM process or not
  911. */
  912. function Terminate()
  913. {
  914. if (olms.lms_initialized == 0) {
  915. olms.G_LastError = G_NotInitialized;
  916. olms.G_LastErrorMessage = G_NotInitializedMessage;
  917. logit_scorm('Error '+ G_NotInitialized + G_NotInitializedMessage, 0);
  918. return('false');
  919. } else {
  920. logit_scorm('Terminate()',0);
  921. olms.G_LastError = G_NoError ;
  922. olms.G_LastErrorMessage = 'No error';
  923. olms.commit = true;
  924. savedata('terminate');
  925. return ('true');
  926. }
  927. }
  928. /**
  929. * LMS-specific code that deals with event handling and inter-frames
  930. * messaging/refreshing.
  931. * Note that from now on, the LMS JS code in this library will act as
  932. * a controller, of the MVC pattern, and receive all requests for frame
  933. * updates, then redispatch to any frame concerned.
  934. */
  935. /**
  936. * Defining the AJAX-object class to be made available from other frames
  937. */
  938. function XAJAXobject() {
  939. this.xajax_switch_item_details=xajax_switch_item_details;
  940. this.switch_item=switch_item;
  941. this.xajax_save_objectives=xajax_save_objectives;
  942. this.xajax_save_item = xajax_save_item;
  943. }
  944. /**
  945. * It is not sure that the SCOs use the above declarations
  946. */
  947. oXAJAX = new XAJAXobject();
  948. oxajax = new XAJAXobject();
  949. /**
  950. * Cross-browser event handling by Scott Andrew
  951. * @param element Element that needs an event attached
  952. * @param string Event type (load, unload, click, keyDown, ...)
  953. * @param string Function name (the event handler)
  954. * @param string used in addEventListener
  955. */
  956. function addEvent(elm, evType, fn, useCapture){
  957. if(elm.addEventListener){
  958. elm.addEventListener(evType, fn, useCapture);
  959. return true;
  960. }else if (elm.attachEvent){
  961. var r = elm.attachEvent('on' + evType, fn);
  962. }else{
  963. elm['on'+evType] = fn;
  964. }
  965. }
  966. /**
  967. * Add listeners to the page objects. This has to be defined for
  968. * the current context as it acts on objects that should exist
  969. * on the page
  970. * possibly deprecated
  971. * @todo Try to use $(document).unload(lms_save_asset()) instead of the addEvent() method
  972. */
  973. function addListeners(){
  974. //exit if the browser doesn't support ID or tag retrieval
  975. logit_lms('Entering addListeners()',2);
  976. if(!document.getElementsByTagName){
  977. logit_lms("getElementsByTagName not available",2);
  978. return;
  979. }
  980. if(!document.getElementById){
  981. logit_lms("getElementById not available",2);
  982. return;
  983. }
  984. //assign event handlers to objects
  985. if(olms.lms_lp_type==1 || olms.lms_item_type=='asset'){
  986. logit_lms('Chamilo LP or asset',2);
  987. //if this path is a Chamilo learnpath, then start manual save
  988. //when something is loaded in there
  989. addEvent(window,'unload',lms_save_asset,false);
  990. logit_lms('Added event listener on content_id for unload',2);
  991. }
  992. logit_lms('Quitting addListeners()',2);
  993. }
  994. /**
  995. * Save a Chamilo learnpath item's time and mark as completed upon
  996. * leaving it
  997. */
  998. function lms_save_asset(){
  999. // only for Chamilo lps
  1000. if (olms.execute_stats) {
  1001. olms.execute_stats=false;
  1002. } else {
  1003. olms.execute_stats=true;
  1004. }
  1005. if(olms.lms_lp_type==1 || olms.lms_item_type=='asset'){
  1006. logit_lms('lms_save_asset',2);
  1007. xajax_save_item(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id, olms.score, olms.max, olms.min, olms.lesson_status, olms.session_time, olms.suspend_data, olms.lesson_location,olms.interactions, olms.lms_item_core_exit);
  1008. if(olms.item_objectives.length>0)
  1009. {
  1010. xajax_save_objectives(olms.lms_lp_id,olms.lms_user_id,olms.lms_view_id,olms.lms_item_id,olms.item_objectives);
  1011. }
  1012. }
  1013. }
  1014. /**
  1015. * Save a Chamilo learnpath item's time and mark as completed upon leaving it.
  1016. * Same function as lms_save_asset() but saves it with empty params
  1017. * to use values set from another side in the database. Only used by Chamilo quizzes.
  1018. * Also save the score locally because it hasn't been done through SetValue().
  1019. * Saving the status will be dealt with by the XAJAX function.
  1020. */
  1021. function chamilo_void_save_asset(myscore,mymax)
  1022. {
  1023. logit_lms('lms_save_asset',2);
  1024. olms.score = myscore;
  1025. if((mymax == null) || (mymax == '')){mymax = 100;} //assume a default of 100, otherwise the score will not get saved (see lpi->set_score())
  1026. xajax_save_item(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id, myscore, mymax);
  1027. }
  1028. /**
  1029. * Logs information about SCORM messages into the log frame
  1030. * @param string Message to log
  1031. * @param integer Priority (0 for top priority, 3 for lowest)
  1032. */
  1033. function logit_scorm(message,priority) {
  1034. if(scorm_logs == 0) {return false;}
  1035. if(scorm_logs>priority){ /* fixed see http://support.chamilo.org/issues/370 */
  1036. if($("#lp_log_name") && $("#log_content")){
  1037. $("#log_content").append("SCORM: " + message + "<br/>");
  1038. }
  1039. params = {
  1040. msg: "SCORM: " + message,
  1041. debug: scorm_logs
  1042. };
  1043. $.ajax({
  1044. type: "POST",
  1045. data: params,
  1046. url: "lp_ajax_log.php",
  1047. dataType: "script",
  1048. async: true
  1049. });
  1050. }
  1051. }
  1052. /**
  1053. * Logs information about LMS activity into the log frame
  1054. * @param string Message to log
  1055. * @param integer Priority (0 for top priority, 3 for lowest)
  1056. */
  1057. function logit_lms(message,priority){
  1058. if(lms_logs>=priority){
  1059. if ($("#lp_log_name") && $("#log_content")) {
  1060. $("#log_content").append("LMS: " + message + "<br />");
  1061. }
  1062. params = {
  1063. msg: "LMS: " + message,
  1064. debug: lms_logs
  1065. };
  1066. $.ajax({
  1067. type: "POST",
  1068. data: params,
  1069. url: "lp_ajax_log.php",
  1070. dataType: "script",
  1071. async: true
  1072. });
  1073. }
  1074. }
  1075. /**
  1076. * Update the Table Of Contents frame, by changing CSS styles, mostly
  1077. * @param string Action to be taken
  1078. * @param integer Item id to update
  1079. */
  1080. function update_toc(update_action,update_id,change_ids)
  1081. {
  1082. if (!change_ids || change_ids != 'no') {
  1083. change_ids = 'yes';
  1084. }
  1085. var myelem = $("#toc_"+update_id);
  1086. var myelemimg = $("#toc_img_"+update_id);
  1087. logit_lms('update_toc("'+update_action+'",'+update_id+')',2);
  1088. if(update_id != 0)
  1089. {
  1090. switch(update_action)
  1091. {
  1092. case 'unhighlight':
  1093. if (update_id%2==0)
  1094. {
  1095. myelem.attr('class',"scorm_item_2");
  1096. }
  1097. else
  1098. {
  1099. myelem.attr('class',"scorm_item_1");
  1100. }
  1101. break;
  1102. case 'highlight':
  1103. if (change_ids=='yes') {
  1104. olms.lms_next_item = update_id;
  1105. olms.lms_previous_item = update_id;
  1106. }
  1107. myelem.attr('class',"scorm_item_highlight");
  1108. break;
  1109. case 'not attempted':
  1110. if( myelemimg.attr('src') != '../img/notattempted.gif') {
  1111. myelemimg.attr('src','../img/notattempted.gif');
  1112. myelemimg.attr('alt','n');
  1113. }
  1114. break;
  1115. case 'incomplete':
  1116. if( myelemimg.attr('src') != '../img/incomplete.png') {
  1117. myelemimg.attr('src','../img/incomplete.png');
  1118. myelemimg.attr('alt','i');
  1119. }
  1120. break;
  1121. case 'completed':
  1122. if( myelemimg.attr('src') != '../img/completed.png') {
  1123. myelemimg.attr('src','../img/completed.png');
  1124. myelemimg.attr('alt','c');
  1125. }
  1126. break;
  1127. case 'failed':
  1128. if( myelemimg.attr('src') != '../img/delete.png') {
  1129. myelemimg.attr('src','../img/delete.png');
  1130. myelemimg.attr('alt','f');
  1131. }
  1132. break;
  1133. case 'passed':
  1134. if( myelemimg.attr('src') != '../img/completed.png' && myelemimg.attr('alt') != 'passed') {
  1135. myelemimg.attr('src','../img/completed.png');
  1136. myelemimg.attr('alt','p');
  1137. }
  1138. break;
  1139. case 'browsed':
  1140. if( myelemimg.attr('src') != '../img/completed.png' && myelemimg.attr('alt') != 'browsed') {
  1141. myelemimg.attr('src','../img/completed.png');
  1142. myelemimg.attr('alt','b');
  1143. }
  1144. break;
  1145. default:
  1146. logit_lms('Update action unknown',2);
  1147. break;
  1148. }
  1149. }
  1150. return true;
  1151. }
  1152. /**
  1153. * Update the stats frame using a reload of the frame to avoid unsynched data
  1154. */
  1155. function update_stats() {
  1156. if (olms.execute_stats) {
  1157. try {
  1158. cont_f = document.getElementById('content_id');
  1159. cont_f.src="lp_controller.php?action=stats";
  1160. cont_f.reload();
  1161. } catch (e) {
  1162. return false;
  1163. }
  1164. }
  1165. olms.execute_stats=false;
  1166. }
  1167. /**
  1168. * Update the stats frame using a reload of the frame to avoid unsynched data
  1169. */
  1170. function update_stats_page()
  1171. {
  1172. var myframe = document.getElementById('content_id');
  1173. var mysrc = myframe.location.href;
  1174. if(mysrc == 'lp_controller.php?action=stats'){
  1175. if(myframe && myframe.src){
  1176. var mysrc = myframe.src;
  1177. myframe.src = mysrc;
  1178. }
  1179. // = mysrc; //refresh page
  1180. }
  1181. return true;
  1182. }
  1183. /**
  1184. * Updates the progress bar with the new status. Prevents the need of a page refresh and flickering
  1185. * @param integer Number of completed items
  1186. * @param integer Number of items in total
  1187. * @param string Display mode (absolute 'abs' or percentage '%').Defaults to %
  1188. */
  1189. function update_progress_bar(nbr_complete, nbr_total, mode)
  1190. {
  1191. logit_lms('update_progress_bar('+nbr_complete+','+nbr_total+','+mode+')',2);
  1192. logit_lms('could update with data: '+olms.lms_lp_id+','+olms.lms_view_id+','+olms.lms_user_id,2);
  1193. if(mode == ''){mode='%';}
  1194. if(nbr_total == 0){nbr_total=1;}
  1195. var percentage = (nbr_complete/nbr_total)*100;
  1196. percentage = Math.round(percentage);
  1197. var pr_text = $("#progress_text");
  1198. var pr_full = $("#progress_img_full");
  1199. var pr_empty = $("#progress_img_empty");
  1200. pr_full.attr('width',percentage*1.2);
  1201. pr_empty.attr('width',(100-percentage)*1.2);
  1202. var mytext = '';
  1203. switch(mode){
  1204. case 'abs':
  1205. mytext = nbr_complete + '/' + nbr_total;
  1206. break;
  1207. case '%':
  1208. default:
  1209. mytext = percentage + '%';
  1210. break;
  1211. }
  1212. pr_text.html(mytext);
  1213. return true;
  1214. }
  1215. /**
  1216. * Analyses the variables that have been modified through this SCO's life and
  1217. * put them into an array for later shipping to lp_ajax_save_item.php
  1218. * @return array Array of SCO variables
  1219. */
  1220. function process_scorm_values () {
  1221. for (i=0;i<olms.scorm_variables.length;i++) {
  1222. if (olms.updatable_vars_list[olms.scorm_variables[i]]) {
  1223. olms.variable_to_send.push(olms.scorm_variables[i]);
  1224. }
  1225. }
  1226. return olms.variable_to_send;
  1227. }
  1228. /**
  1229. * Reinitializes the SCO's modified variables to an empty list.
  1230. * @return void
  1231. * @uses The global updatable_vars_list array to register this
  1232. */
  1233. function reinit_updatable_vars_list () {
  1234. for (i=0;i<olms.scorm_variables.length;i++) {
  1235. if (olms.updatable_vars_list[olms.scorm_variables[i]]) {
  1236. olms.updatable_vars_list[olms.scorm_variables[i]]=false;
  1237. }
  1238. }
  1239. olms.lesson_status='';
  1240. }
  1241. /**
  1242. * Function that handles the saving of an item and switching from an item to another.
  1243. * Once called, this function should be able to do the whole process of
  1244. * (1) saving the current item,
  1245. * (2) refresh all the values inside the SCORM API object,
  1246. * (3) open the new item into the content_id frame,
  1247. * (4) refresh the table of contents
  1248. * (5) refresh the progress bar (completion)
  1249. * (6) refresh the message frame
  1250. * @param integer Chamilo ID for the current item
  1251. * @param string This parameter can be a string specifying the next
  1252. * item (like 'next', 'previous', 'first' or 'last') or the id to the next item
  1253. */
  1254. function switch_item(current_item, next_item){
  1255. // backup these params
  1256. var orig_current_item = current_item;
  1257. var orig_next_item = next_item;
  1258. var orig_lesson_status = olms.lesson_status;
  1259. var orig_item_type = olms.lms_item_types['i'+current_item];
  1260. var next_item_type = olms.lms_item_types['i'+next_item];
  1261. /*
  1262. There are four "cases" for switching items:
  1263. (1) asset switching to asset
  1264. We need to save, then switch
  1265. (2) asset switching to sco
  1266. We need to save, switching not necessary (LMSInitialize does the job)
  1267. (3) sco switching to asset
  1268. We need to switch the document in the content frame, but we cannot
  1269. switch the item details, otherwise the LMSFinish() call (that *must*
  1270. be triggered by the SCO when it unloads) will use bad values. However,
  1271. we need to load the new asset's context once the SCO has unloaded
  1272. (4) sco switching to sco
  1273. We don't neet to switch nor commit, LMSFinish() on unload and
  1274. LMSInitialize on load will do the job
  1275. In any case, we need to change the current document frame.
  1276. These cases, although clear here, are however very difficult to implement
  1277. */
  1278. logit_lms('Called switch_item with params '+olms.lms_item_id+' and '+next_item+'',0);
  1279. if (orig_item_type != 'sco') {
  1280. if (next_item_type != 'sco' ) {
  1281. //case 1
  1282. xajax_save_item(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id, olms.score, olms.max, olms.min, olms.lesson_status, olms.asset_timer, olms.suspend_data, olms.lesson_location,olms.interactions, olms.lms_item_core_exit);
  1283. xajax_switch_item_details(olms.lms_lp_id,olms.lms_user_id,olms.lms_view_id,olms.lms_item_id,next_item);
  1284. } else {
  1285. //case 2
  1286. xajax_save_item(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id, olms.score, olms.max, olms.min, olms.lesson_status, olms.asset_timer, olms.suspend_data, olms.lesson_location,olms.interactions, olms.lms_item_core_exit);
  1287. xajax_switch_item_details(olms.lms_lp_id,olms.lms_user_id,olms.lms_view_id,olms.lms_item_id,next_item);
  1288. }
  1289. } else {
  1290. if (next_item_type != 'sco') {
  1291. //case 3
  1292. xajax_save_item_scorm(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id);
  1293. reinit_updatable_vars_list();
  1294. xajax_switch_item_toc(olms.lms_lp_id,olms.lms_user_id,olms.lms_view_id,olms.lms_item_id,next_item);
  1295. } else {
  1296. //case 4
  1297. xajax_save_item_scorm(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id);
  1298. reinit_updatable_vars_list();
  1299. xajax_switch_item_toc(olms.lms_lp_id,olms.lms_user_id,olms.lms_view_id,olms.lms_item_id,next_item);
  1300. }
  1301. if (olms.item_objectives.length>0) {
  1302. xajax_save_objectives(olms.lms_lp_id,olms.lms_user_id,olms.lms_view_id,olms.lms_item_id,olms.item_objectives);
  1303. }
  1304. }
  1305. /*
  1306. //(1) save the current item
  1307. if (olms.lms_lp_type==1 || olms.lms_item_type=='asset' || olms.session_time == '0' || olms.session_time == '0:00:00') {
  1308. if (olms.lms_lp_type==1) {
  1309. xajax_save_item(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id, olms.score, olms.max, olms.min, olms.lesson_status, olms.asset_timer, olms.suspend_data, olms.lesson_location,olms.interactions, olms.lms_item_core_exit);
  1310. } else {
  1311. xajax_save_item_scorm(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id);
  1312. }
  1313. if (olms.item_objectives.length>0) {
  1314. xajax_save_objectives(olms.lms_lp_id,olms.lms_user_id,olms.lms_view_id,olms.lms_item_id,olms.item_objectives);
  1315. }
  1316. }else{
  1317. */
  1318. /**
  1319. * Because of SCORM 1.2's special rule about unsent commits and the fact
  1320. * that a SCO should be SET TO 'completed' IF NO STATUS WAS SENT (and
  1321. * then some checks have to be done on score), we have to force a
  1322. * special commit here to avoid getting to the next element with a
  1323. * missing prerequisite. The 'onunload' event is treated with
  1324. * savedata_onunload(), and doesn't need to be triggered at any
  1325. * particular time, but here we are in the case of switching to another
  1326. * item, so this is particularly important to complete the element in
  1327. * time.
  1328. * However, this cannot be initiated from the JavaScript, mainly
  1329. * because another onunload event can be triggered by the SCO itself,
  1330. * which can set, for example, the status to incomplete while the
  1331. * status has already been set to "completed" by the hand-made
  1332. * savedata(unload) (and then the status cannot be "incompleted"
  1333. * anymore)
  1334. */
  1335. /*
  1336. if (olms.lms_item_type=='sco' && olms.lesson_status != 'completed' && olms.lesson_status != 'passed' && olms.lesson_status != 'browsed' && olms.lesson_status != 'incomplete' && olms.lesson_status != 'failed') {
  1337. // savedata('finish') treats the special condition and saves the
  1338. // new status to the database, so switch_item_details() enjoys the
  1339. // new status
  1340. savedata('finish');
  1341. }
  1342. xajax_save_item(olms.lms_lp_id, olms.lms_user_id, olms.lms_view_id, olms.lms_item_id, olms.score, olms.max, olms.min, olms.lesson_status, olms.session_time, olms.suspend_data, olms.lesson_location,olms.interactions, olms.lms_item_core_exit);
  1343. */
  1344. /*
  1345. }
  1346. //(2) Refresh all the values inside this SCORM API object - use AJAX
  1347. xajax_switch_item_details(olms.lms_lp_id,olms.lms_user_id,olms.lms_view_id,olms.lms_item_id,next_item);
  1348. */
  1349. olms.execute_stats=false;
  1350. // Considering info_lms_item[0] is initially the oldest and info_lms_item[1]
  1351. // is the newest item, and considering we are done switching the items now,
  1352. // we need to update these markers so that the new item is loaded when
  1353. // changing the document in the content frame
  1354. if (olms.info_lms_item[1]==next_item && next_item!='next' && next_item!='previous') {
  1355. olms.info_lms_item[0]=next_item;
  1356. olms.info_lms_item[1]=next_item;
  1357. } else {
  1358. if (next_item!='next' && next_item!='previous') {
  1359. olms.info_lms_item[0]=olms.info_lms_item[1];
  1360. olms.info_lms_item[1]=next_item;
  1361. }
  1362. }
  1363. if (olms.info_lms_item[0]==next_item && next_item!='next' && next_item!='previous') {
  1364. olms.info_lms_item[0]=next_item;
  1365. olms.info_lms_item[1]=next_item;
  1366. } else {
  1367. if (next_item!='next' && next_item!='previous') {
  1368. olms.info_lms_item[0]=olms.info_lms_item[0];
  1369. olms.info_lms_item[1]=next_item;
  1370. }
  1371. }
  1372. //(3) open the new item in the content_id frame
  1373. switch(next_item){
  1374. case 'next':
  1375. next_item = olms.lms_next_item;
  1376. olms.info_lms_item[0]=olms.info_lms_item[1];
  1377. olms.info_lms_item[1]=olms.lms_next_item;
  1378. break;
  1379. case 'previous':
  1380. next_item = olms.lms_previous_item;
  1381. olms.info_lms_item[0]=olms.info_lms_item[1];
  1382. olms.info_lms_item[1]=olms.lms_previous_item;
  1383. break;
  1384. default:
  1385. break;
  1386. }
  1387. var mysrc = 'lp_controller.php?action=content&lp_id='+olms.lms_lp_id+'&item_id='+next_item;
  1388. var cont_f = $("#content_id");
  1389. <?php if($oLP->mode == 'fullscreen'){ ?>
  1390. cont_f = window.open(''+mysrc,'content_id','toolbar=0,location=0,status=0,scrollbars=1,resizable=1');
  1391. cont_f.onload=function(){
  1392. olms.info_lms_item[0]=olms.info_lms_item[1];
  1393. }
  1394. cont_f.onunload=function(){
  1395. olms.info_lms_item[0]=olms.info_lms_item[1];
  1396. }
  1397. <?php } else { ?>
  1398. cont_f.attr("src",mysrc);
  1399. <?php } ?>
  1400. if(olms.lms_lp_type==1 || olms.lms_item_type=='asset'){
  1401. xajax_start_timer();
  1402. }
  1403. //(4) refresh the audio player if needed
  1404. $.ajax({
  1405. type: "POST",
  1406. url: "lp_nav.php",
  1407. data: "",
  1408. success: function(tmp_data) {
  1409. $("#media").html(tmp_data);
  1410. }
  1411. });
  1412. return true;
  1413. }
  1414. /**
  1415. * Save a specific item (with its interactions, if any) into the LMS through
  1416. * an AJAX call to lp_ajax_save_item.php.
  1417. * Because of the need to pass an array, we have to build the parameters
  1418. * manually into GET[].
  1419. * This function has a twin sister for SCO elements (xajax_save_item_scorm)
  1420. * which takes into account the interactions.
  1421. * @param int ID of the learning path (for the LMS)
  1422. * @param int ID of the user
  1423. * @param int ID of the view of this learning path
  1424. * @param int ID of the item currently looked at
  1425. * @param float Score
  1426. * @param float Max score
  1427. * @param float Min score
  1428. * @param string Lesson status
  1429. * @param string Current session time (in 'xxxx:xx:xx.xx' format)
  1430. * @param string Suspend data (maximum 255 chars)
  1431. * @param string Lesson location (which page we've reached in the SCO)
  1432. * @param array Interactions
  1433. * @param string Core exit value (up to 4096 chars)
  1434. * @return void
  1435. * @uses lp_ajax_save_item.php through an AJAX call
  1436. */
  1437. function xajax_save_item(lms_lp_id, lms_user_id, lms_view_id, lms_item_id, score, max, min, lesson_status, session_time, suspend_data, lesson_location, interactions, lms_item_core_exit) {
  1438. params='';
  1439. params += 'lid='+lms_lp_id+'&uid='+lms_user_id+'&vid='+lms_view_id;
  1440. params += '&iid='+lms_item_id+'&s='+score+'&max='+max+'&min='+min;
  1441. params += '&status='+lesson_status+'&t='+session_time;
  1442. params += '&suspend='+suspend_data+'&loc='+lesson_location;
  1443. params += '&core_exit='+lms_item_core_exit;
  1444. if ( olms.lms_lp_type==1) {
  1445. $.ajax({
  1446. type:"POST",
  1447. data: params,
  1448. url: "lp_ajax_save_item.php",
  1449. dataType: "script",
  1450. async: false
  1451. }
  1452. );
  1453. }
  1454. }
  1455. /**
  1456. * Save a SCORM item's variables, getting its SCORM values from
  1457. * updatable_vars_list. Takes interactions into account and considers whether
  1458. * variables have been modified or not.
  1459. * @param int ID of the learning path
  1460. * @param int ID of the user
  1461. * @param int ID of the view
  1462. * @param int ID of the item
  1463. * @return void
  1464. * @uses olms.updatable_vars_list
  1465. * @uses lp_ajax_save_item.php through an AJAX call
  1466. */
  1467. function xajax_save_item_scorm(lms_lp_id, lms_user_id, lms_view_id, lms_item_id) {
  1468. var is_interactions='false';
  1469. var params='';
  1470. params += 'lid='+lms_lp_id+'&uid='+lms_user_id+'&vid='+lms_view_id+'&iid='+lms_item_id;
  1471. var my_scorm_values=new Array();
  1472. my_scorm_values=process_scorm_values();
  1473. for (k=0;k<my_scorm_values.length;k++) {
  1474. if (my_scorm_values[k]=='cmi.core.session_time') {
  1475. params += '&t='+olms.session_time;
  1476. } else if (my_scorm_values[k]=='cmi.core.lesson_status' && olms.lesson_status!='') {
  1477. params += '&status='+olms.lesson_status;
  1478. } else if (my_scorm_values[k]=='cmi.core.score.raw') {
  1479. params += '&s='+olms.score;
  1480. } else if (my_scorm_values[k]=='cmi.core.score.max') {
  1481. params += '&max='+olms.max;
  1482. } else if (my_scorm_values[k]=='cmi.core.score.min') {
  1483. params += '&min='+olms.min;
  1484. } else if (my_scorm_values[k]=='cmi.core.lesson_location') {
  1485. params += '&loc='+olms.lesson_location;
  1486. } else if (my_scorm_values[k]=='cmi.completion_status') {
  1487. } else if (my_scorm_values[k]=='cmi.score.scaled') {
  1488. } else if (my_scorm_values[k]=='cmi.suspend_data') {
  1489. params += '&suspend='+olms.suspend_data;
  1490. } else if (my_scorm_values[k]=='cmi.completion_status') {
  1491. } else if (my_scorm_values[k]=='cmi.core.exit') {
  1492. params += '&core_exit='+olms.lms_item_core_exit;
  1493. }
  1494. if (my_scorm_values[k]=='interactions') {
  1495. is_interactions='true';
  1496. } else {
  1497. is_interactions='false';
  1498. }
  1499. }
  1500. if (is_interactions=='true') {
  1501. interact_string = '';
  1502. temp = '';
  1503. for (i in olms.interactions) {
  1504. interact_string += '&interact['+i+']=';
  1505. interact_temp = '[';
  1506. for (j in olms.interactions[i]) {
  1507. temp = olms.interactions[i][j];
  1508. temp = ''+temp; // if temp == 1 there are problems with indexOf and an integer number
  1509. //this fix when an interaction have ',' i.e: {a,b,c,d} is replace to {a@.|@b@.|@c@.|@d} see DT#4444
  1510. while(temp.indexOf(',') >= 0){
  1511. temp = temp.replace(',','@.|@');
  1512. };
  1513. interact_temp +=temp+',';
  1514. }
  1515. interact_temp = interact_temp.substr(0,(interact_temp.length-2)) + ']';
  1516. // interact_string += encodeURIComponent(interact_temp);
  1517. interact_string += interact_temp;
  1518. }
  1519. //interact_string = encodeURIComponent(interact_string.substr(0,(interact_string.length-1)));
  1520. params += interact_string;
  1521. is_interactions='false';
  1522. }
  1523. $.ajax({
  1524. type:"POST",
  1525. data: params,
  1526. url: "lp_ajax_save_item.php",
  1527. dataType: "script",
  1528. async: false
  1529. });
  1530. params='';
  1531. my_scorm_values = null;
  1532. }
  1533. /**
  1534. * Starts the timer with the server clock time.
  1535. * @return void
  1536. * @todo check the timer stuff really works
  1537. * @uses lp_ajax_start_timer.php
  1538. */
  1539. function xajax_start_timer() {
  1540. $.ajax({
  1541. type: "GET",
  1542. url: "lp_ajax_start_timer.php",
  1543. dataType: "script",
  1544. async: false
  1545. });
  1546. }
  1547. /**
  1548. * Save a specific item's objectives into the LMS through an Synch JAX call
  1549. * @param int ID of the learning path
  1550. * @param int ID of the user
  1551. * @param int ID of the view
  1552. * @param int ID of the item
  1553. * @param array SCO's recorded objectives
  1554. * @uses lp_ajax_save_objectives.php
  1555. */
  1556. function xajax_save_objectives(lms_lp_id,lms_user_id,lms_view_id,lms_item_id,item_objectives) {
  1557. params='';
  1558. params += 'lid='+lms_lp_id+'&uid='+lms_user_id+'&vid='+lms_view_id;
  1559. params += '&iid='+lms_item_id;
  1560. obj_string = '';
  1561. for (i in item_objectives){
  1562. obj_string += '&objectives['+i+']=';
  1563. obj_temp = '[';
  1564. for (j in item_objectives[i]) {
  1565. obj_temp += item_objectives[i][j]+',';
  1566. }
  1567. obj_temp = obj_temp.substr(0,(obj_temp.length-2)) + ']';
  1568. obj_string += encodeURIComponent(obj_temp);
  1569. }
  1570. params += obj_string;
  1571. $.ajax({
  1572. type: "POST",
  1573. data: params,
  1574. url: "lp_ajax_save_objectives.php",
  1575. dataType: "script",
  1576. async: false
  1577. });
  1578. }
  1579. /**
  1580. * Switch between two items through an AJAX call.
  1581. * @param int ID of the learning path
  1582. * @param int ID of the user
  1583. * @param int ID of the view
  1584. * @param int ID of the item
  1585. * @param int ID of the next item
  1586. * @uses lp_ajax_switch_item.php
  1587. */
  1588. function xajax_switch_item_details(lms_lp_id,lms_user_id,lms_view_id,lms_item_id,next_item) {
  1589. params = {
  1590. 'lid': lms_lp_id,
  1591. 'uid': lms_user_id,
  1592. 'vid': lms_view_id,
  1593. 'iid': lms_item_id,
  1594. 'next': next_item
  1595. };
  1596. $.ajax({
  1597. type: "POST",
  1598. data: params,
  1599. url: "lp_ajax_switch_item.php",
  1600. dataType: "script",
  1601. async: false
  1602. });
  1603. }
  1604. /**
  1605. * Switch between two items through an AJAX call, but only update the TOC and
  1606. * progress bar.
  1607. * @param int ID of the learning path
  1608. * @param int ID of the user
  1609. * @param int ID of the view
  1610. * @param int ID of the item
  1611. * @param int ID of the next item
  1612. * @uses lp_ajax_switch_toc.php
  1613. */
  1614. function xajax_switch_item_toc(lms_lp_id,lms_user_id,lms_view_id,lms_item_id,next_item) {
  1615. params = {
  1616. 'lid': lms_lp_id,
  1617. 'uid': lms_user_id,
  1618. 'vid': lms_view_id,
  1619. 'iid': lms_item_id,
  1620. 'next': next_item
  1621. };
  1622. $.ajax({
  1623. type: "POST",
  1624. data: params,
  1625. url: "lp_ajax_switch_item_toc.php",
  1626. dataType: "script",
  1627. async: true
  1628. });
  1629. }
  1630. /**
  1631. * Add the "addListeners" function to the "onload" event of the window and
  1632. * start the timer if necessary (asset)
  1633. */
  1634. addEvent(window,'load',addListeners,false);
  1635. if(olms.lms_lp_type==1 || olms.lms_item_type=='asset'){
  1636. xajax_start_timer();
  1637. }
  1638. /**
  1639. * Allow attach the glossary terms into html document of scorm. This has
  1640. * nothing to do with SCORM itself, and should not interfere w/ SCORM either.
  1641. * @param string automatic or manual values are allowed
  1642. */
  1643. function attach_glossary_into_scorm(type) {
  1644. var f = $('#content_id')[0];
  1645. //Prevents "f is undefined" javascript error
  1646. if (f == null) {
  1647. logit_lms('attach_glossary_into_scorm failed', 0);
  1648. return false;
  1649. }
  1650. //logit_lms('attach_glossary_into_scorm', 0);
  1651. var doc = f.contentWindow ? f.contentWindow.document :
  1652. f.contentDocument ? f.contentDocument : f.document;
  1653. var $frame_content = $('body',doc);
  1654. var my_text=$frame_content.html();
  1655. my_protocol = location.protocol;
  1656. my_pathname=location.pathname;
  1657. work_path = my_pathname.substr(0,my_pathname.indexOf('/courses/'));
  1658. if (type == 'automatic') {
  1659. $.ajax({
  1660. contentType: "application/x-www-form-urlencoded",
  1661. beforeSend: function(object) {
  1662. },
  1663. type: "POST",
  1664. url: my_protocol+"//"+location.host+work_path+"/main/glossary/glossary_ajax_request.php",
  1665. data: "glossary_data=true",
  1666. success: function(datas) {
  1667. if (datas.length==0) {
  1668. return false;
  1669. }
  1670. // glossary terms
  1671. data_terms=datas.split("[|.|_|.|-|.|]");
  1672. var complex_array = new Array();
  1673. var cp_complex_array = new Array();
  1674. for(i=0;i<data_terms.length;i++) {
  1675. specific_terms=data_terms[i].split("__|__|");
  1676. var real_term = specific_terms[1]; // glossary term
  1677. var real_code = specific_terms[0]; // glossary id
  1678. complex_array[real_code] = real_term;
  1679. cp_complex_array[real_code] = real_term;
  1680. }
  1681. complex_array.reverse();
  1682. for (var my_index in complex_array) {
  1683. n = complex_array[my_index];
  1684. if (n == null) {
  1685. n = '';
  1686. } else {
  1687. for (var cp_my_index in cp_complex_array) {
  1688. cp_data = cp_complex_array[cp_my_index];
  1689. if (cp_data == null) {
  1690. cp_data = '';
  1691. } else {
  1692. if (cp_data == n) {
  1693. my_index = cp_my_index;
  1694. }
  1695. }
  1696. }
  1697. //alert(n + ' ' + my_index);
  1698. $("iframe").contents().find('body').removeHighlight().highlight(n,my_index)
  1699. //logit_lms(n+ ' - '+my_index, 0);
  1700. }
  1701. }
  1702. var complex_array = new Array();
  1703. //mouse over event
  1704. $("iframe").contents().find("body .glossary-ajax").mouseover(function(){
  1705. random_id=Math.round(Math.random()*100);
  1706. div_show_id="div_show_id"+random_id;
  1707. div_content_id="div_content_id"+random_id;
  1708. $(this).append("<div id="+div_show_id+" ><div id="+div_content_id+">&nbsp;</div></div>");
  1709. $("iframe").contents().find("div#"+div_show_id).attr("style","display:inline;float:left;position:absolute;background-color:#F2F2F2;border-bottom: 1px solid #2E2E2E;border-right: 1px solid #2E2E2E;border-left: 1px solid #2E2E2E;border-top: 1px solid #2E2E2E;color:#305582;margin-left:5px;margin-right:5px;");
  1710. $("iframe").contents().find("div#"+div_content_id).attr("style","background-color:#F2F2F2;color:#0B3861;margin-left:8px;margin-right:8px;margin-top:5px;margin-bottom:5px;");
  1711. notebook_id=$(this).attr("name");
  1712. data_notebook=notebook_id.split("link");
  1713. my_glossary_id=data_notebook[1];
  1714. $.ajax({
  1715. contentType: "application/x-www-form-urlencoded",
  1716. beforeSend: function(content_object) {
  1717. $("iframe").contents().find("div#"+div_content_id).html("<img src="+my_protocol+"//"+location.host+work_path+"/main/inc/lib/javascript/indicator.gif />"); },
  1718. type: "POST",
  1719. url: my_protocol+"//"+location.host+work_path+"/main/glossary/glossary_ajax_request.php",
  1720. data: "glossary_id="+my_glossary_id,
  1721. success: function(data) {
  1722. $("iframe").contents().find("div#"+div_content_id).html(data);
  1723. }
  1724. });
  1725. });
  1726. //mouse out event
  1727. $("iframe").contents().find("body .glossary-ajax").mouseout(function(){
  1728. var current_element,
  1729. current_element=$(this);
  1730. div_show_id=current_element.find("div").attr("id");
  1731. $("iframe").contents().find("div#"+div_show_id).remove();
  1732. });
  1733. }
  1734. });
  1735. } else {
  1736. if ('manual') {
  1737. $("iframe").contents().find("body .glossary").mouseover(function(){
  1738. is_glossary_name = $(this).html();
  1739. random_id = Math.round(Math.random()*100);
  1740. div_show_id="div_show_id"+random_id;
  1741. div_content_id="div_content_id"+random_id;
  1742. //Fixes bug "No result found" message #3620
  1743. //$(this).append("<div id="+div_show_id+" ><div id="+div_content_id+">&nbsp;</div></div>");
  1744. $("iframe").contents().find("div#"+div_show_id).attr("style","display:inline;float:left;position:absolute;background-color:#F2F2F2;border-bottom: 1px solid #2E2E2E;border-right: 1px solid #2E2E2E;border-left: 1px solid #2E2E2E;border-top: 1px solid #2E2E2E;color:#305582;margin-left:5px;margin-right:5px;");
  1745. $("iframe").contents().find("div#"+div_content_id).attr("style","background-color:#F2F2F2;color:#0B3861;margin-left:8px;margin-right:8px;margin-top:5px;margin-bottom:5px;");
  1746. $.ajax({
  1747. contentType: "application/x-www-form-urlencoded",
  1748. beforeSend: function(objeto) {
  1749. $("iframe").contents().find("div#"+div_content_id).html("<img src="+my_protocol+"//"+location.host+work_path+"/main/inc/lib/javascript/indicator.gif />"); },
  1750. type: "POST",
  1751. url: my_protocol+"//"+location.host+work_path+"/main/glossary/glossary_ajax_request.php",
  1752. data: "glossary_name="+is_glossary_name,
  1753. success: function(data) {
  1754. $("iframe").contents().find("div#"+div_content_id).html(data);
  1755. }
  1756. });
  1757. });
  1758. $("iframe").contents().find("body .glossary").mouseout(function(){
  1759. current_element=$(this);
  1760. div_show_id=current_element.find("div").attr("id");
  1761. $("iframe").contents().find("div#"+div_show_id).remove();
  1762. });
  1763. }
  1764. }
  1765. }