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