ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilObjLTIConsumer.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
24 
35 {
36  public const DB_TABLE_NAME = 'lti_consumer_settings';
37 
41  protected bool $activationLimited = false;
42  protected ?int $activationStartingTime = null;
43  protected ?int $activationEndingTime = null;
44  protected ?bool $activationVisibility = null;
45 
46  protected int $providerId = 0;
47 
48  protected ?ilLTIConsumeProvider $provider = null;
49 
50  public const LAUNCH_METHOD_OWN_WIN = 'ownWin';
51  public const LAUNCH_METHOD_NEW_WIN = 'newWin';
52  public const LAUNCH_METHOD_EMBEDDED = 'embedded';
53 
54  protected bool $use_xapi = false;
55  protected string $custom_activity_id = '';
56  protected bool $statementsReportEnabled = false;
57 
58  protected float $mastery_score = 0.5;
59 
60  protected string $launchMethod = self::LAUNCH_METHOD_NEW_WIN;
61 
62  protected string $customLaunchKey = '';
63 
64  protected string $customLaunchSecret = '';
65 
66  protected string $customParams = '';
67 
68  protected ?int $ref_id = 0;
69 
70  //Highscore
71  protected bool $_highscore_enabled = false;
72 
73  protected int $anonymity = 0;
74 
75  protected bool $_highscore_achieved_ts = true;
76 
77  protected bool $_highscore_percentage = true;
78 
79  protected bool $_highscore_wtime = true;
80 
81  protected bool $_highscore_own_table = true;
82 
83  protected bool $_highscore_top_table = true;
84 
85  protected int $_highscore_top_num = 10;
86 
87  public const HIGHSCORE_SHOW_ALL_TABLES = 1;
88  public const HIGHSCORE_SHOW_TOP_TABLE = 2;
89  public const HIGHSCORE_SHOW_OWN_TABLE = 3;
90 
91  public const LTI_JWT_CLAIM_PREFIX = 'https://purl.imsglobal.org/spec/lti';
92  public const LTI_1_3_KID = 'lti_1_3_kid';
93  public const LTI_1_3_PRIVATE_KEY = 'lti_1_3_privatekey';
94  public const ERROR_OPEN_SSL_CONF = 'error openssl config invalid';
95  public const OPENSSL_KEYTYPE_RSA = '';
96 
97  public const REG_TOKEN_OP_NEW_REG = 'reg';
98  public const REG_TOKEN_OP_UPDATE_REG = 'reg-update';
99 
103  public function __construct(int $a_id = 0, bool $a_reference = true)
104  {
105  parent::__construct($a_id, $a_reference);
106  }
107 
108  protected function initType(): void
109  {
110  $this->type = "lti";
111  }
112 
113  public function isActivationLimited(): bool
114  {
116  }
117 
118  public function setActivationLimited(bool $activationLimited): void
119  {
120  $this->activationLimited = $activationLimited;
121  }
122 
123  public function getActivationStartingTime(): ?int
124  {
126  }
127 
128  public function setActivationStartingTime(?int $activationStartingTime = null): void
129  {
130  $this->activationStartingTime = $activationStartingTime;
131  }
132 
133  public function getActivationEndingTime(): ?int
134  {
136  }
137 
138  public function setActivationEndingTime(?int $activationEndingTime = null): void
139  {
140  $this->activationEndingTime = $activationEndingTime;
141  }
142 
143  public function getActivationVisibility(): ?bool
144  {
146  }
147 
148  public function setActivationVisibility(bool $activationVisibility): void
149  {
150  $this->activationVisibility = $activationVisibility;
151  }
152 
153  public function getMasteryScore(): float
154  {
155  return $this->mastery_score;
156  }
157 
158  public function setMasteryScore(float $mastery_score): void
159  {
160  $this->mastery_score = $mastery_score;
161  }
162 
163  public function getMasteryScorePercent(): float
164  {
165  return $this->mastery_score * 100;
166  }
167 
168  public function setMasteryScorePercent(float $mastery_score_percent): void
169  {
170  $this->mastery_score = $mastery_score_percent / 100;
171  }
172 
173  public function getProviderId(): int
174  {
175  return $this->providerId;
176  }
177 
178  public function setProviderId(int $providerId): void
179  {
180  $this->providerId = $providerId;
181  }
182 
183  public function initProvider(): void
184  {
185  $this->provider = new ilLTIConsumeProvider($this->getProviderId());
186  }
187 
188  public function getProvider(): ?\ilLTIConsumeProvider
189  {
190  return $this->provider;
191  }
192 
193  public function setProvider(ilLTIConsumeProvider $provider): void
194  {
195  $this->provider = $provider;
196  }
197 
198  public function isLaunchMethodOwnWin(): bool
199  {
200  return $this->launchMethod == self::LAUNCH_METHOD_OWN_WIN;
201  }
202 
203  public function isLaunchMethodEmbedded(): bool
204  {
205  return $this->launchMethod == self::LAUNCH_METHOD_EMBEDDED;
206  }
207 
208  public function getLaunchMethod(): string
209  {
210  return $this->launchMethod;
211  }
212 
213  public function setLaunchMethod(string $launchMethod): void
214  {
215  $this->launchMethod = $launchMethod;
216  }
217 
218  public function getCustomLaunchKey(): string
219  {
220  return $this->customLaunchKey;
221  }
222 
223  public function setCustomLaunchKey(string $customLaunchKey): void
224  {
225  $this->customLaunchKey = $customLaunchKey;
226  }
227 
228  public function getCustomLaunchSecret(): string
229  {
231  }
232 
233  public function setCustomLaunchSecret(string $customLaunchSecret): void
234  {
235  $this->customLaunchSecret = $customLaunchSecret;
236  }
237 
238  public function getCustomParams(): string
239  {
240  return $this->customParams;
241  }
242 
243  public function setCustomParams(string $customParams): void
244  {
245  $this->customParams = $customParams;
246  }
247 
248  public function getLaunchKey(): string
249  {
250  if ($this->getProvider()->isProviderKeyCustomizable()) {
251  return $this->getCustomLaunchKey();
252  }
253 
254  return $this->getProvider()->getProviderKey();
255  }
256 
257  public function getLaunchSecret(): string
258  {
259  if ($this->getProvider()->isProviderKeyCustomizable()) {
260  return $this->getCustomLaunchSecret();
261  }
262 
263  return $this->getProvider()->getProviderSecret();
264  }
265 
266  public function getUseXapi(): bool
267  {
268  return $this->use_xapi;
269  }
270 
271  public function setUseXapi(bool $use_xapi): void
272  {
273  $this->use_xapi = $use_xapi;
274  }
275 
276  public function getCustomActivityId(): string
277  {
279  }
280 
281  public function setCustomActivityId(string $custom_activity_id): void
282  {
283  $this->custom_activity_id = $custom_activity_id;
284  }
285 
286  public function getActivityId(): string
287  {
288  if (strlen($this->getProvider()->getXapiActivityId())) {
289  return $this->getProvider()->getXapiActivityId();
290  }
291 
293  }
294 
295  public function isStatementsReportEnabled(): bool
296  {
298  }
299 
300  public function setStatementsReportEnabled(bool $statementsReportEnabled): void
301  {
302  $this->statementsReportEnabled = $statementsReportEnabled;
303  }
304 
308  public function getCustomParamsArray(): array
309  {
310  $paramsAsArray = [];
311 
312  $params = $this->getCustomParams();
313  // allows foo=bar;foo2=baz2; foo3=baz3
314  $params = preg_split('/; ?/', $params);
315 
316  foreach ($params as $param) {
317  $param = explode('=', $param);
318  // empty field, duplicate/leading/trailing semicolon?
319  if ($param[0] != '') {
320  $value = isset($param[1]) ? $param[1] : '';
321  $paramsAsArray[$param[0]] = $value;
322  }
323  }
324 
325  return $paramsAsArray;
326  }
327 
331  public static function getProviderCustomParamsArray(ilLTIConsumeProvider $provider): array
332  {
333  $paramsAsArray = [];
334 
335  $params = $provider->getCustomParams();
336  // allows foo=bar;foo2=baz2; foo3=baz3
337  $params = preg_split('/; ?/', $params);
338 
339  foreach ($params as $param) {
340  $param = explode('=', $param);
341  // empty field, duplicate/leading/trailing semicolon?
342  if ($param[0] != '') {
343  $value = isset($param[1]) ? $param[1] : '';
344  $paramsAsArray[$param[0]] = $value;
345  }
346  }
347 
348  return $paramsAsArray;
349  }
350 
351  protected function doRead(): void
352  {
353  $this->load();
354  }
355 
356  public function load(): void
357  {
358  global $DIC; /* @var \ILIAS\DI\Container $DIC */
359 
360  $query = "SELECT * FROM {$this->dbTableName()} WHERE obj_id = %s";
361  $res = $DIC->database()->queryF($query, ['integer'], [$this->getId()]);
362 
363  while ($row = $DIC->database()->fetchAssoc($res)) {
364  // if ($row['provider_id']) { //always set
365  $this->setProviderId((int) $row['provider_id']);
366  $this->setProvider(new ilLTIConsumeProvider((int) $row['provider_id']));
367  // }
368 
369  $this->setLaunchMethod($row['launch_method']);
370 
371  $this->setCustomLaunchKey((string) $row['launch_key']);
372  $this->setCustomLaunchSecret((string) $row['launch_secret']);
373  $this->setCustomParams((string) $row['custom_params']);
374 
375  $this->setUseXapi((bool) $row['use_xapi']);
376  $this->setCustomActivityId((string) $row['activity_id']);
377  $this->setStatementsReportEnabled((bool) $row['show_statements']);
378  $this->setHighscoreEnabled((bool) $row['highscore_enabled']);
379  $this->setHighscoreAchievedTS((bool) $row['highscore_achieved_ts']);
380  $this->setHighscorePercentage((bool) $row['highscore_percentage']);
381  $this->setHighscoreWTime((bool) $row['highscore_wtime']);
382  $this->setHighscoreOwnTable((bool) $row['highscore_own_table']);
383  $this->setHighscoreTopTable((bool) $row['highscore_top_table']);
384  $this->setHighscoreTopNum((int) $row['highscore_top_num']);
385 
386  $this->setMasteryScore((float) $row['mastery_score']);
387  }
388 
390  }
391 
392  protected function doUpdate(): void
393  {
394  $this->save();
395  }
396 
397  public function save(): void
398  {
399  global $DIC; /* @var \ILIAS\DI\Container $DIC */
400 
401  $DIC->database()->replace($this->dbTableName(), [
402  'obj_id' => ['integer', $this->getId()]
403  ], [
404  'provider_id' => ['integer', $this->getProviderId()],
405  'launch_method' => ['text', $this->getLaunchMethod()],
406  'launch_key' => ['text', $this->getCustomLaunchKey()],
407  'launch_secret' => ['text', $this->getCustomLaunchSecret()],
408  'custom_params' => ['text', $this->getCustomParams()],
409  'use_xapi' => ['integer',$this->getUseXapi()],
410  'activity_id' => ['text',$this->getCustomActivityId()],
411  'show_statements' => ['integer',$this->isStatementsReportEnabled()],
412  'highscore_enabled' => ['integer', (int) $this->getHighscoreEnabled()],
413  'highscore_achieved_ts' => ['integer', (int) $this->getHighscoreAchievedTS()],
414  'highscore_percentage' => ['integer', (int) $this->getHighscorePercentage()],
415  'highscore_wtime' => ['integer', (int) $this->getHighscoreWTime()],
416  'highscore_own_table' => ['integer', (int) $this->getHighscoreOwnTable()],
417  'highscore_top_table' => ['integer', (int) $this->getHighscoreTopTable()],
418  'highscore_top_num' => ['integer', $this->getHighscoreTopNum()],
419  'mastery_score' => ['float', $this->getMasteryScore()]
420  ]);
421 
423  }
424 
425  protected function loadRepositoryActivationSettings(): void
426  {
427  if ($this->ref_id > 0) {
428  $activation = ilObjectActivation::getItem($this->ref_id);
429  switch ($activation["timing_type"]) {
431  $this->setActivationLimited(true);
432  if (!is_null($activation["timing_start"])) {
433  $activation["timing_start"] = (int) $activation["timing_start"];
434  }
435  $this->setActivationStartingTime($activation["timing_start"]);
436  if (!is_null($activation["timing_end"])) {
437  $activation["timing_end"] = (int) $activation["timing_end"];
438  }
439  $this->setActivationEndingTime($activation["timing_end"]);
440  $this->setActivationVisibility((bool) $activation["visible"]);
441  break;
442 
443  default:
444  $this->setActivationLimited(false);
445  break;
446  }
447  }
448  }
449 
450  protected function saveRepositoryActivationSettings(): void
451  {
452  if ($this->ref_id > 0) {
453  ilObjectActivation::getItem($this->ref_id);
454 
455  $item = new ilObjectActivation();
456  if (!$this->isActivationLimited()) {
457  $item->setTimingType(ilObjectActivation::TIMINGS_DEACTIVATED);
458  } else {
459  $item->setTimingType(ilObjectActivation::TIMINGS_ACTIVATION);
460  $item->setTimingStart($this->getActivationStartingTime());
461  $item->setTimingEnd($this->getActivationEndingTime());
462  $item->toggleVisible($this->getActivationVisibility());
463  }
464 
465  $item->update($this->ref_id);
466  }
467  }
468 
469  protected function dbTableName(): string
470  {
471  return self::DB_TABLE_NAME;
472  }
473 
476 
477 
481  public function setHighscoreEnabled(bool $a_enabled): void
482  {
483  $this->_highscore_enabled = $a_enabled;
484  }
485 
491  public function getHighscoreEnabled(): bool
492  {
494  }
495 
496 
500  public function setHighscoreAchievedTS(bool $a_achieved_ts): void
501  {
502  $this->_highscore_achieved_ts = $a_achieved_ts;
503  }
504 
510  public function getHighscoreAchievedTS(): bool
511  {
513  }
514 
518  public function setHighscorePercentage(bool $a_percentage): void
519  {
520  $this->_highscore_percentage = $a_percentage;
521  }
522 
528  public function getHighscorePercentage(): bool
529  {
531  }
532 
536  public function setHighscoreWTime(bool $a_wtime): void
537  {
538  $this->_highscore_wtime = $a_wtime;
539  }
540 
546  public function getHighscoreWTime(): bool
547  {
549  }
550 
556  public function setHighscoreOwnTable(bool $a_own_table): void
557  {
558  $this->_highscore_own_table = $a_own_table;
559  }
560 
566  public function getHighscoreOwnTable(): bool
567  {
569  }
570 
574  public function setHighscoreTopTable(bool $a_top_table): void
575  {
576  $this->_highscore_top_table = $a_top_table;
577  }
578 
584  public function getHighscoreTopTable(): bool
585  {
587  }
588 
595  public function setHighscoreTopNum(int $a_top_num): void
596  {
597  $this->_highscore_top_num = $a_top_num;
598  }
599 
608  public function getHighscoreTopNum(int $a_retval = 10): int
609  {
610  $retval = $a_retval;
611  if ($this->_highscore_top_num != 0) {
612  $retval = $this->_highscore_top_num;
613  }
614 
615  return $retval;
616  }
617 
618  public function getHighscoreMode(): int
619  {
620  switch (true) {
621  case $this->getHighscoreOwnTable() && $this->getHighscoreTopTable():
622  return self::HIGHSCORE_SHOW_ALL_TABLES;
623 
624  case $this->getHighscoreTopTable():
625  return self::HIGHSCORE_SHOW_TOP_TABLE;
626 
627  case $this->getHighscoreOwnTable():
628  default:
629  return self::HIGHSCORE_SHOW_OWN_TABLE;
630  }
631  }
632 
636  public function setHighscoreMode(int $mode): void
637  {
638  switch ($mode) {
639  case self::HIGHSCORE_SHOW_ALL_TABLES:
640  $this->setHighscoreTopTable(true);
641  $this->setHighscoreOwnTable(true);
642  break;
643 
644  case self::HIGHSCORE_SHOW_TOP_TABLE:
645  $this->setHighscoreTopTable(true);
646  $this->setHighscoreOwnTable(false);
647  break;
648 
649  case self::HIGHSCORE_SHOW_OWN_TABLE:
650  default:
651  $this->setHighscoreTopTable(false);
652  $this->setHighscoreOwnTable(true);
653  break;
654  }
655  }
656  /* End GET/SET for highscore feature*/
660  public function buildLaunchParameters(ilCmiXapiUser $cmixUser, string $token, string $contextType, string $contextId, string $contextTitle, ?string $returnUrl = ''): array
661  {
662  global $DIC; /* @var \ILIAS\DI\Container $DIC */
663 
664  $roles = $DIC->access()->checkAccess('write', '', $this->getRefId()) ? "Instructor" : "Learner";
665  //todo if object is in course or group, roles would have to be taken from there s. Mantis 35435 - if necessary Jour Fixe topic
666  if ($DIC->rbac()->review()->isAssigned($DIC->user()->getId(), SYSTEM_ROLE_ID)) {
667  $roles = "Administrator";
668  }
669 
670  if ($this->getProvider()->getAlwaysLearner() == true) {
671  $roles = "Learner";
672  }
673 
674  $resource_link_id = $this->getRefId();
675  if ($this->getProvider()->getUseProviderId() == true) {
676  $resource_link_id = 'p' . $this->getProvider()->getId();
677  }
678 
679  $usrImage = '';
680  if ($this->getProvider()->getIncludeUserPicture()) {
681  $usrImage = self::getIliasHttpPath() . "/" . $DIC->user()->getPersonalPicturePath("small");
682  }
683 
684  $documentTarget = "window";
685  if ($this->getLaunchMethod() == self::LAUNCH_METHOD_EMBEDDED) {
686  $documentTarget = "iframe";
687  }
688 
689  $nameGiven = '-';
690  $nameFamily = '-';
691  $nameFull = '-';
692  switch ($this->getProvider()->getPrivacyName()) {
694  $nameGiven = $DIC->user()->getFirstname();
695  $nameFull = $DIC->user()->getFirstname();
696  break;
698  $usrName = $DIC->user()->getUTitle() ? $DIC->user()->getUTitle() . ' ' : '';
699  $usrName .= $DIC->user()->getLastname();
700  $nameFamily = $usrName;
701  $nameFull = $usrName;
702  break;
704  $nameGiven = $DIC->user()->getFirstname();
705  $nameFamily = $DIC->user()->getLastname();
706  $nameFull = $DIC->user()->getFullname();
707  break;
708  }
709 
710  $userIdLTI = ilCmiXapiUser::getIdentAsId($this->getProvider()->getPrivacyIdent(), $DIC->user());
711 
712  $emailPrimary = $cmixUser->getUsrIdent();
713  if ($this->getProvider()->getPrivacyIdent() == ilObjCmiXapi::PRIVACY_IDENT_IL_UUID_RANDOM) {
714  $userIdLTI = strstr($emailPrimary, '@' . ilCmiXapiUser::getIliasUuid(), true);
715  }
716 
717  ilLTIConsumerResult::getByKeys($this->getId(), $DIC->user()->getId(), true);
718 
719  //ToDo: Check!
720  $provider_custom_params = self::getProviderCustomParamsArray($this->getProvider());
721  $custom_params = $this->getCustomParamsArray();
722  $merged_params = array_merge($provider_custom_params, $custom_params);
723 
724  $toolConsumerInstanceGuid = CLIENT_ID . ".";
725  $parseIliasUrl = parse_url(self::getIliasHttpPath());
726  if (array_key_exists("path", $parseIliasUrl)) {
727  $toolConsumerInstanceGuid .= implode(".", array_reverse(explode("/", $parseIliasUrl["path"])));
728  }
729  $toolConsumerInstanceGuid .= $parseIliasUrl["host"];
730  $launch_vars = [
731  "lti_message_type" => "basic-lti-launch-request",
732  "lti_version" => "LTI-1p0",
733  "resource_link_id" => $resource_link_id,
734  "resource_link_title" => $this->getTitle(),
735  "resource_link_description" => $this->getDescription(),
736  "user_id" => $userIdLTI,
737  "user_image" => $usrImage,
738  "roles" => $roles,
739  "lis_person_name_given" => $nameGiven,
740  "lis_person_name_family" => $nameFamily,
741  "lis_person_name_full" => $nameFull,
742  "lis_person_contact_email_primary" => $emailPrimary,
743  "context_id" => $contextId,
744  "context_type" => $contextType,
745  "context_title" => $contextTitle,
746  "context_label" => $contextType . " " . $contextId,
747  "launch_presentation_locale" => $this->lng->getLangKey(),
748  "launch_presentation_document_target" => $documentTarget,
749  "launch_presentation_width" => "",//recommended
750  "launch_presentation_height" => "",//recommended
751  "launch_presentation_return_url" => $returnUrl,
752  "tool_consumer_instance_guid" => $toolConsumerInstanceGuid,
753  "tool_consumer_instance_name" => $DIC->settings()->get("short_inst_name") ? $DIC->settings()->get("short_inst_name") : CLIENT_ID,
754  "tool_consumer_instance_description" => ilObjSystemFolder::_getHeaderTitle(),
755  "tool_consumer_instance_url" => ilLink::_getLink(ROOT_FOLDER_ID, "root"),//ToDo? "https://vb52p70.example.com/release_5-3/goto.php?target=root_1&client_id=inno",
756  "tool_consumer_instance_contact_email" => $DIC->settings()->get("admin_email"),
757  "launch_presentation_css_url" => "",
758  "tool_consumer_info_product_family_code" => "ilias",
759  "tool_consumer_info_version" => ILIAS_VERSION,
760  "lis_result_sourcedid" => $token,
761  "lis_outcome_service_url" => self::getIliasHttpPath() . "/Modules/LTIConsumer/result.php?client_id=" . CLIENT_ID,
762  "role_scope_mentor" => ""
763  ];
764 
765  $OAuthParams = [
766  "url" => $this->getProvider()->getProviderUrl(),
767  "key" => $this->getLaunchKey(),
768  "secret" => $this->getLaunchSecret(),
769  "callback" => "about:blank",
770  "http_method" => "POST",
771  "sign_method" => "HMAC_SHA1",
772  "token" => null,
773  "data" => ($launch_vars + $merged_params)
774  ];
775 
776  return ilLTIConsumerLaunch::signOAuth($OAuthParams);
777  }
778 
783  public function buildLaunchParametersLTI13(ilCmiXapiUser $cmixUser, string $endpoint, string $clientId, int $deploymentId, string $nonce, string $contextType, string $contextId, string $contextTitle, ?string $returnUrl = ''): ?array
784  {
785  global $DIC; /* @var \ILIAS\DI\Container $DIC */
786 
787  $roles = $DIC->access()->checkAccess('write', '', $this->getRefId()) ? "Instructor" : "Learner";
788 
789  if ($DIC->rbac()->review()->isAssigned($DIC->user()->getId(), SYSTEM_ROLE_ID)) {
790  $roles = "Administrator";
791  }
792 
793  if ($this->getProvider()->getAlwaysLearner() == true) {
794  $roles = "Learner";
795  }
796 
797  $resource_link_id = $this->getRefId();
798  if ($this->getProvider()->getUseProviderId() == true) {
799  $resource_link_id = 'p' . $this->getProvider()->getId();
800  }
801 
802  $usrImage = '';
803  if ($this->getProvider()->getIncludeUserPicture()) {
804  $usrImage = self::getIliasHttpPath() . "/" . $DIC->user()->getPersonalPicturePath("small");
805  }
806 
807  $documentTarget = "window";
808  if ($this->getLaunchMethod() == self::LAUNCH_METHOD_EMBEDDED) {
809  $documentTarget = "iframe";
810  }
811 
812  $nameGiven = '-';
813  $nameFamily = '-';
814  $nameFull = '-';
815  switch ($this->getProvider()->getPrivacyName()) {
817  $nameGiven = $DIC->user()->getFirstname();
818  $nameFull = $DIC->user()->getFirstname();
819  break;
821  $usrName = $DIC->user()->getUTitle() ? $DIC->user()->getUTitle() . ' ' : '';
822  $usrName .= $DIC->user()->getLastname();
823  $nameFamily = $usrName;
824  $nameFull = $usrName;
825  break;
827  $nameGiven = $DIC->user()->getFirstname();
828  $nameFamily = $DIC->user()->getLastname();
829  $nameFull = $DIC->user()->getFullname();
830  break;
831  }
832 
833  $userIdLTI = ilCmiXapiUser::getIdent($this->getProvider()->getPrivacyIdent(), $DIC->user()); //was: getIdentAsId
834 
835  $emailPrimary = $cmixUser->getUsrIdent();
836 
837  ilLTIConsumerResult::getByKeys($this->getId(), $DIC->user()->getId(), true);
838 
839  $toolConsumerInstanceGuid = CLIENT_ID . ".";
840  $parseIliasUrl = parse_url(self::getIliasHttpPath());
841  if (array_key_exists("path", $parseIliasUrl)) {
842  $toolConsumerInstanceGuid .= implode(".", array_reverse(explode("/", $parseIliasUrl["path"])));
843  }
844  $toolConsumerInstanceGuid .= $parseIliasUrl["host"];
845  $launch_vars = [
846  "lti_message_type" => "basic-lti-launch-request",
847  "lti_version" => "1.3.0",
848  "resource_link_id" => (string) $resource_link_id,
849  "resource_link_title" => $this->getTitle(),
850  "resource_link_description" => $this->getDescription(),
851  "user_id" => (string) $userIdLTI,
852  "user_image" => $usrImage,
853  "roles" => $roles,
854  "lis_person_name_given" => $nameGiven,
855  "lis_person_name_family" => $nameFamily,
856  "lis_person_name_full" => $nameFull,
857  "lis_person_contact_email_primary" => $emailPrimary,
858  "context_id" => $contextId,
859  "context_type" => $contextType,
860  "context_title" => $contextTitle,
861  "context_label" => $contextType . " " . $contextId,
862  "launch_presentation_locale" => $this->lng->getLangKey(),
863  "launch_presentation_document_target" => $documentTarget,
864  "launch_presentation_width" => "",//recommended
865  "launch_presentation_height" => "",//recommended
866  "launch_presentation_return_url" => $returnUrl,
867  "tool_consumer_instance_guid" => $toolConsumerInstanceGuid,
868  "tool_consumer_instance_name" => $DIC->settings()->get("short_inst_name") ? $DIC->settings()->get("short_inst_name") : CLIENT_ID,
869  "tool_consumer_instance_description" => ilObjSystemFolder::_getHeaderTitle(),
870  "tool_consumer_instance_url" => ilLink::_getLink(ROOT_FOLDER_ID, "root"),//ToDo? "https://vb52p70.example.com/release_5-3/goto.php?target=root_1&client_id=inno",
871  "tool_consumer_instance_contact_email" => $DIC->settings()->get("admin_email"),
872  "launch_presentation_css_url" => "",
873  "tool_consumer_info_product_family_code" => "ilias",
874  "tool_consumer_info_version" => ILIAS_VERSION,
875  "lis_result_sourcedid" => "",//$token,
876  "lis_outcome_service_url" => self::getIliasHttpPath() . "/Modules/LTIConsumer/result.php?client_id=" . CLIENT_ID,
877  "role_scope_mentor" => ""
878  ];
879 
880  $provider_custom_params = self::getProviderCustomParamsArray($this->getProvider());
881  $custom_params = $this->getCustomParamsArray();
882  $merged_params = array_merge($provider_custom_params, $custom_params);
883  foreach ($merged_params as $key => $value) {
884  $launch_vars['custom_' . $key] = $value;
885  }
886 
887  if ($this->getProvider()->isGradeSynchronization() || $this->getProvider()->getHasOutcome()) {
888  include_once("Modules/LTIConsumer/classes/class.ilLTIConsumerGradeService.php");
889  $gradeservice = new ilLTIConsumerGradeService();
890  $launch_vars['custom_lineitem_url'] = self::getIliasHttpPath() . "/Modules/LTIConsumer/ltiservices.php/gradeservice/" . $contextId . "/lineitems/" . $this->id . "/lineitem";
891 
892  // ! Moodle as tool provider requires a custom_lineitems_url even though this should be optional in launch request, especially if only posting score scope is permitted by platform
893  // http://www.imsglobal.org/spec/lti-ags/v2p0#example-link-has-a-single-line-item-tool-can-only-post-score
894  $launch_vars['custom_lineitems_url'] = self::getIliasHttpPath() . "/Modules/LTIConsumer/ltiservices.php/gradeservice/" . $contextId . "/lineitems/";
895 
896  $launch_vars['custom_ags_scopes'] = implode(",", $gradeservice->getPermittedScopes());
897  }
898 
899  if (!empty(self::verifyPrivateKey())) {
900  $DIC->ui()->mainTemplate()->setOnScreenMessage('failure', 'ERROR_OPEN_SSL_CONF', true);
901  return null;
902  }
903  return self::LTISignJWT($launch_vars, $endpoint, $clientId, $deploymentId, $nonce);
904  }
905 
910  // ToDo:
911 
912  public static function buildContentSelectionParameters(ilLTIConsumeProvider $provider, int $refId, string $returnUrl, string $nonce): ?array
913  {
914  global $DIC;
915 
916  $clientId = $provider->getClientId();
917  $deploymentId = $provider->getId();
918  $ilLTIConsumerLaunch = new ilLTIConsumerLaunch($refId);
919  $context = $ilLTIConsumerLaunch->getContext();
920  $contextType = $ilLTIConsumerLaunch::getLTIContextType($context["type"]);
921  $contextId = $context["id"];
922  $contextTitle = $context["title"];
923 
924  $roles = "Instructor";
925  $usrImage = '';
926  if ($provider->getIncludeUserPicture()) {
927  $usrImage = self::getIliasHttpPath() . "/" . $DIC->user()->getPersonalPicturePath("small");
928  }
929  $documentTarget = "window";
930  if ($provider->getLaunchMethod() == self::LAUNCH_METHOD_EMBEDDED) {
931  $documentTarget = "iframe";
932  }
933  $nameGiven = '-';
934  $nameFamily = '-';
935  $nameFull = '-';
936  switch ($provider->getPrivacyName()) {
938  $nameGiven = $DIC->user()->getFirstname();
939  $nameFull = $DIC->user()->getFirstname();
940  break;
942  $usrName = $DIC->user()->getUTitle() ? $DIC->user()->getUTitle() . ' ' : '';
943  $usrName .= $DIC->user()->getLastname();
944  $nameFamily = $usrName;
945  $nameFull = $usrName;
946  break;
948  $nameGiven = $DIC->user()->getFirstname();
949  $nameFamily = $DIC->user()->getLastname();
950  $nameFull = $DIC->user()->getFullname();
951  break;
952  }
953 
954  $userIdLTI = ilCmiXapiUser::getIdent($provider->getPrivacyIdent(), $DIC->user()); //was: getIdentAsId
955  $emailPrimary = ilCmiXapiUser::getIdent($provider->getPrivacyIdent(), $DIC->user());
956  $toolConsumerInstanceGuid = CLIENT_ID . ".";
957  $parseIliasUrl = parse_url(self::getIliasHttpPath());
958  if (array_key_exists("path", $parseIliasUrl)) {
959  $toolConsumerInstanceGuid .= implode(".", array_reverse(explode("/", $parseIliasUrl["path"])));
960  }
961  $toolConsumerInstanceGuid .= $parseIliasUrl["host"];
962 
963  $content_select_vars = [
964  "lti_message_type" => "ContentItemSelectionRequest",
965  "lti_version" => "1.3.0",
966  "user_id" => (string) $userIdLTI,
967  "user_image" => $usrImage,
968  "roles" => $roles,
969  "lis_person_name_given" => $nameGiven,
970  "lis_person_name_family" => $nameFamily,
971  "lis_person_name_full" => $nameFull,
972  "lis_person_contact_email_primary" => $emailPrimary,
973  "context_id" => (string) $contextId,
974  "context_type" => $contextType,
975  "context_title" => $contextTitle,
976  "context_label" => $contextType . " " . $contextId,
977  "launch_presentation_locale" => $DIC->language()->getLangKey(),
978  "launch_presentation_document_target" => $documentTarget,
979  "launch_presentation_width" => "",//recommended
980  "launch_presentation_height" => "",//recommended
981  "tool_consumer_instance_guid" => $toolConsumerInstanceGuid,
982  "tool_consumer_instance_name" => $DIC->settings()->get("short_inst_name") ? $DIC->settings()->get("short_inst_name") : CLIENT_ID,
983  "tool_consumer_instance_description" => ilObjSystemFolder::_getHeaderTitle(),
984  "tool_consumer_instance_url" => ilLink::_getLink(ROOT_FOLDER_ID, "root"),//ToDo? "https://vb52p70.example.com/release_5-3/goto.php?target=root_1&client_id=inno",
985  "tool_consumer_instance_contact_email" => $DIC->settings()->get("admin_email"),
986  "tool_consumer_info_product_family_code" => "ilias",
987  "tool_consumer_info_version" => ILIAS_VERSION,
988  "content_item_return_url" => $returnUrl,
989  "accept_types" => "ltiResourceLink",
990  "accept_presentation_document_targets" => "iframe,window,embed",
991  "accept_multiple" => true,
992  "auto_create" => true,
993  ];
994  $provider_custom_params = self::getProviderCustomParamsArray($provider);
995  foreach ($provider_custom_params as $key => $value) {
996  $content_select_vars['custom_' . $key] = $value;
997  }
998 
999  if (!empty(self::verifyPrivateKey())) {
1000  $DIC->ui()->mainTemplate()->setOnScreenMessage('failure', 'ERROR_OPEN_SSL_CONF', true);
1001  return null;
1002  }
1003  return self::LTISignJWT($content_select_vars, '', $clientId, $deploymentId, $nonce);
1004  }
1005 
1006  public static function LTISignJWT(array $parms, string $endpoint, string $oAuthConsumerKey, $typeId = 0, string $nonce = ''): array
1007  {
1008  if (empty($typeId)) {
1009  $typeId = 0;
1010  }
1012  if (isset($parms['lti_message_type']) && array_key_exists($parms['lti_message_type'], $messageTypeMapping)) {
1013  $parms['lti_message_type'] = $messageTypeMapping[$parms['lti_message_type']];
1014  }
1015  if (isset($parms['roles'])) {
1016  $roles = explode(',', $parms['roles']);
1017  $newRoles = array();
1018  foreach ($roles as $role) {
1019  if (strpos($role, 'urn:lti:role:ims/lis/') === 0) {
1020  $role = 'http://purl.imsglobal.org/vocab/lis/v2/membership#' . substr($role, 21);
1021  } elseif (strpos($role, 'urn:lti:instrole:ims/lis/') === 0) {
1022  $role = 'http://purl.imsglobal.org/vocab/lis/v2/institution/person#' . substr($role, 25);
1023  } elseif (strpos($role, 'urn:lti:sysrole:ims/lis/') === 0) {
1024  $role = 'http://purl.imsglobal.org/vocab/lis/v2/system/person#' . substr($role, 24);
1025  } elseif ((strpos($role, '://') === false) && (strpos($role, 'urn:') !== 0)) {
1026  $role = "http://purl.imsglobal.org/vocab/lis/v2/membership#{$role}";
1027  }
1028  $newRoles[] = $role;
1029  }
1030  $parms['roles'] = implode(',', $newRoles);
1031  }
1032  $now = time();
1033  if (empty($nonce)) {
1034  $nonce = bin2hex(openssl_random_pseudo_bytes(10));
1035  }
1037  $payLoad = array(
1038  'nonce' => $nonce,
1039  'iat' => $now,
1040  'exp' => $now + 60,
1041  );
1042  $payLoad['iss'] = self::getIliasHttpPath();
1043  $payLoad['aud'] = $oAuthConsumerKey;
1044  $payLoad[self::LTI_JWT_CLAIM_PREFIX . '/claim/deployment_id'] = strval($typeId);
1045  if (!empty($endpoint)) { // only for launch request
1046  $payLoad[self::LTI_JWT_CLAIM_PREFIX . '/claim/target_link_uri'] = $endpoint;
1047  }
1048 
1049  foreach ($parms as $key => $value) {
1050  $claim = self::LTI_JWT_CLAIM_PREFIX;
1051  if (array_key_exists($key, $claimMapping)) {
1052  $mapping = $claimMapping[$key];
1053 
1054  if (isset($mapping['isArray']) && $mapping['isArray']) {
1055  $value = explode(',', $value);
1056  sort($value);
1057  } elseif (isset($mapping['isBoolean'])) {
1058  $value = $mapping['isBoolean'];
1059  }
1060  if (!empty($mapping['suffix'])) {
1061  $claim .= "-{$mapping['suffix']}";
1062  }
1063  $claim .= '/claim/';
1064  if (is_null($mapping['group'])) {
1065  $payLoad[$mapping['claim']] = $value;
1066  } elseif (empty($mapping['group'])) {
1067  $payLoad["{$claim}{$mapping['claim']}"] = $value;
1068  } else {
1069  $claim .= $mapping['group'];
1070  $payLoad[$claim][$mapping['claim']] = $value;
1071  }
1072  } elseif (strpos($key, 'custom_') === 0) {
1073  $payLoad["{$claim}/claim/custom"][substr($key, 7)] = $value;
1074  } elseif (strpos($key, 'ext_') === 0) {
1075  $payLoad["{$claim}/claim/ext"][substr($key, 4)] = $value;
1076  }
1077  }
1078  //self::getLogger()->debug(json_encode($payLoad,JSON_PRETTY_PRINT));
1079  if (!empty(self::verifyPrivateKey())) {
1080  throw new DomainException(self::ERROR_OPEN_SSL_CONF);
1081  }
1082  $privateKey = self::getPrivateKey();
1083  $jwt = Firebase\JWT\JWT::encode($payLoad, $privateKey['key'], 'RS256', $privateKey['kid']);
1084  $newParms = $parms;//was array();
1085  $newParms['id_token'] = $jwt;
1086  return $newParms;
1087  }
1088 
1089  public static function getPrivateKey(): array
1090  {
1091  global $ilSetting;
1092  $err = self::verifyPrivateKey();
1093  if (!empty($err)) {
1094  return [];
1095  }
1096  $privatekey = $ilSetting->get(self::LTI_1_3_PRIVATE_KEY);
1097  $kid = $ilSetting->get(self::LTI_1_3_KID);
1098  return [
1099  "key" => $privatekey,
1100  "kid" => $kid
1101  ];
1102  }
1103 
1104  public static function verifyPrivateKey(): string
1105  {
1106  global $ilSetting;
1107  $key = $ilSetting->get(self::LTI_1_3_PRIVATE_KEY);
1108 
1109  if (empty($key)) {
1110  $kid = bin2hex(openssl_random_pseudo_bytes(10));
1111  $ilSetting->set(self::LTI_1_3_KID, $kid);
1112  $config = array(
1113  "digest_alg" => "sha256",
1114  "private_key_bits" => 2048,
1115  "private_key_type" => self::OPENSSL_KEYTYPE_RSA
1116  );
1117  $res = openssl_pkey_new($config);
1118  openssl_pkey_export($res, $privatekey);
1119  if (!empty($privatekey)) {
1120  $ilSetting->set(self::LTI_1_3_PRIVATE_KEY, $privatekey);
1121  } else {
1122  return self::ERROR_OPEN_SSL_CONF;
1123  }
1124  }
1125  return '';
1126  }
1127 
1128  public static function getPublicKey(): string
1129  {
1130  $publicKey = null;
1131  $privateKey = self::getPrivateKey();
1132  $res = openssl_pkey_get_private($privateKey['key']);
1133  if ($res !== false) {
1134  $details = openssl_pkey_get_details($res);
1135  $publicKey = $details['key'];
1136  }
1137  return $publicKey;
1138  }
1139 
1140  public static function getJwks(): array
1141  {
1142  $jwks = ['keys' => []];
1143 
1144  $privatekey = self::getPrivateKey();
1145  $res = openssl_pkey_get_private($privatekey['key']);
1146  $details = openssl_pkey_get_details($res);
1147 
1148  $jwk = [];
1149  $jwk['kty'] = 'RSA';
1150  $jwk['alg'] = 'RS256';
1151  $jwk['kid'] = $privatekey['kid'];
1152  $jwk['e'] = rtrim(strtr(base64_encode($details['rsa']['e']), '+/', '-_'), '=');
1153  $jwk['n'] = rtrim(strtr(base64_encode($details['rsa']['n']), '+/', '-_'), '=');
1154  $jwk['use'] = 'sig';
1155 
1156  $jwks['keys'][] = $jwk;
1157  return $jwks;
1158  }
1159 
1160  public static function getIliasHttpPath(): string
1161  {
1162  global $DIC;
1163 
1164  if ($DIC['https']->isDetected()) {
1165  $protocol = 'https://';
1166  } else {
1167  $protocol = 'http://';
1168  }
1169  $host = $_SERVER['HTTP_HOST'];
1170 
1171  $rq_uri = strip_tags($_SERVER['REQUEST_URI']);
1172 
1173  // security fix: this failed, if the URI contained "?" and following "/"
1174  // -> we remove everything after "?"
1175  if (is_int($pos = strpos($rq_uri, "?"))) {
1176  $rq_uri = substr($rq_uri, 0, $pos);
1177  }
1178 
1179  $path = pathinfo($rq_uri);
1180  if (isset($path['extension']) && $path['extension'] !== '') {
1181  $uri = dirname($rq_uri);
1182  } else {
1183  $uri = $rq_uri;
1184  }
1185  $uri = str_replace("Modules/LTIConsumer", "", $uri);
1186  $iliasHttpPath = ilContext::modifyHttpPath(implode('', [$protocol, $host, $uri]));
1187  $f = new \ILIAS\Data\Factory();
1188  $uri = $f->uri(rtrim($iliasHttpPath, "/"));
1189  return $uri->getBaseURI();
1190  }
1191 
1192  public static function getPlattformId(): string
1193  {
1194  return self::getIliasHttpPath();
1195  }
1196 
1197  public static function getAuthenticationRequestUrl(): string
1198  {
1199  return self::getIliasHttpPath() . "/Modules/LTIConsumer/ltiauth.php";
1200  }
1201 
1202  public static function getAccessTokenUrl(): string
1203  {
1204  return self::getIliasHttpPath() . "/Modules/LTIConsumer/ltitoken.php";
1205  }
1206 
1207  public static function getPublicKeysetUrl(): string
1208  {
1209  return self::getIliasHttpPath() . "/Modules/LTIConsumer/lticerts.php";
1210  }
1211 
1212  public static function getRegistrationUrl(): string
1213  {
1214  return self::getIliasHttpPath() . "/Modules/LTIConsumer/ltiregistration.php";
1215  }
1216 
1217  public static function getRegistrationStartUrl(): string
1218  {
1219  return self::getIliasHttpPath() . "/Modules/LTIConsumer/ltiregstart.php";
1220  }
1221 
1222  public static function getRegistrationEndUrl(): string
1223  {
1224  return self::getIliasHttpPath() . "/Modules/LTIConsumer/ltiregend.php";
1225  }
1226 
1227  public static function getOpenidConfigUrl(): string
1228  {
1229  return self::getIliasHttpPath() . "/Modules/LTIConsumer/lticonfig.php";
1230  }
1231 
1232  public static function getOpenidConfig(): array
1233  {
1234  $scopesSupported = array('openid');
1235  $gradeservice = new ilLTIConsumerGradeService();
1236  $scopesSupported = array_merge($scopesSupported, $gradeservice->getPermittedScopes());
1237  return [
1238  "issuer" => self::getPlattformId(),
1239  "authorization_endpoint" => self::getAuthenticationRequestUrl(),
1240  "token_endpoint" => self::getAccessTokenUrl(),
1241  "token_endpoint_auth_methods_supported" => ["private_key_jwt"],
1242  "token_endpoint_auth_signing_alg_values_supported" => ["RS256"],
1243  "jwks_uri" => self::getPublicKeysetUrl(),
1244  "registration_endpoint" => self::getRegistrationUrl(),
1245  "scopes_supported" => $scopesSupported,
1246  "response_types_supported" => ["id_token"],
1247  "subject_types_supported" => ["public", "pairwise"],
1248  "id_token_signing_alg_values_supported" => ["RS256"],
1249  "claims_supported" => ["iss", "aud"],
1250  "https://purl.imsglobal.org/spec/lti-platform-configuration" => [
1251  "product_family_code" => "ilias.de",
1252  "version" => ILIAS_VERSION,
1253  "messages_supported" => [
1254  [
1255  "type" => "LtiResourceLinkRequest",
1256  "placements" => [
1257  ]
1258  ],
1259  [
1260  "type" => "LtiDeepLinkingRequest",
1261  "placements" => [
1262  ]
1263  ]
1264  ]
1265  ]
1266  ];
1267  }
1268 
1269  public static function registerClient(array $data, object $tokenObj): array
1270  {
1271  // first analyse tool_config and filter only accepted params
1272  // append client_id (required) and deployment_id(=provider_id in ILIAS) (optional) to tool_config response
1273  global $DIC;
1274  $reponseData = $data;
1275  $provider = new ilLTIConsumeProvider();
1276  $toolConfig = $data['https://purl.imsglobal.org/spec/lti-tool-configuration'];
1277  $provider->setTitle(strip_tags($data['client_name'], ilObjectGUI::ALLOWED_TAGS_IN_TITLE_AND_DESCRIPTION));
1278  $provider->setProviderUrl($toolConfig['target_link_uri']);
1279  $provider->setInitiateLogin($data['initiate_login_uri']);
1280  $provider->setRedirectionUris(implode(",", $data['redirect_uris']));
1281  if (isset($data['jwks_uri'])) {
1282  $provider->setPublicKeyset($data['jwks_uri']);
1283  }
1284  foreach ($toolConfig['messages'] as $message) {
1285  if (isset($message['type']) && $message['type'] === 'LtiDeepLinkingRequest') {
1286  $provider->setContentItemUrl($message['target_link_uri']);
1287  }
1288  }
1289  /*
1290  if (isset($data['logo_uri'])) { // needs to be uploaded and then assign filepath
1291  $provider->setProviderIconFilename($data['logo_uri']);
1292  }
1293  */
1294  $provider->setKeyType('JWK_KEYSET');
1295  $provider->setLtiVersion('1.3.0');
1296  $provider->setClientId((string) $tokenObj->aud); //client_id
1297  $provider->setCreator((int) $tokenObj->sub); // user_id
1299  $provider->setIsGlobal(false);
1300  $provider->insert();
1301  $reponseData['client_id'] = $tokenObj->aud;
1302  $reponseData['https://purl.imsglobal.org/spec/lti-tool-configuration']['deployment_id'] = $provider->getId();
1303  return $reponseData;
1304  }
1305 
1306  public static function getNewClientId(): string
1307  {
1309  }
1310 
1311  public static function sendResponseError(int $code, string $message, $log = true): void
1312  {
1313  global $DIC;
1314  try {
1315  if ($log) {
1316  self::getLogger()->error("$code $message");
1317  }
1318  $DIC->http()->saveResponse(
1319  $DIC->http()->response()
1320  ->withStatus($code)
1321  ->withBody(Streams::ofString($message))
1322  );
1323  $DIC->http()->sendResponse();
1324  $DIC->http()->close();
1325  } catch (Exception $e) {
1326  $DIC->http()->close();
1327  }
1328  }
1329 
1330  public static function sendResponseJson(array $obj): void
1331  {
1332  global $DIC;
1333  try {
1334  header('Content-Type: application/json; charset=utf-8');
1335  header('Cache-Control: no-store');
1336  header('Pragma: no-cache');
1337  echo json_encode($obj, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
1338  } catch (Exception $e) {
1339  self::sendResponseError(500, "error in sendResponseJson");
1340  $DIC->http()->close();
1341  }
1342  }
1343 
1344  public static function getInstance(int $a_id = 0, bool $a_reference = true): \ilObjLTIConsumer
1345  {
1346  return new self($a_id, $a_reference);
1347  }
1348 
1349  public function isMixedContentType(): bool
1350  {
1351  return true;
1352  }
1353 
1354  public static function getRawData(): ?string
1355  {
1356  return file_get_contents('php://input');
1357  }
1358 
1359  public static function getTokenObject(string $token): ?object
1360  {
1361  try {
1362  $keys = JWK::parseKeySet(self::getJwks());
1363  return JWT::decode($token, $keys);
1364  } catch (Exception $e) {
1365  return null;
1366  }
1367  }
1368 
1369  public static function verifyToken(): ?object
1370  {
1371  global $DIC;
1372  $auth = $DIC->http()->request()->getHeader("Authorization");
1373  // self::getLogger()->dump($auth);
1374  if (count($auth) < 1) {
1375  self::sendResponseError(405, "missing Authorization header");
1376  }
1377  preg_match('/Bearer\s+(.+)$/i', $auth[0], $matches);
1378  if (count($matches) != 2) {
1379  // self::getLogger()->error("405, missing required Authorization Baerer token in ".$auth[0]);
1380  self::sendResponseError(405, "missing required Authorization Baerer token");
1381  }
1382 
1383  $token = $matches[1];
1384  // self::getLogger()->dump($token);
1385  return self::getTokenObject($token);
1386  }
1387 
1388  public static function getLogger(): ilLogger
1389  {
1390  return ilLoggerFactory::getLogger('lti');
1391  }
1392 }
static getIdentAsId(int $userIdentMode, ilObjUser $user)
setUseXapi(bool $use_xapi)
$res
Definition: ltiservices.php:69
setInitiateLogin(string $initiate_login)
$context
Definition: webdav.php:31
setPublicKeyset(string $public_keyset)
const ILIAS_VERSION
getHighscoreWTime()
Gets if the column with the workingtime should be shown.
setActivationEndingTime(?int $activationEndingTime=null)
static getLogger(string $a_component_id)
Get component logger.
setCustomActivityId(string $custom_activity_id)
__construct(int $a_id=0, bool $a_reference=true)
ilObjLTIConsumer constructor.
setCustomParams(string $customParams)
setActivationLimited(bool $activationLimited)
const ROOT_FOLDER_ID
Definition: constants.php:32
setHighscoreEnabled(bool $a_enabled)
HIGHSCORE.
static sendResponseError(int $code, string $message, $log=true)
if(! $DIC->user() ->getId()||!ilLTIConsumerAccess::hasCustomProviderCreationAccess()) $params
Definition: ltiregstart.php:33
getHighscorePercentage()
Gets if the percentage column should be shown.
getHighscoreEnabled()
Gets the setting which determines if the highscore feature is enabled.
setStatementsReportEnabled(bool $statementsReportEnabled)
const SYSTEM_ROLE_ID
Definition: constants.php:29
$clientId
Definition: ltiregend.php:27
setMasteryScorePercent(float $mastery_score_percent)
bool $activationLimited
repository object activation settings (handled by ilObject)
ClientInterface $jwt
JWT object, if any.
Definition: System.php:165
setHighscoreWTime(bool $a_wtime)
Sets if the workingtime of the scores should be shown.
setHighscoreAchievedTS(bool $a_achieved_ts)
Sets if the date and time of the scores achievement should be displayed.
setHighscoreTopTable(bool $a_top_table)
Sets if the top-rankings table should be shown.
setContentItemUrl(string $content_item_url)
setCustomLaunchSecret(string $customLaunchSecret)
$refId
Definition: xapitoken.php:58
static buildContentSelectionParameters(ilLTIConsumeProvider $provider, int $refId, string $returnUrl, string $nonce)
static modifyHttpPath(string $httpPath)
static registerClient(array $data, object $tokenObj)
string $kid
Key ID.
Definition: System.php:88
const PRIVACY_IDENT_IL_UUID_RANDOM
static getIdent(int $userIdentMode, ilObjUser $user)
$path
Definition: ltiservices.php:32
const MESSAGE_TYPE_MAPPING
Mapping for standard message types.
Definition: Util.php:48
global $DIC
Definition: feed.php:28
array $details
Details for error message relating to last request processed.
Definition: System.php:109
static getInstance(int $a_id=0, bool $a_reference=true)
getHighscoreTopNum(int $a_retval=10)
Gets the number of entries which are to be shown in the top-rankings table.
const ALLOWED_TAGS_IN_TITLE_AND_DESCRIPTION
__construct(VocabulariesInterface $vocabularies)
buildLaunchParametersLTI13(ilCmiXapiUser $cmixUser, string $endpoint, string $clientId, int $deploymentId, string $nonce, string $contextType, string $contextId, string $contextTitle, ?string $returnUrl='')
static getRandomString(int $length=8)
Generate a random string.
Definition: Util.php:558
setRedirectionUris(string $redirection_uris)
setLaunchMethod(string $launchMethod)
$token
Definition: xapitoken.php:70
setHighscoreOwnTable(bool $a_own_table)
Sets if the table with the own ranking should be shown.
$_SERVER['HTTP_HOST']
Definition: raiseError.php:10
static getTokenObject(string $token)
$param
Definition: xapitoken.php:46
const CLIENT_ID
Definition: constants.php:41
static LTISignJWT(array $parms, string $endpoint, string $oAuthConsumerKey, $typeId=0, string $nonce='')
string $key
Consumer key/client ID value.
Definition: System.php:193
ilLTIConsumeProvider $provider
setLtiVersion(string $lti_version)
$privateKey
Definition: ltiregstart.php:68
static getByKeys(int $a_obj_id, int $a_usr_id, ?bool $a_create=false)
Get a result by object and user key.
setHighscorePercentage(bool $a_percentage)
Sets if the percentages of the scores pass should be shown.
setActivationVisibility(bool $activationVisibility)
static getItem(int $ref_id)
static getProviderCustomParamsArray(ilLTIConsumeProvider $provider)
setActivationStartingTime(?int $activationStartingTime=null)
static encode(array $payload, $key, string $alg, string $keyId=null, array $head=null)
Converts and signs a PHP array into a JWT string.
Definition: JWT.php:199
buildLaunchParameters(ilCmiXapiUser $cmixUser, string $token, string $contextType, string $contextId, string $contextTitle, ?string $returnUrl='')
global $ilSetting
Definition: privfeed.php:18
setCustomLaunchKey(string $customLaunchKey)
getHighscoreTopTable()
Gets, if the top-rankings table should be shown.
getHighscoreAchievedTS()
Returns if date and time of the scores achievement should be displayed.
ilLogger $log
$message
Definition: xapiexit.php:32
setHighscoreTopNum(int $a_top_num)
Sets the number of entries which are to be shown in the top-rankings table.
static sendResponseJson(array $obj)
static signOAuth(array $a_params)
sign request data with OAuth
setProviderUrl(string $provider_url)
Class ilObjectActivation.
getHighscoreOwnTable()
Gets if the own rankings table should be shown.
setMasteryScore(float $mastery_score)
setProviderId(int $providerId)
const JWT_CLAIM_MAPPING
Mapping for standard message parameters to JWT claim.
Definition: Util.php:58
$typeId
Definition: ltiregstart.php:36
setProvider(ilLTIConsumeProvider $provider)