19 declare(strict_types=1);
    32         $ilDB = $DIC->database();
    35         $data = json_decode(file_get_contents(
'php://input'));
    39         if ($userId == null) {
    41             self::checkIfAllowed($packageId, $userId, 
$data->hash);
    44         if (
$data->last != 
"") {
    45             $last_visited = 
$data->last;
    58         $total_time_sec = null;
    59         if (
$data->total_time_sec != 
"") {
    60             $total_time_sec = 
$data->total_time_sec;
    63                                 SET total_time_sec = %s, last_visited = %s, hash_end =%s, last_access = %s    64                                 WHERE obj_id = %s AND user_id = %s',
    65                 array(
'integer', 
'text', 
'timestamp', 
'timestamp', 
'integer', 
'integer'),
    66                 array($total_time_sec, $last_visited, $endDate, date(
'Y-m-d H:i:s'), $packageId, $userId)
    68             if ($time_from_lms == 
true) {
    69                 self::ensureObjectDataCacheExistence();
    72                 $ilObjDataCache = $DIC[
"ilObjDataCache"];
    80                                 SET last_visited = %s, hash_end =%s, last_access = %s    81                                 WHERE obj_id = %s AND user_id = %s',
    82                 array(
'text', 
'timestamp', 
'timestamp', 
'integer', 
'integer'),
    83                 array($last_visited, $endDate, date(
'Y-m-d H:i:s'), $packageId, $userId)
    87         header(
'Content-Type: text/plain; charset=UTF-8');
    95         $ilDB = $DIC->database();
    97             'select hash from sahs_user where obj_id=%s AND user_id=%s AND hash_end>%s',
    98             array(
'integer', 
'integer', 
'timestamp'),
    99             array($packageId, $userId, date(
'Y-m-d H:i:s'))
   102         if ($rowtmp && (
int) $rowtmp[
'hash'] == $hash) {
   109     protected static function ensureObjectDataCacheExistence(): 
void   116         $ilObjDataCache = $DIC[
"ilObjDataCache"];
   121         $ilObjDataCache = 
new ilObjectDataCache();
   122         $GLOBALS[
'DIC'][
'ilObjDataCache'] = $ilObjDataCache;
   133         ?
string $data = null,
   140         if ($defaultLessonMode === 
"browse") {
   144         $jsMode = strpos(
$_SERVER[
'HTTP_ACCEPT'], 
'text/javascript') !== 
false;
   146         $data = json_decode(is_string(
$data) ? 
$data : file_get_contents(
'php://input'));
   147         $ilLog->debug(
"dataTo_setCMIData: " . file_get_contents(
'php://input'));
   151         if ($userId == null) {
   153             self::checkIfAllowed($packageId, $userId, 
$data->hash);
   167         $new_global_status = 
$data->now_global_status;
   168         $return[
"new_global_status"] = $new_global_status;
   171         $score_scaled = 
$data->node[0][35];
   172         if ($score_scaled != null) {
   180         $ilLog->debug(
"SCORM: return of persistCMIData: " . json_encode($return));
   182             header(
'Content-Type: text/javascript; charset=UTF-8');
   183             print(json_encode($return));
   185             header(
'Content-Type: text/html; charset=UTF-8');
   186             print(var_export($return, 
true));
   198         bool $getInteractions,
   203         $ilDB = $DIC->database();
   212         $i_check = $data->i_check;
   213         $i_set = $data->i_set;
   214         $b_node_update = 
false;
   216         $a_map_cmi_interaction_id = array();
   218         $tables = array(
'node', 
'comment', 
'interaction', 
'objective', 
'correct_response');
   220         foreach ($tables as $table) {
   221             if (!is_array($data->$table)) {
   225             $ilLog->debug(
"SCORM: setCMIData, table -" . $table . 
"-");
   228             foreach ($data->$table as &$row) {
   229                 $ilLog->debug(
"Checking table: " . $table);
   235                             'SELECT cmi_node_id FROM cmi_node WHERE cp_node_id = %s and user_id = %s',
   236                             array(
'integer', 
'integer'),
   237                             array($row[19], $userId)
   241                         if ($rowtmp != null) {
   242                             $cmi_node_id = $rowtmp[
'cmi_node_id'];
   243                             $b_node_update = 
true;
   245                             $cmi_node_id = 
$ilDB->nextId(
'cmi_node');
   246                             $b_node_update = 
false;
   248                         $ilLog->debug(
"setCMIdata with cmi_node_id = " . $cmi_node_id);
   250                             'accesscount' => array(
'integer', $row[0]),
   251                             'accessduration' => array(
'text', $row[1]),
   252                             'accessed' => array(
'text', $row[2]),
   253                             'activityabsduration' => array(
'text', $row[3]),
   254                             'activityattemptcount' => array(
'integer', $row[4]),
   255                             'activityexpduration' => array(
'text', $row[5]),
   256                             'activityprogstatus' => array(
'integer', $row[6]),
   257                             'attemptabsduration' => array(
'text', $row[7]),
   258                             'attemptcomplamount' => array(
'float', $row[8]),
   259                             'attemptcomplstatus' => array(
'integer', $row[9]),
   260                             'attemptexpduration' => array(
'text', $row[10]),
   261                             'attemptprogstatus' => array(
'integer', $row[11]),
   262                             'audio_captioning' => array(
'integer', $row[12]),
   263                             'audio_level' => array(
'float', $row[13]),
   264                             'availablechildren' => array(
'text', $row[14]),
   265                             'cmi_node_id' => array(
'integer', $cmi_node_id),
   266                             'completion' => array(
'float', $row[16]),
   267                             'completion_status' => array(
'text', $row[17]),
   268                             'completion_threshold' => array(
'text', $row[18]),
   269                             'cp_node_id' => array(
'integer', $row[19]),
   270                             'created' => array(
'text', $row[20]),
   271                             'credit' => array(
'text', $row[21]),
   272                             'delivery_speed' => array(
'float', $row[22]),
   273                             'c_entry' => array(
'text', $row[23]),
   274                             'c_exit' => array(
'text', $row[24]),
   275                             'c_language' => array(
'text', $row[25]),
   276                             'launch_data' => array(
'clob', $row[26]),
   277                             'learner_name' => array(
'text', $row[27]),
   278                             'location' => array(
'text', $row[28]),
   279                             'c_max' => array(
'float', $row[29]),
   280                             'c_min' => array(
'float', $row[30]),
   281                             'c_mode' => array(
'text', $row[31]),
   282                             'modified' => array(
'text', $row[32]),
   283                             'progress_measure' => array(
'float', $row[33]),
   284                             'c_raw' => array(
'float', $row[34]),
   285                             'scaled' => array(
'float', $row[35]),
   286                             'scaled_passing_score' => array(
'float', $row[36]),
   287                             'session_time' => array(
'text', $row[37]),
   288                             'success_status' => array(
'text', $row[38]),
   289                             'suspend_data' => array(
'clob', $row[39]),
   290                             'total_time' => array(
'text', $row[40]),
   291                             'user_id' => array(
'integer', $userId),
   292                             'c_timestamp' => array(
'timestamp', date(
'Y-m-d H:i:s')),
   293                             'additional_tables' => array(
'integer', $i_check)
   296                         if ($b_node_update == 
false) {
   297                             $ilDB->insert(
'cmi_node', $a_data);
   298                             $ilLog->debug(
"inserted");
   300                             $ilDB->update(
'cmi_node', $a_data, array(
'cmi_node_id' => array(
'integer', $cmi_node_id)));
   301                             $ilLog->debug(
"updated");
   304                         if ($b_node_update == 
true) {
   309                                     $q = 
'DELETE FROM cmi_comment WHERE cmi_node_id = %s';
   310                                     $ilDB->manipulateF(
$q, array(
'integer'), array($cmi_node_id));
   315                                 if ($getInteractions) {
   318                                         FROM cmi_correct_response cmir    319                                         INNER JOIN cmi_interaction cmii ON cmii.cmi_interaction_id = cmir.cmi_interaction_id    320                                         WHERE cmii.cmi_node_id = %s   322                                     $ilDB->manipulateF(
$q, array(
'integer'), array($cmi_node_id));
   327                                 if ($getInteractions) {
   328                                     $q = 
'DELETE FROM cmi_interaction WHERE cmi_node_id = %s';
   329                                     $ilDB->manipulateF(
$q, array(
'integer'), array($cmi_node_id));
   334                                 if ($getObjectives) {
   335                                     $q = 
'DELETE FROM cmi_objective WHERE cmi_node_id = %s';
   336                                     $ilDB->manipulateF(
$q, array(
'integer'), array($cmi_node_id));
   342                         $result[(string) $row[19]] = $cmi_node_id;
   346                         $row[0] = 
$ilDB->nextId(
'cmi_comment');
   348                         $ilDB->insert(
'cmi_comment', array(
   349                             'cmi_comment_id' => array(
'integer', $row[0]),
   350                             'cmi_node_id' => array(
'integer', $cmi_node_id),
   351                             'c_comment' => array(
'clob', $row[2]),
   352                             'c_timestamp' => array(
'text', $row[3]),
   353                             'location' => array(
'text', $row[4]),
   354                             'sourceislms' => array(
'integer', $row[5])
   359                         $cmi_interaction_id = 
$ilDB->nextId(
'cmi_interaction');
   360                         $a_map_cmi_interaction_id[] = array($row[0], $cmi_interaction_id);
   361                         $ilDB->insert(
'cmi_interaction', array(
   362                             'cmi_interaction_id' => array(
'integer', $cmi_interaction_id),
   363                             'cmi_node_id' => array(
'integer', $cmi_node_id),
   364                             'description' => array(
'clob', $row[2]),
   365                             'id' => array(
'text', $row[3]),
   366                             'latency' => array(
'text', $row[4]),
   367                             'learner_response' => array(
'clob', $row[5]),
   368                             'result' => array(
'text', $row[6]),
   369                             'c_timestamp' => array(
'text', $row[7]),
   370                             'c_type' => array(
'text', $row[8]),
   371                             'weighting' => array(
'float', $row[9])
   376                         $row[2] = 
$ilDB->nextId(
'cmi_objective');
   377                         $cmi_interaction_id = null;
   378                         if ($row[0] != null) {
   379                             foreach ($a_map_cmi_interaction_id as $i => $value) {
   380                                 if ($row[0] == $value[0]) {
   381                                     $cmi_interaction_id = $value[1];
   385                         $ilDB->insert(
'cmi_objective', array(
   386                             'cmi_interaction_id' => array(
'integer', $cmi_interaction_id),
   387                             'cmi_node_id' => array(
'integer', $cmi_node_id),
   388                             'cmi_objective_id' => array(
'integer', $row[2]),
   389                             'completion_status' => array(
'text', $row[3]),
   390                             'description' => array(
'clob', $row[4]),
   391                             'id' => array(
'text', $row[5]),
   392                             'c_max' => array(
'float', $row[6]),
   393                             'c_min' => array(
'float', $row[7]),
   394                             'c_raw' => array(
'float', $row[8]),
   395                             'scaled' => array(
'float', $row[9]),
   396                             'progress_measure' => array(
'float', $row[10]),
   397                             'success_status' => array(
'text', $row[11]),
   398                             'scope' => array(
'text', $row[12])
   402                     case 'correct_response':
   403                         $cmi_interaction_id = null;
   404                         if ($row[1] !== null) {
   405                             foreach ($a_map_cmi_interaction_id as $i => $value) {
   406                                 if ($row[1] == $value[0]) {
   407                                     $cmi_interaction_id = $value[1];
   410                             $row[0] = 
$ilDB->nextId(
'cmi_correct_response');
   411                             $ilDB->insert(
'cmi_correct_response', array(
   412                                 'cmi_correct_resp_id' => array(
'integer', $row[0]),
   413                                 'cmi_interaction_id' => array(
'integer', $cmi_interaction_id),
   414                                 'pattern' => array(
'text', $row[2])
   427         $changed_seq_utilities = $data->changed_seq_utilities;
   428         $ilLog->debug(
"SCORM2004 adl_seq_utilities changed: " . $changed_seq_utilities);
   429         if ($changed_seq_utilities == 1) {
   440     public static function writeGObjective(
int $user, 
int $package, ?array $g_data): array
   443         $ilDB = $DIC->database();
   445         $ilLog->debug(
"SCORM2004 writeGObjective");
   447         $returnAr = array(null, null, null);
   450         if ($g_data == null) {
   454         $rows_to_insert = array();
   456         foreach ($g_data as $key => $value) {
   457             $ilLog->debug(
"SCORM2004 writeGObjective -key: " . $key);
   461             foreach ($value as $skey => $svalue) {
   462                 $ilLog->debug(
"SCORM2004 writeGObjective -skey: " . $skey);
   475                 if (isset($svalue->$user->$package)) {
   476                     $o_value = $svalue->$user->$package;
   486                 $objective_id = $skey;
   489                 if ($key === 
"status") {
   494                     $completed = $svalue->$user->{
"completed"};
   495                     $measure = $svalue->$user->{
"measure"};
   496                     $satisfied = $svalue->$user->{
"satisfied"};
   498                     $returnAr = array($completed, $satisfied, $measure);
   500                     $obj = 
'-course_overall_status-';
   505                                         SELECT user_id FROM cmi_gobjective   506                                         WHERE objective_id =%s   509                         array(
'text', 
'integer', 
'integer'),
   510                         array($obj, $dbuser, $pkg_id)
   512                     $ilLog->debug(
"SCORM2004 Count is: " . 
$ilDB->numRows(
$res));
   516                                                 INSERT INTO cmi_gobjective   517                                                 (user_id, status, scope_id, measure, satisfied, objective_id)   518                                                 VALUES (%s, %s, %s, %s, %s, %s)',
   519                             array(
'integer', 
'text', 
'integer', 
'text', 
'text', 
'text'),
   520                             array($dbuser, $completed, $pkg_id, $measure, $satisfied, $obj)
   522                         $ilLog->debug(
"SCORM2004 cmi_gobjective Insert status=" . $completed . 
" scope_id=" . $pkg_id . 
" measure=" . $measure . 
" satisfied=" . $satisfied . 
" objective_id=" . $obj);
   526                                                 UPDATE cmi_gobjective   530                                                 WHERE objective_id = %s   533                             array(
'text', 
'text', 
'text', 
'text', 
'integer', 
'integer'),
   534                             array($completed, $measure, $satisfied, $obj, $dbuser, $pkg_id)
   540                     if ($rows_to_insert[$objective_id] == null) {
   541                         $rows_to_insert[$objective_id] = array();
   543                     $rows_to_insert[$objective_id][$key] = $toset;
   550             "SELECT global_to_system FROM cp_package WHERE obj_id = %s",
   555         $scope_id = (
$ilDB->fetchObject(
$res)->global_to_system) ? 0 : $package;
   558         $existing_key_template = 
"";
   559         foreach (array_keys($rows_to_insert) as $obj_id) {
   560             $existing_key_template .= 
"'{$obj_id}',";
   563         $existing_key_template = substr($existing_key_template, 0, -1);
   564         $existing_keys = array();
   566         if ($existing_key_template != 
"") {
   573                                                                   AND objective_id IN ($existing_key_template)",
   574                 array(
'integer', 
'integer'),
   575                 array($dbuser, $scope_id)
   579                 $existing_keys[] = $row[
'objective_id'];
   583         foreach ($rows_to_insert as $obj_id => $vals) {
   584             if (in_array($obj_id, $existing_keys)) {
   586                     "UPDATE cmi_gobjective   592                                                                                  completion_status=%s,   594                                                                          WHERE objective_id = %s   608                     array($vals[
'satisfied'],
   613                           $vals[
"completion_status"],
   614                           $vals[
"progress_measure"],
   622                     "INSERT INTO cmi_gobjective   623                                                                         (user_id, satisfied, measure, scope_id, status, objective_id,   624                                                                          score_raw, score_min, score_max, progress_measure, completion_status)   625                                                                         VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
   647                           $vals[
'progress_measure'],
   648                           $vals[
'completion_status']
   664         $ilDB = $DIC->database();
   665         $ilLog = $DIC[
"ilLog"];
   666         $saved_global_status = $data->saved_global_status;
   667         $ilLog->write(
"saved_global_status=" . $saved_global_status);
   670         $totalTime = (
int) $data->totalTimeCentisec;
   671         $totalTime = round($totalTime / 100);
   673             'UPDATE sahs_user SET sco_total_time_sec=%s, status=%s, percentage_completed=%s WHERE obj_id = %s AND user_id = %s',
   674             array(
'integer', 
'integer', 
'integer', 
'integer', 
'integer'),
   675             array($totalTime, $new_global_status, $data->percentageCompleted, $packageId, $userId)
   678         self::ensureObjectDataCacheExistence();
   680         $ilObjDataCache = $DIC[
"ilObjDataCache"];
   683         if ($new_global_status != null) {
   689         if ($time_from_lms == 
false) {
 static persistCMIData(int $packageId, int $refId, string $defaultLessonMode, bool $comments, bool $interactions, bool $objectives, bool $time_from_lms, ?string $data=null, ?int $userId=null)
 
static getLogger(string $a_component_id)
Get component logger. 
 
if($DIC->http() ->wrapper() ->query() ->has('do')) $defaultLessonMode
 
static checkIfAllowed(int $packageId, int $userId, int $hash)
 
static setCMIData(int $userId, int $packageId, object $data, bool $getComments, bool $getInteractions, bool $getObjectives)
 
static syncGlobalStatus(int $userId, int $packageId, int $refId, object $data, int $new_global_status, bool $time_from_lms)
 
static writeGObjective(int $user, int $package, ?array $g_data)
 
Class ilSCORM2004StoreData. 
 
static scormPlayerUnload(int $packageId, int $refId, bool $time_from_lms, ?int $userId=null)
 
static setGlobalObjectives(int $userId, int $packageId, object $data)
 
static getQuantityOfSCOs(int $a_slm_id)
 
static handleOutcomeWithoutLP(int $a_obj_id, int $a_usr_id, ?float $a_percentage)
 
static _syncReadEvent(int $a_obj_id, int $a_user_id, string $a_type, int $a_ref_id, ?bool $time_from_lms=null)
Synch read event table. 
 
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)