19 $data = json_decode(is_string(
$data) ?
$data : file_get_contents(
'php://input'));
21 if ($userId == null) {
22 $userId=(int)
$data->p;
26 if (
$data->last !=
"") $last_visited =
$data->last;
27 $endDate = date(
'Y-m-d H:i:s', mktime(date(
'H'), date(
'i')+5, date(
's'), date(
'm'), date(
'd'), date(
'Y')));
28 $ilDB->manipulateF(
'UPDATE sahs_user 29 SET last_visited = %s, hash_end =%s, last_access = %s 30 WHERE obj_id = %s AND user_id = %s',
31 array(
'text',
'timestamp',
'timestamp',
'integer',
'integer'),
32 array($last_visited, $endDate, date(
'Y-m-d H:i:s'),
$packageId, $userId)
35 header(
'Content-Type: text/plain; charset=UTF-8');
44 if ($defaultLessonMode ==
"browse") {
return;}
46 $jsMode = strpos($_SERVER[
'HTTP_ACCEPT'],
'text/javascript')!==
false;
48 $data = json_decode(is_string(
$data) ?
$data : file_get_contents(
'php://input'));
49 $ilLog->write(
"dataTo_setCMIData: ".file_get_contents(
'php://input'));
51 if ($userId == null) {
52 $userId=(int)
$data->p;
68 $new_global_status =
$data->now_global_status;
69 $return[
"new_global_status"] = $new_global_status;
73 $ilLog->write(
"SCORM: return of persistCMIData: ".json_encode($return));
76 header(
'Content-Type: text/javascript; charset=UTF-8');
77 print(json_encode($return));
81 header(
'Content-Type: text/html; charset=UTF-8');
82 print(var_export($return,
true));
88 $res = $ilDB->queryF(
'select hash from sahs_user where obj_id=%s AND user_id=%s AND hash_end>%s',
89 array(
'integer',
'integer',
'timestamp'),
92 $rowtmp=$ilDB->fetchAssoc(
$res);
93 if ($rowtmp[
'hash']==$hash)
return;
94 else die(
"not allowed");
104 $i_check=
$data->i_check;
106 $b_node_update=
false;
108 $a_map_cmi_interaction_id=array();
110 $tables = array(
'node',
'comment',
'interaction',
'objective',
'correct_response');
112 foreach($tables as $table)
114 if (!is_array(
$data->$table))
continue;
116 $ilLog->write(
"SCORM: setCMIData, table -".$table.
"-");
121 $ilLog->write(
"Checking table: ".$table);
127 $res = $ilDB->queryF(
128 'SELECT cmi_node_id FROM cmi_node WHERE cp_node_id = %s and user_id = %s',
129 array(
'integer',
'integer'),
130 array($row[19],$userId)
132 $rowtmp=$ilDB->fetchAssoc(
$res);
133 $cmi_node_id=$rowtmp[
'cmi_node_id'];
134 if ($cmi_node_id!=null) $b_node_update=
true;
136 $cmi_node_id = $ilDB->nextId(
'cmi_node');
137 $b_node_update=
false;
139 $ilLog->write(
"setCMIdata with cmi_node_id = ".$cmi_node_id);
141 'accesscount' => array(
'integer', $row[0]),
142 'accessduration' => array(
'text', $row[1]),
143 'accessed' => array(
'text', $row[2]),
144 'activityabsduration' => array(
'text', $row[3]),
145 'activityattemptcount' => array(
'integer', $row[4]),
146 'activityexpduration' => array(
'text', $row[5]),
147 'activityprogstatus' => array(
'integer', $row[6]),
148 'attemptabsduration' => array(
'text', $row[7]),
149 'attemptcomplamount' => array(
'float', $row[8]),
150 'attemptcomplstatus' => array(
'integer', $row[9]),
151 'attemptexpduration' => array(
'text', $row[10]),
152 'attemptprogstatus' => array(
'integer', $row[11]),
153 'audio_captioning' => array(
'integer', $row[12]),
154 'audio_level' => array(
'float', $row[13]),
155 'availablechildren' => array(
'text', $row[14]),
156 'cmi_node_id' => array(
'integer', $cmi_node_id),
157 'completion' => array(
'float', $row[16]),
158 'completion_status' => array(
'text', $row[17]),
159 'completion_threshold' => array(
'text', $row[18]),
160 'cp_node_id' => array(
'integer', $row[19]),
161 'created' => array(
'text', $row[20]),
162 'credit' => array(
'text', $row[21]),
163 'delivery_speed' => array(
'float', $row[22]),
164 'c_entry' => array(
'text', $row[23]),
165 'c_exit' => array(
'text', $row[24]),
166 'c_language' => array(
'text', $row[25]),
167 'launch_data' => array(
'clob', $row[26]),
168 'learner_name' => array(
'text', $row[27]),
169 'location' => array(
'text', $row[28]),
170 'c_max' => array(
'float', $row[29]),
171 'c_min' => array(
'float', $row[30]),
172 'c_mode' => array(
'text', $row[31]),
173 'modified' => array(
'text', $row[32]),
174 'progress_measure' => array(
'float', $row[33]),
175 'c_raw' => array(
'float', $row[34]),
176 'scaled' => array(
'float', $row[35]),
177 'scaled_passing_score' => array(
'float', $row[36]),
178 'session_time' => array(
'text', $row[37]),
179 'success_status' => array(
'text', $row[38]),
180 'suspend_data' => array(
'clob', $row[39]),
181 'total_time' => array(
'text', $row[40]),
182 'user_id' => array(
'integer', $userId),
183 'c_timestamp' => array(
'timestamp', date(
'Y-m-d H:i:s')),
184 'additional_tables' => array(
'integer', $i_check)
187 if($b_node_update==
false) {
188 $ilLog->write(
"Want to insert row: ".count($row) );
189 $ilDB->insert(
'cmi_node', $a_data);
191 $ilDB->update(
'cmi_node', $a_data, array(
'cmi_node_id' => array(
'integer', $cmi_node_id)));
192 $ilLog->write(
"updated");
195 if($b_node_update==
true) {
200 $q =
'DELETE FROM cmi_comment WHERE cmi_node_id = %s';
201 $ilDB->manipulateF($q, array(
'integer'), array($cmi_node_id));
206 if ($getInteractions) {
207 $q =
'DELETE FROM cmi_correct_response 208 WHERE cmi_interaction_id IN ( 209 SELECT cmi_interaction.cmi_interaction_id FROM cmi_interaction WHERE cmi_interaction.cmi_node_id = %s)';
210 $ilDB->manipulateF($q, array(
'integer'), array($cmi_node_id));
215 if ($getInteractions) {
216 $q =
'DELETE FROM cmi_interaction WHERE cmi_node_id = %s';
217 $ilDB->manipulateF($q, array(
'integer'), array($cmi_node_id));
222 if ($getObjectives) {
223 $q =
'DELETE FROM cmi_objective WHERE cmi_node_id = %s';
224 $ilDB->manipulateF($q, array(
'integer'), array($cmi_node_id));
230 $result[(string)$row[19]] = $cmi_node_id;
234 $row[0] = $ilDB->nextId(
'cmi_comment');
236 $ilDB->insert(
'cmi_comment', array(
237 'cmi_comment_id' => array(
'integer', $row[0]),
238 'cmi_node_id' => array(
'integer', $cmi_node_id),
239 'c_comment' => array(
'clob', $row[2]),
240 'c_timestamp' => array(
'text', $row[3]),
241 'location' => array(
'text', $row[4]),
242 'sourceislms' => array(
'integer', $row[5])
247 $cmi_interaction_id = $ilDB->nextId(
'cmi_interaction');
248 $a_map_cmi_interaction_id[]=array($row[0],$cmi_interaction_id);
249 $ilDB->insert(
'cmi_interaction', array(
250 'cmi_interaction_id' => array(
'integer', $cmi_interaction_id),
251 'cmi_node_id' => array(
'integer', $cmi_node_id),
252 'description' => array(
'clob', $row[2]),
253 'id' => array(
'text', $row[3]),
254 'latency' => array(
'text', $row[4]),
255 'learner_response' => array(
'clob', $row[5]),
256 'result' => array(
'text', $row[6]),
257 'c_timestamp' => array(
'text', $row[7]),
258 'c_type' => array(
'text', $row[8]),
259 'weighting' => array(
'float', $row[9])
264 $row[2] = $ilDB->nextId(
'cmi_objective');
265 $cmi_interaction_id = null;
266 if ($row[0] != null) {
267 for($i=0;$i<count($a_map_cmi_interaction_id);$i++)
268 if ($row[0] == $a_map_cmi_interaction_id[$i][0]) $cmi_interaction_id=$a_map_cmi_interaction_id[$i][1];
270 $ilDB->insert(
'cmi_objective', array(
271 'cmi_interaction_id' => array(
'integer', $cmi_interaction_id),
272 'cmi_node_id' => array(
'integer', $cmi_node_id),
273 'cmi_objective_id' => array(
'integer', $row[2]),
274 'completion_status' => array(
'text', $row[3]),
275 'description' => array(
'clob', $row[4]),
276 'id' => array(
'text', $row[5]),
277 'c_max' => array(
'float', $row[6]),
278 'c_min' => array(
'float', $row[7]),
279 'c_raw' => array(
'float', $row[8]),
280 'scaled' => array(
'float', $row[9]),
281 'progress_measure' => array(
'float', $row[10]),
282 'success_status' => array(
'text', $row[11]),
283 'scope' => array(
'text', $row[12])
287 case 'correct_response':
288 $cmi_interaction_id = null;
289 if ($row[1] !== null) {
290 for($i=0;$i<count($a_map_cmi_interaction_id);$i++)
291 if ($row[1] == $a_map_cmi_interaction_id[$i][0]) $cmi_interaction_id=$a_map_cmi_interaction_id[$i][1];
292 $row[0] = $ilDB->nextId(
'cmi_correct_response');
293 $ilDB->insert(
'cmi_correct_response', array(
294 'cmi_correct_resp_id' => array(
'integer', $row[0]),
295 'cmi_interaction_id' => array(
'integer', $cmi_interaction_id),
296 'pattern' => array(
'text', $row[2])
334 $changed_seq_utilities=
$data->changed_seq_utilities;
335 $ilLog->write(
"SCORM2004 adl_seq_utilities changed: ".$changed_seq_utilities);
336 if ($changed_seq_utilities == 1) {
344 $saved_global_status=
$data->saved_global_status;
345 $ilLog->write(
"saved_global_status=".$saved_global_status);
352 if (!
$data->packageAttempts) {
353 $val_set = $ilDB->
queryF(
'SELECT package_attempts FROM sahs_user WHERE obj_id = %s AND user_id = %s',
354 array(
'integer',
'integer'), array(
$packageId,$userId));
355 $val_rec = $ilDB->fetchAssoc($val_set);
356 $attempts = $val_rec[
"package_attempts"];
358 $attempts=
$data->packageAttempts;
360 if ($attempts == null) $attempts =
"";
363 $totalTime=(int)
$data->totalTimeCentisec;
364 $totalTime=round($totalTime/100);
365 $ilDB->
queryF(
'UPDATE sahs_user SET sco_total_time_sec=%s, status=%s, percentage_completed=%s, package_attempts=%s WHERE obj_id = %s AND user_id = %s',
366 array(
'integer',
'integer',
'integer',
'integer',
'integer',
'integer'),
367 array($totalTime, $new_global_status,
$data->percentageCompleted, $attempts,
$packageId, $userId));
369 self::ensureObjectDataCacheExistence();
370 global $ilObjDataCache;
371 include_once(
"./Services/Tracking/classes/class.ilChangeEvent.php");
377 if ($new_global_status != null) {
380 include_once(
"./Services/Tracking/classes/class.ilObjUserTracking.php");
381 include_once(
"./Services/Tracking/classes/class.ilLPStatus.php");
395 $ilLog->write(
"SCORM2004 writeGObjective");
397 $returnAr=array(null,null,null);
403 $rows_to_insert = Array();
405 foreach($g_data as $key => $value)
407 $ilLog->write(
"SCORM2004 writeGObjective -key: ".$key);
411 foreach($value as $skey => $svalue)
413 $ilLog->write(
"SCORM2004 writeGObjective -skey: ".$skey);
415 if($g_data->$key->$skey->$user->$package)
417 $o_value = $g_data->$key->$skey->$user->$package;
424 $o_value = $g_data->$key->$skey->$user->{
"null"};
430 $objective_id = $skey;
438 $completed = $g_data->$key->$skey->$user->{completed};
439 $measure = $g_data->$key->$skey->$user->{measure};
440 $satisfied = $g_data->$key->$skey->$user->{satisfied};
442 $returnAr=array($completed, $satisfied, $measure);
444 $obj =
'-course_overall_status-';
447 $res = $ilDB->queryF(
' 448 SELECT user_id FROM cmi_gobjective 449 WHERE objective_id =%s 452 array(
'text',
'integer',
'integer'),
453 array($obj, $dbuser, $pkg_id)
455 $ilLog->write(
"SCORM2004 Count is: ".$ilDB->numRows(
$res));
456 if(!$ilDB->numRows(
$res))
459 INSERT INTO cmi_gobjective 460 (user_id, status, scope_id, measure, satisfied, objective_id) 461 VALUES (%s, %s, %s, %s, %s, %s)',
462 array(
'integer',
'text',
'integer',
'text',
'text',
'text'),
463 array($dbuser, $completed, $pkg_id, $measure, $satisfied, $obj)
465 $ilLog->write(
"SCORM2004 cmi_gobjective Insert status=".$completed.
" scope_id=".$pkg_id.
" measure=".$measure.
" satisfied=".$satisfied.
" objective_id=".$obj);
470 UPDATE cmi_gobjective 474 WHERE objective_id = %s 477 array(
'text',
'text',
'text',
'text',
'integer',
'integer'),
478 array($completed, $measure, $satisfied, $obj, $dbuser, $pkg_id)
480 $ilLog->write(
"SCORM2004 cmi_gobjective Update status=".$completed.
" scope_id=".$pkg_id.
" measure=".$measure.
" satisfied=".$satisfied.
" objective_id=".$obj);
485 if($rows_to_insert[$objective_id] == NULL)
487 $rows_to_insert[$objective_id] = Array();
489 $rows_to_insert[$objective_id][$key] = $toset;
496 $res = $ilDB->queryF(
"SELECT global_to_system 503 $scope_id = ($ilDB->fetchObject(
$res)->global_to_system) ? 0 : $package;
506 $existing_key_template =
"";
507 foreach(array_keys($rows_to_insert) as $obj_id)
509 $existing_key_template .=
"'{$obj_id}',";
513 $existing_key_template = substr($existing_key_template, 0, strlen($existing_key_template) - 1);
514 $existing_keys = Array();
516 if($existing_key_template !=
"")
519 $res = $ilDB->queryF(
"SELECT objective_id 523 AND objective_id IN ($existing_key_template)",
524 array(
'integer',
'integer'),
525 array($dbuser, $scope_id)
528 while(
$row = $ilDB->fetchAssoc(
$res))
530 $existing_keys[] =
$row[
'objective_id'];
534 foreach($rows_to_insert as $obj_id => $vals)
536 if(in_array($obj_id, $existing_keys))
538 $ilDB->manipulateF(
"UPDATE cmi_gobjective 544 completion_status=%s, 546 WHERE objective_id = %s 550 array(
'text',
'text',
'text',
'text',
'text',
'text',
551 'text',
'text',
'integer',
'integer'),
553 array($vals[
'satisfied'], $vals[
"measure"], $vals[
"score_raw"],
554 $vals[
"score_min"], $vals[
"score_max"],
555 $vals[
"completion_status"], $vals[
"progress_measure"],
556 $obj_id, $dbuser, $scope_id)
560 $ilDB->manipulateF(
"INSERT INTO cmi_gobjective 561 (user_id, satisfied, measure, scope_id, status, objective_id, 562 score_raw, score_min, score_max, progress_measure, completion_status) 563 VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
566 array(
'integer',
'text',
'text',
'integer',
'text',
'text',
567 'text',
'text',
'text',
'text',
'text'),
569 array($dbuser, $vals[
'satisfied'], $vals[
'measure'],
570 $scope_id, NULL, $obj_id, $vals[
'score_raw'],
571 $vals[
'score_min'], $vals[
'score_max'],
572 $vals[
'progress_measure'], $vals[
'completion_status'])
585 protected static function ensureObjectDataCacheExistence()
590 global $ilObjDataCache;
597 require_once
'./Services/Object/classes/class.ilObjectDataCache.php';
598 $ilObjDataCache =
new ilObjectDataCache();
599 $GLOBALS[
'ilObjDataCache'] = $ilObjDataCache;
persistCMIData($userId=null, $packageId, $defaultLessonMode, $comments, $interactions, $objectives, $data=null)
scormPlayerUnload($userId=null, $packageId)
Class ilSCORM2004StoreData.
writeGObjective($g_data, $user, $package)
setGlobalObjectives($userId, $packageId, $data)
setCMIData($userId, $packageId, $data, $getComments, $getInteractions, $getObjectives)
queryF($a_query, $a_types, $a_values)
Formatted query (for SELECTS).
_recordReadEvent($a_type, $a_ref_id, $obj_id, $usr_id, $isCatchupWriteEvents=true, $a_ext_rc=false, $a_ext_time=false)
Records a read event and catches up with write events.
static writeStatus($a_obj_id, $a_user_id, $a_status, $a_percentage=false, $a_force_per=false)
Write status for user and object.
while($lm_rec=$ilDB->fetchAssoc($lm_set)) $data
checkIfAllowed($packageId, $userId, $hash)
syncGlobalStatus($userId, $packageId, $data, $new_global_status)