5 declare(strict_types=1);
    41     public const CONVERT_XSL = 
'./Modules/Scorm2004/templates/xsl/op/scorm12To2004.xsl';
    42     public const WRAPPER_HTML = 
'./Modules/Scorm2004/scripts/converter/GenericRunTimeWrapper1.0_aadlc/GenericRunTimeWrapper.htm';
    43     public const WRAPPER_JS = 
'./Modules/Scorm2004/scripts/converter/GenericRunTimeWrapper1.0_aadlc/SCOPlayerWrapper.js';
    50     public function __construct(
int $a_id = 0, 
bool $a_call_by_reference = 
true)
    54         $this->
lng = $DIC->language();
    55         $this->error = $DIC[
"ilErr"];
    56         $this->db = $DIC->database();
    58         $this->
user = $DIC->user();
    59         $this->
tabs = $DIC->tabs();
    71         $this->import_sequencing = $a_val;
    94         if (!function_exists(
'json_encode') || !function_exists(
'json_decode')) {
    98         $needs_convert = 
false;
   105         $check_for_manifest_file = is_file($manifest_file);
   110         if (!$check_for_manifest_file) {
   111             $ilErr->raiseError($this->
lng->txt(
"Manifestfile $manifest_file not found!"), 
$ilErr->MESSAGE);
   116         if ($check_for_manifest_file) {
   117             $manifest_file_array = file($manifest_file);
   119             foreach ($manifest_file_array as $mfa) {
   121                 if (@iconv(
'UTF-8', 
'UTF-8', $mfa) != $mfa) {
   122                     $needs_convert = 
true;
   130             $estimated_manifest_filesize = filesize($manifest_file) * 2;
   134             $check_disc_free = 2;
   139         if ($needs_convert) {
   141             if ($check_for_manifest_file && ($check_disc_free > 1)) {
   143                 if (!copy($manifest_file, $manifest_file . 
".old")) {
   144                     echo 
"Failed to copy $manifest_file...<br>\n";
   149                 $f_write_handler = fopen($manifest_file . 
".new", 
"w");
   150                 $f_read_handler = fopen($manifest_file . 
".old", 
"r");
   151                 while (!feof($f_read_handler)) {
   152                     $zeile = fgets($f_read_handler);
   154                     fwrite($f_write_handler, mb_convert_encoding($zeile, 
"UTF-8", mb_detect_encoding($zeile)));
   156                 fclose($f_read_handler);
   157                 fclose($f_write_handler);
   160                 if (!copy($manifest_file . 
".new", $manifest_file)) {
   161                     echo 
"Failed to copy $manifest_file...<br>\n";
   164                 if (!@is_file($manifest_file)) {
   165                     $ilErr->raiseError($this->
lng->txt(
"cont_no_manifest"), 
$ilErr->WARNING);
   170                 if (!($check_disc_free > 1)) {
   171                     $ilErr->raiseError($this->
lng->txt(
"Not enough space left on device!"), 
$ilErr->MESSAGE);
   177             $hmani = fopen($manifest_file, 
"r");
   178             $start = fread($hmani, 3);
   179             if (strtolower(bin2hex($start)) === 
"efbbbf") {
   180                 $f_write_handler = fopen($manifest_file . 
".new", 
"w");
   181                 while (!feof($hmani)) {
   182                     $n = fread($hmani, 900);
   183                     fwrite($f_write_handler, $n);
   185                 fclose($f_write_handler);
   189                 if (!copy($manifest_file . 
".new", $manifest_file)) {
   190                     echo 
"Failed to copy $manifest_file...<br>\n";
   206         $out = file_get_contents($this->imsmanifestFile);
   207         $check = 
'/xmlns="http:\/\/www.imsglobal.org\/xsd\/imscp_v1p1"/';
   208         $replace = 
"xmlns=\"http://www.imsproject.org/xsd/imscp_rootv1p1p2\"";
   210         file_put_contents($this->imsmanifestFile, 
$out);
   219         ##check manifest-file for version. Check for schemaversion as this is a required element for SCORM 2004   220         ##accept 2004 3rd Edition an CAM 1.3 as valid schemas   224         $this->imsmanifestFile = $manifest;
   225         $doc = 
new DomDocument();
   229         $doc->load($this->imsmanifestFile);
   230         $elements = $doc->getElementsByTagName(
"schemaversion");
   232         if (isset($elements->item(0)->nodeValue)) {
   233             $schema = $elements->item(0)->nodeValue;
   235         if (strtolower(trim($schema)) === 
"cam 1.3" || strtolower(trim($schema)) === 
"2004 3rd edition" || strtolower(trim($schema)) === 
"2004 4th edition") {
   245         $organizations = $doc->getElementsByTagName(
"organizations");
   247         if ($organizations->item(0) == null) {
   248             die(
"organizations missing in manifest");
   250         $default = $organizations->item(0)->getAttribute(
"default");
   251         if ($default == 
"" || $default == null) {
   253             $organization = $doc->getElementsByTagName(
"organization");
   254             $item = $organization->item(0);
   255             if ($item !== null) {
   256                 $ident = $item->getAttribute(
"identifier");
   257                 $organizations->item(0)->setAttribute(
"default", $ident);
   265         $wrapperdir = $this->packageFolder . 
"/GenericRunTimeWrapper1.0_aadlc";
   266         if (!mkdir($wrapperdir) && !is_dir($wrapperdir)) {
   267             throw new \RuntimeException(sprintf(
'Directory "%s" was not created', $wrapperdir));
   269         copy(self::WRAPPER_HTML, $wrapperdir . 
"/GenericRunTimeWrapper.htm");
   270         copy(self::WRAPPER_JS, $wrapperdir . 
"/SCOPlayerWrapper.js");
   273         $this->backupManifest = $this->packageFolder . 
"/imsmanifest.xml.back";
   274         $ret = copy($this->imsmanifestFile, $this->backupManifest);
   277         $this->totransform = $doc;
   278         $ilLog->write(
"SCORM: about to transform to SCORM 2004");
   282         $xsl->load(self::CONVERT_XSL);
   283         $prc = 
new XSLTProcessor();
   284         $r = @$prc->importStyleSheet($xsl);
   286         file_put_contents($this->imsmanifestFile, $prc->transformToXML($this->totransform));
   288         $ilLog->write(
"SCORM: Transformation completed");
   298         $ilDB = $DIC->database();
   300         $result = 
$ilDB->queryF(
   302                         SELECT MAX(c_timestamp) last_access    303                         FROM cmi_node, cp_node    304                         WHERE cmi_node.cp_node_id = cp_node.cp_node_id    305                         AND cp_node.slm_id = %s   307                         GROUP BY c_timestamp',
   308             array(
'integer', 
'integer'),
   309             array($a_obj_id, $a_usr_id)
   311         if (
$ilDB->numRows($result)) {
   312             $row = 
$ilDB->fetchAssoc($result);
   313             return (
string) $row[
"last_access"];
   324         foreach ($a_users as $user) {
   341         $sco_set = 
$ilDB->queryF(
   343                 SELECT DISTINCT cmi_node.cp_node_id id   344                 FROM cp_node, cmi_node    346                 AND cp_node.cp_node_id = cmi_node.cp_node_id    347                 ORDER BY cmi_node.cp_node_id ',
   349             array($this->
getId())
   354         while ($sco_rec = 
$ilDB->fetchAssoc($sco_set)) {
   355             $item[
'id'] = $sco_rec[
"id"];
   356             $item[
'title'] = self::_lookupItemTitle((
int) $sco_rec[
"id"]);
   374         $val_set = 
$ilDB->queryF(
   375             'SELECT cp_node_id FROM cp_node    377                         AND cp_node.slm_id = %s',
   378             array(
'text', 
'integer'),
   379             array(
'item',$this->
getId())
   381         while ($val_rec = 
$ilDB->fetchAssoc($val_set)) {
   382             $scos[] = $val_rec[
'cp_node_id'];
   385         foreach ($scos as $sco) {
   386             $data_set = 
$ilDB->queryF(
   388                                 SELECT c_timestamp last_access, total_time, success_status, completion_status,   389                                            c_raw, scaled, cp_node_id   391                                 WHERE cp_node_id = %s   393                 array(
'integer',
'integer'),
   394                 array($sco,$a_user_id)
   397             while ($data_rec = 
$ilDB->fetchAssoc($data_set)) {
   398                 if ($data_rec[
"success_status"] != 
"" && $data_rec[
"success_status"] !== 
"unknown") {
   399                     $status = $data_rec[
"success_status"];
   401                     if ($data_rec[
"completion_status"] == 
"") {
   404                         $status = $data_rec[
"completion_status"];
   410                     if ($data_rec[
"c_raw"] != null) {
   411                         $score = $data_rec[
"c_raw"];
   412                         if ($data_rec[
"scaled"] != null) {
   416                     if ($data_rec[
"scaled"] != null) {
   417                         $score .= ($data_rec[
"scaled"] * 100) . 
"%";
   419                     $title = self::_lookupItemTitle((
int) $data_rec[
"cp_node_id"]);
   421                     $data[] = array(
"sco_id" => $data_rec[
"cp_node_id"],
   422                         "score" => $score, 
"time" => $time, 
"status" => $status,
"last_access" => $last_access,
"title" => 
$title);
   424                     $data_rec[
"total_time"] = self::_ISODurationToCentisec($data_rec[
"total_time"]) / 100;
   425                     $data[$data_rec[
"cp_node_id"]] = $data_rec;
   439         $val_set = 
$ilDB->queryF(
   440             'SELECT package_attempts FROM sahs_user WHERE user_id = %s AND obj_id = %s',
   441             array(
'integer',
'integer'),
   442             array($a_user_id, $this->
getId())
   445         $val_rec = 
$ilDB->fetchAssoc($val_set);
   447         if ($val_rec[
"package_attempts"] == null) {
   448             $val_rec[
"package_attempts"] = 0;
   451         return (
int) $val_rec[
"package_attempts"];
   460         $val_set = 
$ilDB->queryF(
   461             'SELECT module_version FROM sahs_user WHERE user_id = %s AND obj_id = %s',
   462             array(
'integer',
'integer'),
   463             array($a_user_id, $this->
getId())
   466         $val_rec = 
$ilDB->fetchAssoc($val_set);
   468         if ($val_rec[
"module_version"] == null) {
   469             $val_rec[
"module_version"] = 
"";
   471         return $val_rec[
"module_version"];
   480         $collection = $olp->getCollectionInstance();
   482             $scos = $collection->getItems();
   485         $fhandle = fopen($a_file, 
"rb");
   487         $obj_id = $this->getID();
   489         $usersToDelete = array();
   490         $fields = fgetcsv($fhandle, 4096, 
';');
   491         while (($csv_rows = fgetcsv($fhandle, 4096, 
";")) !== 
false) {
   493             $data = array_combine($fields, $csv_rows);
   495             if (isset(
$data[
"Login"])) {
   498             if (isset(
$data[
"login"])) {
   502             if (isset(
$data[
"user"]) && is_numeric(
$data[
"user"])) {
   507                 if (isset(
$data[
'LastAccess']) && 
$data[
'LastAccess']) {
   509                 } elseif (isset(
$data[
'Date']) && 
$data[
'Date']) {
   515                 if (isset(
$data[
"Status"])) {
   516                     if (is_numeric(
$data[
"Status"])) {
   517                         $status = 
$data[
"Status"];
   527                 if (isset(
$data[
"Attempts"])) {
   528                     $attempts = (
int) 
$data[
"Attempts"];
   531                 $percentage_completed = 0;
   533                     $percentage_completed = 100;
   534                 } elseif (isset(
$data[
'percentageCompletedSCOs'])) {
   535                     $percentage_completed = (
int) 
$data[
'percentageCompletedSCOs'];
   538                 $sco_total_time_sec = null;
   539                 if (isset(
$data[
'SumTotal_timeSeconds'])) {
   540                     $sco_total_time_sec = (
int) 
$data[
'SumTotal_timeSeconds'];
   544                     $usersToDelete[] = $user_id;
   546                     $this->
importSuccessForSahsUser($user_id, $last_access, $status, $attempts, $percentage_completed, $sco_total_time_sec);
   551                     foreach ($scos as $sco_id) {
   554                                                         SELECT completion_status, success_status, user_id FROM cmi_node WHERE cp_node_id = %s AND user_id  = %s',
   555                             array(
'integer',
'integer'),
   556                             array($sco_id,$user_id)
   560                             $nextId = 
$ilDB->nextId(
'cmi_node');
   561                             $val_set = 
$ilDB->manipulateF(
   562                                 'INSERT INTO cmi_node    563                                                         (cp_node_id,user_id,completion_status,c_timestamp,cmi_node_id)    564                                                         VALUES(%s,%s,%s,%s,%s)',
   565                                 array(
'integer',
'integer',
'text',
'timestamp',
'integer'),
   566                                 [$sco_id, $user_id, 
'completed', $last_access?->format(
'Y-m-d H:i:s'), $nextId]
   571                                 if (($row[
"completion_status"] === 
"completed" && $row[
"success_status"] !== 
"failed") || $row[
"success_status"] === 
"passed") {
   572                                     if ($doUpdate != 
true) {
   579                             if ($doUpdate == 
true) {
   583                                         'completion_status' => array(
'text', 
'completed'),
   584                                         'success_status' => array(
'text', 
''),
   585                                         'suspend_data' => array(
'text', 
''),
   586                                         'c_timestamp' => array(
'timestamp', $last_access?->format(
'Y-m-d H:i:s')),
   589                                         'user_id' => array(
'integer', $user_id),
   590                                         'cp_node_id' => array(
'integer', $sco_id)
   602         if (count($usersToDelete) > 0) {
   617         $aV = array(0, 0, 0, 0, 0, 0);
   620         if (strpos($str, 
"P") != 0) {
   624             $aT = array(
"Y", 
"M", 
"D", 
"H", 
"M", 
"S");
   627             $str = substr($str, 1);
   628             for ($i = 0, $max = count($aT); $i < $max; $i++) {
   629                 if (strpos($str, 
"T") === 0) {
   630                     $str = substr($str, 1);
   634                 $p = strpos($str, $aT[$i]);
   637                     if ($i == 1 && strpos($str, 
"T") > -1 && strpos($str, 
"T") < $p) {
   640                     if ($aT[$i] === 
"S") {
   641                         $aV[$i] = substr($str, 0, $p);
   643                         $aV[$i] = intval(substr($str, 0, $p));
   645                     if (!is_numeric($aV[$i])) {
   650                     if ($i > 2 && !$bTFound) {
   654                     $str = substr($str, $p + 1);
   657             if (!$bErr && strlen($str) != 0) {
   665         return $aV[0] * 3_155_760_000 + $aV[1] * 262_980_000 + $aV[2] * 8_640_000 + $aV[3] * 360000 + $aV[4] * 6000 + round($aV[5] * 100);
   671         $val_set = $DIC->database()->queryF(
   673                 SELECT  distinct(cp_node.cp_node_id) FROM cp_node,cp_resource,cp_item    674                 WHERE   cp_item.cp_node_id = cp_node.cp_node_id    675                 AND     cp_item.resourceid = cp_resource.id    678                 AND cp_node.slm_id = %s ',
   679             array(
'text',
'text',
'integer'),
   680             array(
'sco',
'item',$a_slm_id)
   682         return $DIC->database()->numRows($val_set);
   693         $ilDB = $DIC->database();
   694         $ilUser = $DIC->user();
   698         $val_set = 
$ilDB->queryF(
   700                 SELECT cp_node.cp_node_id FROM cp_node,cp_resource,cp_item    701                 WHERE cp_item.cp_node_id = cp_node.cp_node_id    702                 AND cp_item.resourceid = cp_resource.id    705                 AND cp_node.slm_id =  %s',
   706             array(
'text',
'text',
'integer'),
   707             array(
'sco' ,
'item',$a_id)
   709         while ($val_rec = 
$ilDB->fetchAssoc($val_set)) {
   710             $scos[] = $val_rec[
'cp_node_id'];
   716         foreach ($scos as $i => $value) {
   717             $val_set = 
$ilDB->queryF(
   719                                 SELECT * FROM cmi_node    722                                 AND (completion_status = %s OR success_status = %s))',
   723                 array(
'integer',
'integer',
'text',
'text'),
   724                 array($a_user, $value,
'completed',
'passed')
   727             if (
$ilDB->numRows($val_set) > 0) {
   729                 $key = array_search($value, $scos_c);
   730                 unset($scos_c[
$key]);
   734         if (count($scos_c) == 0) {
   751         $ilDB = $DIC->database();
   752         $ilUser = $DIC->user();
   755         $val_set = 
$ilDB->queryF(
   756             "SELECT cp_node.cp_node_id FROM cp_node,cp_resource,cp_item WHERE" .
   757             " cp_item.cp_node_id=cp_node.cp_node_id AND cp_item.resourceId = cp_resource.id AND scormType='sco' AND nodeName='item' AND cp_node.slm_id = %s GROUP BY cp_node.cp_node_id",
   761         while ($val_rec = 
$ilDB->fetchAssoc($val_set)) {
   762             $scos[] = $val_rec[
'cp_node_id'];
   766         foreach ($scos as $i => $iValue) {
   767             $val_set = 
$ilDB->queryF(
   768                 "SELECT scaled FROM cmi_node WHERE (user_id = %s AND cp_node_id = %s)",
   769                 array(
'integer', 
'integer'),
   770                 array($a_user, $scos[$i])
   772             if ($val_set->numRows() > 0) {
   773                 $val_rec = 
$ilDB->fetchAssoc($val_set);
   774                 if ($val_rec[
'scaled'] != null) {
   776                     $scaled = $val_rec[
'scaled'];
   780         return ($set == 1) ? $scaled : -1;
   792         $ilDB = $DIC->database();
   795         $item_set = 
$ilDB->queryF(
   797                         SELECT cp_item.*  FROM cp_node, cp_item WHERE slm_id = %s   798                         AND cp_node.cp_node_id = cp_item.cp_node_id    799                         ORDER BY cp_node.cp_node_id ',
   805         while ($item_rec = 
$ilDB->fetchAssoc($item_set)) {
   808                                 SELECT cp_resource.* FROM cp_node, cp_resource    810                                 AND cp_node.cp_node_id = cp_resource.cp_node_id    811                                 AND cp_resource.id = %s ',
   812                 array(
'integer',
'text'),
   813                 array($a_obj_id,$item_rec[
"resourceid"])
   818                 if (
$res[
"scormtype"] === 
"sco") {
   819                     $items[] = array(
"id" => $item_rec[
"cp_node_id"],
   820                         "title" => $item_rec[
"title"]);
   828     public static function _getStatus(
int $a_obj_id, 
int $a_user_id): bool|string
   832         $ilDB = $DIC->database();
   834         $status_set = 
$ilDB->queryF(
   836                         SELECT * FROM cmi_gobjective    838                         AND objective_id = %s   840             array(
'integer',
'text',
'integer'),
   841             array($a_obj_id,
'-course_overall_status-',$a_user_id)
   844         if ($status_rec = 
$ilDB->fetchAssoc($status_set)) {
   845             return $status_rec[
"status"];
   851     public static function _getSatisfied(
int $a_obj_id, 
int $a_user_id): bool|string
   855         $ilDB = $DIC->database();
   858         $status_set = 
$ilDB->queryF(
   860                         SELECT * FROM cmi_gobjective    862                         AND objective_id = %s   864             array(
'integer',
'text',
'integer'),
   865             array($a_obj_id,
'-course_overall_status-',$a_user_id)
   868         if ($status_rec = 
$ilDB->fetchAssoc($status_set)) {
   869             return $status_rec[
"satisfied"];
   875     public static function _getMeasure(
int $a_obj_id, 
int $a_user_id): float|bool
   879         $ilDB = $DIC->database();
   881         $status_set = 
$ilDB->queryF(
   883                         SELECT * FROM cmi_gobjective    885                         AND objective_id = %s   887             array(
'integer',
'text',
'integer'),
   888             array($a_obj_id,
'-course_overall_status-',$a_user_id)
   891         if ($status_rec = 
$ilDB->fetchAssoc($status_set)) {
   892             return (
float) $status_rec[
"measure"];
   902         $ilDB = $DIC->database();
   906                         SELECT * FROM cp_item   907                         WHERE cp_node_id = %s',
   912         if ($i = 
$ilDB->fetchAssoc(
$r)) {
   925         $ilDB = $DIC->database();
   929         $result = 
$ilDB->query(
   930             'SELECT cp_node.cp_node_id '   931            . 
'FROM cp_node, cp_resource, cp_item '   932            . 
'WHERE cp_item.cp_node_id = cp_node.cp_node_id '   933            . 
'AND cp_item.resourceId = cp_resource.id '   934            . 
'AND scormType = ' . 
$ilDB->quote(
'sco', 
'text') . 
' '   935            . 
'AND nodeName = ' . 
$ilDB->quote(
'item', 
'text') . 
' '   936            . 
'AND cp_node.slm_id = ' . 
$ilDB->quote($a_id, 
'integer') . 
' '   937            . 
'GROUP BY cp_node.cp_node_id'   940         while ($row = 
$ilDB->fetchAssoc($result)) {
   941             $scos[] = $row[
'cp_node_id'];
   946         foreach ($scos as $i => $value) {
   948                 'SELECT c_max FROM cmi_node WHERE (user_id = %s AND cp_node_id = %s)',
   949                 array(
'integer', 
'integer'),
   950                 array($a_user, $value)
   955                 if ($row[
'c_max'] != null) {
   957                     $max = floatval($row[
'c_max']);
   961         return ($set == 1) ? $max : null;
   971         $ilDB = $DIC->database();
   972         $retAr = array(
"raw" => null, 
"max" => null, 
"scaled" => null);
   973         $val_set = 
$ilDB->queryF(
   974             "SELECT c_raw, c_max, scaled FROM cmi_node WHERE (user_id = %s AND cp_node_id = %s)",
   975             array(
'integer', 
'integer'),
   976             array($a_user, $a_cp_node_id)
   978         if ($val_set->numRows() > 0) {
   979             $val_rec = 
$ilDB->fetchAssoc($val_set);
   980             $retAr[
"raw"] = $val_rec[
'c_raw'];
   981             $retAr[
"max"] = $val_rec[
'c_max'];
   982             $retAr[
"scaled"] = $val_rec[
'scaled'];
   983             if ($val_rec[
'scaled'] == null && $val_rec[
'c_raw'] != null && $val_rec[
'c_max'] != null) {
   984                 $retAr[
"scaled"] = ($val_rec[
'c_raw'] / $val_rec[
'c_max']);
 const LP_STATUS_COMPLETED_NUM
 
get_user_id(string $a_login)
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
importSuccess(string $a_file)
 
static getLogger(string $a_component_id)
Get component logger. 
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
 
static _getStatus(int $a_obj_id, int $a_user_id)
 
kindlyToDateTime(string $format, string $maybe_datetime, ?DateTimeImmutable $default=null)
 
const LP_STATUS_NOT_ATTEMPTED
 
static _getSatisfied(int $a_obj_id, int $a_user_id)
 
const LP_STATUS_IN_PROGRESS_NUM
 
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
 
deleteTrackingDataOfUsers(array $a_users)
 
static _ISODurationToCentisec(string $str)
convert ISO 8601 Timeperiods to centiseconds 
 
static _lookupLastAccess(int $a_obj_id, int $a_usr_id)
Return the last access timestamp for a given user. 
 
setImportSequencing(bool $a_val)
Set import sequencing. 
 
static secondsToString(int $seconds, bool $force_with_seconds=false, ?ilLanguage $a_lng=null)
converts seconds to string: Long: 7 days 4 hour(s) ... 
 
getAttemptsForUser(int $a_user_id)
get number of atttempts for a certain user and package 
 
const LP_STATUS_IN_PROGRESS
 
static _getMeasure(int $a_obj_id, int $a_user_id)
 
getTrackedItems()
get all tracked items of current user 
 
static _getUniqueScaledScoreForUser(int $a_id, int $a_user)
Get the Unique Scaled Score of a course Conditions: Only one SCO may set cmi.score.scaled. 
 
static getQuantityOfSCOs(int $a_slm_id)
 
static _lookupItemTitle(int $a_node_id)
 
static _refreshStatus(int $a_obj_id, ?array $a_users=null)
 
__construct(int $a_id=0, bool $a_call_by_reference=true)
Constructor. 
 
static _getScores2004ForUser(int $a_cp_node_id, int $a_user)
 
const LP_STATUS_NOT_ATTEMPTED_NUM
 
getDataDirectory(?string $mode="filesystem")
get data directory of lm 
 
getModuleVersionForUser(int $a_user_id)
get module version that tracking data for a user was recorded on 
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
static _getCourseCompletionForUser(int $a_id, int $a_user)
Get the completion of a SCORM module for a given user. 
 
static _getTrackingItems(int $a_obj_id)
get all tracking items of scorm object currently a for learning progress only 
 
static _deleteReadEventsForUsers(int $a_obj_id, array $a_user_ids)
 
getTrackingDataAgg(int $a_user_id, ?bool $raw=false)
 
importSuccessForSahsUser(int $user_id, ?DateTimeImmutable $last_access, int $status, ?int $attempts=null, ?int $percentage_completed=null, ?int $sco_total_time_sec=null)
 
convert_1_2_to_2004(string $manifest)
 
readObject()
read manifest file 
 
static getInstance(int $obj_id)
 
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
 
static removeCMIDataForUserAndPackage(int $user_id, int $packageId)
 
static _getMaxScoreForUser(int $a_id, int $a_user)
Returns score.max for the learning module, refered to the last sco where score.max is set...
 
const LP_STATUS_FAILED_NUM
 
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)
 
getImportSequencing()
Get import sequencing.