5 require_once(
"./Services/YUI/classes/class.ilYuiUtil.php");
6 require_once(
"./Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModule.php");
26 'user_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>user_id),
27 'learner_name' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>learner_name),
28 'slm_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>slm_id),
29 'mode' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>c_mode),
30 'credit' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>credit),
33 'accesscount' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>accesscount),
34 'accessduration' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>accessduration),
35 'accessed' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>accessed),
36 'activityAbsoluteDuration' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>activityabsduration),
37 'activityAttemptCount' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>activityattemptcount),
38 'activityExperiencedDuration' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>activityexpduration),
39 'activityProgressStatus' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>activityprogstatus),
40 'attemptAbsoluteDuration' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>attemptabsduration),
41 'attemptCompletionAmount' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>attemptcomplamount),
42 'attemptCompletionStatus' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>attemptcomplstatus),
43 'attemptExperiencedDuration' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>attemptexpduration),
44 'attemptProgressStatus' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>attemptprogstatus),
45 'audio_captioning' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>audio_captioning),
46 'audio_level' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>audio_level),
47 'availableChildren' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>availablechildren),
48 'cmi_node_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_node_id),
49 'completion' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>completion),
50 'completion_status' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>completion_status),
51 'completion_threshold' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>completion_threshold),
52 'cp_node_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cp_node_id),
53 'created' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>created),
54 'credit' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>credit),
55 'delivery_speed' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>delivery_speed),
56 'entry' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_entry),
57 'exit' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_exit),
58 'language' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_language),
59 'launch_data' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>launch_data),
60 'learner_name' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>learner_name),
61 'location' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>location),
62 'max' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_max),
63 'min' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_min),
64 'mode' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_mode),
65 'modified' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>modified),
66 'progress_measure' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>progress_measure),
67 'raw' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_raw),
68 'scaled' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>scaled),
69 'scaled_passing_score' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>scaled_passing_score),
70 'session_time' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>session_time),
71 'success_status' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>success_status),
72 'suspend_data' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>suspend_data),
73 'total_time' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>total_time),
74 'user_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>user_id),
77 'cmi_comment_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_comment_id),
78 'cmi_node_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_node_id),
79 'comment' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_comment),
80 'timestamp' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_timestamp),
81 'location' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>location),
82 'sourceIsLMS' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>sourceislms),
84 'correct_response' => array(
85 'cmi_correct_response_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_correct_resp_id),
86 'cmi_interaction_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_interaction_id),
87 'pattern' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>pattern),
89 'interaction' => array(
90 'cmi_interaction_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_interaction_id),
91 'cmi_node_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_node_id),
92 'description' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>description),
93 'id' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>
id),
94 'latency' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>latency),
95 'learner_response' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>learner_response),
96 'result' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>result),
97 'timestamp' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_timestamp),
98 'type' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_type),
99 'weighting' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>weighting),
101 'objective' => array(
102 'cmi_interaction_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_interaction_id),
103 'cmi_node_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_node_id),
104 'cmi_objective_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_objective_id),
105 'completion_status' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>completion_status),
106 'description' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>description),
107 'id' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>
id),
108 'max' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_max),
109 'min' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_min),
110 'raw' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_raw),
111 'scaled' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>scaled),
112 'progress_measure' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>progress_measure),
113 'success_status' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>success_status),
114 'scope' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>scope),
135 $this->userId =
$GLOBALS[
'USER'][
'usr_id'];
137 $this->packageId = (int)
$_REQUEST[
'packageId'];
138 $this->jsMode = strpos($_SERVER[
'HTTP_ACCEPT'],
'text/javascript')!==
false;
150 $this->ref_id =
$_GET[
'ref_id'];
151 $this->userId=$ilUser->getID();
153 if (
$_GET[
'envEditor'] != null) {
154 $this->envEditor =
$_GET[
'envEditor'];
156 $this->envEditor = 0;
168 $next_class = $this->ctrl->getNextClass($this);
169 $cmd = $this->ctrl->getCmd();
171 if (!$ilAccess->checkAccess(
"read",
"",
$_GET[
"ref_id"]))
173 $ilias->raiseError($lng->txt(
"permission_denied"), $ilias->error_obj->WARNING);
204 case 'getGobjective':
208 case 'getSharedData':
212 case 'setSharedData':
218 if ($_SERVER[
'REQUEST_METHOD']==
'POST') {
236 case 'liveLogContent':
249 case 'scormPlayerUnload':
262 $js_data = file_get_contents(
"./Modules/Scorm2004/scripts/buildrte/rte.js");
263 if (self::ENABLE_GZIP==1) {
264 ob_start(
"ob_gzhandler");
265 header(
'Content-Type: text/javascript; charset=UTF-8');
267 header(
'Content-Type: text/javascript; charset=UTF-8');
275 $webdir=str_replace(
"/ilias.php",
"",$_SERVER[
"SCRIPT_NAME"]);
277 $lm_dir=$webdir.
"/".
ILIAS_WEB_DIR.
"/".$this->ilias->client_id .
"/lm_data".
"/lm_".$this->packageId;
288 if ($this->slm->getSession()) {
289 $session_timeout = (int)($ilias->ini->readVariable(
"session",
"expire"))/2;
291 $session_timeout = 0;
296 'cp_url' =>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=cp&ref_id='.
$_GET[
"ref_id"],
297 'cmi_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=cmi&ref_id='.
$_GET[
"ref_id"],
298 'get_adldata_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=getSharedData&ref_id='.
$_GET[
"ref_id"],
299 'set_adldata_url' =>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=setSharedData&ref_id=' .
$_GET[
"ref_id"],
300 'adlact_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=adlact&ref_id='.
$_GET[
"ref_id"],
301 'specialpage_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=specialPage&ref_id='.
$_GET[
"ref_id"],
302 'suspend_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=suspend&ref_id='.
$_GET[
"ref_id"],
303 'get_suspend_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=getSuspend&ref_id='.
$_GET[
"ref_id"],
305 'gobjective_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=gobjective&ref_id='.
$_GET[
"ref_id"],
306 'get_gobjective_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=getGobjective&ref_id='.
$_GET[
"ref_id"],
307 'ping_url' =>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=pingSession&ref_id='.
$_GET[
"ref_id"],
308 'scorm_player_unload_url' =>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=scormPlayerUnload&ref_id='.
$_GET[
"ref_id"],
310 'learner_id' => (
string) $ilUser->getID(),
311 'course_id' => (string) $this->packageId,
312 'learner_name' => $ilUser->getFirstname().
" ".$ilUser->getLastname(),
314 'credit' =>
'credit',
315 'auto_review' => $this->slm->getAutoReview(),
316 'hide_navig' => $this->slm->getHideNavig(),
317 'debug' => $this->slm->getDebug(),
319 'session_ping' => $session_timeout,
320 'envEditor' => $this->envEditor,
321 'post_log_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=postLogEntry&ref_id='.
$_GET[
"ref_id"],
322 'livelog_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=liveLogContent&ref_id='.
$_GET[
"ref_id"],
325 'sequencing_enabled' => $this->slm->getSequencing(),
326 'interactions_storable' => $this->slm->getInteractions(),
327 'objectives_storable' => $this->slm->getObjectives(),
328 'comments_storable' => $this->slm->getComments(),
329 'time_from_lms' => $this->slm->getTime_from_lms(),
330 'auto_last_visited' => $this->slm->getAuto_last_visited(),
331 'checkSetValues' => $this->slm->getCheck_values()
334 $status[
'saved_global_status']=
"";
335 $status[
'last_visited']=null;
336 if($this->slm->getAuto_last_visited()) $status[
'last_visited']=$this->
get_last_visited($this->packageId, $ilUser->getID());
337 $config[
'status'] = $status;
340 $langstrings[
'btnStart'] = $lng->txt(
'scplayer_start');
341 $langstrings[
'btnExit'] = $lng->txt(
'scplayer_exit');
342 $langstrings[
'btnExitAll'] = $lng->txt(
'scplayer_exitall');
343 $langstrings[
'btnSuspendAll'] = $lng->txt(
'scplayer_suspendall');
344 $langstrings[
'btnPrevious'] = $lng->txt(
'scplayer_previous');
345 $langstrings[
'btnContinue'] = $lng->txt(
'scplayer_continue');
346 $langstrings[
'btnhidetree']=$lng->txt(
'scplayer_hidetree');
347 $langstrings[
'btnshowtree']=$lng->txt(
'scplayer_showtree');
348 $langstrings[
'linkexpandTree']=$lng->txt(
'scplayer_expandtree');
349 $langstrings[
'linkcollapseTree']=$lng->txt(
'scplayer_collapsetree');
350 $config[
'langstrings'] = $langstrings;
354 $this->tpl =
new ilTemplate(
"tpl.scorm2004.player.html",
true,
true,
"Modules/Scorm2004");
357 $rte_css = $this->slm->getDataDirectory().
"/ilias_css_4_2/css/style.css";
358 if (is_file($rte_css))
360 $this->tpl->setCurrentBlock(
"rte_css");
361 $this->tpl->setVariable(
"RTE_CSS", $rte_css);
362 $this->tpl->parseCurrentBlock();
365 $this->tpl->setVariable(
'JSON_LANGSTRINGS', json_encode($langstrings));
366 include_once(
"./Services/YUI/classes/class.ilYuiUtil.php");
368 $this->tpl->setVariable(
'TREE_JS',
"./Services/UIComponent/NestedList/js/ilNestedList.js");
369 $this->tpl->setVariable($langstrings);
370 $this->tpl->setVariable(
'DOC_TITLE',
'ILIAS SCORM 2004 Player');
372 $this->tpl->setVariable(
'JS_DATA', json_encode($config));
373 list($tsfrac, $tsint) = explode(
' ', microtime());
374 $this->tpl->setVariable(
'TIMESTAMP', sprintf(
'%d%03d', $tsint, 1000*(
float)$tsfrac));
375 $this->tpl->setVariable(
'BASE_DIR',
'./Modules/Scorm2004/');
376 $this->tpl->setVariable(
'TXT_COLLAPSE',$lng->txt(
'scplayer_collapsetree'));
377 if ($this->slm->getDebug()) {
378 $this->tpl->setVariable(
'TXT_DEBUGGER',$lng->txt(
'scplayer_debugger'));
379 $this->tpl->setVariable(
'DEBUG_URL',
"PopupCenter('ilias.php?baseClass=ilSAHSPresentationGUI&cmd=debugGUI&ref_id=".
$_GET[
"ref_id"].
"','Debug',800,600);");
381 $this->tpl->setVariable(
'TXT_DEBUGGER',
'');
382 $this->tpl->setVariable(
'DEBUG_URL',
'');
386 $this->tpl->setVariable(
'INLINE_CSS', ilSCORM13Player::getInlineCss());
389 if ($this->slm->getCacheDeactivated()){
390 $this->tpl->setVariable(
'JS_SCRIPTS',
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=getRTEjs&ref_id='.
$_GET[
"ref_id"]);
392 $this->tpl->setVariable(
'JS_SCRIPTS',
'./Modules/Scorm2004/scripts/buildrte/rte-min.js');
396 if ($this->slm->getNoMenu()==
"y") {
397 $this->tpl->setVariable(
"VAL_DISPLAY",
"style=\"display:none;\"");
399 $this->tpl->setVariable(
"VAL_DISPLAY",
"");
406 header(
'Content-Type: text/html; charset=utf-8');
407 echo($lng->txt(
"cont_sc_max_attempt_exceed"));
419 $this->tpl->show(
"DEFAULT",
false);
427 $is_tpl =
new ilTemplate(
"tpl.scorm2004.inlinecss.html",
true,
true,
"Modules/Scorm2004");
430 $is_tpl->setVariable(
'IC_NOTATTEMPTED',
ilUtil::getImagePath(
"scorm/not_attempted_s.png",
false));
436 return $is_tpl->get();
443 $res = $ilDB->queryF(
444 'SELECT jsdata FROM cp_package WHERE obj_id = %s',
446 array($this->packageId)
448 $packageData = $ilDB->fetchAssoc(
$res);
450 $jsdata = $packageData[
'jsdata'];
451 if (!$jsdata) $jsdata =
'null';
454 header(
'Content-Type: text/javascript; charset=UTF-8');
459 header(
'Content-Type: text/plain; charset=UTF-8');
460 $jsdata = json_decode($jsdata);
469 $res = $ilDB->queryF(
470 'SELECT activitytree FROM cp_package WHERE obj_id = %s',
472 array($this->packageId)
476 $activitytree =
$data[
'activitytree'];
480 $activitytree =
'null';
484 header(
'Content-Type: text/javascript; charset=UTF-8');
485 print($activitytree);
489 header(
'Content-Type: text/plain; charset=UTF-8');
490 $activitytree = json_decode($activitytree);
491 print_r($activitytree);
498 header(
'Content-Type: text/plain; charset=UTF-8');
505 $data = json_decode(is_string(
$data) ?
$data : file_get_contents(
'php://input'));
509 include_once(
"./Modules/Scorm2004/classes/class.ilSCORM2004Tracking.php");
512 header(
'Content-Type: text/plain; charset=UTF-8');
519 $res = $ilDB->queryF(
520 'SELECT global_to_system FROM cp_package WHERE obj_id = %s',
522 array($this->packageId)
526 $gystem =
$data[
'global_to_system'];
539 $res = $ilDB->queryF(
540 'SELECT data FROM cp_suspend WHERE obj_id = %s AND user_id = %s',
541 array(
'integer',
'integer'),
542 array($this->packageId, $ilUser->getId())
546 $suspend_data =
$data[
'data'];
549 header(
'Content-Type: text/javascript; charset=UTF-8');
550 print($suspend_data);
554 header(
'Content-Type: text/plain; charset=UTF-8');
555 $suspend_data = json_decode($suspend_data);
556 print_r($suspend_data);
561 'DELETE FROM cp_suspend WHERE obj_id = %s AND user_id = %s',
562 array(
'integer',
'integer'),
563 array($this->packageId, $ilUser->getId())
571 $res = $ilDB->queryF(
572 'SELECT * FROM cp_suspend WHERE obj_id = %s AND user_id = %s',
573 array(
'integer',
'integer'),
574 array($this->packageId, $ilUser->getId())
577 if(!$ilDB->numRows(
$res))
579 $ilDB->insert(
'cp_suspend', array(
580 'data' => array(
'clob', file_get_contents(
'php://input')),
581 'obj_id' => array(
'integer', $this->packageId),
582 'user_id' => array(
'integer', $ilUser->getId())
587 $ilDB->update(
'cp_suspend',
589 'data' => array(
'clob', file_get_contents(
'php://input'))
592 'obj_id' => array(
'integer', $this->packageId),
593 'user_id' => array(
'integer', $ilUser->getId())
604 $g_data =
new stdClass();
606 $global_to_system = 1;
608 $res = $ilDB->queryF(
'SELECT global_to_system FROM cp_package WHERE obj_id = %s',
610 array($this->packageId)
614 $global_to_system =
$data[
'global_to_system'];
617 $query =
'SELECT objective_id, scope_id, satisfied, measure, user_id,
618 score_min, score_max, score_raw, completion_status,
620 .
'FROM cmi_gobjective, cp_node, cp_mapinfo '
621 .
'WHERE (cmi_gobjective.objective_id <> %s AND cmi_gobjective.status IS NULL '
622 .
'AND cp_node.slm_id = %s AND cp_node.nodename = %s '
623 .
'AND cp_node.cp_node_id = cp_mapinfo.cp_node_id '
624 .
'AND cmi_gobjective.objective_id = cp_mapinfo.targetobjectiveid) '
625 .
'GROUP BY objective_id, scope_id, satisfied, measure, user_id,
626 score_min, score_max, score_raw, completion_status,
628 $res = $ilDB->queryF(
630 array(
'text',
'integer',
'text'),
631 array(
'-course_overall_status-', $this->packageId,
'mapInfo')
633 while(
$row = $ilDB->fetchAssoc(
$res))
635 if (($global_to_system == 1 &&
$row[
'scope_id'] == 0) || ($global_to_system == 0 &&
$row[
'scope_id'] ==
$this->packageId))
637 $learner =
$row[
'user_id'];
638 $objective_id =
$row[
'objective_id'];
639 if(
$row[
'scope_id'] == 0)
645 $scope =
$row[
'scope_id'];
648 if(
$row[
'satisfied'] != NULL)
650 $toset =
$row[
'satisfied'];
651 $g_data->{
"satisfied"}->{$objective_id}->{$learner}->{$scope} = $toset;
654 if(
$row[
'measure'] != NULL)
656 $toset =
$row[
'measure'];
657 $g_data->{
"measure"}->{$objective_id}->{$learner}->{$scope} = $toset;
660 if(
$row[
'score_raw'] != NULL)
662 $toset =
$row[
'score_raw'];
663 $g_data->{
"score_raw"}->{$objective_id}->{$learner}->{$scope} = $toset;
666 if(
$row[
'score_min'] != NULL)
668 $toset =
$row[
'score_min'];
669 $g_data->{
"score_min"}->{$objective_id}->{$learner}->{$scope} = $toset;
672 if(
$row[
'score_max'] != NULL)
674 $toset =
$row[
'score_max'];
675 $g_data->{
"score_max"}->{$objective_id}->{$learner}->{$scope} = $toset;
678 if(
$row[
'progress_measure'] != NULL)
680 $toset =
$row[
'progress_measure'];
681 $g_data->{
"progress_measure"}->{$objective_id}->{$learner}->{$scope} = $toset;
684 if(
$row[
'completion_status'] != NULL)
686 $toset =
$row[
'completion_status'];
687 $g_data->{
"completion_status"}->{$objective_id}->{$learner}->{$scope} = $toset;
692 $gobjective_data = json_encode($g_data);
693 $ilLog->write(
"SCORM2004 gobjective_data=".$gobjective_data);
696 header(
'Content-Type: text/javascript; charset=UTF-8');
697 print($gobjective_data);
701 header(
'Content-Type: text/plain; charset=UTF-8');
702 $gobjective_data = json_decode($gobjective_data);
703 print_r($gobjective_data);
708 public function writeGObjective($g_data)
711 $ilLog->write(
"SCORM2004 writeGObjective");
712 $user = $ilUser->getId();
713 $package = $this->packageId;
722 $rows_to_insert = Array();
724 foreach($g_data as $key => $value)
726 $ilLog->write(
"SCORM2004 writeGObjective -key: ".$key);
730 foreach($value as $skey => $svalue)
732 $ilLog->write(
"SCORM2004 writeGObjective -skey: ".$skey);
734 if($g_data->$key->$skey->$user->$package)
736 $o_value = $g_data->$key->$skey->$user->$package;
742 $o_value = $g_data->$key->$skey->$user->{
"null"};
748 $objective_id = $skey;
750 $dbuser = $ilUser->getId();
756 $completed = $g_data->$key->$skey->$user->{completed};
757 $measure = $g_data->$key->$skey->$user->{measure};
758 $satisfied = $g_data->$key->$skey->$user->{satisfied};
759 $obj =
'-course_overall_status-';
760 $pkg_id = $this->packageId;
762 $res = $ilDB->queryF(
'
763 SELECT user_id FROM cmi_gobjective
764 WHERE objective_id =%s
767 array(
'text',
'integer',
'integer'),
768 array($obj, $dbuser, $pkg_id)
770 $ilLog->write(
"SCORM2004 Count is: ".$ilDB->numRows(
$res));
771 if(!$ilDB->numRows(
$res))
774 INSERT INTO cmi_gobjective
775 (user_id, status, scope_id, measure, satisfied, objective_id)
776 VALUES (%s, %s, %s, %s, %s, %s)',
777 array(
'integer',
'text',
'integer',
'text',
'text',
'text'),
778 array($dbuser, $completed, $pkg_id, $measure, $satisfied, $obj)
780 $ilLog->write(
"SCORM2004 cmi_gobjective Insert status=".$completed.
" scope_id=".$pkg_id.
" measure=".$measure.
" satisfied=".$satisfied.
" objective_id=".$obj);
785 UPDATE cmi_gobjective
789 WHERE objective_id = %s
792 array(
'text',
'text',
'text',
'text',
'integer',
'integer'),
793 array($completed, $measure, $satisfied, $obj, $dbuser, $pkg_id)
795 $ilLog->write(
"SCORM2004 cmi_gobjective Update status=".$completed.
" scope_id=".$pkg_id.
" measure=".$measure.
" satisfied=".$satisfied.
" objective_id=".$obj);
800 if($rows_to_insert[$objective_id] == NULL)
802 $rows_to_insert[$objective_id] = Array();
804 $rows_to_insert[$objective_id][$key] = $toset;
811 $res = $ilDB->queryF(
"SELECT global_to_system
815 array($this->packageId)
818 $scope_id = ($ilDB->fetchObject(
$res)->global_to_system) ? 0 : $this->packageId;
821 $existing_key_template =
"";
822 foreach(array_keys($rows_to_insert) as $obj_id)
824 $existing_key_template .=
"'{$obj_id}',";
827 $existing_key_template = substr($existing_key_template, 0, strlen($existing_key_template) - 1);
828 $existing_keys = Array();
830 if($existing_key_template !=
"")
833 $res = $ilDB->queryF(
"SELECT objective_id
837 AND objective_id IN ($existing_key_template)",
838 array(
'integer',
'integer'),
839 array($this->userId, $scope_id)
842 while(
$row = $ilDB->fetchAssoc(
$res))
844 $existing_keys[] =
$row[
'objective_id'];
848 foreach($rows_to_insert as $obj_id => $vals)
850 if(in_array($obj_id, $existing_keys))
852 $ilDB->manipulateF(
"UPDATE cmi_gobjective
858 completion_status=%s,
860 WHERE objective_id = %s
864 array(
'text',
'text',
'text',
'text',
'text',
'text',
865 'text',
'text',
'integer',
'integer'),
867 array($vals[
'satisfied'], $vals[
"measure"], $vals[
"score_raw"],
868 $vals[
"score_min"], $vals[
"score_max"],
869 $vals[
"completion_status"], $vals[
"progress_measure"],
870 $obj_id, $this->userId, $scope_id)
874 $ilDB->manipulateF(
"INSERT INTO cmi_gobjective
875 (user_id, satisfied, measure, scope_id, status, objective_id,
876 score_raw, score_min, score_max, progress_measure, completion_status)
877 VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
880 array(
'integer',
'text',
'text',
'integer',
'text',
'text',
881 'text',
'text',
'text',
'text',
'text'),
883 array($this->userId, $vals[
'satisfied'], $vals[
'measure'],
884 $scope_id, NULL, $obj_id, $vals[
'score_raw'],
885 $vals[
'score_min'], $vals[
'score_max'],
886 $vals[
'progress_measure'], $vals[
'completion_status'])
901 public function readSharedData($sco_node_id)
905 $dataStores = array(
"data" => array(),
906 "permissions" => array());
907 $readPermissions = array();
909 $query =
'SELECT target_id, read_shared_data, write_shared_data '
911 .
'WHERE slm_id = %s '
912 .
'AND sco_node_id = %s '
913 .
'GROUP BY target_id, read_shared_data, write_shared_data';
916 $res = $ilDB->queryF(
918 array(
'integer',
'integer'),
919 array($this->packageId, $sco_node_id)
924 while(
$row = $ilDB->fetchAssoc(
$res))
926 $storeVal = (
$row[
'read_shared_data'] == 0 &&
$row[
'write_shared_data'] == 1 )
930 $dataStores[
"data"][
$row[
'target_id']] = array(
"store" => $storeVal,
931 "readSharedData" => $row[
'read_shared_data'],
932 "writeSharedData" => $row[
'write_shared_data']);
933 $dataStores[
"readPermissions"][$row[
'target_id']] = $row[
'read_shared_data'];
936 if(count($dataStores) < 1)
942 else if ($dataStores[
"readPermissions"] != null && array_sum($dataStores[
"readPermissions"]) != 0)
949 $params = array(
"types" => array(
"integer",
"integer"),
950 "values" => array($this->userId, $this->packageId));
956 foreach($dataStores[
"data"] as $key => $val)
958 if($dataStores[
"readPermissions"][$key] == 1
959 && $dataStores[
"data"][$key][
"store"] !=
'notWritten')
961 $params[
"types"][] =
"text";
962 $params[
"values"][] = $key;
963 $paramTemplate .=
'%s, ';
968 $paramTemplate = substr($paramTemplate, 0, strlen($paramTemplate) - 2);
971 $query =
'SELECT target_id, store '
972 .
'FROM adl_shared_data '
973 .
'WHERE user_id = %s '
975 .
'AND target_id IN (' . $paramTemplate .
')';
978 $res = $ilDB->queryF(
984 while(
$row = $ilDB->fetchAssoc(
$res))
986 $dataStores[
"data"][
$row[
'target_id']][
"store"] = $row[
'store'];
990 header(
'Content-Type: text/javascript; charset=UTF-8');
992 echo json_encode($dataStores[
"data"]);
995 public function writeSharedData($sco_node_id)
998 $g_data = json_decode(file_get_contents(
'php://input'));
1001 $query =
'SELECT dm.target_id, sd.store '
1002 .
'FROM cp_datamap dm '
1003 .
'LEFT JOIN adl_shared_data sd '
1004 .
'ON(dm.slm_id = sd.slm_id AND dm.target_id = sd.target_id) '
1005 .
'WHERE sco_node_id = %s '
1006 .
'AND dm.slm_id = %s '
1007 .
'AND write_shared_data = 1 '
1008 .
'AND user_id = %s';
1010 $res = $ilDB->QueryF(
1012 array(
'integer',
'integer',
'integer'),
1013 array($sco_node_id, $this->packageId, $this->userId)
1016 $dataStores = array();
1017 $originalVals = array();
1018 while(
$row = $ilDB->fetchAssoc(
$res))
1020 $id =
$row[
'target_id'];
1021 $dataStores[$id] = $g_data->{$id};
1022 $originalVals[$id] =
$row[
'store'];
1027 foreach($g_data as $key => $obj)
1031 if(array_key_exists($key, $dataStores) )
1033 if($obj ==
'notWritten')
continue;
1035 $query =
'UPDATE adl_shared_data '
1037 .
'WHERE user_id = %s '
1038 .
'AND target_id = %s '
1039 .
'AND slm_id = %s ';
1043 array(
'text',
'integer',
'text',
'integer'),
1044 array($dataStores[$key], $this->userId, $key, $this->packageId)
1049 $res = $ilDB->queryF(
1050 'SELECT write_shared_data '
1051 .
'FROM cp_datamap '
1052 .
'WHERE target_id = %s '
1053 .
'AND slm_id = %s '
1054 .
'AND sco_node_id = %s',
1055 array(
'text',
'integer',
'integer'),
1056 array($key, $this->packageId, $sco_node_id));
1059 if(
$row[
"write_shared_data"] != 1)
1065 $res = $ilDB->manipulateF(
1066 'INSERT INTO adl_shared_data VALUES (%s, %s, %s, %s)',
1067 array(
'integer',
'integer',
'text',
'text'),
1068 array($this->packageId, $this->userId, $key, $obj));
1080 $specialpages = array (
1081 "_COURSECOMPLETE_" =>
"seq_coursecomplete",
1082 "_ENDSESSION_" =>
"seq_endsession",
1083 "_SEQBLOCKED_" =>
"seq_blocked",
1084 "_NOTHING_" =>
"seq_nothing",
1085 "_ERROR_" =>
"seq_error",
1086 "_DEADLOCK_" =>
"seq_deadlock",
1087 "_INVALIDNAVREQ_" =>
"seq_invalidnavreq",
1088 "_SEQABANDON_" =>
"seq_abandon",
1089 "_SEQABANDONALL_" =>
"seq_abandonall",
1090 "_TOC_" =>
"seq_toc"
1093 $this->tpl =
new ilTemplate(
"tpl.scorm2004.specialpages.html",
false,
false,
"Modules/Scorm2004");
1095 $this->tpl->setVariable(
'TXT_SPECIALPAGE',$lng->txt($specialpages[$this->page]));
1096 if ($this->page!=
"_TOC_" && $this->page!=
"_SEQABANDON_" && $this->page!=
"_SEQABANDONALL_" ) {
1097 $this->tpl->setVariable(
'CLOSE_WINDOW',$lng->txt(
'seq_close'));
1099 $this->tpl->setVariable(
'CLOSE_WINDOW',
"");
1101 $this->tpl->show(
"DEFAULT",
false);
1105 public function fetchCMIData()
1107 $data = $this->getCMIData($this->userId, $this->packageId);
1110 header(
'Content-Type: text/javascript; charset=UTF-8');
1111 print(json_encode(
$data));
1115 header(
'Content-Type: text/plain; charset=UTF-8');
1116 print(var_export(
$data,
true));
1120 public function persistCMIData(
$data = null)
1124 if ($this->slm->getDefaultLessonMode() ==
"browse") {
return;}
1126 $data = json_decode(is_string(
$data) ?
$data : file_get_contents(
'php://input'));
1127 $ilLog->write(
"SCORM2004 Got data:". file_get_contents(
'php://input'));
1129 $return = $this->setCMIData($this->userId, $this->packageId,
$data, $this->ref_id);
1131 $ilLog->write(
"SCORM2004 return of persistCMIData: ".json_encode($return));
1135 header(
'Content-Type: text/javascript; charset=UTF-8');
1136 print(json_encode($return));
1140 header(
'Content-Type: text/html; charset=UTF-8');
1141 print(var_export($return,
true));
1149 private function normalizeFields($table, &$node)
1152 foreach (self::$schema[$table] as $k => $v)
1155 if (isset($value) && is_string($v) && !preg_match($v, $value))
1162 private function getCMIData($userId, $packageId)
1168 'schema' => array(),
1172 foreach(self::$schema as $k => &$v)
1174 $result[
'schema'][$k] = array_keys($v);
1179 $q =
'SELECT cmi_node.*
1181 INNER JOIN cp_node ON cmi_node.cp_node_id = cp_node.cp_node_id
1182 WHERE cmi_node.user_id = %s
1183 AND cp_node.slm_id = %s';
1190 if ($this->slm->getComments()) $q =
'SELECT
1191 cmi_comment.cmi_comment_id,
1192 cmi_comment.cmi_node_id,
1193 cmi_comment.c_comment,
1194 cmi_comment.c_timestamp,
1195 cmi_comment.location,
1196 cmi_comment.sourceislms
1198 INNER JOIN cmi_node ON cmi_node.cmi_node_id = cmi_comment.cmi_node_id
1199 INNER JOIN cp_node ON cp_node.cp_node_id = cmi_node.cp_node_id
1200 WHERE cmi_node.user_id = %s
1201 AND cp_node.slm_id = %s
1202 ORDER BY cmi_comment.cmi_comment_id';
1207 case "correct_response":
1210 if ($this->slm->getInteractions()) $q =
'SELECT cmi_correct_response.*
1211 FROM cmi_correct_response
1212 INNER JOIN cmi_interaction
1213 ON cmi_interaction.cmi_interaction_id = cmi_correct_response.cmi_interaction_id
1214 INNER JOIN cmi_node ON cmi_node.cmi_node_id = cmi_interaction.cmi_node_id
1215 INNER JOIN cp_node ON cp_node.cp_node_id = cmi_node.cp_node_id
1216 WHERE cmi_node.user_id = %s
1217 AND cp_node.slm_id = %s
1218 ORDER BY cmi_correct_response.cmi_correct_resp_id';
1225 if ($this->slm->getInteractions()) $q =
'SELECT
1226 cmi_interaction.cmi_interaction_id,
1227 cmi_interaction.cmi_node_id,
1228 cmi_interaction.description,
1230 cmi_interaction.latency,
1231 cmi_interaction.learner_response,
1232 cmi_interaction.result,
1233 cmi_interaction.c_timestamp,
1234 cmi_interaction.c_type,
1235 cmi_interaction.weighting
1236 FROM cmi_interaction
1237 INNER JOIN cmi_node ON cmi_node.cmi_node_id = cmi_interaction.cmi_node_id
1238 INNER JOIN cp_node ON cp_node.cp_node_id = cmi_node.cp_node_id
1239 WHERE cmi_node.user_id = %s
1240 AND cp_node.slm_id = %s
1241 ORDER BY cmi_interaction.cmi_interaction_id';
1247 if ($this->slm->getObjectives()) $q =
'SELECT
1248 cmi_objective.cmi_interaction_id,
1249 cmi_objective.cmi_node_id,
1250 cmi_objective.cmi_objective_id,
1251 cmi_objective.completion_status,
1252 cmi_objective.description,
1254 cmi_objective.c_max,
1255 cmi_objective.c_min,
1256 cmi_objective.c_raw,
1257 cmi_objective.scaled,
1258 cmi_objective.progress_measure,
1259 cmi_objective.success_status,
1262 INNER JOIN cmi_node ON cmi_node.cmi_node_id = cmi_objective.cmi_node_id
1263 INNER JOIN cp_node ON cp_node.cp_node_id = cmi_node.cp_node_id
1264 WHERE cmi_node.user_id = %s
1265 AND cp_node.slm_id = %s
1266 ORDER BY cmi_objective.cmi_objective_id';
1271 $q =
'SELECT usr_data.usr_id user_id,
1272 CONCAT(CONCAT(COALESCE(usr_data.firstname, \'\'), \' \'), COALESCE(usr_data.lastname, \'\')) learner_name,
1273 sahs_lm.id slm_id , sahs_lm.default_lesson_mode "mode", sahs_lm.credit
1274 FROM usr_data, cp_package
1275 INNER JOIN sahs_lm ON cp_package.obj_id = sahs_lm.id
1276 WHERE usr_data.usr_id = %s
1277 AND sahs_lm.id = %s';
1283 $result[
'data'][$k] = array();
1285 $types = array(
'integer',
'integer');
1286 $values = array($userId, $packageId);
1287 $res = $ilDB->queryF($q, $types, $values);
1289 while(
$row = $ilDB->fetchAssoc(
$res))
1291 $tmp_result = array();
1292 foreach(
$row as $key => $value)
1294 if ($k ==
"comment" && $key ==
"c_timestamp" && strpos($value,
' ')==10) $value = str_replace(
' ',
'T',$value);
1295 $tmp_result[] = $value;
1296 if($k==
"node" && $key==
"additional_tables" && $i_check<$value){
1301 $result[
'data'][$k][] = $tmp_result;
1308 private function setCMIData($userId, $packageId,
$data)
1316 $i_check=
$data->i_check;
1317 $i_set=
$data->i_set;
1318 $b_node_update=
false;
1320 $a_map_cmi_interaction_id=array();
1322 $tables = array(
'node',
'comment',
'interaction',
'objective',
'correct_response');
1324 foreach($tables as $table)
1326 if (!is_array(
$data->$table))
continue;
1328 $ilLog->write(
"SCORM: setCMIData, table -".$table.
"-");
1333 $ilLog->write(
"Checking table: ".$table);
1343 $res = $ilDB->queryF(
1344 'SELECT cmi_node_id FROM cmi_node WHERE cp_node_id = %s and user_id = %s',
1345 array(
'integer',
'integer'),
1346 array($row[19],$userId)
1348 $rowtmp=$ilDB->fetchAssoc(
$res);
1349 $cmi_node_id=$rowtmp[
'cmi_node_id'];
1350 if ($cmi_node_id!=null) $b_node_update=
true;
1352 $cmi_node_id = $ilDB->nextId(
'cmi_node');
1353 $b_node_update=
false;
1355 $ilLog->write(
"setCMIdata with cmi_node_id = ".$cmi_node_id);
1357 'accesscount' => array(
'integer', $row[0]),
1358 'accessduration' => array(
'text', $row[1]),
1359 'accessed' => array(
'text', $row[2]),
1360 'activityabsduration' => array(
'text', $row[3]),
1361 'activityattemptcount' => array(
'integer', $row[4]),
1362 'activityexpduration' => array(
'text', $row[5]),
1363 'activityprogstatus' => array(
'integer', $row[6]),
1364 'attemptabsduration' => array(
'text', $row[7]),
1365 'attemptcomplamount' => array(
'float', $row[8]),
1366 'attemptcomplstatus' => array(
'integer', $row[9]),
1367 'attemptexpduration' => array(
'text', $row[10]),
1368 'attemptprogstatus' => array(
'integer', $row[11]),
1369 'audio_captioning' => array(
'integer', $row[12]),
1370 'audio_level' => array(
'float', $row[13]),
1371 'availablechildren' => array(
'text', $row[14]),
1372 'cmi_node_id' => array(
'integer', $cmi_node_id),
1373 'completion' => array(
'float', $row[16]),
1374 'completion_status' => array(
'text', $row[17]),
1375 'completion_threshold' => array(
'text', $row[18]),
1376 'cp_node_id' => array(
'integer', $row[19]),
1377 'created' => array(
'text', $row[20]),
1378 'credit' => array(
'text', $row[21]),
1379 'delivery_speed' => array(
'float', $row[22]),
1380 'c_entry' => array(
'text', $row[23]),
1381 'c_exit' => array(
'text', $row[24]),
1382 'c_language' => array(
'text', $row[25]),
1383 'launch_data' => array(
'clob', $row[26]),
1384 'learner_name' => array(
'text', $row[27]),
1385 'location' => array(
'text', $row[28]),
1386 'c_max' => array(
'float', $row[29]),
1387 'c_min' => array(
'float', $row[30]),
1388 'c_mode' => array(
'text', $row[31]),
1389 'modified' => array(
'text', $row[32]),
1390 'progress_measure' => array(
'float', $row[33]),
1391 'c_raw' => array(
'float', $row[34]),
1392 'scaled' => array(
'float', $row[35]),
1393 'scaled_passing_score' => array(
'float', $row[36]),
1394 'session_time' => array(
'text', $row[37]),
1395 'success_status' => array(
'text', $row[38]),
1396 'suspend_data' => array(
'clob', $row[39]),
1397 'total_time' => array(
'text', $row[40]),
1398 'user_id' => array(
'integer', $userId),
1399 'c_timestamp' => array(
'timestamp', date(
'Y-m-d H:i:s')),
1400 'additional_tables' => array(
'integer', $i_check)
1403 if($b_node_update==
false) {
1404 $ilLog->write(
"Want to insert row: ".count($row) );
1405 $ilDB->insert(
'cmi_node', $a_data);
1407 $ilDB->update(
'cmi_node', $a_data, array(
'cmi_node_id' => array(
'integer', $cmi_node_id)));
1408 $ilLog->write(
"updated");
1411 if($b_node_update==
true) {
1415 if ($this->slm->getComments()) {
1416 $q =
'DELETE FROM cmi_comment WHERE cmi_node_id = %s';
1417 $ilDB->manipulateF($q, array(
'integer'), array($cmi_node_id));
1422 if ($this->slm->getInteractions()) {
1423 $q =
'DELETE FROM cmi_correct_response
1424 WHERE cmi_interaction_id IN (
1425 SELECT cmi_interaction.cmi_interaction_id FROM cmi_interaction WHERE cmi_interaction.cmi_node_id = %s)';
1426 $ilDB->manipulateF($q, array(
'integer'), array($cmi_node_id));
1431 if ($this->slm->getInteractions()) {
1432 $q =
'DELETE FROM cmi_interaction WHERE cmi_node_id = %s';
1433 $ilDB->manipulateF($q, array(
'integer'), array($cmi_node_id));
1438 if ($this->slm->getObjectives()) {
1439 $q =
'DELETE FROM cmi_objective WHERE cmi_node_id = %s';
1440 $ilDB->manipulateF($q, array(
'integer'), array($cmi_node_id));
1446 $result[(string)$row[19]] = $cmi_node_id;
1450 $row[0] = $ilDB->nextId(
'cmi_comment');
1452 $ilDB->insert(
'cmi_comment', array(
1453 'cmi_comment_id' => array(
'integer', $row[0]),
1454 'cmi_node_id' => array(
'integer', $cmi_node_id),
1455 'c_comment' => array(
'clob', $row[2]),
1456 'c_timestamp' => array(
'text', $row[3]),
1457 'location' => array(
'text', $row[4]),
1458 'sourceislms' => array(
'integer', $row[5])
1463 $cmi_interaction_id = $ilDB->nextId(
'cmi_interaction');
1464 $a_map_cmi_interaction_id[]=array($row[0],$cmi_interaction_id);
1465 $ilDB->insert(
'cmi_interaction', array(
1466 'cmi_interaction_id' => array(
'integer', $cmi_interaction_id),
1467 'cmi_node_id' => array(
'integer', $cmi_node_id),
1468 'description' => array(
'clob', $row[2]),
1469 'id' => array(
'text', $row[3]),
1470 'latency' => array(
'text', $row[4]),
1471 'learner_response' => array(
'clob', $row[5]),
1472 'result' => array(
'text', $row[6]),
1473 'c_timestamp' => array(
'text', $row[7]),
1474 'c_type' => array(
'text', $row[8]),
1475 'weighting' => array(
'float', $row[9])
1480 $row[2] = $ilDB->nextId(
'cmi_objective');
1481 $cmi_interaction_id = null;
1482 if ($row[0] != null) {
1483 for($i=0;$i<count($a_map_cmi_interaction_id);$i++)
1484 if ($row[0] == $a_map_cmi_interaction_id[$i][0]) $cmi_interaction_id=$a_map_cmi_interaction_id[$i][1];
1486 $ilDB->insert(
'cmi_objective', array(
1487 'cmi_interaction_id' => array(
'integer', $cmi_interaction_id),
1488 'cmi_node_id' => array(
'integer', $cmi_node_id),
1489 'cmi_objective_id' => array(
'integer', $row[2]),
1490 'completion_status' => array(
'text', $row[3]),
1491 'description' => array(
'clob', $row[4]),
1492 'id' => array(
'text', $row[5]),
1493 'c_max' => array(
'float', $row[6]),
1494 'c_min' => array(
'float', $row[7]),
1495 'c_raw' => array(
'float', $row[8]),
1496 'scaled' => array(
'float', $row[9]),
1497 'progress_measure' => array(
'float', $row[10]),
1498 'success_status' => array(
'text', $row[11]),
1499 'scope' => array(
'text', $row[12])
1503 case 'correct_response':
1504 $cmi_interaction_id = null;
1505 if ($row[1] !== null) {
1506 for($i=0;$i<count($a_map_cmi_interaction_id);$i++)
1507 if ($row[1] == $a_map_cmi_interaction_id[$i][0]) $cmi_interaction_id=$a_map_cmi_interaction_id[$i][1];
1508 $row[0] = $ilDB->nextId(
'cmi_correct_response');
1509 $ilDB->insert(
'cmi_correct_response', array(
1510 'cmi_correct_resp_id' => array(
'integer', $row[0]),
1511 'cmi_interaction_id' => array(
'integer', $cmi_interaction_id),
1512 'pattern' => array(
'text', $row[2])
1521 $changed_seq_utilities=
$data->changed_seq_utilities;
1522 $ilLog->write(
"SCORM2004 adl_seq_utilities changed: ".$changed_seq_utilities);
1523 if ($changed_seq_utilities == 1) {
1524 $this->writeGObjective(
$data->adl_seq_utilities);
1535 include_once(
"./Services/Tracking/classes/class.ilLPStatusWrapper.php");
1546 $result[
"new_global_status"]=
"";
1550 function quoteJSONArray($a_array)
1554 if(!is_array($a_array) or !count($a_array))
1559 foreach($a_array as $k => $item)
1561 if ($item != null) {
1562 $a_array[$k] = $ilDB->quote($item);
1564 $a_array[$k] =
"NULL";
1580 include_once(
"./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1589 public function getCookie()
1591 return unserialize(base64_decode(
$_COOKIE[IL_OP_COOKIE_NAME]));
1594 public function setCookie($cook)
1596 setCookie(IL_OP_COOKIE_NAME, base64_encode(serialize($cook)));
1609 die(
'Error: Cookie could not be established');
1612 $SAHS_LM_POSITION = 1;
1614 $comp = explode(
'/', (
string)
$path);
1615 $sahs = $comp[$SAHS_LM_POSITION];
1616 $cook = $this->getCookie();
1617 $perm = $cook[$sahs];
1626 header(
'HTTP/1.0 401 Unauthorized');
1627 die(
'/* Unauthorized */');
1630 $cook[$sahs] = $perm;
1631 $this->setCookie($cook);
1634 $path =
'.' .
$path;
1635 if (!is_file($path))
1637 header(
'HTTP/1.0 404 Not Found');
1638 die(
'/* Not Found ' . $path .
'*/');
1642 header(
'Content-Type: ' . $this->getMimetype($path));
1645 header(
'Expires: ' . gmdate(
'D, d M Y H:i:s', time() + session_cache_expire()*60) .
' GMT');
1646 header(
'Cache-Control: private');
1656 function get_max_attempts()
1660 $res = $ilDB->queryF(
1661 'SELECT max_attempt FROM sahs_lm WHERE id = %s',
1663 array($this->packageId)
1667 return $row[
'max_attempt'];
1670 function get_Module_Version()
1674 $res = $ilDB->queryF(
1675 'SELECT module_version FROM sahs_lm WHERE id = %s',
1677 array($this->packageId));
1680 return $row[
'module_version'];
1686 function get_actual_attempts()
1690 $res = $ilDB->queryF(
'
1691 SELECT rvalue FROM cmi_custom
1692 WHERE user_id = %s AND sco_id = %s
1693 AND lvalue = %s AND obj_id = %s',
1694 array(
'integer',
'integer',
'text',
'integer'),
1695 array($this->userId, 0,
'package_attempts', $this->packageId)
1699 $row[
'rvalue'] = str_replace(
"\r\n",
"\n",
$row[
'rvalue']);
1700 if(
$row[
'rvalue'] == null)
1704 return $row[
'rvalue'];
1710 function increase_attempt()
1715 $res = $ilDB->queryF(
'
1716 SELECT rvalue FROM cmi_custom
1721 array(
'integer',
'integer',
'text',
'integer'),
1722 array($this->userId, 0,
'package_attempts', $this->packageId)
1728 $row[
'rvalue'] = str_replace(
"\r\n",
"\n",
$row[
'rvalue']);
1729 if(
$row[
'rvalue'] == null)
1733 $new_rec =
$row[
'rvalue'] + 1;
1736 if(!is_array($tmp_row) || !count($tmp_row))
1738 $ilDB->manipulateF(
'
1739 INSERT INTO cmi_custom (rvalue, user_id, sco_id, obj_id, lvalue, c_timestamp)
1740 VALUES(%s, %s, %s, %s, %s, %s)',
1741 array(
'text',
'integer',
'integer',
'integer',
'text',
'timestamp'),
1742 array($new_rec, $this->userId, 0, $this->packageId,
'package_attempts', date(
'Y-m-d H:i:s'))
1747 $ilDB->manipulateF(
'
1755 array(
'text',
'timestamp',
'integer',
'integer',
'integer',
'text'),
1756 array($new_rec, date(
'Y-m-d H:i:s'), $this->userId, 0, $this->packageId,
'package_attempts')
1763 function resetSharedData()
1767 $res = $ilDB->queryF(
'
1768 SELECT shared_data_global_to_system
1772 array($this->packageId)
1775 $shared_global_to_sys = $ilDB->fetchObject(
$res)->shared_data_global_to_system;
1777 $res = $ilDB->queryF(
'
1782 array(
'integer',
'integer'),
1783 array($this->packageId, $this->userId)
1788 $dat = $ilDB->fetchObject(
$res)->data;
1789 if($dat != null && $dat !=
'' ) $suspended =
true;
1791 if($shared_global_to_sys == 0 && !$suspended)
1793 $ilDB->manipulateF(
'
1794 DELETE FROM adl_shared_data
1797 array(
'integer',
'integer'),
1798 array($this->packageId, $this->userId)
1805 function save_module_version()
1809 $res = $ilDB->queryF(
'
1810 SELECT rvalue FROM cmi_custom
1815 array(
'integer',
'integer',
'text',
'integer'),
1816 array($this->userId, 0,
'module_version', $this->packageId)
1818 if(!$ilDB->numRows(
$res))
1820 $ilDB->manipulateF(
'
1821 INSERT INTO cmi_custom (rvalue, user_id, sco_id, obj_id, lvalue, c_timestamp)
1822 VALUES(%s, %s, %s, %s, %s, %s)',
1823 array(
'text',
'integer',
'integer',
'integer',
'text',
'timestamp'),
1824 array($this->get_Module_Version(), $this->userId, 0, $this->packageId,
'module_version', date(
'Y-m-d H:i:s'))
1830 $ilDB->manipulateF(
'
1838 array(
'text',
'timestamp',
'integer',
'integer',
'integer',
'text'),
1839 array($this->get_Module_Version(), date(
'Y-m-d H:i:s'), $this->userId, 0, $this->packageId,
'module_version')
1846 private function getNodeData($sco_id,$fh)
1850 $fieldList =
"cmi_node.cp_node_id, cmi_node.completion_threshold, cmi_node.c_exit, cmi_node.completion_status, cmi_node.progress_measure, cmi_node.success_status, cmi_node.scaled, cmi_node.session_time,".
1851 "cmi_node.c_min, cmi_node.c_max, cmi_node.c_raw, cmi_node.location, cmi_node.suspend_data, cmi_node.scaled_passing_score, cmi_node.total_time";
1854 $res = $ilDB->queryF(
'
1855 SELECT '.$fieldList.
'
1856 FROM cmi_node,cp_node,cp_item
1857 WHERE cp_node.slm_id = %s
1858 AND cp_node.cp_node_id = cp_item.cp_node_id
1860 AND cmi_node.cp_node_id = cp_item.cp_node_id
1861 AND cmi_node.user_id = %s',
1862 array(
'integer',
'text',
'integer'),
1863 array($this->packageId, $sco_id, $this->userId)
1866 $ilLog->write(
"DEBUG SQL".
$row);
1870 private function logTmpName()
1872 $filename = $this->logDirectory().
"/".$this->packageId.
".tmp";
1875 $fHandle = fopen(
$filename,
'a') or die(
"can't open file");
1876 fwrite($fHandle, $string);
1882 private function summaryFileName()
1884 $filename = $this->logDirectory().
"/".$this->packageId.
"_summary_".$this->get_actual_attempts();
1888 while (file_exists(
$filename.
"_".$adder.$suffix)) {
1890 $adder = (string) $i;
1892 $retname =
$filename.
"_".$adder.$suffix;
1894 if (!file_exists($retname)) {
1896 $fHandle = fopen($retname,
'a') or die(
"can't open file");
1897 fwrite($fHandle, $string);
1903 private function logFileName()
1906 $lng->loadLanguageModule(
"scormdebug");
1908 $filename = $this->logDirectory().
"/".$this->packageId.
"_".$this->get_actual_attempts();
1911 if (!file_exists($path_csv)) {
1913 $fHandle = fopen($path_csv,
'a') or die(
"can't open file");
1914 $string =
'"CourseId";"ScoId";"ScoTitle";"Timestamp";"Action";"Key";"Value";"Return Value";"Errorcode";"Timespan";"ErrorDescription"'.
"\n";
1915 fwrite($fHandle, $string);
1918 if (!file_exists($path_txt)) {
1919 if (file_exists($this->logTmpName())) {
1920 unlink($this->logTmpName());
1923 $fHandle2 = fopen($path_txt,
'a') or die(
"can't open file");
1924 $logtpl = $this->getLogTemplate();
1925 $logtpl->setCurrentBlock(
'NewLog');
1926 $logtpl->setVariable(
"COURSETITLE", $this->slm->getTitle());
1927 $logtpl->setVariable(
"COURSEID", $this->packageId);
1928 $logtpl->setVariable(
"TIMESTAMP", date(
"d.m.Y H:i",time()));
1929 $logtpl->setVariable(
"SESSION", $this->get_actual_attempts());
1930 $logtpl->setVariable(
"error0", $lng->txt(
"error0"));
1931 $logtpl->setVariable(
"error101", $lng->txt(
"error101"));
1932 $logtpl->setVariable(
"error102", $lng->txt(
"error102"));
1933 $logtpl->setVariable(
"error103", $lng->txt(
"error103"));
1934 $logtpl->setVariable(
"error104", $lng->txt(
"error104"));
1935 $logtpl->setVariable(
"error111", $lng->txt(
"error111"));
1936 $logtpl->setVariable(
"error112", $lng->txt(
"error112"));
1937 $logtpl->setVariable(
"error113", $lng->txt(
"error113"));
1938 $logtpl->setVariable(
"error122", $lng->txt(
"error122"));
1939 $logtpl->setVariable(
"error123", $lng->txt(
"error123"));
1940 $logtpl->setVariable(
"error132", $lng->txt(
"error132"));
1941 $logtpl->setVariable(
"error133", $lng->txt(
"error133"));
1942 $logtpl->setVariable(
"error142", $lng->txt(
"error142"));
1943 $logtpl->setVariable(
"error143", $lng->txt(
"error143"));
1944 $logtpl->setVariable(
"error201", $lng->txt(
"error201"));
1945 $logtpl->setVariable(
"error301", $lng->txt(
"error301"));
1946 $logtpl->setVariable(
"error351", $lng->txt(
"error351"));
1947 $logtpl->setVariable(
"error391", $lng->txt(
"error391"));
1948 $logtpl->setVariable(
"error401", $lng->txt(
"error401"));
1949 $logtpl->setVariable(
"error402", $lng->txt(
"error402"));
1950 $logtpl->setVariable(
"error403", $lng->txt(
"error403"));
1951 $logtpl->setVariable(
"error404", $lng->txt(
"error404"));
1952 $logtpl->setVariable(
"error405", $lng->txt(
"error405"));
1953 $logtpl->setVariable(
"error406", $lng->txt(
"error406"));
1954 $logtpl->setVariable(
"error407", $lng->txt(
"error407"));
1955 $logtpl->setVariable(
"error408", $lng->txt(
"error408"));
1956 $logtpl->setVariable(
"SetValue", $lng->txt(
"SetValue"));
1957 $logtpl->setVariable(
"GetValue", $lng->txt(
"GetValue"));
1958 $logtpl->setVariable(
"Commit", $lng->txt(
"Commit"));
1959 $logtpl->setVariable(
"Initialize", $lng->txt(
"Initialize"));
1960 $logtpl->setVariable(
"Terminate", $lng->txt(
"Terminate"));
1961 $logtpl->setVariable(
"GetErrorString", $lng->txt(
"GetErrorString"));
1962 $logtpl->setVariable(
"GetLastError", $lng->txt(
"GetLastError"));
1963 $logtpl->setVariable(
"GetDiagnostic", $lng->txt(
"GetDiagnostic"));
1964 $logtpl->setVariable(
"cmi._version", $lng->txt(
"cmi._version"));
1965 $logtpl->setVariable(
"cmi.comments_from_learner._children", $lng->txt(
"cmi.comments_from_learner._children"));
1966 $logtpl->setVariable(
"cmi.comments_from_learner._count", $lng->txt(
"cmi.comments_from_learner._count"));
1967 $logtpl->setVariable(
"cmi.comments_from_learner.n.comment", $lng->txt(
"cmi.comments_from_learner.n.comment"));
1968 $logtpl->setVariable(
"cmi.comments_from_learner.n.location", $lng->txt(
"cmi.comments_from_learner.n.location"));
1969 $logtpl->setVariable(
"cmi.comments_from_learner.n.timestamp", $lng->txt(
"cmi.comments_from_learner.n.timestamp"));
1970 $logtpl->setVariable(
"cmi.comments_from_lms._children", $lng->txt(
"cmi.comments_from_lms._children"));
1971 $logtpl->setVariable(
"cmi.comments_from_lms._count", $lng->txt(
"cmi.comments_from_lms._count"));
1972 $logtpl->setVariable(
"cmi.comments_from_lms.n.comment", $lng->txt(
"cmi.comments_from_lms.n.comment"));
1973 $logtpl->setVariable(
"cmi.comments_from_lms.n.location", $lng->txt(
"cmi.comments_from_lms.n.location"));
1974 $logtpl->setVariable(
"cmi.comments_from_lms.n.timestamp", $lng->txt(
"cmi.comments_from_lms.n.timestamp"));
1975 $logtpl->setVariable(
"cmi.completion_status", $lng->txt(
"cmi.completion_status"));
1976 $logtpl->setVariable(
"cmi.completion_threshold", $lng->txt(
"cmi.completion_threshold"));
1977 $logtpl->setVariable(
"cmi.credit", $lng->txt(
"cmi.credit"));
1978 $logtpl->setVariable(
"cmi.entry", $lng->txt(
"cmi.entry"));
1979 $logtpl->setVariable(
"cmi.exit", $lng->txt(
"cmi.exit"));
1980 $logtpl->setVariable(
"cmi.interactions._children", $lng->txt(
"cmi.interactions._children"));
1981 $logtpl->setVariable(
"cmi.interactions._count", $lng->txt(
"cmi.interactions._count"));
1982 $logtpl->setVariable(
"cmi.interactions.n.id", $lng->txt(
"cmi.interactions.n.id"));
1983 $logtpl->setVariable(
"cmi.interactions.n.type", $lng->txt(
"cmi.interactions.n.type"));
1984 $logtpl->setVariable(
"cmi.interactions.n.objectives._count", $lng->txt(
"cmi.interactions.n.objectives._count"));
1985 $logtpl->setVariable(
"cmi.interactions.n.objectives.n.id", $lng->txt(
"cmi.interactions.n.objectives.n.id"));
1986 $logtpl->setVariable(
"cmi.interactions.n.timestamp", $lng->txt(
"cmi.interactions.n.timestamp"));
1987 $logtpl->setVariable(
"cmi.interactions.n.correct_responses._count", $lng->txt(
"cmi.interactions.n.correct_responses._count"));
1988 $logtpl->setVariable(
"cmi.interactions.n.correct_responses.n.pattern", $lng->txt(
"cmi.interactions.n.correct_responses.n.pattern"));
1989 $logtpl->setVariable(
"cmi.interactions.n.weighting", $lng->txt(
"cmi.interactions.n.weighting"));
1990 $logtpl->setVariable(
"cmi.interactions.n.learner_response", $lng->txt(
"cmi.interactions.n.learner_response"));
1991 $logtpl->setVariable(
"cmi.interactions.n.result", $lng->txt(
"cmi.interactions.n.result"));
1992 $logtpl->setVariable(
"cmi.interactions.n.latency", $lng->txt(
"cmi.interactions.n.latency"));
1993 $logtpl->setVariable(
"cmi.interactions.n.description", $lng->txt(
"cmi.interactions.n.description"));
1994 $logtpl->setVariable(
"cmi.launch_data", $lng->txt(
"cmi.launch_data"));
1995 $logtpl->setVariable(
"cmi.learner_id", $lng->txt(
"cmi.learner_id"));
1996 $logtpl->setVariable(
"cmi.learner_name", $lng->txt(
"cmi.learner_name"));
1997 $logtpl->setVariable(
"cmi.learner_preference._children", $lng->txt(
"cmi.learner_preference._children"));
1998 $logtpl->setVariable(
"cmi.learner_preference.audio_level", $lng->txt(
"cmi.learner_preference.audio_level"));
1999 $logtpl->setVariable(
"cmi.learner_preference.language", $lng->txt(
"cmi.learner_preference.language"));
2000 $logtpl->setVariable(
"cmi.learner_preference.delivery_speed", $lng->txt(
"cmi.learner_preference.delivery_speed"));
2001 $logtpl->setVariable(
"cmi.learner_preference.audio_captioning", $lng->txt(
"cmi.learner_preference.audio_captioning"));
2002 $logtpl->setVariable(
"cmi.location", $lng->txt(
"cmi.location"));
2003 $logtpl->setVariable(
"cmi.max_time_allowed", $lng->txt(
"cmi.max_time_allowed"));
2004 $logtpl->setVariable(
"cmi.mode", $lng->txt(
"cmi.mode"));
2005 $logtpl->setVariable(
"cmi.objectives._children", $lng->txt(
"cmi.objectives._children"));
2006 $logtpl->setVariable(
"cmi.objectives._count", $lng->txt(
"cmi.objectives._count"));
2007 $logtpl->setVariable(
"cmi.objectives.n.id", $lng->txt(
"cmi.objectives.n.id"));
2008 $logtpl->setVariable(
"cmi.objectives.n.score._children", $lng->txt(
"cmi.objectives.n.score._children"));
2009 $logtpl->setVariable(
"cmi.objectives.n.score.scaled", $lng->txt(
"cmi.objectives.n.score.scaled"));
2010 $logtpl->setVariable(
"cmi.objectives.n.score.raw", $lng->txt(
"cmi.objectives.n.score.raw"));
2011 $logtpl->setVariable(
"cmi.objectives.n.score.min", $lng->txt(
"cmi.objectives.n.score.min"));
2012 $logtpl->setVariable(
"cmi.objectives.n.score.max", $lng->txt(
"cmi.objectives.n.score.max"));
2013 $logtpl->setVariable(
"cmi.objectives.n.success_status", $lng->txt(
"cmi.objectives.n.success_status"));
2014 $logtpl->setVariable(
"cmi.objectives.n.completion_status", $lng->txt(
"cmi.objectives.n.completion_status"));
2015 $logtpl->setVariable(
"cmi.objectives.n.progress_measure", $lng->txt(
"cmi.objectives.n.progress_measure"));
2016 $logtpl->setVariable(
"cmi.objectives.n.description", $lng->txt(
"cmi.objectives.n.description"));
2017 $logtpl->setVariable(
"cmi.progress_measure", $lng->txt(
"cmi.progress_measure"));
2018 $logtpl->setVariable(
"cmi.scaled_passing_score", $lng->txt(
"cmi.scaled_passing_score"));
2019 $logtpl->setVariable(
"cmi.score._children", $lng->txt(
"cmi.score._children"));
2020 $logtpl->setVariable(
"cmi.score.scaled", $lng->txt(
"cmi.score.scaled"));
2021 $logtpl->setVariable(
"cmi.score.raw", $lng->txt(
"cmi.score.raw"));
2022 $logtpl->setVariable(
"cmi.score.min", $lng->txt(
"cmi.score.min"));
2023 $logtpl->setVariable(
"cmi.score.max", $lng->txt(
"cmi.score.max"));
2024 $logtpl->setVariable(
"cmi.session_time", $lng->txt(
"cmi.session_time"));
2025 $logtpl->setVariable(
"cmi.success_status", $lng->txt(
"cmi.success_status"));
2026 $logtpl->setVariable(
"cmi.suspend_data", $lng->txt(
"cmi.suspend_data"));
2027 $logtpl->setVariable(
"cmi.time_limit_action", $lng->txt(
"cmi.time_limit_action"));
2028 $logtpl->setVariable(
"cmi.total_time", $lng->txt(
"cmi.total_time"));
2029 $logtpl->setVariable(
"adl.nav.request", $lng->txt(
"adl.nav.request"));
2030 $logtpl->setVariable(
"adl.nav.request_valid.continue", $lng->txt(
"adl.nav.request_valid.continue"));
2031 $logtpl->setVariable(
"adl.nav.request_valid.previous", $lng->txt(
"adl.nav.request_valid.previous"));
2032 $logtpl->setVariable(
"adl.nav.request_valid.choice", $lng->txt(
"adl.nav.request_valid.choice"));
2033 $logtpl->setVariable(
"i_green", $lng->txt(
"i_green"));
2034 $logtpl->setVariable(
"i_red", $lng->txt(
"i_red"));
2035 $logtpl->setVariable(
"i_orange", $lng->txt(
"i_orange"));
2036 $logtpl->setVariable(
"i_fuchsia", $lng->txt(
"i_fuchsia"));
2037 $logtpl->setVariable(
"i_gray", $lng->txt(
"i_gray"));
2038 $logtpl->setVariable(
"error", $lng->txt(
"error"));
2039 $logtpl->setVariable(
"strange_error", $lng->txt(
"strange_error"));
2040 $logtpl->setVariable(
"strange_API-Call", $lng->txt(
"strange_API-Call"));
2041 $logtpl->setVariable(
"unknown", $lng->txt(
"unknown"));
2042 $logtpl->setVariable(
"undefined_color", $lng->txt(
"undefined_color"));
2043 $logtpl->setVariable(
"description_for", $lng->txt(
"description_for"));
2044 $logtpl->setVariable(
"hide", $lng->txt(
"hide"));
2045 $logtpl->setVariable(
"all_API-calls_shown", $lng->txt(
"all_API-calls_shown"));
2046 $logtpl->setVariable(
"show_only_important_API-calls", $lng->txt(
"show_only_important_API-calls"));
2047 $logtpl->setVariable(
"only_important_API-Calls_shown", $lng->txt(
"only_important_API-Calls_shown"));
2048 $logtpl->setVariable(
"show_all_API-calls", $lng->txt(
"show_all_API-calls"));
2049 $logtpl->setVariable(
"log_for", $lng->txt(
"log_for"));
2050 $logtpl->setVariable(
"started", $lng->txt(
"started"));
2051 $logtpl->setVariable(
"nr_session", $lng->txt(
"nr_session"));
2052 $logtpl->setVariable(
"id_learning_module", $lng->txt(
"id_learning_module"));
2053 if($this->slm->getCheck_values()==
false) $logtpl->setVariable(
"CHECK_VALUES", $lng->txt(
"sent_values_not_checked"));
2054 $logtpl->parseCurrentBlock();
2055 fwrite($fHandle2,$logtpl->get());
2061 function getDataDirectory2()
2063 $webdir=str_replace(
"/ilias.php",
"",$_SERVER[
"SCRIPT_NAME"]);
2065 $lm_dir=$webdir.
"/".
ILIAS_WEB_DIR.
"/".$this->ilias->client_id .
"/lm_data".
"/lm_".$this->packageId;
2069 private function logDirectory()
2073 $logDir=$this->slm->getDataDirectory().
"/logs";
2074 if (!file_exists($logDir)) {
2083 header(
'Content-Type: text/html; charset=UTF-8');
2084 echo file_get_contents($this->logDirectory().
"/".
$filename);
2091 header(
"Expires: 0");
2092 header(
"Cache-Control: private");
2093 header(
"Cache-Control: must-revalidate, post-check=0, pre-check=0");
2094 header(
"Pragma: cache");
2095 header(
"Content-Description: File Transfer");
2096 header(
"Content-Type: application/octet-stream");
2097 header(
"Content-disposition: attachment; filename=$filename");
2098 echo file_get_contents($this->logDirectory().
"/".
$filename);
2102 private function getLogFileList($s_delete,$s_download,$s_open)
2106 if ($fileInfo->isDot()) {
2109 $item[
'filename'] = $fileInfo->getFilename();
2110 $parts = pathinfo($item[
'filename']);
2111 $fnameparts = preg_split(
'/_/', $parts[
'filename'], -1, PREG_SPLIT_NO_EMPTY);
2112 $deleteUrl =
' <a href=#'.
" onclick=\"javascript:deleteFile('".$item[
'filename'].
"');\">".$s_delete.
"</a>";
2114 if ($this->get_actual_attempts()==$fnameparts[1]) {$deleteUrl=
"";}
2116 $urlDownload =
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=downloadLog&ref_id='.
$_GET[
"ref_id"].
'&logFile='.$fileInfo->getFilename();
2117 $urlOpen =
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=openLog&ref_id='.
$_GET[
"ref_id"].
'&logFile='.$fileInfo->getFilename();
2118 $item[
'date'] = date(
'Y/m/d H:i:s', $fileInfo->getCTime());
2119 if ($parts[
'extension'] ==
"html") {
2120 $item[
'action'] =$deleteUrl.
" <a href=".$urlDownload.
">".$s_download.
"</a> <a target=_new href=".$urlOpen.
">".$s_open.
"</a>";
2122 $item[
'action'] =$deleteUrl.
" <a href=".$urlDownload.
">".$s_download.
"</a>";
2124 if ($parts[
'extension'] ==
"html" || $parts[
'extension'] ==
"csv") {
2125 array_push(
$data,$item);
2128 usort(
$data,
"datecmp");
2132 public function liveLogContent()
2134 header(
'Content-Type: text/html; charset=UTF-8');
2135 print file_get_contents($this->logFileName().
".html");
2138 public function debugGUI()
2141 $lng->loadLanguageModule(
"scormdebug");
2153 $this->tpl =
new ilTemplate(
"tpl.scorm2004.debug.html",
false,
false,
"./Modules/Scorm2004");
2154 $this->tpl->setVariable(
'CONSOLE', $lng->txt(
"debugwindow_console"));
2155 $this->tpl->setVariable(
'LOGS', $lng->txt(
"debugwindow_logs"));
2156 $this->tpl->setVariable(
'COMMENT', $lng->txt(
"debugwindow_comment"));
2157 $this->tpl->setVariable(
'COMMENT_ENTER', $lng->txt(
"debugwindow_comment_enter"));
2158 $this->tpl->setVariable(
'START_RECORDING', $lng->txt(
"debugwindow_start_recording"));
2159 $this->tpl->setVariable(
'STOP_RECORDING', $lng->txt(
"debugwindow_stop_recording"));
2160 $this->tpl->setVariable(
'DELETE_LOGFILE', $lng->txt(
"debugwindow_delete_logfile"));
2161 $this->tpl->setVariable(
'SUBMISSION_FAILED', $lng->txt(
"debugwindow_submission_failed"));
2162 $this->tpl->setVariable(
'SUBMIT', $lng->txt(
"debugwindow_submit"));
2163 $this->tpl->setVariable(
'CANCEL', $lng->txt(
"debugwindow_cancel"));
2164 $this->tpl->setVariable(
'FILENAME', $lng->txt(
"debugwindow_filename"));
2165 $this->tpl->setVariable(
'DATE', $lng->txt(
"debugwindow_date"));
2166 $this->tpl->setVariable(
'ACTION', $lng->txt(
"debugwindow_action"));
2167 $this->tpl->setVariable(
'RECORD_IMG',
ilUtil::getImagePath(
"record.png",
"./Modules/Scorm2004"));
2169 $this->tpl->setVariable(
'COMMENT_IMG',
ilUtil::getImagePath(
"comment.png",
"./Modules/Scorm2004"));
2170 $logfile = $this->logFileName().
".html";
2171 $this->tpl->setVariable(
'LOGFILE',$this->logFileName().
".html");
2172 $this->tpl->setVariable(
'FILES_DATA', json_encode($this->getLogFileList($lng->txt(
"debugwindow_delete"), $lng->txt(
"debugwindow_download"), $lng->txt(
"debugwindow_open"))));
2175 include_once
"Services/YUI/classes/class.ilYuiUtil.php";
2178 echo $this->tpl->get(
"DEFAULT",
true);
2181 private function getLogTemplate()
2183 return new ilTemplate(
"tpl.scorm2004.debugtxt.txt",
true,
true,
"Modules/Scorm2004");
2186 private function getDebugValues($test_sco =
false)
2202 $debug_fields = parse_ini_file(
"./Modules/Scorm2004/scripts/rtemain/debug_default.ini",
true);
2205 $ini_array = $debug_fields[
'test_sco'];
2207 $ini_array = $debug_fields[
'normal_sco'];
2209 foreach ($ini_array as $key => $value) {
2211 array_push($dvalues,$key);
2217 public function postLogEntry()
2220 $lng->loadLanguageModule(
"scormdebug");
2222 $logdata = json_decode(file_get_contents(
'php://input'));
2224 $tmp_name = $this->logTmpName();
2226 $fh_txt = fopen(
$filename.
".html",
'a') or die(
"can't open txt file");
2227 $fh_csv = fopen(
$filename.
".csv",
'a') or die(
"can't open csv file");
2228 $fh_tmp = fopen($tmp_name,
'r') or die(
"can't open tmp file");
2231 if (filesize($tmp_name)>0) {
2232 $tmp_content = unserialize(fread($fh_tmp,filesize($tmp_name)));
2234 $tmp_content = null;
2240 $fh_tmp2 = fopen($tmp_name,
'w') or die(
"can't open tmp file");
2244 $tmp_content[$logdata->scoid][$logdata->key][
'value'] = $logdata->value;
2245 $tmp_content[$logdata->scoid][$logdata->key][
'status'] = $logdata->result;
2246 $tmp_content[$logdata->scoid][$logdata->key][
'action'] = $logdata->action;
2248 fwrite($fh_tmp2,serialize($tmp_content));
2254 $errorcode = $logdata->errorcode;
2255 $fixedFailure =
false;
2256 $toleratedFailure =
false;
2257 $extraErrorDescription =
"";
2258 if ($errorcode == 200000) {
2260 $toleratedFailure =
true;
2261 $extraErrorDescription =
"tolerated failure";
2263 if ($errorcode>99999) {
2265 $fixedFailure =
true;
2266 $extraErrorDescription =
" failure corrected by ILIAS";
2268 if (strpos($logdata->action,
"ANALYZE")===
false)
2270 $errorDescriptions = array(
"0" =>
"",
2271 "101" =>
"General Exeption",
2272 "102" =>
"General Initialization Failure",
2273 "103" =>
"Already Initialized",
2274 "104" =>
"Content Instance Terminated",
2275 "111" =>
"General Termination Failure",
2276 "112" =>
"Termination Before Initialization",
2277 "113" =>
"Termination After Termination",
2278 "122" =>
"Retrieve Data Before Initialization",
2279 "123" =>
"Retrieve Data After Termination",
2280 "132" =>
"Store Data Before Initialization",
2281 "133" =>
"Store Data After Termination",
2282 "142" =>
"Commit Before Initialization",
2283 "143" =>
"Commit After Termination",
2284 "201" =>
"General Argument Error",
2285 "301" =>
"General Get Failure",
2286 "351" =>
"General Set Failure",
2287 "391" =>
"General Commit Failure",
2288 "401" =>
"Undefined Data Model Element",
2289 "402" =>
"Unimplemented Data Model Element",
2290 "403" =>
"Data Model Element Value Not Initialized",
2291 "404" =>
"Data Model Element Is Read Only",
2292 "405" =>
"Data Model Element Is Write Only",
2293 "406" =>
"Data Model Element Type Mismatch",
2294 "407" =>
"Data Model Element Value Out Of Range",
2295 "408" =>
"Data Model Dependency Not Established");
2296 $csv_string = $this->packageId.
';"'
2297 .$logdata->scoid.
'";"'
2298 .$logdata->scotitle.
'";'
2299 .date(
"d.m.Y H:i",time()).
';"'
2300 .$logdata->action.
'";"'
2301 .$logdata->key.
'";"'
2302 .str_replace(
"\"",
"\"\"",$logdata->value).
'";"'
2303 .str_replace(
"\"",
"\"\"",$logdata->result).
'";'
2305 .$logdata->timespan.
';"'
2306 .$errorDescriptions[$errorcode].$extraErrorDescription.
'"'.
"\n";
2307 fwrite($fh_csv,$csv_string);
2311 if($logdata->action ==
"Commit" || $logdata->action ==
"Terminate")
2314 $sql_data = $this->getNodeData($logdata->scoid,$fh_csv);
2315 foreach ($sql_data as $key => $value) {
2316 $sql_string = $this->packageId.
';"'
2317 .$logdata->scoid.
'";"'
2318 .$logdata->scotitle.
'";'
2319 .$timestamp.
';"SQL";"'
2321 .str_replace(
"\"",
"\"\"",$value).
'";;;;'.
"\n";
2322 fwrite($fh_csv,$sql_string);
2327 if ($logdata->action ==
"DELETE")
2336 $logtpl = $this->getLogTemplate();
2339 $ArGetValues = array(
'comments_from_lms',
'completion_threshold',
'credit',
'entry',
'launch_data',
'learner_id',
'learner_name',
'max_time_allowed',
'mode',
'scaled_passing_score',
'time_limit_action',
'total_time');
2341 switch ($logdata->action) {
2343 if ($logdata->result ==
"true" && $errorcode == 0) $color =
"green";
2344 if ($color==
"green" && $logdata->key ==
"cmi.exit" && $logdata->value!=
"suspend") $color =
"orange";
2345 if ($fixedFailure ==
false && $errorcode!=406) $logdata->value =
'"'.$logdata->value.
'"';
2346 if ($toleratedFailure ==
true) $color =
"fuchsia";
2347 if ($fixedFailure ==
true) $color =
"gray";
2350 if ($errorcode == 0) $color =
"green";
2353 if ($errorcode == 0)
2356 $logtpl->setCurrentBlock(
"InitializeStart");
2357 $logtpl->setVariable(
"SCO-title", $lng->txt(
"SCO-title"));
2358 $logtpl->setVariable(
"SCO_TITLE", $logdata->scotitle);
2359 $logtpl->setVariable(
"SCO-name", $lng->txt(
"SCO-name"));
2360 $logtpl->setVariable(
"SCO_NAME", $logdata->scoid);
2361 $logtpl->setVariable(
"started", $lng->txt(
"started"));
2362 $logtpl->setVariable(
"TIMESTAMP",
$timestamp);
2363 $logtpl->setVariable(
"milliseconds", $lng->txt(
"milliseconds"));
2364 $logtpl->setVariable(
"API-call", $lng->txt(
"API-call"));
2365 $logtpl->setVariable(
"return_value", $lng->txt(
"return_value"));
2366 $logtpl->setVariable(
"error", $lng->txt(
"error"));
2367 $logtpl->parseCurrentBlock();
2371 if ($errorcode == 0) $color =
"green";
2372 if ($fixedFailure ==
true) $color =
"gray";
2375 if ($errorcode == 0) $color =
"green";
2377 case 'GetErrorString':
2379 if ($errorcode == 0) $color =
"green";
2381 case 'GetLastError':
2382 $logtpl->setCurrentBlock(
"GetLastError");
2383 $logtpl->setVariable(
"TIMESPAN", $logdata->timespan);
2384 $logtpl->setVariable(
"RESULT", $logdata->result);
2385 $logtpl->parseCurrentBlock();
2387 case 'GetDiagnostic':
2388 $logtpl->setCurrentBlock(
"GetDiagnostic");
2389 $logtpl->setVariable(
"TIMESPAN", $logdata->timespan);
2390 $logtpl->setVariable(
"KEY", $logdata->key);
2391 $logtpl->setVariable(
"RESULT", $logdata->result);
2392 $logtpl->parseCurrentBlock();
2395 $logtpl->setCurrentBlock(
"INFO");
2396 $logtpl->setVariable(
"hint", $lng->txt(
"hint"));
2397 $logtpl->setVariable(
"KEY", $lng->txt($logdata->key));
2398 $logtpl->setVariable(
"VALUE", $logdata->value);
2399 $logtpl->parseCurrentBlock();
2402 $logtpl->setCurrentBlock(
"COMMENT");
2403 $logtpl->setVariable(
"comment", $lng->txt(
"comment"));
2404 $logtpl->setVariable(
"generated", $lng->txt(
"generated"));
2405 $logtpl->setVariable(
"TIMESTAMP",
$timestamp);
2406 $logtpl->setVariable(
"VALUE", $logdata->value);
2407 $logtpl->parseCurrentBlock();
2410 $logtpl->setCurrentBlock(
"ANALYZE");
2411 if (count($logdata->value) == 0) {
2413 $logtpl->setVariable(
"ANALYZE_SUMMARY", $lng->txt(
"no_missing_API-calls"));
2414 $logtpl->setVariable(
"VALUE",
"");
2416 $tmpvalue =
"SetValue(\"".implode(
"\", ... ),<br/>SetValue(\"",$logdata->value).
"\", ... )";
2417 for ($i=0; $i <count($ArGetValues); $i++){
2418 $tmpvalue = str_replace(
"SetValue(\"cmi.".$ArGetValues[$i].
"\", ... )",
"GetValue(\"cmi.".$ArGetValues[$i].
"\")",$tmpvalue);
2420 $logtpl->setVariable(
"ANALYZE_SUMMARY", $lng->txt(
"missing_API-calls"));
2421 $logtpl->setVariable(
"VALUE", $tmpvalue);
2423 $logtpl->setVariable(
"summary_for_SCO_without_test", $lng->txt(
"summary_for_SCO_without_test"));
2424 $logtpl->setVariable(
"generated", $lng->txt(
"generated"));
2425 $logtpl->setVariable(
"TIMESTAMP",
$timestamp);
2426 $logtpl->setVariable(
"COLOR", $color);
2427 $logtpl->parseCurrentBlock();
2430 $logtpl->setCurrentBlock(
"ANALYZETEST");
2431 if (count($logdata->value) == 0) {
2433 $logtpl->setVariable(
"ANALYZE_SUMMARY", $lng->txt(
"no_missing_API-calls"));
2434 $logtpl->setVariable(
"VALUE",
"");
2436 $tmpvalue =
"SetValue(\"".implode(
"\", ... ),<br/>SetValue(\"",$logdata->value).
"\", ... )";
2437 for ($i=0; $i <count($ArGetValues); $i++){
2438 $tmpvalue = str_replace(
"SetValue(\"cmi.".$ArGetValues[$i].
"\", ... )",
"GetValue(\"cmi.".$ArGetValues[$i].
"\")",$tmpvalue);
2440 $logtpl->setVariable(
"ANALYZE_SUMMARY", $lng->txt(
"missing_API-calls"));
2441 $logtpl->setVariable(
"VALUE", $tmpvalue);
2443 $logtpl->setVariable(
"summary_for_SCO_with_test", $lng->txt(
"summary_for_SCO_with_test"));
2444 $logtpl->setVariable(
"generated", $lng->txt(
"generated"));
2445 $logtpl->setVariable(
"TIMESTAMP",
$timestamp);
2446 $logtpl->setVariable(
"COLOR", $color);
2447 $logtpl->parseCurrentBlock();
2450 $logtpl->setCurrentBlock(
"SUMMARY");
2451 $logtpl->setVariable(
"summary_csv", $lng->txt(
"summary_csv"));
2452 $logtpl->setVariable(
"TIMESTAMP",
$timestamp);
2453 $logtpl->setVariable(
"summary_download", $lng->txt(
"summary_download"));
2454 $logtpl->parseCurrentBlock();
2461 if ($logdata->action ==
'SetValue' || $logdata->action ==
'GetValue')
2463 $logtpl->setCurrentBlock($logdata->action);
2464 $logtpl->setVariable(
"ACTION", $logdata->action);
2465 $logtpl->setVariable(
"TIMESPAN", $logdata->timespan);
2466 $logtpl->setVariable(
"KEY", $logdata->key);
2467 $logtpl->setVariable(
"VALUE", $logdata->value);
2468 $logtpl->setVariable(
"RESULT", $logdata->result);
2469 $logtpl->setVariable(
"ERRORCODE", $errorcode);
2470 $debugfields=$this->getDebugValues(
true);
2472 for ($i=0; $i <count($debugfields) ; $i++){
2473 if ($logdata->key == $debugfields[$i]) $importantkey=1;
2475 $logtpl->setVariable(
"IMPORTANTKEY",
"".$importantkey);
2476 $logtpl->setVariable(
"COLOR", $color);
2477 $logtpl->parseCurrentBlock();
2479 else if ($logdata->action !=
'INFO' && $logdata->action !=
'ANALYZE' && $logdata->action !=
'ANALYZETEST' && $logdata->action !=
'SUMMARY' && $logdata->action !=
'COMMENT' && $logdata->action !=
'GetDiagnostic' && $logdata->action !=
'GetLastError')
2481 $logtpl->setCurrentBlock(
"defaultCall");
2482 $logtpl->setVariable(
"ACTION", $logdata->action);
2483 $logtpl->setVariable(
"TIMESPAN", $logdata->timespan);
2484 $logtpl->setVariable(
"KEY", $logdata->key);
2485 $logtpl->setVariable(
"VALUE", $logdata->value);
2486 $logtpl->setVariable(
"RESULT", $logdata->result);
2487 $logtpl->setVariable(
"ERRORCODE", $errorcode);
2488 $logtpl->setVariable(
"IMPORTANTKEY",
"".$importantkey);
2489 $logtpl->setVariable(
"COLOR", $color);
2490 $logtpl->parseCurrentBlock();
2503 if ($logdata->action ==
"SUMMARY") {
2504 $this->createSummary($tmp_content);
2507 fwrite($fh_txt,$logtpl->get());
2512 private function getStructureFlat(
$data)
2514 for ($i=0; $i <count(
$data) ; $i++) {
2516 $element[
'title'] =
$data[$i][
'title'];
2517 $element[
'id'] =
$data[$i][
'id'];
2518 if (
$data[$i][
'sco'] == 1) {
2519 $element[
'sco'] =
"sco";
2521 $element[
'sco'] =
"assset";
2523 if (
$data[$i][
'href'] !=null ) {
2524 array_push($this->flat_structure,$element);
2526 if (
$data[$i][
'item']!=null) {
2527 $this->getStructureFlat(
$data[$i][
'item']);
2532 private function createSummary($api_data)
2538 $columns_fixed = array(
'id',
'title',
'type',
'attempted');
2540 $ini_data = parse_ini_file(
"./Modules/Scorm2004/scripts/rtemain/debug_default.ini",
true);
2541 $ini_array = $ini_data[
'summary'];
2542 $colums_variable = array();
2543 $api_keys = array();
2545 foreach ($ini_array as $key => $value) {
2547 array_push($colums_variable,$key);
2548 array_push($api_keys,$key);
2549 array_push($colums_variable,
"Status");
2553 $header_array = array_merge($columns_fixed, $colums_variable);
2555 $csv_header = implode(
";",$header_array);
2558 $res = $ilDB->queryF(
2559 'SELECT jsdata FROM cp_package WHERE obj_id = %s',
2561 array($this->packageId)
2564 $packageData = $ilDB->fetchAssoc(
$res);
2566 $structure = json_decode($packageData[
'jsdata'],
true);
2569 $this->flat_structure = array();
2570 $this->getStructureFlat($structure[
'item'][
'item']);
2572 foreach ($this->flat_structure as $tree_element) {
2574 $csv_data = $csv_data.$tree_element[
'id'].
";".$tree_element[
'title'].
";".$tree_element[
'sco'].
";";
2575 if ($api_data[$tree_element[
'id']] != null) {
2576 $csv_data = $csv_data.
"X".
";";
2578 $csv_data = $csv_data.
";";
2582 $id = $tree_element[
'id'];
2583 foreach ($api_keys as $api_element) {
2584 if ($api_data[$id]!=null) {
2585 if ($api_data[$id][$api_element]!=null) {
2586 $csv_data = $csv_data.$api_data[$id][$api_element][
'value'].
";".$api_data[$id][$api_element][
'status'].
";";
2588 $csv_data = $csv_data.
";;";
2592 $csv_data = $csv_data.
"\n";
2595 $fh = fopen($this->summaryFileName(),
"w");
2596 fwrite($fh,$csv_header.
"\n".$csv_data);
2598 unlink($this->logTmpName());
2604 function get_last_visited($a_obj_id, $a_user_id)
2608 $val_set = $ilDB->queryF(
'
2609 SELECT rvalue FROM cmi_custom
2614 array(
'integer',
'integer',
'text',
'integer'),
2615 array($a_user_id, 0,
'last_visited',$a_obj_id));
2617 $val_rec = $ilDB->fetchAssoc($val_set);
2618 return $val_rec[
"rvalue"];
2621 function set_last_visited($a_obj_id, $a_user_id, $last_visited)
2624 $pre_last_visited=$this->get_last_visited($a_obj_id, $a_user_id);
2626 if ($pre_last_visited == $last_visited)
return;
2627 if ($pre_last_visited == null) {
2628 $ilDB->manipulateF(
'
2629 INSERT INTO cmi_custom (rvalue, user_id, sco_id, obj_id, lvalue, c_timestamp)
2630 VALUES(%s, %s, %s, %s, %s, %s)',
2631 array(
'text',
'integer',
'integer',
'integer',
'text',
'timestamp'),
2632 array($last_visited, $a_user_id, 0, $a_obj_id,
'last_visited', date(
'Y-m-d H:i:s'))
2637 $ilDB->manipulateF(
'
2645 array(
'text',
'timestamp',
'integer',
'integer',
'integer',
'text'),
2646 array($last_visited, date(
'Y-m-d H:i:s'), $a_user_id, 0, $a_obj_id,
'last_visited')
2654 if (strtotime($a[
'date']) == strtotime($b[
'date'])) {
2657 return (strtotime($a[
'date']) < strtotime($b[
'date'])) ? 1 :-1;