3declare(strict_types=1);
34 $lng->loadLanguageModule(
"scormtrac");
40 'lm_id,lm_title,identifierref,sco_id,sco_marked_for_learning_progress,sco_title,' . $udh[
"cols"]
41 .
',c_timestamp,lvalue,rvalue'
43 $a_true = explode(
',', $udh[
"default"] .
",identifierref,c_timestamp,lvalue,rvalue");
44 for (
$i = 0, $iMax = count($a_cols);
$i < $iMax;
$i++) {
45 $cols[$a_cols[
$i]] = array(
"txt" =>
$lng->txt($a_cols[
$i]),
"default" =>
false);
47 for (
$i = 0, $iMax = count($a_true);
$i < $iMax;
$i++) {
48 $cols[$a_true[
$i]][
"default"] =
true;
59 $allowExportPrivacy = $privacy->enabledExportSCORM();
60 $returnData = array();
61 if ($allowExportPrivacy ==
true) {
62 $returnData[
"cols"] =
'login,user,email,department';
64 $returnData[
"cols"] =
'user';
66 $returnData[
"default"] =
'user';
77 $lng->loadLanguageModule(
"scormtrac");
83 'lm_id,lm_title,sco_id,sco_marked_for_learning_progress,sco_title,' . $udh[
"cols"]
84 .
',lesson_status,credit,c_entry,c_exit,c_max,c_min,c_raw,session_time,total_time,c_timestamp,suspend_data,launch_data'
86 $a_true = explode(
',', $udh[
"default"] .
",sco_title,lesson_status");
87 for (
$i = 0, $iMax = count($a_cols);
$i < $iMax;
$i++) {
88 $cols[$a_cols[
$i]] = array(
"txt" =>
$lng->txt($a_cols[
$i]),
"default" =>
false);
90 for (
$i = 0, $iMax = count($a_true);
$i < $iMax;
$i++) {
91 $cols[$a_true[
$i]][
"default"] =
true;
103 $lng->loadLanguageModule(
"scormtrac");
108 'lm_id,lm_title,sco_id,sco_marked_for_learning_progress,sco_title,' . $udh[
"cols"]
109 .
',counter,id,weighting,type,result,student_response,latency,time,c_timestamp'
111 $a_true = explode(
',', $udh[
"default"] .
",sco_title,id,result,student_response");
112 for (
$i = 0, $iMax = count($a_cols);
$i < $iMax;
$i++) {
113 $cols[$a_cols[
$i]] = array(
"txt" =>
$lng->txt($a_cols[
$i]),
"default" =>
false);
115 for (
$i = 0, $iMax = count($a_true);
$i < $iMax;
$i++) {
116 $cols[$a_true[
$i]][
"default"] =
true;
128 $lng->loadLanguageModule(
"scormtrac");
133 'lm_id,lm_title,sco_id,sco_marked_for_learning_progress,sco_title,' . $udh[
"cols"]
134 .
',counter,id,c_max,c_min,c_raw,ostatus,c_timestamp'
136 $a_true = explode(
',', $udh[
"default"] .
",sco_title,id,c_raw,ostatus");
137 for (
$i = 0, $iMax = count($a_cols);
$i < $iMax;
$i++) {
138 $cols[$a_cols[
$i]] = array(
"txt" =>
$lng->txt($a_cols[
$i]),
"default" =>
false);
140 for (
$i = 0, $iMax = count($a_true);
$i < $iMax;
$i++) {
141 $cols[$a_true[
$i]][
"default"] =
true;
153 $lng->loadLanguageModule(
"scormtrac");
158 $a_cols = explode(
',',
'LearningModuleId,LearningModuleTitle,LearningModuleVersion,' . $udh[
"cols"]
159 .
',status,Percentage,Attempts,existingSCOs,startedSCOs,completedSCOs,passedSCOs,roundedTotal_timeSeconds,offline_mode,last_access');
160 $a_true = explode(
',', $udh[
"default"] .
",LearningModuleTitle,status,Percentage,Attempts");
162 for (
$i = 0, $iMax = count($a_cols);
$i < $iMax;
$i++) {
163 $cols[$a_cols[
$i]] = array(
"txt" =>
$lng->txt($a_cols[
$i]),
"default" =>
false);
165 for (
$i = 0, $iMax = count($a_true);
$i < $iMax;
$i++) {
166 $cols[$a_true[
$i]][
"default"] =
true;
178 bool $allowExportPrivacy,
185 $lng->loadLanguageModule(
"scormtrac");
187 $returnData = array();
193 $query =
'SELECT user_id, st.obj_id, sco_id, identifierref, c_timestamp, lvalue, rvalue '
194 .
'FROM scorm_tracking st '
195 .
'JOIN sc_item si ON st.sco_id = si.obj_id '
196 .
'WHERE ' .
$ilDB->in(
'sco_id', $a_sco,
false,
'integer') .
' '
197 .
'AND ' .
$ilDB->in(
'user_id', $a_user,
false,
'integer') .
' '
201 $query .=
'sco_id, user_id';
203 $query .=
'user_id, sco_id';
207 $data[
"lm_id"] = $obj_id;
208 $data[
"lm_title"] = $lmTitle;
209 $data = array_merge(
$data, self::userDataArrayForExport((
int)
$data[
"user_id"], $allowExportPrivacy));
210 $data[
"sco_marked_for_learning_progress"] = $scoProgress[
$data[
"sco_id"]];
211 $data[
"sco_title"] = $scoTitles[
$data[
"sco_id"]];
214 $returnData[] =
$data;
227 $scoTitles = array();
229 $query =
'SELECT obj_id, title
231 WHERE slm_id = %s AND c_type = %s';
234 array(
'integer',
'text'),
235 array($obj_id,
'sit')
238 $scoTitles[$row[
'obj_id']] = $row[
'title'];
251 $collection = $olp->getCollectionInstance();
253 foreach ($a_scos as $sco_id => $value) {
254 if ($collection && $collection->isAssignedEntry($sco_id)) {
255 $a_scos[$sco_id] =
$lng->txt(
'yes');
257 $a_scos[$sco_id] =
$lng->txt(
'no');
265 $userArray = array();
266 if ($b_allowExportPrivacy ==
false) {
267 $userArray[
"user"] = $user;
271 $userArray[
"login"] =
"";
272 $userArray[
"user"] =
"";
273 $userArray[
"email"] =
"";
274 $userArray[
"department"] =
"";
277 $userArray[
"login"] = $e_user->getLogin();
278 $userArray[
"user"] = $e_user->getLastname() .
', ' . $e_user->getFirstname();
279 $userArray[
"email"] =
"" . $e_user->getEmail();
280 $userArray[
"department"] =
"" . $e_user->getDepartment();
293 bool $allowExportPrivacy,
300 $lng->loadLanguageModule(
"scormtrac");
302 $returnData = array();
304 $scoTitles = $this->scoTitlesForExportSelected($obj_id);
306 $scoProgress = $this->markedLearningStatusForExportSelected($scoTitles, $obj_id);
310 foreach ($a_user as $value) {
311 $a_empty[$value] = array();
315 $query =
'SELECT user_id, sco_id, max(c_timestamp) as c_timestamp '
316 .
'FROM scorm_tracking '
317 .
'WHERE ' .
$ilDB->in(
'sco_id', $a_sco,
false,
'integer') .
' '
318 .
'AND ' .
$ilDB->in(
'user_id', $a_user,
false,
'integer') .
' '
319 .
'GROUP BY user_id, sco_id '
322 $query .=
'sco_id, user_id';
324 $query .=
'user_id, sco_id';
329 $a_empty[$row[
"user_id"]][$row[
"sco_id"]] =
"";
332 $a_lesson_status = $this->getScormTrackingValue($obj_id, $a_user, $a_sco, $a_empty,
'cmi.core.lesson_status');
333 $a_credit = $this->getScormTrackingValue($obj_id, $a_user, $a_sco, $a_empty,
'cmi.core.credit');
334 $a_c_entry = $this->getScormTrackingValue($obj_id, $a_user, $a_sco, $a_empty,
'cmi.core.entry');
335 $a_c_exit = $this->getScormTrackingValue($obj_id, $a_user, $a_sco, $a_empty,
'cmi.core.exit');
336 $a_c_max = $this->getScormTrackingValue($obj_id, $a_user, $a_sco, $a_empty,
'cmi.core.score.max');
337 $a_c_min = $this->getScormTrackingValue($obj_id, $a_user, $a_sco, $a_empty,
'cmi.core.score.min');
338 $a_c_raw = $this->getScormTrackingValue($obj_id, $a_user, $a_sco, $a_empty,
'cmi.core.score.raw');
339 $a_session_time = $this->getScormTrackingValue($obj_id, $a_user, $a_sco, $a_empty,
'cmi.core.session_time');
340 $a_total_time = $this->getScormTrackingValue($obj_id, $a_user, $a_sco, $a_empty,
'cmi.core.total_time');
341 $a_suspend_data = $this->getScormTrackingValue($obj_id, $a_user, $a_sco, $a_empty,
'cmi.suspend_data');
342 $a_launch_data = $this->getScormTrackingValue($obj_id, $a_user, $a_sco, $a_empty,
'cmi.launch_data');
344 foreach ($dbdata as
$data) {
345 $data[
"lm_id"] = $obj_id;
346 $data[
"lm_title"] = $lmTitle;
348 $data = array_merge(
$data, self::userDataArrayForExport((
int)
$data[
"user_id"], $allowExportPrivacy));
350 $data[
"sco_marked_for_learning_progress"] = $scoProgress[
$data[
"sco_id"]];
351 $data[
"sco_title"] = $scoTitles[
$data[
"sco_id"]];
355 $data[
"lesson_status"] = $a_lesson_status[
$data[
'user_id']][
$data[
'sco_id']];
366 $data[
"session_time"] = $a_session_time[
$data[
'user_id']][
$data[
'sco_id']];
369 $data[
"total_time"] = $a_total_time[
$data[
'user_id']][
$data[
'sco_id']];
373 $data[
"suspend_data"] = $a_suspend_data[
$data[
'user_id']][
$data[
'sco_id']];
374 $data[
"launch_data"] = $a_launch_data[
$data[
'user_id']][
$data[
'sco_id']];
375 $returnData[] =
$data;
384 public function getScormTrackingValue(
int $obj_id, array $a_user, array $a_sco, array $a_empty,
string $lvalue): array
389 $query =
'SELECT user_id, sco_id, rvalue '
390 .
'FROM scorm_tracking '
391 .
'WHERE obj_id = %s '
392 .
'AND ' .
$ilDB->in(
'user_id', $a_user,
false,
'integer') .
' '
393 .
'AND ' .
$ilDB->in(
'sco_id', $a_sco,
false,
'integer') .
' '
397 array(
'integer',
'text'),
398 array($obj_id, $lvalue)
401 if (!is_null(
$data[
'rvalue'])) {
415 bool $allowExportPrivacy,
422 $returnData = array();
424 $scoTitles = $this->scoTitlesForExportSelected($obj_id);
426 $scoProgress = $this->markedLearningStatusForExportSelected($scoTitles, $obj_id);
430 $interactionsCounter = array();
433 $query =
'SELECT user_id, sco_id, lvalue, c_timestamp '
434 .
'FROM scorm_tracking '
435 .
'WHERE obj_id = %s AND ' .
$ilDB->in(
'sco_id', $a_sco,
false,
'integer') .
' '
436 .
'AND ' .
$ilDB->in(
'user_id', $a_user,
false,
'integer') .
' '
437 .
'AND left(lvalue,17) = %s '
440 $query .=
'sco_id, user_id, lvalue';
442 $query .=
'user_id, sco_id, lvalue';
446 array(
'integer',
'text'),
447 array($obj_id,
'cmi.interactions.')
451 $tmpar = explode(
'.', $row[
"lvalue"]);
452 $tmpcounter = $tmpar[2];
453 if (in_array($tmpcounter, $interactionsCounter) ==
false) {
454 $interactionsCounter[] = $tmpcounter;
456 if ($tmpcounter != $prevcounter) {
458 $tmpar[
"user_id"] = $row[
"user_id"];
459 $tmpar[
"sco_id"] = $row[
"sco_id"];
460 $tmpar[
"counter"] = $tmpcounter;
462 $tmpar[
"weighting"] =
"";
464 $tmpar[
"result"] =
"";
465 $tmpar[
"student_response"] =
"";
466 $tmpar[
"latency"] =
"";
468 $tmpar[
"c_timestamp"] = $row[
"c_timestamp"];
470 $prevcounter = $tmpcounter;
476 $a_weighting = array();
479 $a_student_response = array();
480 $a_latency = array();
482 foreach ($interactionsCounter as $value) {
485 $this->getScormTrackingValueForInteractionsOrObjectives(
494 $a_weighting = array_merge(
496 $this->getScormTrackingValueForInteractionsOrObjectives(
505 $a_type = array_merge(
507 $this->getScormTrackingValueForInteractionsOrObjectives(
516 $a_result = array_merge(
518 $this->getScormTrackingValueForInteractionsOrObjectives(
527 $a_student_response = array_merge(
529 $this->getScormTrackingValueForInteractionsOrObjectives(
538 $a_latency = array_merge(
540 $this->getScormTrackingValueForInteractionsOrObjectives(
549 $a_time = array_merge(
551 $this->getScormTrackingValueForInteractionsOrObjectives(
561 foreach ($dbdata as
$data) {
562 $data[
"lm_id"] = $obj_id;
563 $data[
"lm_title"] = $lmTitle;
565 $data = array_merge(
$data, self::userDataArrayForExport((
int)
$data[
"user_id"], $allowExportPrivacy));
567 $data[
"sco_marked_for_learning_progress"] = $scoProgress[
$data[
"sco_id"]];
568 $data[
"sco_title"] = $scoTitles[
$data[
"sco_id"]];
570 $combinedId =
'' .
$data[
"user_id"] .
'-' .
$data[
"sco_id"] .
'-' .
$data[
"counter"];
571 if (array_key_exists($combinedId, $a_id)) {
572 $data[
"id"] = $a_id[$combinedId];
574 if (array_key_exists($combinedId, $a_weighting)) {
575 $data[
"weighting"] = $a_weighting[$combinedId];
577 if (array_key_exists($combinedId, $a_type)) {
578 $data[
"type"] = $a_type[$combinedId];
580 if (array_key_exists($combinedId, $a_result)) {
581 $data[
"result"] = $a_result[$combinedId];
583 if (array_key_exists($combinedId, $a_student_response)) {
584 $data[
"student_response"] = $a_student_response[$combinedId];
586 if (array_key_exists($combinedId, $a_latency)) {
587 $data[
"latency"] = $a_latency[$combinedId];
589 if (array_key_exists($combinedId, $a_time)) {
590 $data[
"time"] = $a_time[$combinedId];
594 $returnData[] =
$data;
615 $query =
'SELECT user_id, sco_id, rvalue '
616 .
'FROM scorm_tracking '
617 .
'WHERE obj_id = %s '
618 .
'AND ' .
$ilDB->in(
'user_id', $a_user,
false,
'integer') .
' '
619 .
'AND ' .
$ilDB->in(
'sco_id', $a_sco,
false,
'integer') .
' '
623 array(
'integer',
'text'),
624 array($obj_id,
'cmi.' . $topic .
'.' . $counter .
'.' . $lvalue)
627 if (!is_null(
$data[
'rvalue'])) {
628 $a_return[
'' .
$data[
'user_id'] .
'-' .
$data[
'sco_id'] .
'-' . $counter] =
$data[
'rvalue'];
641 bool $allowExportPrivacy,
648 $returnData = array();
650 $scoTitles = $this->scoTitlesForExportSelected($obj_id);
652 $scoProgress = $this->markedLearningStatusForExportSelected($scoTitles, $obj_id);
656 $objectivesCounter = array();
659 $query =
'SELECT user_id, sco_id, lvalue, c_timestamp '
660 .
'FROM scorm_tracking '
661 .
'WHERE obj_id = %s AND ' .
$ilDB->in(
'sco_id', $a_sco,
false,
'integer') .
' '
662 .
'AND ' .
$ilDB->in(
'user_id', $a_user,
false,
'integer') .
' '
663 .
'AND left(lvalue,15) = %s '
666 $query .=
'sco_id, user_id, lvalue';
668 $query .=
'user_id, sco_id, lvalue';
672 array(
'integer',
'text'),
673 array($obj_id,
'cmi.objectives.')
677 $tmpar = explode(
'.', $row[
"lvalue"]);
678 $tmpcounter = $tmpar[2];
679 if (in_array($tmpcounter, $objectivesCounter) ==
false) {
680 $objectivesCounter[] = $tmpcounter;
682 if ($tmpcounter != $prevcounter) {
684 $tmpar[
"user_id"] = $row[
"user_id"];
685 $tmpar[
"sco_id"] = $row[
"sco_id"];
686 $tmpar[
"counter"] = $tmpcounter;
688 $tmpar[
"c_max"] =
"";
689 $tmpar[
"c_min"] =
"";
690 $tmpar[
"c_raw"] =
"";
691 $tmpar[
"ostatus"] =
"";
692 $tmpar[
"c_timestamp"] = $row[
"c_timestamp"];
694 $prevcounter = $tmpcounter;
702 foreach ($objectivesCounter as $value) {
705 $this->getScormTrackingValueForInteractionsOrObjectives(
714 $a_c_max = array_merge(
716 $this->getScormTrackingValueForInteractionsOrObjectives(
725 $a_c_min = array_merge(
727 $this->getScormTrackingValueForInteractionsOrObjectives(
736 $a_c_raw = array_merge(
738 $this->getScormTrackingValueForInteractionsOrObjectives(
747 $a_status = array_merge(
749 $this->getScormTrackingValueForInteractionsOrObjectives(
759 foreach ($dbdata as
$data) {
760 $data[
"lm_id"] = $obj_id;
761 $data[
"lm_title"] = $lmTitle;
763 $data = array_merge(
$data, self::userDataArrayForExport((
int)
$data[
"user_id"], $allowExportPrivacy));
765 $data[
"sco_marked_for_learning_progress"] = $scoProgress[
$data[
"sco_id"]];
766 $data[
"sco_title"] = $scoTitles[
$data[
"sco_id"]];
768 $combinedId =
'' .
$data[
"user_id"] .
'-' .
$data[
"sco_id"] .
'-' .
$data[
"counter"];
769 if (array_key_exists($combinedId, $a_id)) {
770 $data[
"id"] = $a_id[$combinedId];
772 if (array_key_exists($combinedId, $a_c_max)) {
773 $data[
"c_max"] = $a_c_max[$combinedId];
775 if (array_key_exists($combinedId, $a_c_min)) {
776 $data[
"c_min"] = $a_c_min[$combinedId];
778 if (array_key_exists($combinedId, $a_c_raw)) {
779 $data[
"c_raw"] = $a_c_raw[$combinedId];
781 if (array_key_exists($combinedId, $a_status)) {
782 $data[
"ostatus"] = $a_status[$combinedId];
786 $returnData[] =
$data;
802 $query =
'SELECT count(distinct(scorm_object.obj_id)) counter '
803 .
'FROM scorm_object, sc_item, sc_resource '
804 .
'WHERE scorm_object.slm_id = %s '
805 .
'AND scorm_object.obj_id = sc_item.obj_id '
806 .
'AND sc_item.identifierref = sc_resource.import_id '
807 .
'AND (sc_resource.scormtype = %s OR sc_resource.scormtype is null)';
810 array(
'integer',
'text'),
811 array($obj_id,
'sco')
814 $scoCounter = (
int) $row[
'counter'];
818 $u_startedSCO = array();
819 $u_completedSCO = array();
820 $u_passedSCO = array();
821 foreach ($a_user as $value) {
822 $u_startedSCO[$value] = 0;
823 $u_completedSCO[$value] = 0;
824 $u_passedSCO[$value] = 0;
827 $query =
'SELECT user_id, count(distinct(SCO_ID)) counter '
828 .
'FROM scorm_tracking '
829 .
'WHERE obj_id = %s '
831 .
'AND ' .
$ilDB->in(
'user_id', $a_user,
false,
'integer') .
' '
832 .
'GROUP BY user_id';
839 $u_startedSCO[
$data[
'user_id']] =
$data[
'counter'];
842 $query =
'SELECT user_id, count(*) counter '
843 .
'FROM scorm_tracking '
844 .
'WHERE obj_id = %s AND lvalue = %s AND rvalue like %s '
845 .
'AND ' .
$ilDB->in(
'user_id', $a_user,
false,
'integer') .
' '
846 .
'GROUP BY user_id';
849 array(
'integer',
'text',
'text'),
850 array($obj_id,
'cmi.core.lesson_status',
'completed')
853 $u_completedSCO[
$data[
'user_id']] =
$data[
'counter'];
858 array(
'integer',
'text',
'text'),
859 array($obj_id,
'cmi.core.lesson_status',
'passed')
862 $u_passedSCO[
$data[
'user_id']] =
$data[
'counter'];
867 $query =
'SELECT * FROM sahs_user WHERE obj_id = ' .
$ilDB->quote($obj_id,
'integer')
868 .
' AND ' .
$ilDB->in(
'user_id', $a_user,
false,
'integer')
869 .
' ORDER BY user_id';
874 return $this->exportSelectedSuccessRows(
892 bool $allowExportPrivacy,
896 array $u_completedSCO,
901 $returnData = array();
902 foreach ($dbdata as
$data) {
904 $dat[
"LearningModuleId"] = $obj_id;
905 $dat[
"LearningModuleTitle"] =
"" . $lmTitle;
906 $dat[
"LearningModuleVersion"] =
"" .
$data[
"module_version"];
908 $dat = array_merge($dat, self::userDataArrayForExport((
int)
$data[
"user_id"], $allowExportPrivacy));
910 $dat[
"status"] =
"" .
$data[
"status"];
911 $dat[
"Percentage"] =
"" .
$data[
"percentage_completed"];
912 $dat[
"Attempts"] =
"" .
$data[
"package_attempts"];
913 $dat[
"existingSCOs"] =
"" . $scoCounter;
914 $dat[
"startedSCOs"] =
"" . $u_startedSCO[
$data[
"user_id"]];
915 $dat[
"completedSCOs"] =
"" . $u_completedSCO[
$data[
"user_id"]];
916 $dat[
"passedSCOs"] =
"" . $u_passedSCO[
$data[
"user_id"]];
917 $dat[
"roundedTotal_timeSeconds"] =
"" .
$data[
"sco_total_time_sec"];
918 if (is_null(
$data[
"offline_mode"])) {
919 $dat[
"offline_mode"] =
"";
921 $dat[
"offline_mode"] =
$data[
"offline_mode"];
923 $dat[
"last_access"] =
"" .
$data[
"last_access"];
924 $returnData[] = $dat;
937 $tarr = explode(
":", $a_time);
939 if (count($tarr) != 3 || is_nan((
float) $tarr[0]) || is_nan((
float) $tarr[1]) || is_nan((
float) $tarr[2])) {
942 $csec = (
int) $tarr[0] * 360000 + (
int) $tarr[1] * 6000 + $tarr[2] * 100;
943 return round($csec / 100);
static getInstance(int $obj_id)
static _exists(int $id, bool $reference=false, ?string $type=null)
checks if an object exists in object_data
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
exportSelectedRaw(array $a_user, array $a_sco, bool $b_orderBySCO, bool $allowExportPrivacy, int $obj_id, string $lmTitle)
markedLearningStatusForExportSelected(array $a_scos, int $obj_id)
exportSelectedObjectives(array $a_user, array $a_sco, bool $b_orderBySCO, bool $allowExportPrivacy, int $obj_id, string $lmTitle)
static exportSelectedSuccessColumns()
static exportSelectedObjectivesColumns()
scoTitlesForExportSelected(int $obj_id)
static exportSelectedRawColumns()
exportSelectedSuccess(array $a_user, bool $allowExportPrivacy, int $obj_id, string $lmTitle)
static userDataHeaderForExport()
static exportSelectedCoreColumns(bool $b_orderBySCO, bool $b_allowExportPrivacy)
static userDataArrayForExport(int $user, bool $b_allowExportPrivacy=false)
getScormTrackingValue(int $obj_id, array $a_user, array $a_sco, array $a_empty, string $lvalue)
static exportSelectedInteractionsColumns()
getScormTrackingValueForInteractionsOrObjectives(int $obj_id, array $a_user, array $a_sco, string $lvalue, int $counter, string $topic)
exportSelectedCore(array $a_user, array $a_sco, bool $b_orderBySCO, bool $allowExportPrivacy, int $obj_id, string $lmTitle)
exportSelectedSuccessRows(array $a_user, bool $allowExportPrivacy, array $dbdata, int $scoCounter, array $u_startedSCO, array $u_completedSCO, array $u_passedSCO, int $obj_id, string $lmTitle)
exportSelectedInteractions(array $a_user, array $a_sco, bool $b_orderBySCO, bool $allowExportPrivacy, int $obj_id, string $lmTitle)
SCORMTimeToSeconds(string $a_time)