19declare(strict_types=1);
157 public function __construct(
int $a_id = 0,
bool $a_reference =
true)
162 $this->lrsTypeId = 0;
167 $this->activityId =
'';
169 $this->publisherId =
'';
171 $this->instructions =
'';
173 $this->launchUrl =
'';
174 $this->launchParameters =
'';
176 $this->entitlementKey =
'';
178 $this->authFetchUrlEnabled =
false;
183 $this->switchToReviewEnabled =
true;
186 $this->keepLpStatusEnabled =
true;
190 $this->userPrivacyComment =
'';
192 $this->currentCmixUser =
null;
194 $this->statementsReportEnabled =
false;
196 $this->xmlManifest =
'';
199 $this->bypassProxyEnabled =
false;
207 return new self($a_id, $a_reference);
212 $this->type =
"cmix";
357 return $olp->getCurrentMode();
419 return ucfirst($this->launchMode);
454 return $this->masteryScore * 100;
459 $this->masteryScore = $masteryScorePercent / 100;
698 protected function load(): void
700 $query =
"SELECT * FROM " . self::DB_TABLE_NAME .
" WHERE obj_id = %s";
704 if ($row[
'lrs_type_id']) {
718 $this->
setMoveOn((
string) $row[
'moveon']);
779 $DIC->database()->replace(self::DB_TABLE_NAME, [
780 'obj_id' => [
'integer', $this->
getId()]
790 'moveon' => [
'text', $this->
getMoveOn()],
803 'version' => [
'integer', $this->
getVersion()],
813 'achieved' => [
'integer', (
int) $this->
getAchieved()],
814 'answered' => [
'integer', (
int) $this->
getAnswered()],
815 'completed' => [
'integer', (
int) $this->
getCompleted()],
816 'failed' => [
'integer', (
int) $this->
getFailed()],
818 'passed' => [
'integer', (
int) $this->
getPassed()],
820 'satisfied' => [
'integer', (
int) $this->
getSatisfied()],
822 'hide_data' => [
'integer', (
int) $this->
getHideData()],
823 'c_timestamp' => [
'integer', (
int) $this->
getTimestamp()],
824 'duration' => [
'integer', (
int) $this->
getDuration()],
836 switch ($activation[
"timing_type"]) {
839 if (!is_null($activation[
"timing_start"])) {
840 $activation[
"timing_start"] = (
int) $activation[
"timing_start"];
843 if (!is_null($activation[
"timing_end"])) {
844 $activation[
"timing_end"] = (
int) $activation[
"timing_end"];
872 $item->update($this->ref_id);
884 SET privacy_ident = %s,
899 no_substatements = %s,
901 WHERE lrs_type_id = %s
904 $DIC->database()->manipulateF(
955 SET bypass_proxy = %s
956 WHERE lrs_type_id = %s
959 $DIC->database()->manipulateF(
961 [
'integer',
'integer'],
974 SELECT DISTINCT s.obj_id FROM " . self::DB_TABLE_NAME .
" s
975 INNER JOIN " . self::DB_USERS_TABLE_NAME .
" u ON u.obj_id = s.obj_id
976 WHERE bypass_proxy = %s
979 $res =
$DIC->database()->queryF($query, array(
'integer'), array(1));
983 while ($row =
$DIC->database()->fetchAssoc(
$res)) {
984 $objects[] = (
int) $row[
'obj_id'];
1020 $this->_highscore_enabled = $a_enabled;
1037 $this->_highscore_achieved_ts = $a_achieved_ts;
1054 $this->_highscore_percentage = $a_percentage;
1071 $this->_highscore_wtime = $a_wtime;
1089 $this->_highscore_own_table = $a_own_table;
1106 $this->_highscore_top_table = $a_top_table;
1125 $this->_highscore_top_num = $a_top_num;
1136 $retval = $a_retval;
1137 if ($this->_highscore_top_num != 0) {
1192 'obj_id' => $this->
getId(),
1260 $new_obj->setMoveOn($this->
getMoveOn());
1286 $new_obj->setFailed($this->
getFailed());
1288 $new_obj->setPassed($this->
getPassed());
1301 $dirUtil->ensureCreatedObjectDirectory();
1312 $query =
"DELETE FROM " . self::DB_TABLE_NAME .
" WHERE obj_id = " . $this->
database->quote($this->
getId(),
'integer');
1313 $this->
database->manipulate($query);
1319 if (is_dir($thisDir)) {
1327 $query =
"DELETE FROM " . self::DB_RESULTS_TABLE_NAME .
1328 " WHERE obj_id = " . $this->
database->quote($this->
getId(),
'integer');
1329 $this->
database->manipulate($query);
1358 $data ??= random_bytes(16);
1359 assert(strlen(
$data) == 16);
1367 return vsprintf(
'%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex(
$data), 4));
1373 if (
null === $this->currentCmixUser) {
1374 $this->currentCmixUser =
new ilCmiXapiUser($this->
getId(), $DIC->user()->getId(), $this->getPrivacyIdent());
1384 if (
null === $cmixUser) {
1396 if (
null === $cmixUser) {
1401 if (!$moveOn ||
$moveOn ==
'') {
1406 if ($launchMode == self::LAUNCH_MODE_NORMAL) {
1407 if ($cmixUser->getSatisfied() && $this->isSwitchToReviewEnabled()) {
1414 "launchMethod" =>
"OwnWindow",
1418 if ($lmsLaunchMethod ===
"ownWin") {
1423 $ctxTemplate[
'returnURL'] = $href;
1425 $ctxTemplate[
'returnURL'] = ILIAS_HTTP_PATH .
"/components/ILIAS/CmiXapi/xapiexit.php?lang={$lang}";
1434 $ctxTemplate[
'entitlementKey'] = array(
"courseStructure" => $this->
getEntitlementKey());
1436 return $ctxTemplate;
1444 if (
null === $cmixUser) {
1449 if ($launchMode == self::LAUNCH_MODE_NORMAL) {
1450 if ($cmixUser->getSatisfied() && $this->isSwitchToReviewEnabled()) {
1455 $extensions[
'https://w3id.org/xapi/cmi5/context/extensions/launchmode'] =
$launchMode;
1457 $extensions[
'https://w3id.org/xapi/cmi5/context/extensions/moveon'] = $this->
getLMSMoveOn();
1460 $extensions[
'https://w3id.org/xapi/cmi5/context/extensions/launchparameters'] = $this->
getLaunchParameters();
1463 $extensions[
'https://w3id.org/xapi/cmi5/context/extensions/masteryscore'] = $this->
getMasteryScore();
1467 "extensions" => $extensions
1478 if (
null === $cmixUser) {
1485 $registration = $cmixUser->getRegistration();
1497 'extensions' => $extensions,
1498 'registration' => $registration,
1499 'contextActivities' => $contextActivities
1512 if (
null === $cmixUser) {
1518 $this->
log()->error(
'error: no name in cmixuser');
1519 $name =
'UNDEFINED';
1521 $homePage = ($this->anonymousHomePage ==
true) ? self::ANONYMOUS_HOMEPAGE : self::iliasUrl();
1524 'objectType' =>
'Agent',
1526 'homePage' => $homePage,
1527 'name' => $cmixUser->getUsrIdent()
1531 $actor[
'name'] = $name;
1535 'objectType' =>
'Agent',
1536 'mbox' =>
'mailto:' . $cmixUser->getUsrIdent()
1539 $actor[
'name'] = $name;
1552 if (
null === $cmixUser) {
1556 'https://w3id.org/xapi/cmi5/context/extensions/sessionid' => $this->
getSessionId($cmixUser),
1557 'https://ilias.de/cmi5/activityid' => $this->
getActivityId()
1575 "objectType" =>
"Activity",
1576 "id" =>
"{$publisherId}",
1593 "id" =>
"https://w3id.org/xapi/cmi5/context/categories/cmi5",
1594 "objectType" =>
"Activity"
1629 if (
null === $cmixUser) {
1634 if ($launchMode == self::LAUNCH_MODE_NORMAL) {
1635 if ($cmixUser->getSatisfied() && $this->isSwitchToReviewEnabled()) {
1640 $statement = $this->
getStatement(
'launched', $cmixUser);
1641 $statement[
'context'][
'extensions'][
'https://w3id.org/xapi/cmi5/context/extensions/launchmode'] =
$launchMode;
1643 $statement[
'context'][
'extensions'][
'https://w3id.org/xapi/cmi5/context/extensions/moveon'] = $this->
getLMSMoveOn();
1646 $statement[
'context'][
'extensions'][
'https://w3id.org/xapi/cmi5/context/extensions/launchparameters'] = $this->
getLaunchParameters();
1649 $statement[
'context'][
'extensions'][
'https://w3id.org/xapi/cmi5/context/extensions/masteryscore'] = $this->
getMasteryScore();
1660 if (
null === $cmixUser) {
1663 $statement = $this->
getStatement(
'abandoned', $cmixUser);
1665 $statement[
'context'][
'extensions'][
'https://w3id.org/xapi/cmi5/context/extensions/sessionid'] = $sessionId;
1666 $statement[
'result'] = array(
1678 if (
null === $cmixUser) {
1681 $statement = $this->
getStatement(
'satisfied', $cmixUser);
1684 $type =
"https://w3id.org/xapi/cmi5/activitytype/course";
1685 $statement[
'object'][
'definition'][
'type'] =
$type;
1686 $statement[
'context'][
'contextActivities'][
'grouping'][0][
'definition'][
'type'] =
$type;
1705 'X-Experience-API-Version' =>
'1.0.3',
1706 'Authorization' => $defaultBasicAuth,
1707 'Cache-Control' =>
'no-cache, no-store, must-revalidate'
1718 $defaultLastStatementUrl = $defaultLrs .
"?pipeline=" . urlencode($pipeline);
1719 $client =
new GuzzleHttp\Client();
1721 GuzzleHttp\RequestOptions::VERIFY =>
true,
1722 GuzzleHttp\RequestOptions::CONNECT_TIMEOUT => 10,
1723 GuzzleHttp\RequestOptions::HTTP_ERRORS =>
false
1725 $defaultLastStatementRequest =
new GuzzleHttp\Psr7\Request(
1727 $defaultLastStatementUrl,
1730 $promises = array();
1731 $promises[
'defaultLastStatement'] =
$client->sendAsync($defaultLastStatementRequest, $req_opts);
1733 $responses = GuzzleHttp\Promise\Utils::settle($promises)->wait();
1736 return json_decode($body, (
bool) JSON_OBJECT_AS_ARRAY);
1737 }
catch (Exception
$e) {
1738 $this->
log()->error(
'error:' . $e->getMessage());
1749 $pipeline = array();
1753 $match[
'statement.object.objectType'] =
'Activity';
1754 $match[
'statement.actor.objectType'] =
'Agent';
1760 $activityId[
'statement.context.extensions.https://ilias&46;de/cmi5/activityid'] = $this->
getActivityId();
1765 $activityId[
'$or'] = [];
1766 $activityId[
'$or'][] = [
'statement.object.id' => $activityQuery];
1767 $activityId[
'$or'][] = [
'statement.context.contextActivities.parent.id' => $activityQuery];
1770 $sessionId = array();
1771 $sessionId[
'statement.context.extensions.https://w3id&46;org/xapi/cmi5/context/extensions/sessionid'] = $sess;
1772 $match[
'$and'] = array();
1774 $match[
'$and'][] = $sessionId;
1775 $sort = array(
'statement.timestamp' => -1);
1776 $project = array(
'statement.timestamp' => 1,
'statement.verb.id' => 1);
1777 $pipeline[] = array(
'$match' => $match);
1778 $pipeline[] = array(
'$sort' => $sort);
1779 $pipeline[] = array(
'$limit' => 1);
1780 $pipeline[] = array(
'$project' => $project);
1788 $regex =
'/^(https?:\/\/[^\/]+).*/';
1789 preg_match($regex, (
string)
$DIC->http()->request()->getUri(), $request_parts);
1790 return $request_parts[1];
1799 return \ilLoggerFactory::getLogger(
'cmix');
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
static checkResponse(array $response, &$body, array $allowedStatus=[200, 204])
static getCmi5SessionByUsrIdAndObjIdAndRefId(int $usrId, int $objId, ?int $refId=null)
const MOVEON_COMPLETED_OR_PASSED
const MOVEON_NOT_APPLICABLE
getLrsEndpointStatementsAggregationLink()
static getName(int $userNameMode, ilObjUser $user)
static getWebspaceDir(string $mode="filesystem")
get webspace directory
static delDir(string $a_dir, bool $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static rCopy(string $a_sdir, string $a_tdir, bool $preserveTimeAttributes=false)
Copies content of a directory $a_sdir recursively to a directory $a_tdir.
static _removeEntriesForObject(int $a_obj_id)
remove all history entries for an object
const LP_MODE_CMIX_COMPLETED_OR_PASSED
const LP_MODE_CMIX_COMPL_WITH_FAILED
const LP_MODE_CMIX_PASSED
const LP_MODE_CMIX_COMPL_OR_PASSED_WITH_FAILED
const LP_MODE_DEACTIVATED
const LP_MODE_CMIX_COMPLETED
const LP_MODE_CMIX_PASSED_WITH_FAILED
static _getStaticLink(?int $a_ref_id, string $a_type='', bool $a_fallback_goto=true, string $append="")
Component logger with individual log levels by component id.
getStatement(string $verb, ?ilCmiXapiUser $cmixUser=null)
blueprint statement
setActivationEndingTime(?int $activationEndingTime=null)
setDuration(bool $duration)
setBypassProxyEnabled(bool $bypassProxyEnabled)
setHighscoreMode(int $mode)
bool $_highscore_top_table
setOnlyMoveon(bool $only_moveon)
bool $activationVisibility
getHighscoreWTime()
Gets if the column with the workingtime should be shown.
setHideData(bool $hide_data)
const DB_RESULTS_TABLE_NAME
bool $_highscore_own_table
getHighscoreTopNum(?int $a_retval=10)
Gets the number of entries which are to be shown in the top-rankings table.
getActivationStartingTime()
const PRIVACY_NAME_FULLNAME
setPrivacyName(int $userName)
setContentType(string $contentType)
getActivationEndingTime()
const LAUNCH_METHOD_NEW_WIN
getLPMode()
only for internal LMS usage
const PRIVACY_NAME_FIRSTNAME
setNoSubstatements(bool $no_substatements)
ilCmiXapiUser $currentCmixUser
getSessionId(?ilCmiXapiUser $cmixUser=null)
getActivationVisibility()
static getObjectsHavingBypassProxyEnabledAndRegisteredUsers()
setActivationVisibility(bool $activationVisibility)
setHighscoreWTime(bool $a_wtime)
Sets if the workingtime of the scores should be shown.
const PRIVACY_IDENT_IL_UUID_USER_ID
setLaunchMethod(string $launchMethod)
setPublisherId(string $publisherId)
const HIGHSCORE_SHOW_ALL_TABLES
setHighscoreTopNum(int $a_top_num)
Sets the number of entries which are to be shown in the top-rankings table.
getHighscorePercentage()
Gets if the percentage column should be shown.
setSwitchToReviewEnabled(bool $switchToReviewEnabled)
setLaunchParameters(string $launchParameters)
getSwitchToReviewEnabled()
const HIGHSCORE_SHOW_TOP_TABLE
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
const DB_USERS_TABLE_NAME
loadRepositoryActivationSettings()
doCloneObject(ilObject2 $new_obj, int $a_target_id, ?int $a_copy_id=null)
saveRepositoryActivationSettings()
bool $activationLimited
repository object activation settings (handled by ilObject)
setAnswered(bool $answered)
int $activationStartingTime
getLaunchedContextTemplate(?ilCmiXapiUser $cmixUser=null)
getHighscoreTopTable()
Gets, if the top-rankings table should be shown.
setSourceType(string $sourceType)
setStatementsReportEnabled(bool $statementsReportEnabled)
bool $_highscore_enabled
HIGHSCORE.
setHighscoreOwnTable(bool $a_own_table)
Sets if the table with the own ranking should be shown.
getStatementExtensions(?ilCmiXapiUser $cmixUser=null)
Minimal extensions.
getSatisfiedStatement(?ilCmiXapiUser $cmixUser=null)
static guidv4(?string $data=null)
bool $keepLpStatusEnabled
setLrsTypeId(int $lrsTypeId)
const PRIVACY_IDENT_IL_UUID_LOGIN
setDeleteData(int $deleteData)
setAchieved(bool $achieved)
getLaunchedStatement(?ilCmiXapiUser $cmixUser=null)
setMoveOn(string $moveOn)
Attention: this is the original moveOn from course import should only be set on import!
setLaunchMode(string $launchMode)
getMoveOn()
Attention: this is the original imported moveOn for using in LaunchData and LaunchStatement use getLM...
const PRIVACY_IDENT_REAL_EMAIL
bool $statementsReportEnabled
setMasteryScorePercent(float $masteryScorePercent)
const PRIVACY_IDENT_IL_UUID_SHA256
setProgressed(bool $progressed)
string $userPrivacyComment
getLMSMoveOn()
for CMI5 statements | state moveOn values
setInstructions(string $instructions)
setXmlManifest(string $xmlManifest)
const PRIVACY_IDENT_IL_UUID_EXT_ACCOUNT
setHighscoreTopTable(bool $a_top_table)
Sets if the top-rankings table should be shown.
ilCmiXapiLrsType $lrsType
bool $_highscore_percentage
bool $_highscore_achieved_ts
getLaunchData(?ilCmiXapiUser $cmixUser=null, string $lang='en')
LMS.LaunchData.
const PRIVACY_NAME_LASTNAME
getStatementContextActivities()
Minimal statementActivities.
isStatementsReportEnabled()
setInitialized(bool $initialized)
getHighscoreOwnTable()
Gets if the own rankings table should be shown.
bool $authFetchUrlEnabled
getLastStatement(string $sess)
get latest statement from session
setCompleted(bool $completed)
__construct(int $a_id=0, bool $a_reference=true)
ilObjCmiXapi constructor.
const HIGHSCORE_SHOW_OWN_TABLE
const PRIVACY_IDENT_IL_UUID_SHA256URL
setMasteryScore(float $masteryScore)
setHighscoreAchievedTS(bool $a_achieved_ts)
Sets if the date and time of the scores achievement should be displayed.
bool $switchToReviewEnabled
setActivationLimited(bool $activationLimited)
getHighscoreEnabled()
Gets the setting which determines if the highscore feature is enabled.
setActivationStartingTime(?int $activationStartingTime=null)
setLaunchUrl(string $launchUrl)
setLrsType(\ilCmiXapiLrsType $lrsType)
setUserPrivacyComment(string $userPrivacyComment)
setEntitlementKey(string $entitlementKey)
const LAUNCH_METHOD_IFRAME
setHighscoreEnabled(bool $a_enabled)
Sets if the highscore feature should be enabled.
static updatePrivacySettingsFromLrsType(ilCmiXapiLrsType $lrsType)
static updateByPassProxyFromLrsType(ilCmiXapiLrsType $lrsType)
isSwitchToReviewEnabled()
setKeepLpStatusEnabled(bool $keepLpStatusEnabled)
setAuthFetchUrlEnabled(bool $authFetchUrlEnabled)
setHighscorePercentage(bool $a_percentage)
Sets if the percentages of the scores pass should be shown.
static getInstance(int $a_id=0, bool $a_reference=true)
int $activationEndingTime
getAbandonedStatement(?string $sessionId, ?string $duration, ?ilCmiXapiUser $cmixUser=null)
setActivityId(string $activityId)
getLastStatementPipline(string $sess)
getStatementActor(?ilCmiXapiUser $cmixUser=null)
statement actor
setPrivacyIdent(int $userIdent)
const LAUNCH_METHOD_OWN_WIN
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
cloneMetaData(ilObject $target_obj)
Copy meta data.
Class ilObjectActivation.
const TIMINGS_DEACTIVATED
static getItem(int $ref_id)
static getInstance(int $obj_id)
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc