58        $DIC->ctrl()->redirectToURL($launchLink);
 
   64            $launchLink = $this->
object->getLaunchUrl();
 
   66            if (preg_match(
"/^(https?:\/\/)/", $this->object->getLaunchUrl()) == 1) {
 
   67                $launchLink = $this->
object->getLaunchUrl();
 
   69                $launchLink = implode(
'/', [
 
   74                $launchLink .= DIRECTORY_SEPARATOR . $this->
object->getLaunchUrl();
 
   91        if ($this->object->isBypassProxyEnabled()) {
 
   92            $params[
'endpoint'] = urlencode(rtrim($this->object->getLrsType()->getLrsEndpoint(), 
'/') . 
'/');
 
   94            $link = ILIAS_HTTP_PATH;
 
   95            if (in_array((
int) 
$_SERVER[
'SERVER_PORT'], [80, 443])) {
 
   98            $params[
'endpoint'] = urlencode(rtrim($link . 
'/' . self::XAPI_PROXY_ENDPOINT, 
'/') . 
'/');
 
  101        if ($this->object->isAuthFetchUrlEnabled()) {
 
  104            if ($this->object->isBypassProxyEnabled()) {
 
  105                $params[
'auth'] = urlencode($this->object->getLrsType()->getBasicAuth());
 
  107                $params[
'auth'] = urlencode(
'Basic ' . base64_encode(
 
  113        $params[
'activity_id'] = urlencode($this->object->getActivityId());
 
  114        $params[
'activityId'] = urlencode($this->object->getActivityId());
 
  115        $params[
'actor'] = urlencode(json_encode($this->object->getStatementActor($this->cmixUser)));
 
  117            $registration = $this->cmixUser->getRegistration();
 
  119            if ($registration == 
'') {
 
  122            $params[
'registration'] = $registration;
 
  131        $link = implode(
'/', [
 
  132            ILIAS_HTTP_PATH, 
'Modules', 
'CmiXapi', 
'xapitoken.php' 
  134        if (in_array((
int) 
$_SERVER[
'SERVER_PORT'], [80, 443])) {
 
  139        $link = iLUtil::appendUrlParameterString($link, 
"param={$param}");
 
  151            session_name() => session_id(),
 
  152            'obj_id' => $this->
object->getId(),
 
  153            'ref_id' => $this->
object->getRefId(),
 
  159        $param = urlencode(base64_encode(openssl_encrypt(
 
  160            json_encode($params),
 
  174            $DIC->user()->getId(),
 
  175            $this->object->getRefId(),
 
  176            $this->object->getId(),
 
  177            $this->object->getLrsType()->getTypeId()
 
  192        $this->cmixUser = 
new ilCmiXapiUser($this->object->getId(), 
$DIC->user()->getId(), $this->object->getPrivacyIdent());
 
  193        $user_ident = $this->cmixUser->getUsrIdent();
 
  194        if ($user_ident == 
'' || $user_ident == 
null) {
 
  196            $this->cmixUser->setUsrIdent($user_ident);
 
  201            $this->cmixUser->save();
 
  214        $language = 
$DIC->user()->getLanguage();
 
  217            "languagePreference" => 
"{$language}",
 
  218            "audioPreference" => 
"{$audio}" 
  232        $lrsType = $this->
object->getLrsType();
 
  233        $defaultLrs = $lrsType->getLrsEndpoint();
 
  235        $defaultBasicAuth = $lrsType->getBasicAuth();
 
  238            'X-Experience-API-Version' => 
'1.0.3',
 
  239            'Authorization' => $defaultBasicAuth,
 
  240            'Content-Type' => 
'application/json;charset=utf-8',
 
  241            'Cache-Control' => 
'no-cache, no-store, must-revalidate' 
  244        $registration = $this->cmixUser->getRegistration();
 
  246        if ($registration == 
'') {
 
  250        $activityId = $this->
object->getActivityId();
 
  254        $defaultAgentProfileUrl = $defaultLrs . 
"/agents/profile";
 
  255        $profileParams[
'agent'] = json_encode($this->object->getStatementActor($this->cmixUser));
 
  256        $profileParams[
'profileId'] = 
'cmi5LearnerPreferences';
 
  260        $launchDataParams = [];
 
  261        $defaultStateUrl = $defaultLrs . 
"/activities/state";
 
  263        $launchDataParams[
'agent'] = json_encode($this->object->getStatementActor($this->cmixUser));
 
  264        $launchDataParams[
'activityId'] = $activityId;
 
  265        $launchDataParams[
'activity_id'] = $activityId;
 
  266        $launchDataParams[
'registration'] = $registration;
 
  267        $launchDataParams[
'stateId'] = 
'LMS.LaunchData';
 
  270        $cmi5LearnerPreferences = json_encode($cmi5LearnerPreferencesObj);
 
  271        $lang = $cmi5LearnerPreferencesObj[
'languagePreference'];
 
  274        $oldSession = $tokenObject->getCmi5Session();
 
  275        $oldSessionLaunchedTimestamp = 
'';
 
  278        if (!empty($oldSession)) {
 
  279            $oldSessionData = json_decode($tokenObject->getCmi5SessionData());
 
  280            $oldSessionLaunchedTimestamp = $oldSessionData->launchedTimestamp;
 
  281            $tokenObject->delete();
 
  284            $lastStatement = $this->
object->getLastStatement($oldSession);
 
  288                $start = 
new DateTime($oldSessionLaunchedTimestamp);
 
  289                $end = 
new DateTime($lastStatement[0][
'statement'][
'timestamp']);
 
  290                $diff = $end->diff($start);
 
  300        $lpMode = $this->
object->getLPMode();
 
  307        $tokenObject->setCmi5Session($cmi5_session);
 
  308        $sessionData = array();
 
  309        $sessionData[
'cmi5LearnerPreferences'] = $cmi5LearnerPreferencesObj;
 
  312        $sessionData[
'launchedTimestamp'] = $now->toXapiTimestamp(); 
 
  313        $tokenObject->setCmi5SessionData(json_encode($sessionData));
 
  314        $tokenObject->update();
 
  315        $defaultStatementsUrl = $defaultLrs . 
"/statements";
 
  318        $launchData = json_encode($this->object->getLaunchData($this->cmixUser, 
$lang));
 
  319        $launchedStatement = $this->
object->getLaunchedStatement($this->cmixUser);
 
  320        $launchedStatementParams = [];
 
  321        $launchedStatementParams[
'statementId'] = $launchedStatement[
'id'];
 
  326            $abandonedStatement = $this->
object->getAbandonedStatement($oldSession, $duration, $this->cmixUser);
 
  327            $abandonedStatementParams = [];
 
  328            $abandonedStatementParams[
'statementId'] = $abandonedStatement[
'id'];
 
  333            $satisfiedStatement = $this->
object->getSatisfiedStatement($this->cmixUser);
 
  334            $satisfiedStatementParams = [];
 
  335            $satisfiedStatementParams[
'statementId'] = $satisfiedStatement[
'id'];
 
  338        $client = 
new GuzzleHttp\Client();
 
  340            GuzzleHttp\RequestOptions::VERIFY => 
true,
 
  341            GuzzleHttp\RequestOptions::CONNECT_TIMEOUT => 10,
 
  342            GuzzleHttp\RequestOptions::HTTP_ERRORS => 
false 
  344        $defaultProfileRequest = 
new GuzzleHttp\Psr7\Request(
 
  348            $cmi5LearnerPreferences
 
  350        $defaultLaunchDataRequest = 
new GuzzleHttp\Psr7\Request(
 
  352            $defaultLaunchDataUrl,
 
  356        $defaultLaunchedStatementRequest = 
new GuzzleHttp\Psr7\Request(
 
  358            $defaultLaunchedStatementUrl,
 
  360            json_encode($launchedStatement)
 
  363            $defaultAbandonedStatementRequest = 
new GuzzleHttp\Psr7\Request(
 
  365                $defaultAbandonedStatementUrl,
 
  367                json_encode($abandonedStatement)
 
  371            $defaultSatisfiedStatementRequest = 
new GuzzleHttp\Psr7\Request(
 
  373                $defaultSatisfiedStatementUrl,
 
  375                json_encode($satisfiedStatement)
 
  379        $promises[
'defaultProfile'] = 
$client->sendAsync($defaultProfileRequest, $req_opts);
 
  380        $promises[
'defaultLaunchData'] = 
$client->sendAsync($defaultLaunchDataRequest, $req_opts);
 
  381        $promises[
'defaultLaunchedStatement'] = 
$client->sendAsync($defaultLaunchedStatementRequest, $req_opts);
 
  383            $promises[
'defaultAbandonedStatement'] = 
$client->sendAsync($defaultAbandonedStatementRequest, $req_opts);
 
  386            $promises[
'defaultSatisfiedStatement'] = 
$client->sendAsync($defaultSatisfiedStatementRequest, $req_opts);
 
  389            $responses = GuzzleHttp\Promise\Utils::settle($promises)->wait();
 
  394        } 
catch (Exception 
$e) {
 
  395            $this->
log()->error(
'error:' . $e->getMessage());
 
  397        return array(
'cmi5_session' => $cmi5_session, 
'token' => 
$token);
 
  406            return \ilLoggerFactory::getLogger(
'cmix');
 
An exception for terminatinating execution or to throw for unit testing.
static buildQuery(array $params, $encoding=PHP_QUERY_RFC3986)
static checkResponse($response, &$body, $allowedStatus=[200, 204])
static fillToken($usrId, $refId, $objId, $lrsTypeId=0)
static getInstanceByToken($token)
const OPENSSL_ENCRYPTION_METHOD
const RELATIVE_CONTENT_DIRECTORY_NAMEBASE
static dateIntervalToISO860Duration(\DateInterval $d)
getLaunchParameters($token)
getCmi5LearnerPreferences()
CMI5preLaunch($token)
Prelaunch post cmi5LearnerPreference (agent profile) post LMS.LaunchData.
const XAPI_PROXY_ENDPOINT
buildAuthTokenFetchParam()
__construct(ilObjCmiXapi $object)
static getIdent($userIdentMode, ilObjUser $user)
static generateCMI5Registration($objId, $usrId)
static generateRegistration(ilObjCmiXapi $obj, ilObjUser $user)
const LP_MODE_DEACTIVATED
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
static guidv4($data=null)
static _isAnonymous($usr_id)
static appendUrlParameterString($a_url, $a_par, $xml_style=false)
append URL parameter string ("par1=value1&par2=value2...") to given URL string
static getWebspaceDir($mode="filesystem")
get webspace directory
if($_SERVER['argc']< 4) $client