ILIAS  release_7 Revision v7.30-3-g800a261c036
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;
145
149 protected $userName;
154
155
160
165
169 protected $xmlManifest;
170
174 protected $version;
175
180
182 protected $only_moveon = false;
183
185 protected $achieved = true;
186
188 protected $answered = true;
189
191 protected $completed = true;
192
194 protected $failed = true;
195
197 protected $initialized = true;
198
200 protected $passed = true;
201
203 protected $progressed = true;
204
206 protected $satisfied = true;
207
209 protected $terminated = true;
210
212 protected $hide_data = false;
213
215 protected $timestamp = false;
216
218 protected $duration = true;
219
221 protected $no_substatements = false;
222
224 protected $currentCmixUser = null;
225
231 public function __construct($a_id = 0, $a_reference = true)
232 {
233 $this->lrsTypeId = 0;
234 //$this->lrsType = $lrsType;
235
236 $this->contentType = self::CONT_TYPE_GENERIC;
237 $this->sourceType = self::SRC_TYPE_REMOTE;
238
239 $this->activityId = '';
240
241 $this->publisherId = '';
242
243 $this->instructions = '';
244
245 $this->launchUrl = '';
246 $this->launchParameters = '';
247 $this->moveOn = '';
248 $this->entitlementKey = '';
249
250 $this->authFetchUrlEnabled = 0;
251
252 $this->launchMethod = self::LAUNCH_METHOD_NEW_WIN;
253 $this->launchMode = self::LAUNCH_MODE_NORMAL;
254
255 $this->switchToReviewEnabled = 1;
256
257 $this->masteryScore = self::LMS_MASTERY_SCORE;
258 $this->keepLpStatusEnabled = 1;
259
260 $this->userIdent = self::PRIVACY_IDENT_IL_UUID_USER_ID;
261 $this->userName = self::PRIVACY_NAME_NONE;
262 $this->userPrivacyComment = '';
263
264 $this->currentCmixUser = null;
265
266 $this->statementsReportEnabled = 0;
267
268 $this->xmlManifest = '';
269 $this->version = 0;
270
271 $this->bypassProxyEnabled = false;
272
273 parent::__construct($a_id, $a_reference);
274 }
275
276
277 public static function getInstance($a_id = 0, $a_reference = true)
278 {
279 return new self($a_id, $a_reference);
280 }
281
282 protected function initType() : void
283 {
284 $this->type = "cmix";
285 }
286
290 public function getLrsTypeId()
291 {
292 return $this->lrsTypeId;
293 }
294
298 public function setLrsTypeId($lrsTypeId)
299 {
300 $this->lrsTypeId = $lrsTypeId;
301 }
302
306 public function getLrsType()
307 {
308 return $this->lrsType;
309 }
310
314 public function setLrsType($lrsType)
315 {
316 $this->lrsType = $lrsType;
317 }
318
319 public function initLrsType()
320 {
321 $this->setLrsType(new ilCmiXapiLrsType($this->getLrsTypeId()));
322 }
323
327 public function getContentType()
328 {
329 return $this->contentType;
330 }
331
336 {
337 //bug before 21-07-24
338 if ($contentType == "learning") {
340 }
341 $this->contentType = $contentType;
342 }
343
347 public function isMixedContentType() : bool
348 {
349 // after 21-07-24 and before cmi5 refactoring
350 // launched before cmi5 refactoring ident in: statement.actor.mbox
351 // launched after cmi5 refactoring ident in: statement.actor.account.name
352 return (($this->getContentType() == self::CONT_TYPE_CMI5) && empty($this->getPublisherId()));
353 }
354
358 public function getSourceType()
359 {
360 return $this->sourceType;
361 }
362
366 public function isSourceTypeRemote()
367 {
368 return $this->sourceType == self::SRC_TYPE_REMOTE;
369 }
370
374 public function isSourceTypeExternal()
375 {
376 return $this->sourceType == self::SRC_TYPE_EXTERNAL;
377 }
378
382 public function setSourceType($sourceType)
383 {
384 $this->sourceType = $sourceType;
385 }
386
390 public function getActivityId()
391 {
392 return $this->activityId;
393 }
394
398 public function setActivityId($activityId)
399 {
400 $this->activityId = $activityId;
401 }
402
406 public function getPublisherId()
407 {
408 return $this->publisherId;
409 }
410
415 {
416 $this->publisherId = $publisherId;
417 }
418
422 public function getInstructions()
423 {
424 return $this->instructions;
425 }
426
431 {
432 $this->instructions = $instructions;
433 }
434
438 public function getLaunchUrl()
439 {
440 return $this->launchUrl;
441 }
442
446 public function setLaunchUrl($launchUrl)
447 {
448 $this->launchUrl = $launchUrl;
449 }
450
454 public function getLaunchParameters()
455 {
457 }
458
463 {
464 $this->launchParameters = $launchParameters;
465 }
466
472 public function getMoveOn()
473 {
474 return $this->moveOn;
475 }
476
482 public function setMoveOn($moveOn)
483 {
484 $this->moveOn = $moveOn;
485 }
486
491 public function getLPMode()
492 {
493 $olp = ilObjectLP::getInstance($this->getId());
494 return $olp->getCurrentMode();
495 }
496
501 public function getLMSMoveOn()
502 {
504 switch ($this->getLPMode()) {
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 {
1685 global $DIC;
1686 $res = $DIC->database()->queryF(
1687 "SELECT DISTINCT registration FROM " . self::DB_USERS_TABLE_NAME . " WHERE obj_id = %s",
1688 array('text'),
1689 array($this->getId())
1690 );
1691 $ret = [];
1692 while ($row = $DIC->database()->fetchAssoc($res)) {
1693 $ret[] = $row['registration'];
1694 }
1695 return $ret;
1696 }
1697
1698 public static function guidv4($data = null)
1699 {
1700 // Generate 16 bytes (128 bits) of random data or use the data passed into the function.
1701 $data = $data ?? random_bytes(16);
1702 assert(strlen($data) == 16);
1703
1704 // Set version to 0100
1705 $data[6] = chr(ord($data[6]) & 0x0f | 0x40);
1706 // Set bits 6-7 to 10
1707 $data[8] = chr(ord($data[8]) & 0x3f | 0x80);
1708
1709 // Output the 36 character UUID.
1710 return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
1711 }
1712
1713 public function getCurrentCmixUser()
1714 {
1715 global $DIC;
1716 if (null === $this->currentCmixUser) {
1717 $this->currentCmixUser = new ilCmiXapiUser($this->getId(), $DIC->user()->getId(), $this->getPrivacyIdent());
1718 }
1720 }
1721
1722 public function getSessionId($cmixUser = null)
1723 {
1724 if (null === $cmixUser) {
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 $cmixUser = $this->getCurrentCmixUser();
1737 }
1738 // ToDo
1739 $moveOn = $this->getLMSMoveOn();
1740 if (!$moveOn || $moveOn == '') {
1741 $moveOn = 'Completed';
1742 }
1743 $launchMode = $this->getLaunchMode();
1744 // only check switch if self::LAUNCH_MODE_NORMAL
1745 if ($launchMode == self::LAUNCH_MODE_NORMAL) {
1746 if ($cmixUser->getSatisfied() && $this->isSwitchToReviewEnabled()) {
1748 }
1749 }
1750 $ctxTemplate = [
1751 "contextTemplate" => $this->getLaunchedContextTemplate($cmixUser),
1752 "launchMode" => ucfirst($launchMode),
1753 "launchMethod" => "OwnWindow",
1754 "moveOn" => $moveOn
1755 ];
1756 $lmsLaunchMethod = $this->getLaunchMethod();
1757 if ($lmsLaunchMethod === "ownWin") {
1758 include_once('./Services/Link/classes/class.ilLink.php');
1759 $href = ilLink::_getStaticLink(
1760 $this->getRefId(),
1761 $this->getType()
1762 );
1763 $ctxTemplate['returnURL'] = $href;
1764 } else {
1765 $ctxTemplate['returnURL'] = ILIAS_HTTP_PATH . "/Modules/CmiXapi/xapiexit.php?lang={$lang}";
1766 }
1767 if (!empty($this->getMasteryScore())) {
1768 $ctxTemplate['masteryScore'] = $this->getMasteryScore();
1769 }
1770 if (!empty($this->getLaunchParameters())) {
1771 $ctxTemplate['launchParameters'] = $this->getLaunchParameters();
1772 }
1773 if (!empty($this->getEntitlementKey())) {
1774 $ctxTemplate['entitlementKey'] = array("courseStructure" => $this->getEntitlementKey());
1775 }
1776 return $ctxTemplate;
1777 }
1778
1779 public function getLaunchedContextTemplate($cmixUser = null)
1780 {
1781 if (null === $cmixUser) {
1782 $cmixUser = $this->getCurrentCmixUser();
1783 }
1784 $launchMode = $this->getLaunchMode();
1785 // only check switch if self::LAUNCH_MODE_NORMAL
1786 if ($launchMode == self::LAUNCH_MODE_NORMAL) {
1787 if ($cmixUser->getSatisfied() && $this->isSwitchToReviewEnabled()) {
1789 }
1790 }
1791 $extensions = $this->getStatementExtensions($cmixUser);
1792 $extensions['https://w3id.org/xapi/cmi5/context/extensions/launchmode'] = $launchMode;
1793 if (!empty($this->getLMSMoveOn())) {
1794 $extensions['https://w3id.org/xapi/cmi5/context/extensions/moveon'] = $this->getLMSMoveOn();
1795 }
1796 if (!empty($this->getLaunchParameters())) {
1797 $extensions['https://w3id.org/xapi/cmi5/context/extensions/launchparameters'] = $this->getLaunchParameters();
1798 }
1799 if (!empty($this->getMasteryScore())) {
1800 $extensions['https://w3id.org/xapi/cmi5/context/extensions/masteryscore'] = $this->getMasteryScore();
1801 }
1802 $contextTemplate = array(
1803 "contextActivities" => $this->getStatementContextActivities(),
1804 "extensions" => $extensions
1805 );
1806 return $contextTemplate;
1807 }
1808
1812 public function getStatement(string $verb, $cmixUser = null)
1813 {
1814 if (null === $cmixUser) {
1815 $cmixUser = $this->getCurrentCmixUser();
1816 }
1817 $id = self::guidv4();
1818 $actor = $this->getStatementActor($cmixUser);
1819 $verbUri = ilCmiXapiVerbList::getInstance()->getVerbUri($verb);
1820 $extensions = $this->getStatementExtensions($cmixUser);
1821 $registration = $cmixUser->getRegistration();
1822 $contextActivities = $this->getStatementContextActivities();
1823 $object = $this->getStatementObject();
1824 $statement = array(
1825 'id' => $id,
1826 'actor' => $actor,
1827 'verb' =>
1828 array(
1829 'id' => $verbUri
1830 ),
1831 'context' =>
1832 array(
1833 'extensions' => $extensions,
1834 'registration' => $registration,
1835 'contextActivities' => $contextActivities
1836 ),
1837 'object' => $object
1838 );
1839 return $statement;
1840 }
1841
1845 public function getStatementActor($cmixUser = null)
1846 {
1847 global $DIC;
1848 if (null === $cmixUser) {
1849 $cmixUser = $this->getCurrentCmixUser();
1850 }
1851 $user = new ilObjUser($cmixUser->getUsrId()); // ToDo: Caching Names
1852 $name = ilCmiXapiUser::getName($this->getPrivacyName(), $user);
1853 if ($name == '') {
1854 $this->log()->error('error: no name in cmixuser');
1855 $name = 'UNDEFINED';
1856 }
1857 $homePage = ($this->anonymousHomePage == true) ? self::ANONYMOUS_HOMEPAGE : self::iliasUrl();
1858 if ($this->getContentType() == self::CONT_TYPE_CMI5) {
1859 $actor = [
1860 'objectType' => 'Agent',
1861 'account' => [
1862 'homePage' => $homePage,
1863 'name' => $cmixUser->getUsrIdent()
1864 ]
1865 ];
1866 if ($name !== '') {
1867 $actor['name'] = $name;
1868 }
1869 } else {
1870 $actor = [
1871 'objectType' => 'Agent',
1872 'mbox' => 'mailto:' . $cmixUser->getUsrIdent()
1873 ];
1874 if ($name !== '') {
1875 $actor['name'] = $name;
1876 }
1877 }
1878 return $actor;
1879 }
1880
1884 public function getStatementExtensions($cmixUser = null)
1885 {
1886 if (null === $cmixUser) {
1887 $cmixUser = $this->getCurrentCmixUser();
1888 }
1889 $extensions = array(
1890 'https://w3id.org/xapi/cmi5/context/extensions/sessionid' => $this->getSessionId($cmixUser),
1891 'https://ilias.de/cmi5/activityid' => $this->getActivityId()
1892 );
1893 return $extensions;
1894 }
1895
1900 {
1901 $publisherId = $this->getPublisherId();
1902 $activityId = $this->getActivityId();
1903 if (empty($publisherId)) {
1905 }
1906 $ctxActivities = array(
1907 "grouping" => [
1908 [
1909 "objectType" => "Activity",
1910 "id" => "{$publisherId}",
1911 'definition' =>
1912 array(
1913 'name' =>
1914 array(
1915 'de-DE' => $this->getTitle(),
1916 'en-US' => $this->getTitle()
1917 ),
1918 'description' =>
1919 array(
1920 'de-DE' => $this->getDescription(),
1921 'en-US' => $this->getDescription()
1922 )
1923 )]
1924 ],
1925 "category" => [
1926 [
1927 "id" => "https://w3id.org/xapi/cmi5/context/categories/cmi5",
1928 "objectType" => "Activity"
1929 ]
1930 ]
1931 );
1932 return $ctxActivities;
1933 }
1934
1935 public function getStatementObject()
1936 {
1937 $object = array(
1938 'id' => $this->getActivityId(),
1939 'definition' =>
1940 array(
1941 'name' =>
1942 array(
1943 'de-DE' => $this->getTitle(),
1944 'en-US' => $this->getTitle()
1945 ),
1946 'description' =>
1947 array(
1948 'de-DE' => $this->getDescription(),
1949 'en-US' => $this->getDescription()
1950 )
1951 )
1952 );
1953 return $object;
1954 }
1955
1956 public function getLaunchedStatement($cmixUser = null)
1957 {
1958 if (null === $cmixUser) {
1959 $cmixUser = $this->getCurrentCmixUser();
1960 }
1961 $launchMode = $this->getLaunchMode();
1962 // only check switch if self::LAUNCH_MODE_NORMAL
1963 if ($launchMode == self::LAUNCH_MODE_NORMAL) {
1964 if ($cmixUser->getSatisfied() && $this->isSwitchToReviewEnabled()) {
1966 }
1967 }
1968
1969 $statement = $this->getStatement('launched', $cmixUser);
1970 $statement['context']['extensions']['https://w3id.org/xapi/cmi5/context/extensions/launchmode'] = $launchMode;
1971 if (!empty($this->getLMSMoveOn())) {
1972 $statement['context']['extensions']['https://w3id.org/xapi/cmi5/context/extensions/moveon'] = $this->getLMSMoveOn();
1973 }
1974 if (!empty($this->getLaunchParameters())) {
1975 $statement['context']['extensions']['https://w3id.org/xapi/cmi5/context/extensions/launchparameters'] = $this->getLaunchParameters();
1976 }
1977 if (!empty($this->getMasteryScore())) {
1978 $statement['context']['extensions']['https://w3id.org/xapi/cmi5/context/extensions/masteryscore'] = $this->getMasteryScore();
1979 }
1980 return $statement;
1981 }
1982
1983 public function getAbandonedStatement($sessionId, $duration, $cmixUser = null)
1984 {
1985 if (null === $cmixUser) {
1986 $cmixUser = $this->getCurrentCmixUser();
1987 }
1988 $statement = $this->getStatement('abandoned', $cmixUser);
1989 // overwrite session with abandoned oldSession
1990 $statement['context']['extensions']['https://w3id.org/xapi/cmi5/context/extensions/sessionid'] = $sessionId;
1991 $statement['result'] = array(
1992 'duration' => $duration
1993 );
1994 return $statement;
1995 }
1996
1997 public function getSatisfiedStatement($cmixUser = null)
1998 {
1999 if (null === $cmixUser) {
2000 $cmixUser = $this->getCurrentCmixUser();
2001 }
2002 $statement = $this->getStatement('satisfied', $cmixUser);
2003 // add type, see https://aicc.github.io/CMI-5_Spec_Current/samples/scenarios/16-not_applicable-no_launch/#satisfied-statement
2004 // see also: https://github.com/AICC/CMI-5_Spec_Current/blob/quartz/cmi5_spec.md#verbs_satisfied
2005 $type = "https://w3id.org/xapi/cmi5/activitytype/course";
2006 $statement['object']['definition']['type'] = $type;
2007 $statement['context']['contextActivities']['grouping'][0]['definition']['type'] = $type;
2008 return $statement;
2009 }
2010
2014 public function getLastStatement($sess)
2015 {
2016 global $DIC;
2017 $lrsType = $this->getLrsType();
2018
2019 //$this->getLrsEndpoint())) . '/api/' . self::ENDPOINT_AGGREGATE_SUFFIX;
2020 $defaultLrs = $lrsType->getLrsEndpointStatementsAggregationLink();
2021 //$fallbackLrs = $lrsType->getLrsFallbackEndpoint();
2022 $defaultBasicAuth = $lrsType->getBasicAuth();
2023 //$fallbackBasicAuth = $lrsType->getFallbackBasicAuth();
2024 $defaultHeaders = [
2025 'X-Experience-API-Version' => '1.0.3',
2026 'Authorization' => $defaultBasicAuth,
2027 'Cache-Control' => 'no-cache, no-store, must-revalidate'
2028 ];
2029 /*
2030 $fallbackHeaders = [
2031 'X-Experience-API-Version' => '1.0.3',
2032 'Authorization' => $fallbackBasicAuth,
2033 'Content-Type' => 'application/json;charset=utf-8',
2034 'Cache-Control' => 'no-cache, no-store, must-revalidate'
2035 ];
2036 */
2037 $pipeline = json_encode($this->getLastStatementPipline($sess));
2038 $defaultLastStatementUrl = $defaultLrs . "?pipeline=" . urlencode($pipeline);
2039 $client = new GuzzleHttp\Client();
2040 $req_opts = array(
2041 GuzzleHttp\RequestOptions::VERIFY => true,
2042 GuzzleHttp\RequestOptions::CONNECT_TIMEOUT => 10,
2043 GuzzleHttp\RequestOptions::HTTP_ERRORS => false
2044 );
2045 $defaultLastStatementRequest = new GuzzleHttp\Psr7\Request(
2046 'GET',
2047 $defaultLastStatementUrl,
2048 $defaultHeaders
2049 );
2050 $promises = array();
2051 $promises['defaultLastStatement'] = $client->sendAsync($defaultLastStatementRequest, $req_opts);
2052 try {
2053 $responses = GuzzleHttp\Promise\Utils::settle($promises)->wait();
2054 $body = '';
2055 ilCmiXapiAbstractRequest::checkResponse($responses['defaultLastStatement'], $body, [200]);
2056 return json_decode($body, JSON_OBJECT_AS_ARRAY);
2057 } catch (Exception $e) {
2058 $this->log()->error('error:' . $e->getMessage());
2059 return null;
2060 }
2061 }
2062
2063 public function getLastStatementPipline($sess)
2064 {
2065 global $DIC;
2066 $pipeline = array();
2067
2068 // filter activityId
2069 $match = array();
2070 $match['statement.object.objectType'] = 'Activity';
2071 $match['statement.actor.objectType'] = 'Agent';
2072
2073 $activityId = array();
2074
2075 if ($this->getContentType() == ilObjCmiXapi::CONT_TYPE_CMI5 && !$this->isMixedContentType()) {
2076 // https://github.com/AICC/CMI-5_Spec_Current/blob/quartz/cmi5_spec.md#963-extensions
2077 $activityId['statement.context.extensions.https://ilias&46;de/cmi5/activityid'] = $this->getActivityId();
2078 } else {
2079 $activityQuery = [
2080 '$regex' => '^' . preg_quote($this->getActivityId()) . ''
2081 ];
2082 $activityId['$or'] = [];
2083 $activityId['$or'][] = ['statement.object.id' => $activityQuery];
2084 $activityId['$or'][] = ['statement.context.contextActivities.parent.id' => $activityQuery];
2085 $activityId['$or'][] = ['statement.context.contextActivities.grouping.id' => $activityQuery];
2086 }
2087
2088 $sessionId = array();
2089 $sessionId['statement.context.extensions.https://w3id&46;org/xapi/cmi5/context/extensions/sessionid'] = $sess;
2090 $match['$and'] = array();
2091 $match['$and'][] = $activityId;
2092 $match['$and'][] = $sessionId;
2093 $sort = array('statement.timestamp' => -1);
2094 $project = array('statement.timestamp' => 1, 'statement.verb.id' => 1);
2095 $pipeline[] = array('$match' => $match);
2096 $pipeline[] = array('$sort' => $sort);
2097 $pipeline[] = array('$limit' => 1);
2098 $pipeline[] = array('$project' => $project);
2099
2100 return $pipeline;
2101 }
2102
2103 public static function iliasUrl()
2104 {
2105 $regex = '/^(https?\:\/\/[^\/]+).*/';
2106 preg_match($regex, $GLOBALS['DIC']->http()->request()->getUri(), $request_parts);
2107 return $request_parts[1];
2108 }
2109
2110 public static function log()
2111 {
2112 global $log;
2113 if (self::PLUGIN) {
2114 return $log;
2115 } else {
2116 return \ilLoggerFactory::getLogger('cmix');
2117 }
2118 }
2119
2120
2124 public function isActivationLimited()
2125 {
2127 }
2128
2129
2134 {
2135 $this->activationLimited = $activationLimited;
2136 }
2137
2142 {
2144 }
2145
2150 {
2151 $this->activationStartingTime = $activationStartingTime;
2152 }
2153
2157 public function getActivationEndingTime()
2158 {
2160 }
2161
2166 {
2167 $this->activationEndingTime = $activationEndingTime;
2168 }
2169
2173 public function getActivationVisibility()
2174 {
2176 }
2177
2182 {
2183 $this->activationVisibility = $activationVisibility;
2184 }
2185}
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)
const PRIVACY_IDENT_IL_UUID_SHA256URL
$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
global $DIC
Definition: goto.php:24
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