ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.ilObjCmiXapi.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 1998-2019 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5
16{
17 const PLUGIN = false;
18
19 const DB_TABLE_NAME = 'cmix_settings';
20 const DB_USERS_TABLE_NAME = 'cmix_users';
21 const DB_RESULTS_TABLE_NAME = 'cmix_results';
22
30
34 protected $lrsTypeId;
35
39 protected $lrsType;
40
44 protected $contentType;
45 const CONT_TYPE_GENERIC = 'generic';
46 const CONT_TYPE_CMI5 = 'cmi5';
47
51 protected $sourceType;
52 const SRC_TYPE_REMOTE = 'remoteSource';
53 const SRC_TYPE_LOCAL = 'localSource';
54 const SRC_TYPE_EXTERNAL = 'externalSource';
55
59 protected $activityId;
60
64 protected $publisherId;
65
69 protected $instructions;
70
74 protected $launchUrl;
75
80
84 protected $moveOn;
85
89 protected $entitlementKey;
90
95
99 protected $anonymousHomePage = false;
100 const ANONYMOUS_HOMEPAGE = 'https://example.org';
101
105 protected $launchMethod;
106 const LAUNCH_METHOD_OWN_WIN = 'ownWin';
107 const LAUNCH_METHOD_NEW_WIN = 'newWin';
108 const LAUNCH_METHOD_IFRAME = 'iframe';
109
113 protected $launchMode;
114 const LAUNCH_MODE_NORMAL = 'Normal';
115 const LAUNCH_MODE_BROWSE = 'Browse';
116 const LAUNCH_MODE_REVIEW = 'Review';
117
122
126 const LMS_MASTERY_SCORE = 0.7;
127 protected $masteryScore;
128
133
137 protected $userIdent;
144
148 protected $userName;
153
154
159
164
168 protected $xmlManifest;
169
173 protected $version;
174
179
181 protected $only_moveon = false;
182
184 protected $achieved = true;
185
187 protected $answered = true;
188
190 protected $completed = true;
191
193 protected $failed = true;
194
196 protected $initialized = true;
197
199 protected $passed = true;
200
202 protected $progressed = true;
203
205 protected $satisfied = true;
206
208 protected $terminated = true;
209
211 protected $hide_data = false;
212
214 protected $timestamp = false;
215
217 protected $duration = true;
218
220 protected $no_substatements = false;
221
223 protected $currentCmixUser = null;
224
230 public function __construct($a_id = 0, $a_reference = true)
231 {
232 $this->lrsTypeId = 0;
233 //$this->lrsType = $lrsType;
234
235 $this->contentType = self::CONT_TYPE_GENERIC;
236 $this->sourceType = self::SRC_TYPE_REMOTE;
237
238 $this->activityId = '';
239
240 $this->publisherId = '';
241
242 $this->instructions = '';
243
244 $this->launchUrl = '';
245 $this->launchParameters = '';
246 $this->moveOn = '';
247 $this->entitlementKey = '';
248
249 $this->authFetchUrlEnabled = 0;
250
251 $this->launchMethod = self::LAUNCH_METHOD_NEW_WIN;
252 $this->launchMode = self::LAUNCH_MODE_NORMAL;
253
254 $this->switchToReviewEnabled = 1;
255
256 $this->masteryScore = self::LMS_MASTERY_SCORE;
257 $this->keepLpStatusEnabled = 1;
258
259 $this->userIdent = self::PRIVACY_IDENT_IL_UUID_USER_ID;
260 $this->userName = self::PRIVACY_NAME_NONE;
261 $this->userPrivacyComment = '';
262
263 $this->currentCmixUser = null;
264
265 $this->statementsReportEnabled = 0;
266
267 $this->xmlManifest = '';
268 $this->version = 0;
269
270 $this->bypassProxyEnabled = false;
271
272 parent::__construct($a_id, $a_reference);
273 }
274
275
276 public static function getInstance($a_id = 0, $a_reference = true)
277 {
278 return new self($a_id, $a_reference);
279 }
280
281 protected function initType() : void
282 {
283 $this->type = "cmix";
284 }
285
289 public function getLrsTypeId()
290 {
291 return $this->lrsTypeId;
292 }
293
297 public function setLrsTypeId($lrsTypeId)
298 {
299 $this->lrsTypeId = $lrsTypeId;
300 }
301
305 public function getLrsType()
306 {
307 return $this->lrsType;
308 }
309
313 public function setLrsType($lrsType)
314 {
315 $this->lrsType = $lrsType;
316 }
317
318 public function initLrsType()
319 {
320 $this->setLrsType(new ilCmiXapiLrsType($this->getLrsTypeId()));
321 }
322
326 public function getContentType()
327 {
328 return $this->contentType;
329 }
330
335 {
336 //bug before 21-07-24
337 if ($contentType == "learning") {
339 }
340 $this->contentType = $contentType;
341 }
342
346 public function isMixedContentType() : bool
347 {
348 // after 21-07-24 and before cmi5 refactoring
349 // launched before cmi5 refactoring ident in: statement.actor.mbox
350 // launched after cmi5 refactoring ident in: statement.actor.account.name
351 return (($this->getContentType() == self::CONT_TYPE_CMI5) && empty($this->getPublisherId()));
352 }
353
357 public function getSourceType()
358 {
359 return $this->sourceType;
360 }
361
365 public function isSourceTypeRemote()
366 {
367 return $this->sourceType == self::SRC_TYPE_REMOTE;
368 }
369
373 public function isSourceTypeExternal()
374 {
375 return $this->sourceType == self::SRC_TYPE_EXTERNAL;
376 }
377
381 public function setSourceType($sourceType)
382 {
383 $this->sourceType = $sourceType;
384 }
385
389 public function getActivityId()
390 {
391 return $this->activityId;
392 }
393
397 public function setActivityId($activityId)
398 {
399 $this->activityId = $activityId;
400 }
401
405 public function getPublisherId()
406 {
407 return $this->publisherId;
408 }
409
414 {
415 $this->publisherId = $publisherId;
416 }
417
421 public function getInstructions()
422 {
423 return $this->instructions;
424 }
425
430 {
431 $this->instructions = $instructions;
432 }
433
437 public function getLaunchUrl()
438 {
439 return $this->launchUrl;
440 }
441
445 public function setLaunchUrl($launchUrl)
446 {
447 $this->launchUrl = $launchUrl;
448 }
449
453 public function getLaunchParameters()
454 {
456 }
457
462 {
463 $this->launchParameters = $launchParameters;
464 }
465
471 public function getMoveOn()
472 {
473 return $this->moveOn;
474 }
475
481 public function setMoveOn($moveOn)
482 {
483 $this->moveOn = $moveOn;
484 }
485
490 public function getLPMode()
491 {
492 $olp = ilObjectLP::getInstance($this->getId());
493 return $olp->getCurrentMode();
494 }
495
500 public function getLMSMoveOn()
501 {
503 switch ($this->getLPMode())
504 {
507 break;
511 break;
515 break;
519 break;
520 }
521 return $moveOn;
522 }
523
527 public function getEntitlementKey()
528 {
530 }
531
536 {
537 $this->entitlementKey = $entitlementKey;
538 }
539
543 public function isAuthFetchUrlEnabled()
544 {
546 }
547
552 {
553 $this->authFetchUrlEnabled = $authFetchUrlEnabled;
554 }
555
559 public function getLaunchMethod()
560 {
561 return $this->launchMethod;
562 }
563
568 {
569 $this->launchMethod = $launchMethod;
570 }
571
575 public function getLaunchMode()
576 {
577 return ucfirst($this->launchMode);
578 }
579
583 public function setLaunchMode($launchMode)
584 {
585 $this->launchMode = ucfirst($launchMode);
586 }
587
591 public function isSwitchToReviewEnabled()
592 {
594 }
595
599 public function getSwitchToReviewEnabled()
600 {
602 }
603
608 {
609 $this->switchToReviewEnabled = $switchToReviewEnabled;
610 }
611
615 public function getMasteryScore()
616 {
617 return $this->masteryScore;
618 }
619
624 {
625 $this->masteryScore = $masteryScore;
626 }
627
631 public function getMasteryScorePercent()
632 {
633 return $this->masteryScore * 100;
634 }
635
639 public function setMasteryScorePercent($masteryScorePercent)
640 {
641 $this->masteryScore = $masteryScorePercent / 100;
642 }
643
647 public function isKeepLpStatusEnabled()
648 {
650 }
651
656 {
657 $this->keepLpStatusEnabled = $keepLpStatusEnabled;
658 }
659
663 public function getPrivacyIdent()
664 {
665 return $this->userIdent;
666 }
667
672 {
673 $this->userIdent = $userIdent;
674 }
675
679 public function getPrivacyName()
680 {
681 return $this->userName;
682 }
683
687 public function setPrivacyName($userName)
688 {
689 $this->userName = $userName;
690 }
691
695 public function getOnlyMoveon(): bool
696 {
697 return $this->only_moveon;
698 }
699
703 public function setOnlyMoveon(bool $only_moveon)
704 {
705 $this->only_moveon = $only_moveon;
706 }
707
711 public function getAchieved(): bool
712 {
713 return $this->achieved;
714 }
715
719 public function setAchieved(bool $achieved)
720 {
721 $this->achieved = $achieved;
722 }
723
727 public function getAnswered(): bool
728 {
729 return $this->answered;
730 }
731
735 public function setAnswered(bool $answered)
736 {
737 $this->answered = $answered;
738 }
739
743 public function getCompleted(): bool
744 {
745 return $this->completed;
746 }
747
751 public function setCompleted(bool $completed)
752 {
753 $this->completed = $completed;
754 }
755
759 public function getFailed(): bool
760 {
761 return $this->failed;
762 }
763
767 public function setFailed(bool $failed)
768 {
769 $this->failed = $failed;
770 }
771
775 public function getInitialized(): bool
776 {
777 return $this->initialized;
778 }
779
783 public function setInitialized(bool $initialized)
784 {
785 $this->initialized = $initialized;
786 }
787
791 public function getPassed(): bool
792 {
793 return $this->passed;
794 }
795
799 public function setPassed(bool $passed)
800 {
801 $this->passed = $passed;
802 }
803
807 public function getProgressed(): bool
808 {
809 return $this->progressed;
810 }
811
815 public function setProgressed(bool $progressed)
816 {
817 $this->progressed = $progressed;
818 }
819
823 public function getSatisfied(): bool
824 {
825 return $this->satisfied;
826 }
827
831 public function setSatisfied(bool $satisfied)
832 {
833 $this->satisfied = $satisfied;
834 }
835
839 public function getTerminated(): bool
840 {
841 return $this->terminated;
842 }
843
847 public function setTerminated(bool $terminated)
848 {
849 $this->terminated = $terminated;
850 }
851
855 public function getHideData(): bool
856 {
857 return $this->hide_data;
858 }
859
863 public function setHideData(bool $hide_data)
864 {
865 $this->hide_data = $hide_data;
866 }
867
871 public function getTimestamp(): bool
872 {
873 return $this->timestamp;
874 }
875
879 public function setTimestamp(bool $timestamp)
880 {
881 $this->timestamp = $timestamp;
882 }
883
887 public function getDuration(): bool
888 {
889 return $this->duration;
890 }
891
895 public function setDuration(bool $duration)
896 {
897 $this->duration = $duration;
898 }
899
903 public function getNoSubstatements(): bool
904 {
906 }
907
912 {
913 $this->no_substatements = $no_substatements;
914 }
915
919 public function getUserPrivacyComment()
920 {
922 }
923
928 {
929 $this->userPrivacyComment = $userPrivacyComment;
930 }
931
936 {
938 }
939
944 {
945 $this->statementsReportEnabled = $statementsReportEnabled;
946 }
947
951 public function getXmlManifest()
952 {
953 return $this->xmlManifest;
954 }
955
960 {
961 $this->xmlManifest = $xmlManifest;
962 }
963
967 public function getVersion()
968 {
969 return $this->version;
970 }
971
975 public function setVersion($version)
976 {
977 $this->version = $version;
978 }
979
983 public function isBypassProxyEnabled() : bool
984 {
986 }
987
992 {
993 $this->bypassProxyEnabled = $bypassProxyEnabled;
994 }
995
996 public function doRead()
997 {
998 $this->load();
999 }
1000
1001 public function load()
1002 {
1003 global $DIC; /* @var \ILIAS\DI\Container $DIC */
1004
1005 $query = "SELECT * FROM " . self::DB_TABLE_NAME . " WHERE obj_id = %s";
1006 $res = $DIC->database()->queryF($query, ['integer'], [$this->getId()]);
1007
1008 while ($row = $DIC->database()->fetchAssoc($res)) {
1009 if ($row['lrs_type_id']) {
1010 $this->setLrsTypeId((int) $row['lrs_type_id']);
1011 $this->initLrsType();
1012 }
1013
1014 $this->setContentType($row['content_type']);
1015 $this->setSourceType($row['source_type']);
1016
1017 $this->setActivityId($row['activity_id']);
1018 $this->setPublisherId($row['publisher_id']);
1019 $this->setInstructions($row['instructions']);
1020
1021 $this->setLaunchUrl($row['launch_url']);
1022 $this->setLaunchParameters($row['launch_parameters']);
1023 $this->setMoveOn($row['moveon']);
1024 $this->setEntitlementKey($row['entitlement_key']);
1025 $this->setAuthFetchUrlEnabled((bool) $row['auth_fetch_url']);
1026
1027 $this->setLaunchMethod($row['launch_method']);
1028
1029 $this->setLaunchMode($row['launch_mode']);
1030 $this->setSwitchToReviewEnabled((bool) $row['switch_to_review']);
1031 $this->setMasteryScore((float) $row['mastery_score']);
1032 $this->setKeepLpStatusEnabled((bool) $row['keep_lp']);
1033
1034 $this->setPrivacyIdent($row['privacy_ident']);
1035 $this->setPrivacyName($row['privacy_name']);
1036
1037 $this->setOnlyMoveon((bool) $row['only_moveon']);
1038 $this->setAchieved((bool) $row['achieved']);
1039 $this->setAnswered((bool) $row['answered']);
1040 $this->setCompleted((bool) $row['completed']);
1041 $this->setFailed((bool) $row['failed']);
1042 $this->setInitialized((bool) $row['initialized']);
1043 $this->setPassed((bool) $row['passed']);
1044 $this->setProgressed((bool) $row['progressed']);
1045 $this->setSatisfied((bool) $row['satisfied']);
1046 $this->setTerminated((bool) $row['c_terminated']);
1047 $this->setHideData((bool) $row['hide_data']);
1048 $this->setTimestamp((bool) $row['c_timestamp']);
1049 $this->setDuration((bool) $row['duration']);
1050 $this->setNoSubstatements((bool) $row['no_substatements']);
1051
1052 $this->setUserPrivacyComment($row['usr_privacy_comment']);
1053
1054 $this->setStatementsReportEnabled((bool) $row['show_statements']);
1055
1056 $this->setXmlManifest($row['xml_manifest']);
1057 $this->setVersion((int) $row['version']);
1058
1059 $this->setBypassProxyEnabled((bool) $row['bypass_proxy']);
1060
1061 $this->setHighscoreEnabled((bool) $row['highscore_enabled']);
1062 $this->setHighscoreAchievedTS((bool) $row['highscore_achieved_ts']);
1063 $this->setHighscorePercentage((bool) $row['highscore_percentage']);
1064 $this->setHighscoreWTime((bool) $row['highscore_wtime']);
1065 $this->setHighscoreOwnTable((bool) $row['highscore_own_table']);
1066 $this->setHighscoreTopTable((bool) $row['highscore_top_table']);
1067 $this->setHighscoreTopNum((int) $row['highscore_top_num']);
1068 }
1069
1071 }
1072
1073 public function doUpdate()
1074 {
1075 $this->save();
1076 }
1077
1078 public function save()
1079 {
1080 global $DIC; /* @var \ILIAS\DI\Container $DIC */
1081
1082 $DIC->database()->replace(self::DB_TABLE_NAME, [
1083 'obj_id' => ['integer', $this->getId()]
1084 ], [
1085 'lrs_type_id' => ['integer', $this->getLrsTypeId()],
1086 'content_type' => ['text', $this->getContentType()],
1087 'source_type' => ['text', $this->getSourceType()],
1088 'activity_id' => ['text', $this->getActivityId()],
1089 'publisher_id' => ['text', $this->getPublisherId()],
1090 'instructions' => ['text', $this->getInstructions()],
1091 'launch_url' => ['text', $this->getLaunchUrl()],
1092 'launch_parameters' => ['text', $this->getLaunchParameters()],
1093 'moveon' => ['text', $this->getMoveOn()],
1094 'entitlement_key' => ['text', $this->getEntitlementKey()],
1095 'auth_fetch_url' => ['integer', (int) $this->isAuthFetchUrlEnabled()],
1096 'launch_method' => ['text', $this->getLaunchMethod()],
1097 'launch_mode' => ['text', $this->getLaunchMode()],
1098 'switch_to_review' => ['integer', (int) $this->isSwitchToReviewEnabled()],
1099 'mastery_score' => ['float', $this->getMasteryScore()],
1100 'keep_lp' => ['integer', (int) $this->isKeepLpStatusEnabled()],
1101 'privacy_ident' => ['integer', $this->getPrivacyIdent()],
1102 'privacy_name' => ['integer', $this->getPrivacyName()],
1103 'usr_privacy_comment' => ['text', $this->getUserPrivacyComment()],
1104 'show_statements' => ['integer', (int) $this->isStatementsReportEnabled()],
1105 'xml_manifest' => ['text', $this->getXmlManifest()],
1106 'version' => ['integer', $this->getVersion()],
1107 'bypass_proxy' => ['integer', (int) $this->isBypassProxyEnabled()],
1108 'highscore_enabled' => ['integer', (int) $this->getHighscoreEnabled()],
1109 'highscore_achieved_ts' => ['integer', (int) $this->getHighscoreAchievedTS()],
1110 'highscore_percentage' => ['integer', (int) $this->getHighscorePercentage()],
1111 'highscore_wtime' => ['integer', (int) $this->getHighscoreWTime()],
1112 'highscore_own_table' => ['integer', (int) $this->getHighscoreOwnTable()],
1113 'highscore_top_table' => ['integer', (int) $this->getHighscoreTopTable()],
1114 'highscore_top_num' => ['integer', (int) $this->getHighscoreTopNum()],
1115 'only_moveon' => ['integer', (int)$this->getOnlyMoveon()],
1116 'achieved' => ['integer', (int)$this->getAchieved()],
1117 'answered' => ['integer', (int)$this->getAnswered()],
1118 'completed' => ['integer', (int)$this->getCompleted()],
1119 'failed' => ['integer', (int)$this->getFailed()],
1120 'initialized' => ['integer', (int)$this->getInitialized()],
1121 'passed' => ['integer', (int)$this->getPassed()],
1122 'progressed' => ['integer', (int)$this->getProgressed()],
1123 'satisfied' => ['integer', (int)$this->getSatisfied()],
1124 'c_terminated' => ['integer', (int)$this->getTerminated()],
1125 'hide_data' => ['integer', (int)$this->getHideData()],
1126 'c_timestamp' => ['integer', (int)$this->getTimestamp()],
1127 'duration' => ['integer', (int)$this->getDuration()],
1128 'no_substatements' => ['integer', (int)$this->getNoSubstatements()]
1129 ]);
1130
1132 }
1133
1135 {
1136 if ($this->ref_id) {
1137 include_once "./Services/Object/classes/class.ilObjectActivation.php";
1138 $activation = ilObjectActivation::getItem($this->ref_id);
1139 switch ($activation["timing_type"]) {
1141 $this->setActivationLimited(true);
1142 $this->setActivationStartingTime($activation["timing_start"]);
1143 $this->setActivationEndingTime($activation["timing_end"]);
1144 $this->setActivationVisibility($activation["visible"]);
1145 break;
1146
1147 default:
1148 $this->setActivationLimited(false);
1149 break;
1150 }
1151 }
1152 }
1153
1155 {
1156 if ($this->ref_id) {
1157 include_once "./Services/Object/classes/class.ilObjectActivation.php";
1158 ilObjectActivation::getItem($this->ref_id);
1159
1160 $item = new ilObjectActivation;
1161 if (!$this->isActivationLimited()) {
1163 } else {
1164 $item->setTimingType(ilObjectActivation::TIMINGS_ACTIVATION);
1165 $item->setTimingStart($this->getActivationStartingTime());
1166 $item->setTimingEnd($this->getActivationEndingTime());
1167 $item->toggleVisible($this->getActivationVisibility());
1168 }
1169
1170 $item->update($this->ref_id);
1171 }
1172 }
1173
1175 {
1176 global $DIC; /* @var \ILIAS\DI\Container $DIC */
1177
1178 $tableName = self::DB_TABLE_NAME;
1179
1180 $query = "
1181 UPDATE {$tableName}
1182 SET privacy_ident = %s,
1183 privacy_name = %s,
1184 only_moveon = %s,
1185 achieved = %s,
1186 answered = %s,
1187 completed = %s,
1188 failed = %s,
1189 initialized = %s,
1190 passed = %s,
1191 progressed = %s,
1192 satisfied = %s,
1193 c_terminated = %s,
1194 hide_data = %s,
1195 c_timestamp = %s,
1196 duration = %s,
1197 no_substatements = %s
1198 WHERE lrs_type_id = %s
1199 ";
1200
1201 $DIC->database()->manipulateF(
1202 $query,
1203 ['integer',
1204 'integer',
1205 'integer',
1206 'integer',
1207 'integer',
1208 'integer',
1209 'integer',
1210 'integer',
1211 'integer',
1212 'integer',
1213 'integer',
1214 'integer',
1215 'integer',
1216 'integer',
1217 'integer',
1218 'integer',
1219 'integer'
1220 ],
1221 [$lrsType->getPrivacyIdent(),
1222 $lrsType->getPrivacyName(),
1223 $lrsType->getOnlyMoveon(),
1224 $lrsType->getAchieved(),
1225 $lrsType->getAnswered(),
1226 $lrsType->getCompleted(),
1227 $lrsType->getFailed(),
1228 $lrsType->getInitialized(),
1229 $lrsType->getPassed(),
1230 $lrsType->getProgressed(),
1231 $lrsType->getSatisfied(),
1232 $lrsType->getTerminated(),
1233 $lrsType->getHideData(),
1234 $lrsType->getTimestamp(),
1235 $lrsType->getDuration(),
1236 $lrsType->getNoSubstatements(),
1237 $lrsType->getTypeId()
1238 ]
1239 );
1240 }
1241
1243 {
1244 global $DIC; /* @var \ILIAS\DI\Container $DIC */
1245
1246 $tableName = self::DB_TABLE_NAME;
1247
1248 $query = "
1249 UPDATE {$tableName}
1250 SET bypass_proxy = %s
1251 WHERE lrs_type_id = %s
1252 ";
1253
1254 $DIC->database()->manipulateF(
1255 $query,
1256 ['integer', 'integer'],
1257 [$lrsType->isBypassProxyEnabled(), $lrsType->getTypeId()]
1258 );
1259 }
1260
1262 {
1263 global $DIC; /* @var \ILIAS\DI\Container $DIC */
1264
1265 $query = "
1266 SELECT DISTINCT s.obj_id FROM " . self::DB_TABLE_NAME . " s
1267 INNER JOIN " . self::DB_USERS_TABLE_NAME . " u ON u.obj_id = s.obj_id
1268 WHERE bypass_proxy = %s
1269 ";
1270
1271 $res = $DIC->database()->queryF($query, array('integer'), array(1));
1272
1273 $objects = array();
1274
1275 while ($row = $DIC->database()->fetchAssoc($res)) {
1276 $objects[] = $row['obj_id'];
1277 }
1278
1279 return $objects;
1280 }
1281
1282
1283
1286
1290 protected $_highscore_enabled = 0;
1291
1292
1296 protected $anonymity = 0;
1297
1302
1307
1311 protected $_highscore_wtime = 1;
1312
1317
1322
1326 protected $_highscore_top_num = 10;
1327
1331
1332
1333
1339 public function setHighscoreEnabled($a_enabled)
1340 {
1341 $this->_highscore_enabled = (bool) $a_enabled;
1342 }
1343
1349 public function getHighscoreEnabled()
1350 {
1351 return (bool) $this->_highscore_enabled;
1352 }
1353
1359 public function setHighscoreAchievedTS($a_achieved_ts)
1360 {
1361 $this->_highscore_achieved_ts = (bool) $a_achieved_ts;
1362 }
1363
1369 public function getHighscoreAchievedTS()
1370 {
1371 return (bool) $this->_highscore_achieved_ts;
1372 }
1373
1379 public function setHighscorePercentage($a_percentage)
1380 {
1381 $this->_highscore_percentage = (bool) $a_percentage;
1382 }
1383
1389 public function getHighscorePercentage()
1390 {
1391 return (bool) $this->_highscore_percentage;
1392 }
1393
1399 public function setHighscoreWTime($a_wtime)
1400 {
1401 $this->_highscore_wtime = (bool) $a_wtime;
1402 }
1403
1409 public function getHighscoreWTime()
1410 {
1411 return (bool) $this->_highscore_wtime;
1412 }
1413
1419 public function setHighscoreOwnTable($a_own_table)
1420 {
1421 $this->_highscore_own_table = (bool) $a_own_table;
1422 }
1423
1429 public function getHighscoreOwnTable()
1430 {
1431 return (bool) $this->_highscore_own_table;
1432 }
1433
1439 public function setHighscoreTopTable($a_top_table)
1440 {
1441 $this->_highscore_top_table = (bool) $a_top_table;
1442 }
1443
1449 public function getHighscoreTopTable()
1450 {
1451 return (bool) $this->_highscore_top_table;
1452 }
1453
1460 public function setHighscoreTopNum($a_top_num)
1461 {
1462 $this->_highscore_top_num = (int) $a_top_num;
1463 }
1464
1473 public function getHighscoreTopNum($a_retval = 10)
1474 {
1475 $retval = $a_retval;
1476 if ((int) $this->_highscore_top_num != 0) {
1477 $retval = $this->_highscore_top_num;
1478 }
1479
1480 return $retval;
1481 }
1482
1486 public function getHighscoreMode()
1487 {
1488 switch (true) {
1489 case $this->getHighscoreOwnTable() && $this->getHighscoreTopTable():
1491
1492 case $this->getHighscoreTopTable():
1494
1495 case $this->getHighscoreOwnTable():
1496 default:
1498 }
1499 }
1500
1504 public function setHighscoreMode($mode)
1505 {
1506 switch ($mode) {
1508 $this->setHighscoreTopTable(1);
1509 $this->setHighscoreOwnTable(1);
1510 break;
1511
1513 $this->setHighscoreTopTable(1);
1514 $this->setHighscoreOwnTable(0);
1515 break;
1516
1518 default:
1519 $this->setHighscoreTopTable(0);
1520 $this->setHighscoreOwnTable(1);
1521 break;
1522 }
1523 }
1524
1525 /* End GET/SET for highscore feature*/
1526
1527
1528 public function getDataSetMapping()
1529 {
1530 if (null === ($lrsTypeId = $this->getLrsTypeId())) {
1531 $this->doRead();
1532 }
1533 $mapping = [
1534 'obj_id' => $this->getId(),
1535 'lrs_type_id' => $this->getLrsTypeId(),
1536 'content_type' => $this->getContentType(),
1537 'source_type' => $this->getSourceType(),
1538 'activity_id' => $this->getActivityId(),
1539 'publisher_id' => $this->getPublisherId(),
1540 'instructions' => $this->getInstructions(),
1541 'launch_url' => $this->getLaunchUrl(),
1542 'launch_parameters' => $this->getLaunchParameters(),
1543 'moveon' => $this->getMoveOn(),
1544 'entitlement_key' => $this->getEntitlementKey(),
1545 'auth_fetch_url' => (int) $this->isAuthFetchUrlEnabled(),
1546 'launch_method' => $this->getLaunchMethod(),
1547 'launch_mode' => $this->getLaunchMode(),
1548 'switch_to_review' => (int) $this->isSwitchToReviewEnabled(),
1549 'mastery_score' => $this->getMasteryScore(),
1550 'keep_lp' => (int) $this->isKeepLpStatusEnabled(),
1551 'privacy_ident' => $this->getPrivacyIdent(),
1552 'privacy_name' => $this->getPrivacyName(),
1553 'usr_privacy_comment' => $this->getUserPrivacyComment(),
1554 'show_statements' => (int) $this->isStatementsReportEnabled(),
1555 'xml_manifest' => $this->getXmlManifest(),
1556 'version' => $this->getVersion(),
1557 'highscore_enabled' => (int) $this->getHighscoreEnabled(),
1558 'highscore_achieved_ts' => (int) $this->getHighscoreAchievedTS(),
1559 'highscore_percentage' => (int) $this->getHighscorePercentage(),
1560 'highscore_wtime' => (int) $this->getHighscoreWTime(),
1561 'highscore_own_table' => (int) $this->getHighscoreOwnTable(),
1562 'highscore_top_table' => (int) $this->getHighscoreTopTable(),
1563 'highscore_top_num' => (int) $this->getHighscoreTopNum(),
1564 'only_moveon' => (int) $this->getOnlyMoveon(),
1565 'achieved' => (int) $this->getAchieved(),
1566 'answered' => (int) $this->getAnswered(),
1567 'completed' => (int) $this->getCompleted(),
1568 'failed' => (int) $this->getFailed(),
1569 'initialized' => (int) $this->getInitialized(),
1570 'passed' => (int) $this->getPassed(),
1571 'progressed' => (int) $this->getProgressed(),
1572 'satisfied' => (int) $this->getSatisfied(),
1573 'c_terminated' => (int) $this->getTerminated(),
1574 'hide_data' => (int) $this->getHideData(),
1575 'c_timestamp' => (int) $this->getTimestamp(),
1576 'duration' => (int) $this->getDuration(),
1577 'no_substatements' => (int) $this->getNoSubstatements()
1578 //'bypass_proxy' => (int) $this->isBypassProxyEnabled()
1579 ];
1580 return $mapping;
1581 }
1582
1590 protected function doCloneObject($new_obj, $a_target_id, $a_copy_id = null, $a_omit_tree = false)
1591 {
1592 global $DIC; /* @var \ILIAS\DI\Container $DIC */
1593
1594 $this->cloneMetaData($new_obj);
1595
1596 $new_obj->setLrsTypeId($this->getLrsTypeId());
1597 $new_obj->setContentType($this->getContentType());
1598 $new_obj->setSourceType($this->getSourceType());
1599 $new_obj->setActivityId($this->getActivityId());
1600 $new_obj->setPublisherId($this->getPublisherId());
1601 $new_obj->setInstructions($this->getInstructions());
1602 $new_obj->setLaunchUrl($this->getLaunchUrl());
1603 $new_obj->setLaunchParameters($this->getLaunchParameters());
1604 $new_obj->setMoveOn($this->getMoveOn());
1605 $new_obj->setEntitlementKey($this->getEntitlementKey());
1606 $new_obj->setAuthFetchUrlEnabled($this->isAuthFetchUrlEnabled());
1607 $new_obj->setLaunchMethod($this->getLaunchMethod());
1608 $new_obj->setLaunchMode($this->getLaunchMode());
1609 $new_obj->setSwitchToReviewEnabled($this->isSwitchToReviewEnabled());
1610 $new_obj->setMasteryScore($this->getMasteryScore());
1611 $new_obj->setKeepLpStatusEnabled($this->isKeepLpStatusEnabled());
1612 $new_obj->setPrivacyIdent($this->getPrivacyIdent());
1613 $new_obj->setPrivacyName($this->getPrivacyName());
1614 $new_obj->setUserPrivacyComment($this->getUserPrivacyComment());
1615 $new_obj->setStatementsReportEnabled($this->isStatementsReportEnabled());
1616 $new_obj->setXmlManifest($this->getXmlManifest());
1617 $new_obj->setVersion($this->getVersion());
1618 $new_obj->setHighscoreEnabled($this->getHighscoreEnabled());
1619 $new_obj->setHighscoreAchievedTS($this->getHighscoreAchievedTS());
1620 $new_obj->setHighscorePercentage($this->getHighscorePercentage());
1621 $new_obj->setHighscoreWTime($this->getHighscoreWTime());
1622 $new_obj->setHighscoreOwnTable($this->getHighscoreOwnTable());
1623 $new_obj->setHighscoreTopTable($this->getHighscoreTopTable());
1624 $new_obj->setHighscoreTopNum($this->getHighscoreTopNum());
1625 $new_obj->setBypassProxyEnabled($this->isBypassProxyEnabled());
1626 $new_obj->setOnlyMoveon($this->getOnlyMoveon());
1627 $new_obj->setAchieved($this->getAchieved());
1628 $new_obj->setAnswered($this->getAnswered());
1629 $new_obj->setCompleted($this->getCompleted());
1630 $new_obj->setFailed($this->getFailed());
1631 $new_obj->setInitialized($this->getInitialized());
1632 $new_obj->setPassed($this->getPassed());
1633 $new_obj->setProgressed($this->getProgressed());
1634 $new_obj->setSatisfied($this->getSatisfied());
1635 $new_obj->setTerminated($this->getTerminated());
1636 $new_obj->setHideData($this->getHideData());
1637 $new_obj->setTimestamp($this->getTimestamp());
1638 $new_obj->setDuration($this->getDuration());
1639 $new_obj->setNoSubstatements($this->getNoSubstatements());
1640 $new_obj->update();
1641
1642 if ($this->getSourceType() == self::SRC_TYPE_LOCAL) {
1643 $dirUtil = new ilCmiXapiContentUploadImporter($new_obj);
1644 $dirUtil->ensureCreatedObjectDirectory();
1645 $newDir = implode(DIRECTORY_SEPARATOR, [\ilUtil::getWebspaceDir(), $dirUtil->getWebDataDirRelativeObjectDirectory()]);
1646 $dirUtil = new ilCmiXapiContentUploadImporter($this);
1647 $thisDir = implode(DIRECTORY_SEPARATOR, [\ilUtil::getWebspaceDir(), $dirUtil->getWebDataDirRelativeObjectDirectory()]);
1648 ilUtil::rCopy($thisDir, $newDir);
1649 }
1650 }
1651
1652 protected function doDelete()
1653 {
1654 global $DIC;
1655 $ilDB = $DIC['ilDB'];
1656
1657 // delete file data entry
1658 $query = "DELETE FROM " . self::DB_TABLE_NAME . " WHERE obj_id = " . $ilDB->quote($this->getId(), 'integer');
1659 $ilDB->manipulate($query);
1660
1661 // delete history entries
1662 require_once("./Services/History/classes/class.ilHistory.php");
1664
1665 // delete entire directory and its content
1666 $dirUtil = new ilCmiXapiContentUploadImporter($this);
1667 $thisDir = implode(DIRECTORY_SEPARATOR, [\ilUtil::getWebspaceDir(), $dirUtil->getWebDataDirRelativeObjectDirectory()]);
1668 if (is_dir($thisDir)) {
1669 ilUtil::delDir($thisDir);
1670 }
1671
1672 // delete meta data
1673 $this->deleteMetaData();
1674
1675 //delete results
1676 $query = "DELETE FROM " . self::DB_RESULTS_TABLE_NAME .
1677 "WHERE obj_id = " . $ilDB->quote($this->getId(), 'integer') . " ";
1678 $ilDB->manipulate($query);
1679
1680 // TODO check xapidel
1681 }
1682
1683 public function getRegistrations() {
1684 global $DIC;
1685 $res = $DIC->database()->queryF(
1686 "SELECT DISTINCT registration FROM " . self::DB_USERS_TABLE_NAME ." WHERE obj_id = %s",
1687 array('text'),
1688 array($this->getId())
1689 );
1690 $ret = [];
1691 while ($row = $DIC->database()->fetchAssoc($res)) {
1692 $ret[] = $row['registration'];
1693 }
1694 return $ret;
1695 }
1696
1697 public static function guidv4($data = null) {
1698 // Generate 16 bytes (128 bits) of random data or use the data passed into the function.
1699 $data = $data ?? random_bytes(16);
1700 assert(strlen($data) == 16);
1701
1702 // Set version to 0100
1703 $data[6] = chr(ord($data[6]) & 0x0f | 0x40);
1704 // Set bits 6-7 to 10
1705 $data[8] = chr(ord($data[8]) & 0x3f | 0x80);
1706
1707 // Output the 36 character UUID.
1708 return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
1709 }
1710
1711 public function getCurrentCmixUser()
1712 {
1713 global $DIC;
1714 if (null === $this->currentCmixUser)
1715 {
1716 $this->currentCmixUser = new ilCmiXapiUser($this->getId(), $DIC->user()->getId(), $this->getPrivacyIdent());
1717 }
1719 }
1720
1721 public function getSessionId($cmixUser = null)
1722 {
1723 if (null === $cmixUser)
1724 {
1725 $cmixUser = $this->getCurrentCmixUser();
1726 }
1727 return ilCmiXapiAuthToken::getCmi5SessionByUsrIdAndObjIdAndRefId($cmixUser->getUsrId(),$this->getId(), $this->getRefId());
1728 }
1729
1733 public function getLaunchData($cmixUser = null, $lang = 'en')
1734 {
1735 if (null === $cmixUser)
1736 {
1737 $cmixUser = $this->getCurrentCmixUser();
1738 }
1739 // ToDo
1740 $moveOn = $this->getLMSMoveOn();
1741 if (!$moveOn || $moveOn == '')
1742 {
1743 $moveOn = 'Completed';
1744 }
1745 $launchMode = $this->getLaunchMode();
1746 // only check switch if self::LAUNCH_MODE_NORMAL
1747 if ($launchMode == self::LAUNCH_MODE_NORMAL) {
1748 if ($cmixUser->getSatisfied() && $this->isSwitchToReviewEnabled()) {
1750 }
1751 }
1752 $ctxTemplate = [
1753 "contextTemplate" => $this->getLaunchedContextTemplate($cmixUser),
1754 "launchMode" => ucfirst($launchMode),
1755 "launchMethod" => "OwnWindow",
1756 "moveOn" => $moveOn
1757 ];
1758 $lmsLaunchMethod = $this->getLaunchMethod();
1759 if ($lmsLaunchMethod === "ownWin") {
1760 include_once('./Services/Link/classes/class.ilLink.php');
1761 $href = ilLink::_getStaticLink(
1762 $this->getRefId(),
1763 $this->getType()
1764 );
1765 $ctxTemplate['returnURL'] = $href;
1766 }
1767 else {
1768 $ctxTemplate['returnURL'] = ILIAS_HTTP_PATH."/Modules/CmiXapi/xapiexit.php?lang={$lang}";
1769 }
1770 if (!empty($this->getMasteryScore())) {
1771 $ctxTemplate['masteryScore'] = $this->getMasteryScore();
1772 }
1773 if (!empty($this->getLaunchParameters())) {
1774 $ctxTemplate['launchParameters'] = $this->getLaunchParameters();
1775 }
1776 if (!empty($this->getEntitlementKey())) {
1777 $ctxTemplate['entitlementKey'] = array("courseStructure" => $this->getEntitlementKey());
1778 }
1779 return $ctxTemplate;
1780 }
1781
1782 public function getLaunchedContextTemplate($cmixUser = null)
1783 {
1784 if (null === $cmixUser)
1785 {
1786 $cmixUser = $this->getCurrentCmixUser();
1787 }
1788 $launchMode = $this->getLaunchMode();
1789 // only check switch if self::LAUNCH_MODE_NORMAL
1790 if ($launchMode == self::LAUNCH_MODE_NORMAL) {
1791 if ($cmixUser->getSatisfied() && $this->isSwitchToReviewEnabled()) {
1793 }
1794 }
1795 $extensions = $this->getStatementExtensions($cmixUser);
1796 $extensions['https://w3id.org/xapi/cmi5/context/extensions/launchmode'] = $launchMode;
1797 if (!empty($this->getLMSMoveOn())) {
1798 $extensions['https://w3id.org/xapi/cmi5/context/extensions/moveon'] = $this->getLMSMoveOn();
1799 }
1800 if (!empty($this->getLaunchParameters())) {
1801 $extensions['https://w3id.org/xapi/cmi5/context/extensions/launchparameters'] = $this->getLaunchParameters();
1802 }
1803 if (!empty($this->getMasteryScore())) {
1804 $extensions['https://w3id.org/xapi/cmi5/context/extensions/masteryscore'] = $this->getMasteryScore();
1805 }
1806 $contextTemplate = array(
1807 "contextActivities" => $this->getStatementContextActivities(),
1808 "extensions" => $extensions
1809 );
1810 return $contextTemplate;
1811 }
1812
1816 public function getStatement(string $verb, $cmixUser = null)
1817 {
1818 if (null === $cmixUser)
1819 {
1820 $cmixUser = $this->getCurrentCmixUser();
1821 }
1822 $id = self::guidv4();
1823 $actor = $this->getStatementActor($cmixUser);
1824 $verbUri = ilCmiXapiVerbList::getInstance()->getVerbUri($verb);
1825 $extensions = $this->getStatementExtensions($cmixUser);
1826 $registration = $cmixUser->getRegistration();
1827 $contextActivities = $this->getStatementContextActivities();
1828 $object = $this->getStatementObject();
1829 $statement = array (
1830 'id' => $id,
1831 'actor' => $actor,
1832 'verb' =>
1833 array (
1834 'id' => $verbUri
1835 ),
1836 'context' =>
1837 array (
1838 'extensions' => $extensions,
1839 'registration' => $registration,
1840 'contextActivities' => $contextActivities
1841 ),
1842 'object' => $object
1843 );
1844 return $statement;
1845 }
1846
1850 public function getStatementActor($cmixUser = null)
1851 {
1852 global $DIC;
1853 if (null === $cmixUser)
1854 {
1855 $cmixUser = $this->getCurrentCmixUser();
1856 }
1857 $user = new ilObjUser($cmixUser->getUsrId()); // ToDo: Caching Names
1858 $name = ilCmiXapiUser::getName($this->getPrivacyName(), $user);
1859 if ($name == '') {
1860 $this->log()->error('error: no name in cmixuser');
1861 $name = 'UNDEFINED';
1862 }
1863 $homePage = ($this->anonymousHomePage == true) ? self::ANONYMOUS_HOMEPAGE : self::iliasUrl();
1864 if ($this->getContentType() == self::CONT_TYPE_CMI5)
1865 {
1866 $actor = [
1867 'objectType' => 'Agent',
1868 'account' => [
1869 'homePage' => $homePage,
1870 'name' => $cmixUser->getUsrIdent()
1871 ]
1872 ];
1873 if ($name !== '')
1874 {
1875 $actor['name'] = $name;
1876 }
1877 }
1878 else
1879 {
1880 $actor = [
1881 'objectType' => 'Agent',
1882 'mbox' => 'mailto:'.$cmixUser->getUsrIdent()
1883 ];
1884 if ($name !== '')
1885 {
1886 $actor['name'] = $name;
1887 }
1888 }
1889 return $actor;
1890 }
1891
1895 public function getStatementExtensions($cmixUser = null)
1896 {
1897 if (null === $cmixUser)
1898 {
1899 $cmixUser = $this->getCurrentCmixUser();
1900 }
1901 $extensions = array (
1902 'https://w3id.org/xapi/cmi5/context/extensions/sessionid' => $this->getSessionId($cmixUser),
1903 'https://ilias.de/cmi5/activityid' => $this->getActivityId()
1904 );
1905 return $extensions;
1906 }
1907
1912 {
1913 $publisherId = $this->getPublisherId();
1914 $activityId = $this->getActivityId();
1915 if (empty($publisherId))
1916 {
1918 }
1919 $ctxActivities = array(
1920 "grouping" => [
1921 [
1922 "objectType" => "Activity",
1923 "id" => "{$publisherId}",
1924 'definition' =>
1925 array (
1926 'name' =>
1927 array (
1928 'de-DE' => $this->getTitle(),
1929 'en-US' => $this->getTitle()
1930 ),
1931 'description' =>
1932 array (
1933 'de-DE' => $this->getDescription(),
1934 'en-US' => $this->getDescription()
1935 )
1936 )]
1937 ],
1938 "category" => [
1939 [
1940 "id" => "https://w3id.org/xapi/cmi5/context/categories/cmi5",
1941 "objectType" => "Activity"
1942 ]
1943 ]
1944 );
1945 return $ctxActivities;
1946 }
1947
1948 public function getStatementObject()
1949 {
1950 $object = array (
1951 'id' => $this->getActivityId(),
1952 'definition' =>
1953 array (
1954 'name' =>
1955 array (
1956 'de-DE' => $this->getTitle(),
1957 'en-US' => $this->getTitle()
1958 ),
1959 'description' =>
1960 array (
1961 'de-DE' => $this->getDescription(),
1962 'en-US' => $this->getDescription()
1963 )
1964 )
1965 );
1966 return $object;
1967 }
1968
1969 public function getLaunchedStatement($cmixUser = null)
1970 {
1971 if (null === $cmixUser) {
1972 $cmixUser = $this->getCurrentCmixUser();
1973 }
1974 $launchMode = $this->getLaunchMode();
1975 // only check switch if self::LAUNCH_MODE_NORMAL
1976 if ($launchMode == self::LAUNCH_MODE_NORMAL) {
1977 if ($cmixUser->getSatisfied() && $this->isSwitchToReviewEnabled()) {
1979 }
1980 }
1981
1982 $statement = $this->getStatement('launched', $cmixUser);
1983 $statement['context']['extensions']['https://w3id.org/xapi/cmi5/context/extensions/launchmode'] = $launchMode;
1984 if (!empty($this->getLMSMoveOn())) {
1985 $statement['context']['extensions']['https://w3id.org/xapi/cmi5/context/extensions/moveon'] = $this->getLMSMoveOn();
1986 }
1987 if (!empty($this->getLaunchParameters())) {
1988 $statement['context']['extensions']['https://w3id.org/xapi/cmi5/context/extensions/launchparameters'] = $this->getLaunchParameters();
1989 }
1990 if (!empty($this->getMasteryScore())) {
1991 $statement['context']['extensions']['https://w3id.org/xapi/cmi5/context/extensions/masteryscore'] = $this->getMasteryScore();
1992 }
1993 return $statement;
1994 }
1995
1996 public function getAbandonedStatement($sessionId, $duration, $cmixUser = null)
1997 {
1998 if (null === $cmixUser)
1999 {
2000 $cmixUser = $this->getCurrentCmixUser();
2001 }
2002 $statement = $this->getStatement('abandoned',$cmixUser);
2003 // overwrite session with abandoned oldSession
2004 $statement['context']['extensions']['https://w3id.org/xapi/cmi5/context/extensions/sessionid'] = $sessionId;
2005 $statement['result'] = array(
2006 'duration' => $duration
2007 );
2008 return $statement;
2009 }
2010
2011 public function getSatisfiedStatement($cmixUser = null)
2012 {
2013 if (null === $cmixUser)
2014 {
2015 $cmixUser = $this->getCurrentCmixUser();
2016 }
2017 $statement = $this->getStatement('satisfied', $cmixUser);
2018 // add type, see https://aicc.github.io/CMI-5_Spec_Current/samples/scenarios/16-not_applicable-no_launch/#satisfied-statement
2019 // see also: https://github.com/AICC/CMI-5_Spec_Current/blob/quartz/cmi5_spec.md#verbs_satisfied
2020 $type = "https://w3id.org/xapi/cmi5/activitytype/course";
2021 $statement['object']['definition']['type'] = $type;
2022 $statement['context']['contextActivities']['grouping'][0]['definition']['type'] = $type;
2023 return $statement;
2024 }
2025
2029 public function getLastStatement($sess)
2030 {
2031 global $DIC;
2032 $lrsType = $this->getLrsType();
2033
2034 //$this->getLrsEndpoint())) . '/api/' . self::ENDPOINT_AGGREGATE_SUFFIX;
2035 $defaultLrs = $lrsType->getLrsEndpointStatementsAggregationLink();
2036 //$fallbackLrs = $lrsType->getLrsFallbackEndpoint();
2037 $defaultBasicAuth = $lrsType->getBasicAuth();
2038 //$fallbackBasicAuth = $lrsType->getFallbackBasicAuth();
2039 $defaultHeaders = [
2040 'X-Experience-API-Version' => '1.0.3',
2041 'Authorization' => $defaultBasicAuth,
2042 'Cache-Control' => 'no-cache, no-store, must-revalidate'
2043 ];
2044 /*
2045 $fallbackHeaders = [
2046 'X-Experience-API-Version' => '1.0.3',
2047 'Authorization' => $fallbackBasicAuth,
2048 'Content-Type' => 'application/json;charset=utf-8',
2049 'Cache-Control' => 'no-cache, no-store, must-revalidate'
2050 ];
2051 */
2052 $pipeline = json_encode($this->getLastStatementPipline($sess));
2053 $defaultLastStatementUrl = $defaultLrs . "?pipeline=" . urlencode($pipeline);
2054 $client = new GuzzleHttp\Client();
2055 $req_opts = array(
2056 GuzzleHttp\RequestOptions::VERIFY => true,
2057 GuzzleHttp\RequestOptions::CONNECT_TIMEOUT => 10,
2058 GuzzleHttp\RequestOptions::HTTP_ERRORS => false
2059 );
2060 $defaultLastStatementRequest = new GuzzleHttp\Psr7\Request(
2061 'GET',
2062 $defaultLastStatementUrl,
2063 $defaultHeaders
2064 );
2065 $promises = array();
2066 $promises['defaultLastStatement'] = $client->sendAsync($defaultLastStatementRequest, $req_opts);
2067 try
2068 {
2069 $responses = GuzzleHttp\Promise\Utils::settle($promises)->wait();
2070 $body = '';
2071 ilCmiXapiAbstractRequest::checkResponse($responses['defaultLastStatement'],$body,[200]);
2072 return json_decode($body,JSON_OBJECT_AS_ARRAY);
2073 }
2074 catch(Exception $e)
2075 {
2076 $this->log()->error('error:' . $e->getMessage());
2077 return null;
2078 }
2079 }
2080
2082 {
2083 global $DIC;
2084 $pipeline = array();
2085
2086 // filter activityId
2087 $match = array();
2088 $match['statement.object.objectType'] = 'Activity';
2089 $match['statement.actor.objectType'] = 'Agent';
2090
2091 $activityId = array();
2092
2094 {
2095 // https://github.com/AICC/CMI-5_Spec_Current/blob/quartz/cmi5_spec.md#963-extensions
2096 $activityId['statement.context.extensions.https://ilias&46;de/cmi5/activityid'] = $this->getActivityId();
2097 }
2098 else
2099 {
2100 $activityQuery = [
2101 '$regex' => '^' . preg_quote($this->getActivityId()) . ''
2102 ];
2103 $activityId['$or'] = [];
2104 $activityId['$or'][] = ['statement.object.id' => $activityQuery];
2105 $activityId['$or'][] = ['statement.context.contextActivities.parent.id' => $activityQuery];
2106 $activityId['$or'][] = ['statement.context.contextActivities.grouping.id' => $activityQuery];
2107 }
2108
2109 $sessionId = array();
2110 $sessionId['statement.context.extensions.https://w3id&46;org/xapi/cmi5/context/extensions/sessionid'] = $sess;
2111 $match['$and'] = array();
2112 $match['$and'][] = $activityId;
2113 $match['$and'][] = $sessionId;
2114 $sort = array('statement.timestamp' => -1);
2115 $project = array('statement.timestamp' => 1, 'statement.verb.id' => 1);
2116 $pipeline[] = array('$match' => $match);
2117 $pipeline[] = array('$sort' => $sort);
2118 $pipeline[] = array('$limit' => 1);
2119 $pipeline[] = array('$project' => $project);
2120
2121 return $pipeline;
2122 }
2123
2124 public static function iliasUrl() {
2125 $regex = '/^(https?\:\/\/[^\/]+).*/';
2126 preg_match($regex, $GLOBALS['DIC']->http()->request()->getUri(), $request_parts);
2127 return $request_parts[1];
2128 }
2129
2130 public static function log() {
2131 global $log;
2132 if (self::PLUGIN) {
2133 return $log;
2134 }
2135 else {
2136 return \ilLoggerFactory::getLogger('cmix');
2137 }
2138 }
2139
2140
2144 public function isActivationLimited()
2145 {
2147 }
2148
2149
2154 {
2155 $this->activationLimited = $activationLimited;
2156 }
2157
2162 {
2164 }
2165
2170 {
2171 $this->activationStartingTime = $activationStartingTime;
2172 }
2173
2177 public function getActivationEndingTime()
2178 {
2180 }
2181
2186 {
2187 $this->activationEndingTime = $activationEndingTime;
2188 }
2189
2193 public function getActivationVisibility()
2194 {
2196 }
2197
2202 {
2203 $this->activationVisibility = $activationVisibility;
2204 }
2205
2206}
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
An exception for terminatinating execution or to throw for unit testing.
static checkResponse($response, &$body, $allowedStatus=[200, 204])
static getCmi5SessionByUsrIdAndObjIdAndRefId(int $usrId, int $objId, $refId=null)
const MOVEON_COMPLETED_OR_PASSED
const MOVEON_NOT_APPLICABLE
static getName($userNameMode, ilObjUser $user)
static _removeEntriesForObject($a_obj_id)
remove all history entries for an object
const LP_MODE_CMIX_COMPL_OR_PASSED_WITH_FAILED
setMasteryScore($masteryScore)
setDuration(bool $duration)
setBypassProxyEnabled(bool $bypassProxyEnabled)
doCloneObject($new_obj, $a_target_id, $a_copy_id=null, $a_omit_tree=false)
Clone object.
setOnlyMoveon(bool $only_moveon)
setActivityId($activityId)
getHighscoreWTime()
Gets if the column with the workingtime should be shown.
setPublisherId($publisherId)
setHideData(bool $hide_data)
getLastStatementPipline($sess)
setPrivacyIdent($userIdent)
getLaunchedStatement($cmixUser=null)
setMasteryScorePercent($masteryScorePercent)
getLastStatement($sess)
get latest statement from session
setStatementsReportEnabled($statementsReportEnabled)
setSourceType($sourceType)
getHighscoreTopNum($a_retval=10)
Gets the number of entries which are to be shown in the top-rankings table.
setLaunchMode($launchMode)
getLaunchData($cmixUser=null, $lang='en')
LMS.LaunchData.
setNoSubstatements(bool $no_substatements)
static getObjectsHavingBypassProxyEnabledAndRegisteredUsers()
setLaunchMethod($launchMethod)
const PRIVACY_IDENT_IL_UUID_USER_ID
setHighscoreEnabled($a_enabled)
Sets if the highscore feature should be enabled.
setHighscoreTopNum($a_top_num)
Sets the number of entries which are to be shown in the top-rankings table.
__construct($a_id=0, $a_reference=true)
ilObjCmiXapi constructor.
getHighscorePercentage()
Gets if the percentage column should be shown.
getStatementExtensions($cmixUser=null)
Minimal extensions.
getSatisfiedStatement($cmixUser=null)
setActivationLimited($activationLimited)
setHighscoreTopTable($a_top_table)
Sets if the top-rankings table should be shown.
setSatisfied(bool $satisfied)
setTimestamp(bool $timestamp)
getHighscoreAchievedTS()
Returns if date and time of the scores achievement should be displayed.
setTerminated(bool $terminated)
const PRIVACY_IDENT_IL_UUID_RANDOM
static guidv4($data=null)
setActivationStartingTime($activationStartingTime)
setAnswered(bool $answered)
getStatementActor($cmixUser=null)
statement actor
setActivationVisibility($activationVisibility)
setXmlManifest($xmlManifest)
getHighscoreTopTable()
Gets, if the top-rankings table should be shown.
setLaunchUrl($launchUrl)
setAuthFetchUrlEnabled($authFetchUrlEnabled)
setUserPrivacyComment($userPrivacyComment)
setHighscoreOwnTable($a_own_table)
Sets if the table with the own ranking should be shown.
const PRIVACY_IDENT_IL_UUID_LOGIN
setAchieved(bool $achieved)
const PRIVACY_IDENT_REAL_EMAIL
setHighscoreAchievedTS($a_achieved_ts)
Sets if the date and time of the scores achievement should be displayed.
const PRIVACY_IDENT_IL_UUID_SHA256
setProgressed(bool $progressed)
setInstructions($instructions)
const PRIVACY_IDENT_IL_UUID_EXT_ACCOUNT
setHighscorePercentage($a_percentage)
Sets if the percentages of the scores pass should be shown.
setLrsTypeId($lrsTypeId)
getStatementContextActivities()
Minimal statementActivities.
getLaunchedContextTemplate($cmixUser=null)
getAbandonedStatement($sessionId, $duration, $cmixUser=null)
setInitialized(bool $initialized)
getHighscoreOwnTable()
Gets if the own rankings table should be shown.
setCompleted(bool $completed)
static getInstance($a_id=0, $a_reference=true)
setLaunchParameters($launchParameters)
$activationLimited
repository object activation settings (handled by ilObject)
setPassed(bool $passed)
getHighscoreEnabled()
Gets the setting which determines if the highscore feature is enabled.
getSessionId($cmixUser=null)
setEntitlementKey($entitlementKey)
setActivationEndingTime($activationEndingTime)
getStatement(string $verb, $cmixUser=null)
blueprint statement
setPrivacyName($userName)
setHighscoreWTime($a_wtime)
Sets if the workingtime of the scores should be shown.
static updatePrivacySettingsFromLrsType(ilCmiXapiLrsType $lrsType)
static updateByPassProxyFromLrsType(ilCmiXapiLrsType $lrsType)
setFailed(bool $failed)
setSwitchToReviewEnabled($switchToReviewEnabled)
setContentType($contentType)
setKeepLpStatusEnabled($keepLpStatusEnabled)
Class ilObject2 This is an intermediate progress of ilObject class.
getRefId()
get reference id @access public
cloneMetaData($target_obj)
Copy meta data.
deleteMetaData()
delete meta data entry
getType()
get object type @access public
getDescription()
get object description
getTitle()
get object title @access public
Class ilObjectActivation.
setTimingType($a_type)
Set timing type.
static getItem($a_ref_id)
Get item data.
static getInstance($a_obj_id)
getId()
get object id @access public
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static getWebspaceDir($mode="filesystem")
get webspace directory
static rCopy($a_sdir, $a_tdir, $preserveTimeAttributes=false)
Copies content of a directory $a_sdir recursively to a directory $a_tdir.
if($_SERVER['argc']< 4) $client
Definition: cron.php:12
if($format !==null) $name
Definition: metadata.php:230
static http()
Fetches the global http state from ILIAS.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$ret
Definition: parser.php:6
$query
foreach($_POST as $key=> $value) $res
global $ilDB
$data
Definition: storeScorm.php:23
$lang
Definition: xapiexit.php:8
$DIC
Definition: xapitoken.php:46