5 require_once(
"./Services/YUI/classes/class.ilYuiUtil.php");
6 require_once(
"./Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModule.php");
28 'user_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>user_id),
29 'learner_name' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>learner_name),
30 'slm_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>slm_id),
31 'mode' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>c_mode),
32 'credit' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>credit),
35 'accesscount' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>accesscount),
36 'accessduration' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>accessduration),
37 'accessed' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>accessed),
38 'activityAbsoluteDuration' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>activityabsduration),
39 'activityAttemptCount' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>activityattemptcount),
40 'activityExperiencedDuration' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>activityexpduration),
41 'activityProgressStatus' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>activityprogstatus),
42 'attemptAbsoluteDuration' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>attemptabsduration),
43 'attemptCompletionAmount' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>attemptcomplamount),
44 'attemptCompletionStatus' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>attemptcomplstatus),
45 'attemptExperiencedDuration' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>attemptexpduration),
46 'attemptProgressStatus' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>attemptprogstatus),
47 'audio_captioning' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>audio_captioning),
48 'audio_level' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>audio_level),
49 'availableChildren' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>availablechildren),
50 'cmi_node_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_node_id),
51 'completion' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>completion),
52 'completion_status' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>completion_status),
53 'completion_threshold' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>completion_threshold),
54 'cp_node_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cp_node_id),
55 'created' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>created),
56 'credit' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>credit),
57 'delivery_speed' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>delivery_speed),
58 'entry' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_entry),
59 'exit' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_exit),
60 'language' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_language),
61 'launch_data' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>launch_data),
62 'learner_name' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>learner_name),
63 'location' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>location),
64 'max' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_max),
65 'min' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_min),
66 'mode' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_mode),
67 'modified' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>modified),
68 'progress_measure' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>progress_measure),
69 'raw' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_raw),
70 'scaled' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>scaled),
71 'scaled_passing_score' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>scaled_passing_score),
72 'session_time' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>session_time),
73 'success_status' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>success_status),
74 'suspend_data' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>suspend_data),
75 'total_time' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>total_time),
76 'user_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>user_id),
79 'cmi_comment_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_comment_id),
80 'cmi_node_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_node_id),
81 'comment' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_comment),
82 'timestamp' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_timestamp),
83 'location' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>location),
84 'sourceIsLMS' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>sourceislms),
86 'correct_response' => array(
87 'cmi_correct_response_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_correct_resp_id),
88 'cmi_interaction_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_interaction_id),
89 'pattern' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>pattern),
91 'interaction' => array(
92 'cmi_interaction_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_interaction_id),
93 'cmi_node_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_node_id),
94 'description' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>description),
95 'id' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>
id),
96 'latency' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>latency),
97 'learner_response' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>learner_response),
98 'result' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>result),
99 'timestamp' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_timestamp),
100 'type' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_type),
101 'weighting' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>weighting),
103 'objective' => array(
104 'cmi_interaction_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_interaction_id),
105 'cmi_node_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_node_id),
106 'cmi_objective_id' => array(
'pattern'=>null,
'permission' => self::NONE,
'default'=>null,
'dbfield'=>cmi_objective_id),
107 'completion_status' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>completion_status),
108 'description' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>description),
109 'id' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>
id),
110 'max' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_max),
111 'min' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_min),
112 'raw' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>c_raw),
113 'scaled' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>scaled),
114 'progress_measure' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>progress_measure),
115 'success_status' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>success_status),
116 'scope' => array(
'pattern'=>null,
'permission' => self::READWRITE,
'default'=>null,
'dbfield'=>scope),
136 $this->userId =
$GLOBALS[
'USER'][
'usr_id'];
138 $this->packageId = (int)
$_REQUEST[
'packageId'];
139 $this->jsMode = strpos($_SERVER[
'HTTP_ACCEPT'],
'text/javascript')!==
false;
151 $this->ref_id =
$_GET[
'ref_id'];
152 $this->userId=$ilUser->getID();
154 if (
$_GET[
'envEditor'] != null) {
155 $this->envEditor =
$_GET[
'envEditor'];
157 $this->envEditor = 0;
169 $next_class = $this->ctrl->getNextClass($this);
170 $cmd = $this->ctrl->getCmd();
172 if (!$ilAccess->checkAccess(
"read",
"",
$_GET[
"ref_id"]))
174 $ilias->raiseError($lng->txt(
"permission_denied"), $ilias->error_obj->WARNING);
205 case 'getGobjective':
211 if ($_SERVER[
'REQUEST_METHOD']==
'POST') {
234 if (self::ENABLE_JS_DEBUG==1) {
237 $js_data = file_get_contents(
"./Modules/Scorm2004/scripts/buildrte/".
$filename);
238 if (self::ENABLE_GZIP==1) {
239 ob_start(
"ob_gzhandler");
240 header(
'Content-Type: text/javascript; charset=UTF-8');
242 header(
'Content-Type: text/javascript; charset=UTF-8');
252 $webdir=str_replace(
"/ilias.php",
"",$_SERVER[
"SCRIPT_NAME"]);
254 $lm_dir=$webdir.
"/".
ILIAS_WEB_DIR.
"/".$this->ilias->client_id .
"/lm_data".
"/lm_".$this->packageId;
265 if ($this->slm->getSession()) {
266 $session_timeout = (int)($ilias->ini->readVariable(
"session",
"expire"))/2;
268 $session_timeout = 0;
273 'cp_url' =>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=cp&ref_id='.
$_GET[
"ref_id"],
274 'cmi_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=cmi&ref_id='.
$_GET[
"ref_id"],
275 'adlact_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=adlact&ref_id='.
$_GET[
"ref_id"],
276 'specialpage_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=specialPage&ref_id='.
$_GET[
"ref_id"],
277 'suspend_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=suspend&ref_id='.
$_GET[
"ref_id"],
278 'get_suspend_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=getSuspend&ref_id='.
$_GET[
"ref_id"],
279 'gobjective_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=gobjective&ref_id='.
$_GET[
"ref_id"],
280 'get_gobjective_url'=>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=getGobjective&ref_id='.
$_GET[
"ref_id"],
281 'ping_url' =>
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=pingSession&ref_id='.
$_GET[
"ref_id"],
283 'learner_id' => (
string) $ilUser->getID(),
284 'course_id' => (string) $this->packageId,
285 'learner_name' => $ilUser->getFirstname().
" ".$ilUser->getLastname(),
287 'credit' =>
'credit',
288 'auto_review' => $this->slm->getAutoReview(),
289 'hide_navig' => $this->slm->getHideNavig(),
290 'debug' => $this->slm->getDebug(),
292 'session_ping' => $session_timeout,
293 'envEditor' => $this->envEditor
298 $langstrings[
'btnStart'] = $lng->txt(
'scplayer_start');
299 $langstrings[
'btnExit'] = $lng->txt(
'scplayer_exit');
300 $langstrings[
'btnExitAll'] = $lng->txt(
'scplayer_exitall');
301 $langstrings[
'btnSuspendAll'] = $lng->txt(
'scplayer_suspendall');
302 $langstrings[
'btnPrevious'] = $lng->txt(
'scplayer_previous');
303 $langstrings[
'btnContinue'] = $lng->txt(
'scplayer_continue');
304 $langstrings[
'btnhidetree']=$lng->txt(
'scplayer_hidetree');
305 $langstrings[
'btnshowtree']=$lng->txt(
'scplayer_showtree');
306 $config[
'langstrings'] = $langstrings;
309 $this->tpl =
new ilTemplate(
"tpl.scorm2004.player.html",
false,
false,
"Modules/Scorm2004");
310 $this->tpl->setVariable(
'JSON_LANGSTRINGS', json_encode($langstrings));
311 include_once(
"./Services/YUI/classes/class.ilYuiUtil.php");
313 $this->tpl->setVariable($langstrings);
314 $this->tpl->setVariable(
'DOC_TITLE',
'ILIAS SCORM 2004 Player');
316 $this->tpl->setVariable(
'JS_DATA', json_encode(
$config));
317 list($tsfrac, $tsint) = explode(
' ', microtime());
318 $this->tpl->setVariable(
'TIMESTAMP', sprintf(
'%d%03d', $tsint, 1000*(
float)$tsfrac));
319 $this->tpl->setVariable(
'BASE_DIR',
'./Modules/Scorm2004/');
324 $this->tpl->setVariable(
'IC_NOTATTEMPTED',
ilUtil::getImagePath(
"scorm/not_attempted_s.gif",
false));
332 $this->tpl->setVariable(
'JS_SCRIPTS',
'ilias.php?baseClass=ilSAHSPresentationGUI' .
'&cmd=getRTEjs&ref_id='.
$_GET[
"ref_id"]);
335 if ($this->slm->getNoMenu()==
"y") {
336 $this->tpl->setVariable(
"VAL_DISPLAY",
"style=\"display:none;\"");
343 header(
'Content-Type: text/html; charset=utf-8');
344 echo($lng->txt(
"cont_sc_max_attempt_exceed"));
355 $this->tpl->show(
"DEFAULT",
false);
362 $res = $ilDB->queryF(
363 'SELECT jsdata FROM cp_package WHERE obj_id = %s',
365 array($this->packageId)
367 $packageData = $ilDB->fetchAssoc(
$res);
369 $jsdata = $packageData[
'jsdata'];
370 if (!$jsdata) $jsdata =
'null';
373 header(
'Content-Type: text/javascript; charset=UTF-8');
378 header(
'Content-Type: text/plain; charset=UTF-8');
379 $jsdata = json_decode($jsdata);
388 $res = $ilDB->queryF(
389 'SELECT activitytree FROM cp_package WHERE obj_id = %s',
391 array($this->packageId)
395 $activitytree =
$data[
'activitytree'];
399 $activitytree =
'null';
403 header(
'Content-Type: text/javascript; charset=UTF-8');
404 print($activitytree);
408 header(
'Content-Type: text/plain; charset=UTF-8');
409 $activitytree = json_decode($activitytree);
410 print_r($activitytree);
417 header(
'Content-Type: text/plain; charset=UTF-8');
423 global
$ilDB, $ilUser;
425 $res = $ilDB->queryF(
426 'SELECT global_to_system FROM cp_package WHERE obj_id = %s',
428 array($this->packageId)
432 $gystem =
$data[
'global_to_system'];
443 global
$ilDB, $ilUser;
445 $res = $ilDB->queryF(
446 'SELECT data FROM cp_suspend WHERE obj_id = %s AND user_id = %s',
447 array(
'integer',
'integer'),
448 array($this->packageId, $ilUser->getId())
452 $suspend_data =
$data[
'data'];
455 header(
'Content-Type: text/javascript; charset=UTF-8');
456 print($suspend_data);
460 header(
'Content-Type: text/plain; charset=UTF-8');
461 $suspend_data = json_decode($suspend_data);
462 print_r($suspend_data);
467 'DELETE FROM cp_suspend WHERE obj_id = %s AND user_id = %s',
468 array(
'integer',
'integer'),
469 array($this->packageId, $ilUser->getId())
475 global
$ilDB, $ilUser;
477 $res = $ilDB->queryF(
478 'SELECT * FROM cp_suspend WHERE obj_id = %s AND user_id = %s',
479 array(
'integer',
'integer'),
480 array($this->packageId, $ilUser->getId())
483 if(!$ilDB->numRows(
$res))
485 $ilDB->insert(
'cp_suspend', array(
486 'data' => array(
'clob', file_get_contents(
'php://input')),
487 'obj_id' => array(
'integer', $this->packageId),
488 'user_id' => array(
'integer', $ilUser->getId())
493 $ilDB->update(
'cp_suspend',
495 'data' => array(
'clob', file_get_contents(
'php://input'))
498 'obj_id' => array(
'integer', $this->packageId),
499 'user_id' => array(
'integer', $ilUser->getId())
507 global
$ilDB, $ilUser;
510 $g_data =
new stdClass();
512 $query =
'SELECT objective_id, scope_id, satisfied, measure, user_id '
513 .
'FROM cmi_gobjective, cp_node, cp_mapinfo '
514 .
'WHERE (cmi_gobjective.objective_id <> %s AND cmi_gobjective.status IS NULL '
515 .
'AND cp_node.slm_id = %s AND cp_node.nodename = %s '
516 .
'AND cp_node.cp_node_id = cp_mapinfo.cp_node_id '
517 .
'AND cmi_gobjective.objective_id = cp_mapinfo.targetobjectiveid) '
518 .
'GROUP BY objective_id, scope_id, satisfied, measure, user_id';
519 $res = $ilDB->queryF(
521 array(
'text',
'integer',
'text'),
522 array(
'-course_overall_status-', $this->packageId,
'mapInfo')
524 while(
$row = $ilDB->fetchAssoc(
$res))
526 $learner =
$row[
'user_id'];
527 $objective_id =
$row[
'objective_id'];
528 if(
$row[
'scope_id'] == 0)
534 $scope =
$row[
'scope_id'];
537 if(
$row[
'satisfied'] != NULL)
539 $toset =
$row[
'satisfied'];
540 $g_data->{
"satisfied"}->{$objective_id}->{$learner}->{$scope} = $toset;
543 if(
$row[
'measure'] != NULL)
545 $toset =
$row[
'measure'];
546 $g_data->{
"measure"}->{$objective_id}->{$learner}->{$scope} = $toset;
549 $gobjective_data = json_encode($g_data);
552 header(
'Content-Type: text/javascript; charset=UTF-8');
553 print($gobjective_data);
557 header(
'Content-Type: text/plain; charset=UTF-8');
558 $gobjective_data = json_decode($gobjective_data);
559 print_r($gobjective_data);
564 public function writeGObjective()
568 $user = $ilUser->getId();
569 $package = $this->packageId;
572 $g_data = json_decode(file_get_contents(
'php://input'));
578 foreach($g_data as $key => $value)
583 foreach($value as $skey => $svalue)
586 if($g_data->$key->$skey->$user->$package)
588 $o_value = $g_data->$key->$skey->$user->$package;
594 $o_value = $g_data->$key->$skey->$user->{
"null"};
600 $objective_id = $skey;
602 $dbuser = $ilUser->getId();
605 if($key ==
"satisfied")
607 $res = $ilDB->queryF(
'
608 SELECT * FROM cmi_gobjective
609 WHERE objective_id = %s
612 array(
'text',
'integer',
'integer'),
613 array($objective_id, $dbuser, $scope)
615 $ilLog->write(
"Count is: ".$ilDB->numRows(
$res));
616 if(!$ilDB->numRows(
$res))
619 INSERT INTO cmi_gobjective
620 (objective_id, user_id, satisfied, scope_id)
621 VALUES (%s, %s, %s, %s)',
622 array(
'text',
'integer',
'text',
'integer'),
623 array($objective_id, $dbuser, $toset, $scope)
629 UPDATE cmi_gobjective
631 WHERE objective_id = %s
634 array(
'text',
'text',
'integer',
'integer'),
635 array($toset, $objective_id, $dbuser, $scope)
639 if($key ==
"measure")
641 $res = $ilDB->queryF(
'
642 SELECT * FROM cmi_gobjective
643 WHERE objective_id = %s
646 array(
'text',
'integer',
'integer'),
647 array($objective_id, $dbuser, $scope)
649 $ilLog->write(
"Count is: ".$ilDB->numRows(
$res));
650 if(!$ilDB->numRows(
$res))
653 INSERT INTO cmi_gobjective
654 (objective_id, user_id, measure, scope_id)
655 VALUES (%s, %s, %s, %s)',
656 array(
'text',
'integer',
'text',
'integer'),
657 array($objective_id, $dbuser, $toset, $scope)
663 UPDATE cmi_gobjective
665 WHERE objective_id =%s
668 array(
'text',
'text',
'integer',
'integer'),
669 array($toset, $objective_id, $dbuser, $scope)
676 $completed = $g_data->$key->$skey->$user->{completed};
677 $measure = $g_data->$key->$skey->$user->{measure};
678 $satisfied = $g_data->$key->$skey->$user->{satisfied};
679 $obj =
'-course_overall_status-';
680 $pkg_id = $this->packageId;
683 SELECT * FROM cmi_gobjective
684 WHERE objective_id =%s
687 array(
'text',
'integer',
'integer'),
688 array($obj, $dbuser, $pkg_id)
694 INSERT INTO cmi_gobjective
695 (user_id, status, scope_id, measure, satisfied, objective_id)
696 VALUES (%s, %s, %s, %s, %s, %s)',
697 array(
'integer',
'text',
'integer',
'text',
'text',
'text'),
698 array($dbuser, $completed, $pkg_id, $measure, $satisfied, $obj)
704 UPDATE cmi_gobjective
708 WHERE objective_id = %s
711 array(
'text',
'text',
'text',
'text',
'integer',
'integer'),
712 array($completed, $measure, $satisfied, $obj, $dbuser, $pkg_id)
720 include_once(
"./Services/Tracking/classes/class.ilLPStatusWrapper.php");
728 $specialpages = array (
729 "_COURSECOMPLETE_" =>
"seq_coursecomplete",
730 "_ENDSESSION_" =>
"seq_endsession",
731 "_SEQBLOCKED_" =>
"seq_blocked",
732 "_NOTHING_" =>
"seq_nothing",
733 "_ERROR_" =>
"seq_error",
734 "_DEADLOCK_" =>
"seq_deadlock",
735 "_INVALIDNAVREQ_" =>
"seq_invalidnavreq",
736 "_SEQABANDON_" =>
"seq_abandon",
737 "_SEQABANDONALL_" =>
"seq_abandonall",
741 $this->tpl =
new ilTemplate(
"tpl.scorm2004.specialpages.html",
false,
false,
"Modules/Scorm2004");
743 $this->tpl->setVariable(
'TXT_SPECIALPAGE',$lng->txt($specialpages[$this->page]));
744 if ($this->page!=
"_TOC_" && $this->page!=
"_SEQABANDON_" && $this->page!=
"_SEQABANDONALL_" ) {
745 $this->tpl->setVariable(
'CLOSE_WINDOW',$lng->txt(
'seq_close'));
747 $this->tpl->setVariable(
'CLOSE_WINDOW',
"");
749 $this->tpl->show(
"DEFAULT",
false);
753 public function fetchCMIData()
755 $data = $this->getCMIData($this->userId, $this->packageId);
758 header(
'Content-Type: text/javascript; charset=UTF-8');
759 print(json_encode(
$data));
763 header(
'Content-Type: text/plain; charset=UTF-8');
764 print(var_export(
$data,
true));
768 public function persistCMIData(
$data = null)
772 if ($this->slm->getDefaultLessonMode() ==
"browse") {
return;}
774 $data = json_decode(is_string(
$data) ?
$data : file_get_contents(
'php://input'));
775 $ilLog->write(
"Got data:". file_get_contents(
'php://input'));
777 $return = $this->setCMIData($this->userId, $this->packageId,
$data, $this->ref_id);
781 header(
'Content-Type: text/javascript; charset=UTF-8');
782 print(json_encode($return));
786 header(
'Content-Type: text/html; charset=UTF-8');
787 print(var_export($return,
true));
795 private function normalizeFields($table, &$node)
798 foreach (self::$schema[$table] as $k => $v)
801 if (isset($value) && is_string($v) && !preg_match($v, $value))
808 private function getCMIData($userId, $packageId)
817 foreach(self::$schema as $k => &$v)
819 $result[
'schema'][$k] = array_keys($v);
824 $q =
'SELECT cmi_node.*
826 INNER JOIN cp_node ON cmi_node.cp_node_id = cp_node.cp_node_id
827 WHERE cmi_node.user_id = %s
828 AND cp_node.slm_id = %s';
833 $q =
'SELECT cmi_comment.*
835 INNER JOIN cmi_node ON cmi_node.cmi_node_id = cmi_comment.cmi_node_id
836 INNER JOIN cp_node ON cp_node.cp_node_id = cmi_node.cp_node_id
837 WHERE cmi_node.user_id = %s
838 AND cp_node.slm_id = %s';
842 case "correct_response":
843 $q =
'SELECT cmi_correct_response.*
844 FROM cmi_correct_response
845 INNER JOIN cmi_interaction
846 ON cmi_interaction.cmi_interaction_id = cmi_correct_response.cmi_interaction_id
847 INNER JOIN cmi_node ON cmi_node.cmi_node_id = cmi_interaction.cmi_node_id
848 INNER JOIN cp_node ON cp_node.cp_node_id = cmi_node.cp_node_id
849 WHERE cmi_node.user_id = %s
850 AND cp_node.slm_id = %s';
855 $q =
'SELECT cmi_interaction.*
857 INNER JOIN cmi_node ON cmi_node.cmi_node_id = cmi_interaction.cmi_node_id
858 INNER JOIN cp_node ON cp_node.cp_node_id = cmi_node.cp_node_id
859 WHERE cmi_node.user_id = %s
860 AND cp_node.slm_id = %s';
865 $q =
'SELECT cmi_objective.*
867 INNER JOIN cmi_node ON cmi_node.cmi_node_id = cmi_objective.cmi_node_id
868 INNER JOIN cp_node ON cp_node.cp_node_id = cmi_node.cp_node_id
869 WHERE cmi_node.user_id = %s
870 AND cp_node.slm_id = %s';
875 $q =
'SELECT usr_data.usr_id user_id,
876 CONCAT(CONCAT(COALESCE(usr_data.firstname, \'\'), \' \'), COALESCE(usr_data.lastname, \'\')) learner_name,
877 sahs_lm.id slm_id , sahs_lm.default_lesson_mode "mode", sahs_lm.credit
878 FROM usr_data, cp_package
879 INNER JOIN sahs_lm ON cp_package.obj_id = sahs_lm.id
880 WHERE usr_data.usr_id = %s
881 AND sahs_lm.id = %s';
887 $types = array(
'integer',
'integer');
888 $values = array($userId, $packageId);
889 $res = $ilDB->queryF($q, $types, $values);
891 $result[
'data'][$k] = array();
893 while(
$row = $ilDB->fetchAssoc(
$res))
895 $tmp_result = array();
896 foreach(
$row as $key => $value)
898 $tmp_result[] = $value;
900 $result[
'data'][$k][] = $tmp_result;
906 private function removeCMIData($userId, $packageId, $cp_node_id=null)
912 $delorder = array(
'correct_response',
'objective',
'interaction',
'comment',
'node');
914 foreach($delorder as $k)
916 if(is_null($cp_node_id))
922 cmi_correct_response WHERE cmi_interaction_id IN (
923 SELECT cmi_interaction.cmi_interaction_id FROM cmi_interaction
924 INNER JOIN cmi_node ON cmi_node.cmi_node_id = cmi_interaction.cmi_node_id
925 INNER JOIN cp_node ON cmi_node.cp_node_id = cp_node.cp_node_id
926 WHERE cmi_node.user_id = %s
927 AND cp_node.slm_id = %s)';
931 $q =
'DELETE FROM cmi_interaction
932 WHERE cmi_node_id IN (
933 SELECT cmi_node.cmi_node_id FROM cmi_node
934 INNER JOIN cp_node ON cmi_node.cp_node_id = cp_node.cp_node_id
935 WHERE cmi_node.user_id = %s
936 AND cp_node.slm_id = %s)';
940 $q =
'DELETE FROM cmi_comment
941 WHERE cmi_node_id IN (
942 SELECT cmi_node.cmi_node_id FROM cmi_node
943 INNER JOIN cp_node ON cmi_node.cp_node_id = cp_node.cp_node_id
944 WHERE cmi_node.user_id = %s
945 AND cp_node.slm_id = %s)';
949 $q =
'DELETE FROM cmi_objective
950 WHERE cmi_node_id IN (
951 SELECT cmi_node.cmi_node_id FROM cmi_node
952 INNER JOIN cp_node ON cmi_node.cp_node_id = cp_node.cp_node_id
953 WHERE cmi_node.user_id = %s
954 AND cp_node.slm_id = %s)';
958 $q =
'DELETE FROM cmi_node
959 WHERE user_id = %s AND cp_node_id IN (
960 SELECT cp_node_id FROM cp_node
965 $types = array(
'integer',
'integer');
966 $values = array($userId, $packageId);
967 $ilDB->manipulateF($q, $types, $values);
973 case "correct_response":
974 $q =
'DELETE FROM cmi_correct_response
975 WHERE cmi_interaction_id IN (
976 SELECT cmi_interaction.cmi_interaction_id FROM cmi_interaction
977 INNER JOIN cmi_node ON cmi_node.cmi_node_id = cmi_interaction.cmi_node_id
978 WHERE cmi_node.cp_node_id = %s
979 AND cmi_node.user_id = %s)';
983 $q =
'DELETE FROM cmi_interaction
984 WHERE cmi_node_id IN (
985 SELECT cmi_node.cmi_node_id FROM cmi_node
986 WHERE cmi_node.cp_node_id = %s
987 AND cmi_node.user_id = %s)';
991 $q =
'DELETE FROM cmi_comment
992 WHERE cmi_node_id IN (
993 SELECT cmi_node.cmi_node_id FROM cmi_node
994 WHERE cmi_node.cp_node_id = %s
995 AND cmi_node.user_id = %s)';
999 $q =
'DELETE FROM cmi_objective
1000 WHERE cmi_node_id IN (
1001 SELECT cmi_node.cmi_node_id FROM cmi_node
1002 WHERE cmi_node.cp_node_id = %s
1003 AND cmi_node.user_id = %s)';
1007 $q =
'DELETE FROM cmi_node WHERE cp_node_id = %s
1008 AND cmi_node.user_id = %s';
1012 $types = array(
'integer',
'integer');
1013 $values = array($cp_node_id, $userId);
1014 $ilDB->manipulateF($q, $types, $values);
1018 include_once(
"./Services/Tracking/classes/class.ilLPStatusWrapper.php");
1023 private function setCMIData($userId, $packageId,
$data, $a_ref_id)
1034 $tables = array(
'node',
'comment',
'interaction',
'objective',
'correct_response');
1036 foreach($tables as $table)
1038 $schem = & self::$schema[$table];
1041 if (!is_array(
$data->$table))
continue;
1047 foreach($schem as &$field)
1049 $field[
'no'] = $i++;
1058 case 'correct_response':
1059 $no = $schem[
'cmi_interaction_id'][
'no'];
1060 $ilLog->write(
"correct_response no: ".$no);
1061 $ilLog->write(
"The Row: ".count($row));
1062 $row[$no] = $map[
'interaction'][$row[$no]];
1063 $ilLog->write(
"Value: ".print_r($map[
'interaction'],
true));
1066 $no = $schem[
'cmi_node_id'][
'no'];
1067 $row[$no] = $map[
'node'][$row[$no]];
1070 $no = $schem[
'cmi_interaction_id'][
'no'];
1071 $row[$no] = $map[
'interaction'][$row[$no]];
1072 $no = $schem[
'cmi_node_id'][
'no'];
1073 $row[$no] = $map[
'node'][$row[$no]];
1076 $no = $schem[
'user_id'][
'no'];
1077 $row[$no] = $userId;
1083 $cp_no = $schem[
'cp_' . $table .
'_id'][
'no'];
1084 $cmi_no = $schem[
'cmi_' . $table .
'_id'][
'no'];
1088 $cmi_id = $row[$cmi_no];
1091 $row[$cmi_no] = null;
1094 foreach(array_keys($schem) as $key)
1099 if($table ===
'node')
1101 $this->removeCMIData($userId, $packageId, $row[$cp_no]);
1106 $ilLog->write(
"Checking table: ".$table);
1110 case 'correct_response':
1111 $row[$cmi_no] = $ilDB->nextId(
'cmi_correct_response');
1118 if (count($row) == 3)
1120 $ilDB->manipulateF(
'
1121 INSERT INTO cmi_correct_response
1122 (cmi_correct_resp_id, cmi_interaction_id, pattern)
1123 VALUES (%s, %s, %s)',
1124 array(
'integer',
'integer',
'text'),
1130 $ilLog->write(
"ERROR SCORM Player, setCMIData, incorrect number of values for cmi_correct_response.");
1136 $row[$cmi_no] = $ilDB->nextId(
'cmi_comment');
1138 $ilDB->insert(
'cmi_comment', array(
1139 'cmi_comment_id' => array(
'integer', $row[$cmi_no]),
1140 'cmi_node_id' => array(
'integer', $row[1]),
1141 'c_comment' => array(
'clob', $row[2]),
1142 'c_timestamp' => array(
'timestamp', $row[3]),
1143 'location' => array(
'text', $row[4]),
1144 'sourceislms' => array(
'integer', $row[5])
1149 $row[$cmi_no] = $ilDB->nextId(
'cmi_interaction');
1151 $ilDB->insert(
'cmi_interaction', array(
1152 'cmi_interaction_id' => array(
'integer', $row[$cmi_no]),
1153 'cmi_node_id' => array(
'integer', $row[1]),
1154 'description' => array(
'clob', $row[2]),
1155 'id' => array(
'text', $row[3]),
1156 'latency' => array(
'text', $row[4]),
1157 'learner_response' => array(
'clob', $row[5]),
1158 'result' => array(
'text', $row[6]),
1159 'c_timestamp' => array(
'text', $row[7]),
1160 'c_type' => array(
'text', $row[8]),
1161 'weighting' => array(
'float', $row[9])
1166 $row[$cmi_no] = $ilDB->nextId(
'cmi_objective');
1168 $ilDB->insert(
'cmi_objective', array(
1169 'cmi_interaction_id' => array(
'integer', $row[0]),
1170 'cmi_node_id' => array(
'integer', $row[1]),
1171 'cmi_objective_id' => array(
'integer', $row[$cmi_no]),
1172 'completion_status' => array(
'float', $row[3]),
1173 'description' => array(
'clob', $row[4]),
1174 'id' => array(
'text', $row[5]),
1175 'c_max' => array(
'float', $row[6]),
1176 'c_min' => array(
'float', $row[7]),
1177 'c_raw' => array(
'float', $row[8]),
1178 'scaled' => array(
'float', $row[9]),
1179 'progress_measure' => array(
'float', $row[10]),
1180 'success_status' => array(
'text', $row[11]),
1181 'scope' => array(
'text', $row[12])
1186 $row[$cmi_no] = $ilDB->nextId(
'cmi_node');
1188 $node_fields = array(
1189 'accesscount',
'accessduration',
'accessed',
'activityabsduration',
'activityattemptcount',
1190 'activityexpduration',
'activityprogstatus',
'attemptabsduration',
'attemptcomplamount',
'attemptcomplstatus',
1191 'attemptexpduration',
'attemptprogstatus',
'audio_captioning',
'audio_level',
'availablechildren',
1192 'cmi_node_id',
'completion',
'completion_status',
'completion_threshold',
'cp_node_id',
1193 'created',
'credit',
'delivery_speed',
'c_entry',
'c_exit',
1194 'c_language',
'launch_data',
'learner_name',
'location',
'c_max',
1195 'c_min',
'c_mode',
'modified',
'progress_measure',
'c_raw',
1196 'scaled',
'scaled_passing_score',
'session_time',
'success_status',
'suspend_data',
1197 'total_time',
'user_id',
'c_timestamp'
1200 $node_types = array(
1201 'integer',
'text',
'text',
'text',
'integer',
'text',
'integer',
'text',
'float',
'integer',
1202 'text',
'integer',
'integer',
'float',
'text',
'integer',
'float',
'text',
'text',
'integer',
1203 'text',
'text',
'float',
'text',
'text',
'text',
'clob',
'text',
'text',
'float',
1204 'float',
'text',
'text',
'float',
'float',
'float',
'float',
'text',
'text',
'clob',
1205 'text',
'integer',
'timestamp'
1208 $node_data = array();
1209 foreach($node_fields as $key => $node_field)
1212 $value = $row[$cmi_no];
1214 $value = date(
'Y-m-d H:i:s');
1216 $value = $row[$key];
1217 $node_data[$node_field] = array($node_types[$key], $value);
1220 $ilLog->write(
"Want to insert row: ".count($row) );
1221 $ilDB->insert(
'cmi_node', $node_data);
1234 if($table ===
'node')
1236 $result[(string)$row[$cp_no]] = $row[$cmi_no];
1240 $map[$table][$cmi_id] = $row[$cmi_no];
1247 include_once(
"./Modules/Scorm2004/classes/class.ilSCORM2004Tracking.php");
1251 include_once(
"./Services/Tracking/classes/class.ilLPStatusWrapper.php");
1257 function quoteJSONArray($a_array)
1261 if(!is_array($a_array) or !count($a_array))
1266 foreach($a_array as $k => $item)
1268 if ($item != null) {
1269 $a_array[$k] = $ilDB->quote($item);
1271 $a_array[$k] =
"NULL";
1288 require_once(
'classes/mimemap.php');
1291 return $ext ? $ext : mime_content_type(
$filename);
1299 public function getCookie()
1301 return unserialize(base64_decode(
$_COOKIE[IL_OP_COOKIE_NAME]));
1304 public function setCookie($cook)
1306 setCookie(IL_OP_COOKIE_NAME, base64_encode(serialize($cook)));
1319 die(
'Error: Cookie could not be established');
1322 $SAHS_LM_POSITION = 1;
1324 $comp = explode(
'/', (
string)
$path);
1325 $sahs = $comp[$SAHS_LM_POSITION];
1326 $cook = $this->getCookie();
1327 $perm = $cook[$sahs];
1336 header(
'HTTP/1.0 401 Unauthorized');
1337 die(
'/* Unauthorized */');
1340 $cook[$sahs] = $perm;
1341 $this->setCookie($cook);
1344 $path =
'.' .
$path;
1345 if (!is_file($path))
1347 header(
'HTTP/1.0 404 Not Found');
1348 die(
'/* Not Found ' . $path .
'*/');
1352 header(
'Content-Type: ' . $this->getMimetype($path));
1355 header(
'Expires: ' . gmdate(
'D, d M Y H:i:s', time() + session_cache_expire()*60) .
' GMT');
1356 header(
'Cache-Control: private');
1366 function get_max_attempts()
1370 $res = $ilDB->queryF(
1371 'SELECT max_attempt FROM sahs_lm WHERE id = %s',
1373 array($this->packageId)
1377 return $row[
'max_attempt'];
1380 function get_module_version()
1384 $res = $ilDB->queryF(
1385 'SELECT module_version FROM sahs_lm WHERE id = %s',
1387 array($this->packageId));
1390 return $row[
'module_version'];
1396 function get_actual_attempts()
1398 global
$ilDB, $ilUser;
1400 $res = $ilDB->queryF(
'
1401 SELECT rvalue FROM cmi_custom
1402 WHERE user_id = %s AND sco_id = %s
1403 AND lvalue = %s AND obj_id = %s',
1404 array(
'integer',
'integer',
'text',
'integer'),
1405 array($this->userId, 0,
'package_attempts', $this->packageId)
1409 $row[
'rvalue'] = str_replace(
"\r\n",
"\n",
$row[
'rvalue']);
1410 if(
$row[
'rvalue'] == null)
1414 return $row[
'rvalue'];
1420 function increase_attempt()
1422 global
$ilDB, $ilUser;
1425 $res = $ilDB->queryF(
'
1426 SELECT rvalue FROM cmi_custom
1431 array(
'integer',
'integer',
'text',
'integer'),
1432 array($this->userId, 0,
'package_attempts', $this->packageId)
1438 $row[
'rvalue'] = str_replace(
"\r\n",
"\n",
$row[
'rvalue']);
1439 if(
$row[
'rvalue'] == null)
1443 $new_rec =
$row[
'rvalue'] + 1;
1446 if(!is_array($tmp_row) || !count($tmp_row))
1448 $ilDB->manipulateF(
'
1449 INSERT INTO cmi_custom (rvalue, user_id, sco_id, obj_id, lvalue, c_timestamp)
1450 VALUES(%s, %s, %s, %s, %s, %s)',
1451 array(
'text',
'integer',
'integer',
'integer',
'text',
'timestamp'),
1452 array($new_rec, $this->userId, 0, $this->packageId,
'package_attempts', date(
'Y-m-d H:i:s'))
1457 $ilDB->manipulateF(
'
1465 array(
'text',
'timestamp',
'integer',
'integer',
'integer',
'text'),
1466 array($new_rec, date(
'Y-m-d H:i:s'), $this->userId, 0, $this->packageId,
'package_attempts')
1474 function save_module_version()
1476 global
$ilDB, $ilUser;
1478 $res = $ilDB->queryF(
'
1479 SELECT * FROM cmi_custom
1484 array(
'integer',
'integer',
'text',
'integer'),
1485 array($this->userId, 0,
'module_version', $this->packageId)
1487 if(!$ilDB->numRows(
$res))
1489 $ilDB->manipulateF(
'
1490 INSERT INTO cmi_custom (rvalue, user_id, sco_id, obj_id, lvalue, c_timestamp)
1491 VALUES(%s, %s, %s, %s, %s, %s)',
1492 array(
'text',
'integer',
'integer',
'integer',
'text',
'timestamp'),
1493 array($this->get_Module_Version(), $this->userId, 0, $this->packageId,
'module_version', date(
'Y-m-d H:i:s'))
1498 $ilDB->manipulateF(
'
1506 array(
'text',
'timestamp',
'integer',
'integer',
'integer',
'text'),
1507 array($this->get_Module_Version(), date(
'Y-m-d H:i:s'), $this->userId, 0, $this->packageId,
'module_version')