ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
class.ilObjLTIConsumerGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
23 
42 {
43  public const CFORM_CUSTOM_NEW = 99;
44  public const CFORM_DYNAMIC_REGISTRATION = 98; //
45 
46  public const TAB_ID_INFO = 'tab_info';
47  public const TAB_ID_CONTENT = 'tab_content';
48  public const TAB_ID_SETTINGS = 'tab_settings';
49  public const TAB_ID_STATEMENTS = 'tab_statements';
50  public const TAB_ID_SCORING = 'tab_scoring';
51  public const TAB_ID_GRADE_SYNCHRONIZATION = 'tab_grade_synchronization';
52  public const TAB_ID_METADATA = 'tab_metadata';
53  public const TAB_ID_LEARNING_PROGRESS = 'learning_progress';
54  public const TAB_ID_PERMISSIONS = 'perm_settings';
55 
56  public const DEFAULT_CMD = 'launch';
57 
58  public ?ilObject $object = null;
61 
62  public int $parent_node_id = 0; //check
63 
64  public function __construct(int $a_id = 0, int $a_id_type = self::REPOSITORY_NODE_ID, int $a_parent_node_id = 0)
65  {
66  global $DIC;
67  /* @var \ILIAS\DI\Container $DIC */
68 
69  parent::__construct($a_id, $a_id_type, $a_parent_node_id);
70  $this->parent_node_id = $a_parent_node_id;
71  if ($this->object instanceof ilObjLTIConsumer) {
72  $this->ltiAccess = new ilLTIConsumerAccess($this->object);
73  }
74  $this->lom_services = $DIC->learningObjectMetadata();
75 
76  $DIC->language()->loadLanguageModule("lti");
77  $DIC->language()->loadLanguageModule("rep");
78  }
79 
80  public function getType(): string
81  {
82  return 'lti';
83  }
84 
88  protected function initCreateForm(string $a_new_type): array
89  {
90  $forms = array(
91  self::CFORM_NEW => $this->initNewForm($a_new_type)
92  );
93 
95  $forms[self::CFORM_DYNAMIC_REGISTRATION] = $this->initDynRegForm($a_new_type);
96  $forms[self::CFORM_CUSTOM_NEW] = $this->initCustomCreateForm($a_new_type);
97  }
98 
99  return $forms;
100  }
101 
102  public function saveObject(): void
103  {
104  // create permission is already checked in createObject. This check here is done to prevent hacking attempts
105  if (!$this->checkPermissionBool("create", "", $this->requested_new_type)) {
106  $this->error->raiseError($this->lng->txt("no_create_permission"), $this->error->MESSAGE);
107  }
108 
109  $this->lng->loadLanguageModule($this->requested_new_type);
110  $this->ctrl->setParameter($this, "new_type", $this->requested_new_type);
111 
112  $forms = $this->initCreateForm($this->requested_new_type);
113 
114  foreach ($forms as $form) {
115  if ($form->checkInput()) {
116  $this->ctrl->setParameter($this, "new_type", "");
117 
118  $class_name = "ilObj" . $this->obj_definition->getClassName($this->requested_new_type);
119  $newObj = new $class_name();
120  $newObj->setType($this->requested_new_type);
121  $newObj->setTitle($form->getInput("title"));
122  $newObj->setDescription($form->getInput("desc"));
123  $newObj->processAutoRating();
124  $newObj->create();
125 
126  $this->putObjectInTree($newObj);
127 
128  $dtpl = $this->getDidacticTemplateVar("dtpl");
129  if ($dtpl) {
130  $newObj->applyDidacticTemplate($dtpl);
131  }
132 
133  $this->afterSave($newObj);
134  }
135 
136  $form->setValuesByPost();
137  $this->tpl->setContent($form->getHTML());
138  }
139 
140  }
141 
142  protected function getCreationFormsHTML(StandardForm|ilPropertyFormGUI|array $forms): string
143  {
144  if (!is_array($forms)) {
145  throw new Exception('We only deal with arrays here.');
146  }
147 
148  $acc = new ilAccordionGUI();
149  $acc->setBehaviour(ilAccordionGUI::FIRST_OPEN);
150  array_walk(
151  $forms,
152  function (ilPropertyFormGUI $v, string $k) use ($acc): void {
153  $acc->addItem(
154  $v->getTitle(),
155  $v->getHTML()
156  );
157  }
158  );
159 
160  return $acc->getHTML();
161  }
162 
163  protected function initNewForm(string $a_new_type): \ilLTIConsumerProviderSelectionFormTableGUI
164  {
165  global $DIC;
166  /* @var \ILIAS\DI\Container $DIC */
167 
168  $form = $this->buildProviderSelectionForm($a_new_type);
169 
170  $globalProviderList = new ilLTIConsumeProviderList();
171  $globalProviderList->setAvailabilityFilter((string) ilLTIConsumeProvider::AVAILABILITY_CREATE);
172  $globalProviderList->setScopeFilter(ilLTIConsumeProviderList::SCOPE_GLOBAL);
173 
174  $userProviderList = new ilLTIConsumeProviderList();
175  $userProviderList->setAvailabilityFilter((string) ilLTIConsumeProvider::AVAILABILITY_CREATE);
176  $userProviderList->setScopeFilter(ilLTIConsumeProviderList::SCOPE_USER);
177  $userProviderList->setCreatorFilter($DIC->user()->getId());
178 
179  if ($form->getFilter('title')) {
180  $globalProviderList->setTitleFilter($form->getFilter('title'));
181  $userProviderList->setTitleFilter($form->getFilter('title'));
182  }
183 
184  if ($form->getFilter('category')) {
185  $globalProviderList->setCategoryFilter($form->getFilter('category'));
186  $userProviderList->setCategoryFilter($form->getFilter('category'));
187  }
188 
189  if ($form->getFilter('keyword')) {
190  $globalProviderList->setKeywordFilter($form->getFilter('keyword'));
191  $userProviderList->setKeywordFilter($form->getFilter('keyword'));
192  }
193 
194  if ($form->getFilter('outcome')) {
195  $globalProviderList->setHasOutcomeFilter(true);
196  $userProviderList->setHasOutcomeFilter(true);
197  }
198 
199  if ($form->getFilter('internal')) {
200  $globalProviderList->setIsExternalFilter(false);
201  $userProviderList->setIsExternalFilter(false);
202  }
203 
204  if ($form->getFilter('with_key')) {
205  $globalProviderList->setIsProviderKeyCustomizableFilter(false);
206  $userProviderList->setIsProviderKeyCustomizableFilter(false);
207  }
208 
209  $globalProviderList->load();
210  $userProviderList->load();
211 
212  $form->setData([...$globalProviderList->getTableData(), ...$userProviderList->getTableData()]);
213 
214  return $form;
215  }
216 
217  public function initDynRegForm(string $a_new_type): \ilLTIConsumeProviderFormGUI
218  {
219  global $DIC;
220  /* @var \ILIAS\DI\Container $DIC */
223  $form->initDynRegForm($this->ctrl->getFormAction($this, "cancelDynReg"));
224  $form->setTitle($DIC->language()->txt($a_new_type . '_dynamic_registration'));
225  return $form;
226  }
227 
228  public function initShowToolConfig(string $a_new_type, int $a_provider_id): \ilLTIConsumeProviderFormGUI
229  {
230  global $DIC;
231 
232  //ToDo: Error Handling
233  $provider = new ilLTIConsumeProvider($a_provider_id);
234 
236 
237  $form->initToolConfigForm($this->ctrl->getFormAction($this, "cancelDynReg"), '', '');
238 
239  $form->clearCommandButtons();
240  $form->addCommandButton("saveDynReg", $this->lng->txt('save'));
241  $form->addCommandButton("cancelDynReg", $this->lng->txt("cancel"));
242 
243  $form->setTitle($DIC->language()->txt($a_new_type . '_custom_new'));
244 
245  return $form;
246  }
247 
248  public function initCustomCreateForm(string $a_new_type): \ilLTIConsumeProviderFormGUI
249  {
250  global $DIC;
251  /* @var \ILIAS\DI\Container $DIC */
252 
254 
256 
257  $form->initForm($this->ctrl->getFormAction($this, "save"), '', '');
258 
259  $form->clearCommandButtons();
260  $form->addCommandButton("saveCustom", $this->lng->txt($a_new_type . "_add_own_provider"));
261  $form->addCommandButton("cancel", $this->lng->txt("cancel"));
262 
263  $form->setTitle($DIC->language()->txt($a_new_type . '_custom_new'));
264 
265  return $form;
266  }
267 
269  {
271  $a_new_type,
272  $this,
273  'create',
274  'applyProviderFilter',
275  'resetProviderFilter'
276  );
277  }
278 
279  protected function applyProviderFilter(): void
280  {
281  $form = $this->buildProviderSelectionForm('');
282  $form->applyFilter();
283  $this->createObject();
284  }
285 
286  protected function resetProviderFilter(): void
287  {
288  $form = $this->buildProviderSelectionForm('');
289  $form->resetFilter();
290  $this->createObject();
291  }
292 
293  protected function createNewObject(string $newType, string $title, string $description): ilObject
294  {
295  $classname = "ilObj" . $this->obj_definition->getClassName($newType);
296 
297  $newObj = new $classname();
298  $newObj->setType($newType);
299  $newObj->setTitle($title);
300  $newObj->setDescription($description);
301  $newObj->create();
302  $this->putObjectInTree($newObj);
303  return $newObj;
304  }
305 
306  public function saveCustom(): void
307  {
309  throw new ilLtiConsumerException('permission denied!');
310  }
311 
312  global $DIC;
313  /* @var \ILIAS\DI\Container $DIC */
314 
315  $new_type = $this->getRequestValue("new_type");
316 
317  $DIC->ctrl()->setParameter($this, "new_type", $new_type);
318 
319  $DIC->language()->loadLanguageModule($new_type);
320 
321  $form = $this->initCustomCreateForm($new_type);
322 
323  if ($form->checkInput()) {
324  $DIC->ctrl()->setParameter($this, "new_type", "");
325 
326  // create object
327  $newObj = $this->createNewObject(
328  $new_type,
329  $form->getInput('title'),
330  $form->getInput('desc')
331  );
332 
333  // apply didactic template?
334  $dtpl = $this->getDidacticTemplateVar("dtpl");
335  if ($dtpl) {
336  $newObj->applyDidacticTemplate($dtpl);
337  }
338 
339  $this->afterSave($newObj);
340 
341  return;
342  }
343 
344  $form->setValuesByPost();
345 
346  $DIC->ui()->mainTemplate()->setContent($form->getHtml());
347  }
348 
349  public function addDynReg(): void
350  {
351  global $DIC;
353  throw new ilLtiConsumerException('permission denied!');
354  }
355  $new_type = $this->getRequestValue("new_type");
356 
357  $DIC->ctrl()->setParameter($this, "new_type", $new_type);
358 
359  $DIC->language()->loadLanguageModule($new_type);
360  $form = $this->initDynRegForm($new_type);
361  $error = ($this->getRequestValue('error') != null) ? $this->getRequestValue('error') : "";
362  $form->setValuesByPost();
363  if (!empty($error)) {
364  $DIC->ctrl()->setParameter($this, "new_type", "");
365  $DIC->ui()->mainTemplate()->setOnScreenMessage('failure', base64_decode($error));
366  $DIC->ui()->mainTemplate()->setContent($form->getDynRegError());
367  return;
368  }
369  if ($form->checkInput()) {
370  $DIC->ctrl()->setParameter($this, "new_type", "");
371  $DIC->ui()->mainTemplate()->setContent($form->getDynRegRequest());
372  return;
373  }
374  $DIC->ui()->mainTemplate()->setContent($form->getHTML());
375  }
376 
377  public function cancelDynReg(): void
378  {
379  global $DIC;
381  throw new ilLtiConsumerException('permission denied!');
382  }
383  $new_type = $this->getRequestValue("new_type");
384  //$provider_id = $this->getRequestValue("provider_id");
385  if (ilSession::has('lti_dynamic_registration_client_id')) {
386  $providerId = ilLTIConsumeProvider::getProviderIdFromClientId(ilSession::get('lti_dynamic_registration_client_id'));
387  if ($providerId > 0) {
388  try {
390  //ToDo: check if provider is in use? should never happen...
391  $provider->delete();
392  } catch (\ILIAS\Filesystem\Exception\IOException $e) {
393  //ToDo: error handling
394  }
395  }
396  }
397  $DIC->ctrl()->setParameterByClass(ilRepositoryGUI::class, 'new_type', $new_type);
398  $DIC->ctrl()->redirectByClass(ilRepositoryGUI::class, 'create');
399  }
400 
401  public function showToolConfig(): void
402  {
403  global $DIC;
405  throw new ilLtiConsumerException('permission denied!');
406  }
407  $new_type = $this->getRequestValue("new_type");
408  $DIC->ctrl()->setParameter($this, "new_type", $new_type);
409  $provider_id = $this->getRequestValue("provider_id");
410  $DIC->ctrl()->setParameter($this, "provider_id", $provider_id);
411  $DIC->language()->loadLanguageModule($new_type);
412  $form = $this->initShowToolConfig($new_type, (int) $provider_id);
413  $DIC->ui()->mainTemplate()->setContent($form->getHTML());
414  }
415 
416  public function saveDynReg(): void
417  {
418  global $DIC;
420  throw new ilLtiConsumerException('permission denied!');
421  }
422  $new_type = $this->getRequestValue("new_type");
423  $DIC->ctrl()->setParameter($this, "new_type", $new_type);
424  $provider_id = $this->getRequestValue("provider_id");
425  $DIC->ctrl()->setParameter($this, "provider_id", $provider_id);
426  $DIC->language()->loadLanguageModule($new_type);
427  ilSession::clear('lti_dynamic_registration_client_id');
428  ilSession::clear('lti_dynamic_registration_custom_params');
429  $form = $this->initShowToolConfig($new_type, (int) $provider_id);
430  $form->setValuesByPost();
431  if ($form->checkInput()) { // update only overridable fields
432  $provider = $form->getProvider();
433  $form->initProvider($provider);
434  $provider->update();
435  // jump to provider selection is one option:
436  // $DIC->ctrl()->redirectByClass([ilRepositoryGUI::class, ilObjLTIConsumerGUI::class],"create");
437  // direct redirection to save is onle less click (there is a switch for save | contentSelection in GUI class):
438  $DIC->ctrl()->redirectByClass([ilRepositoryGUI::class, ilObjLTIConsumerGUI::class], "save");
439  return;
440  }
441  $DIC->ui()->mainTemplate()->setContent($form->getHTML());
442  }
443 
444  public function contentSelection(string $providerId, string $newType, string $refId, ilLTIConsumeProvider $provider): void
445  {
446  global $DIC;
448  throw new ilLtiConsumerException('permission denied!');
449  }
450  $DIC->ctrl()->setParameter($this, "new_type", $newType);
451  $DIC->ctrl()->setParameter($this, "provider_id", $providerId);
452  $DIC->ctrl()->setParameter($this, "ref_id", $refId);
453 
454  $form = new ilLTIConsumeProviderFormGUI($provider);
455  $formaction = $this->ctrl->getFormAction($this, "cancelContentSelection");
456  $DIC->ui()->mainTemplate()->setContent($form->getContentSelectionFrame($formaction));
457  }
458 
459  public function contentSelectionRequest(): void
460  {
461  global $DIC;
463  throw new ilLtiConsumerException('permission denied!');
464  }
465  $new_type = $this->getRequestValue("new_type");
466  $DIC->ctrl()->setParameter($this, "new_type", $new_type);
467  $provider_id = $this->getRequestValue("provider_id");
468  $DIC->ctrl()->setParameter($this, "provider_id", $provider_id);
469  $ref_id = $this->getRequestValue("ref_id");
470  $DIC->ctrl()->setParameter($this, "ref_id", $ref_id);
471  $DIC->language()->loadLanguageModule($new_type);
472  $provider = new ilLTIConsumeProvider((int) $provider_id);
473  $redirectUrl = $DIC->ctrl()->getLinkTarget($this, 'contentSelectionRequest');
474 
475  if (!ilSession::has('lti13_login_data')) {
476  $userIdLTI = ilCmiXapiUser::getIdentAsId($provider->getPrivacyIdent(), $DIC->user());
477  //$emailPrimary = ilCmiXapiUser::getIdent($provider->getPrivacyIdent(), $DIC->user());
478  $ltiMessageHint = (string) $ref_id . ":" . CLIENT_ID . ":" . base64_encode($redirectUrl);
479  $tplLogin = new ilTemplate("tpl.lti_initial_login.html", true, true, "components/ILIAS/LTIConsumer");
480  $tplLogin->setVariable("LTI_INITIAL_LOGIN_ACTION", $provider->getInitiateLogin());
481  $tplLogin->setVariable("ISS", ilObjLTIConsumer::getIliasHttpPath());
482  $tplLogin->setVariable("TARGET_LINK_URL", $provider->getProviderUrl());
483  $tplLogin->setVariable("LOGIN_HINT", $userIdLTI);
484  $tplLogin->setVariable("LTI_MESSAGE_HINT", $ltiMessageHint);
485  $tplLogin->setVariable("CLIENT_ID", $provider->getClientId());
486  $tplLogin->setVariable("LTI_DEPLOYMENT_ID", (string) $provider->getId());
487  echo $tplLogin->get();
488  exit; //TODO: no exit
489  } else {
490  $loginData = ilSession::get('lti13_login_data');
491  // ToDo: correct Link!! replace ILIAS_HTTP_PATH
492  $data = ilObjLTIConsumer::buildContentSelectionParameters($provider, (int) $ref_id, ilObjLTIConsumer::getIliasHttpPath() . "/" . $DIC->ctrl()->getLinkTarget($this, 'contentSelectionResponse'), $loginData['nonce']);
493  $tplContentSelection = new ilTemplate("tpl.lti_jwt_autosubmit.html", true, true, "components/ILIAS/LTIConsumer");
494  $tplContentSelection->setVariable("LTI_JWT_FORM_ACTION", $provider->getContentItemUrl());
495  $tplContentSelection->setVariable("LTI_JWT_ID_TOKEN", $data['id_token']);
496  $tplContentSelection->setVariable("LTI_JWT_STATE", $loginData['state']);
497  ilSession::clear('lti13_login_data');
498  echo $tplContentSelection->get();
499  exit; //TODO: no exit
500  }
501  }
502 
503  public function contentSelectionResponse(): void
504  {
505  global $DIC;
507  throw new ilLtiConsumerException('permission denied!');
508  }
509  $new_type = $this->getRequestValue("new_type");
510  $DIC->ctrl()->setParameter($this, "new_type", $new_type);
511  $provider_id = $this->getRequestValue("provider_id");
512  $DIC->ctrl()->setParameter($this, "provider_id", $provider_id);
513  $ref_id = $this->getRequestValue("ref_id");
514  $DIC->ctrl()->setParameter($this, "ref_id", $ref_id);
515  $DIC->language()->loadLanguageModule($new_type);
516  $token = '';
517  if ($DIC->http()->wrapper()->post()->has('JWT')) {
518  $token = $DIC->http()->wrapper()->post()->retrieve('JWT', $DIC->refinery()->kindlyTo()->string());
519  }
520  if ($DIC->http()->wrapper()->post()->has('jwt')) {
521  $token = $DIC->http()->wrapper()->post()->retrieve('jwt', $DIC->refinery()->kindlyTo()->string());
522  }
523  if (!empty($token)) {
524  $provider = new ilLTIConsumeProvider((int) $provider_id);
526  } else {
527  echo "no token";
528  exit;
529  //ToDo:
530  }
531  }
532 
533  public function cancelContentSelection(): void
534  {
535  global $DIC;
537  throw new ilLtiConsumerException('permission denied!');
538  }
539  $new_type = $this->getRequestValue("new_type");
540  $DIC->ctrl()->setParameterByClass(ilRepositoryGUI::class, 'new_type', $new_type);
541  $DIC->ctrl()->redirectByClass(ilRepositoryGUI::class, 'create');
542  }
543 
545  {
546  if ($provider->getKeyType() == 'RSA_KEY') {
547  $key = $provider->getPublicKey();
548  $keys = new Firebase\JWT\Key($key, "RS256");
549  } else {
550  $jwks = file_get_contents($provider->getPublicKeyset());
551  //ToDo: Errorhandling
552  $keyset = json_decode($jwks, true);
553  $keys = Firebase\JWT\JWK::parseKeySet($keyset);
554  }
555  $data = Firebase\JWT\JWT::decode($token, $keys);
556  //ilObjLTIConsumer::getLogger()->debug(var_export($data,TRUE));
557  $refId = $this->getRequestValue('ref_id');
558 
559  foreach ($data->{'https://purl.imsglobal.org/spec/lti-dl/claim/content_items'} as $item) {
560  $gui = new ilObjLTIConsumerGUI(0, self::REPOSITORY_NODE_ID, (int) $refId);
561  $description = "";
562  if (isset($item->description)) {
563  $description = $item->description;
564  }
565  $newObj = $gui->createNewObject('lti', $item->title, $description);
566  $dtpl = $gui->getDidacticTemplateVar("dtpl");
567  if ($dtpl) {
568  $newObj->applyDidacticTemplate($dtpl);
569  }
570 
571  $newObj->setProviderId($provider->getId());
572  $newObj->setProvider($provider);
573  // custom params
574  $customParams = [];
575  foreach ($item->{'custom'} as $key => $value) {
576  $customParams[] = $key . "=" . $value;
577  }
578  if (count($customParams) > 0) {
579  $newObj->setCustomParams(implode(";", $customParams));
580  }
581  $newObj->save();
582  $this->initMetadata($newObj);
583  }
585  $template = new ilTemplate('tpl.lti_content_selection_finished.html', true, true, 'components/ILIAS/LTIConsumer');
586  $redirect = ilObjLTIConsumer::getIliasHttpPath() . "/" . "goto.php?target=" . $type . "_" . $refId;
587  $template->setVariable("CONTENT_SELECTION_REDIRECT", $redirect);
588  echo $template->get();
589  exit;
590  }
591 
599  protected function afterSave(\ilObject $newObject): void
600  {
601  global $DIC; //check
602  if ($DIC->http()->wrapper()->query()->has('provider_id')) {
603  $newObject->setProviderId((int) $DIC->http()->wrapper()->query()->retrieve('provider_id', $DIC->refinery()->kindlyTo()->int()));
604  $newObject->initProvider();
605  $newObject->save();
606 
607  $newObject->setTitle($newObject->getProvider()->getTitle());
608  $newObject->setMasteryScore($newObject->getProvider()->getMasteryScore());
609  $newObject->update();
610 
611  $this->initMetadata($newObject);
612  $DIC->ctrl()->redirectByClass(ilLTIConsumerSettingsGUI::class);
613  }
614 
616  throw new ilLtiConsumerException('permission denied!');
617  }
618 
619  $form = $this->initCustomCreateForm($newObject->getType());
620 
621  if ($form->checkInput()) {
623  $form->initProvider($provider);
625  $provider->setIsGlobal(false);
626  $provider->setCreator($DIC->user()->getId());
627  $provider->save();
628 
629  $newObject->setProviderId($provider->getId());
630  $newObject->setProvider($provider);
631  $newObject->save();
632 
633  $newObject->setTitle($provider->getTitle());
634  $newObject->setMasteryScore($newObject->getProvider()->getMasteryScore());
635  $newObject->update();
636 
637  $this->initMetadata($newObject);
638  $DIC->ctrl()->redirectByClass([ilLTIConsumerSettingsGUI::class, ilLTIConsumeProviderSettingsGUI::class]);
639  }
640  throw new ilLtiConsumerException(
641  'form validation seems to not have worked in ilObjLTIConsumer::saveCustom()!'
642  );
643  }
644 
645  public function initMetadata(\ilObject $object): void
646  {
647  // create LOM set from scratch
648  $this->lom_services->derive()
649  ->fromBasicProperties($object->getTitle())
650  ->forObject($object->getId(), $object->getId(), $object->getType());
651 
652  // in a second step, set the keywords
653  $keywords = [];
654  foreach ($object->getProvider()->getKeywordsArray() as $keyword) {
655  if ($keyword !== '') {
656  $keywords[] = $keyword;
657  }
658  }
659  $this->lom_services->manipulate($object->getId(), $object->getId(), $object->getType())
660  ->prepareCreateOrUpdate(
661  $this->lom_services->paths()->keywords(),
662  ...$keywords
663  )->execute();
664  }
665 
670  protected function initHeaderAction(?string $a_sub_type = null, ?int $a_sub_id = null): ?\ilObjectListGUI
671  {
672  global $DIC;
673  /* @var \ILIAS\DI\Container $DIC */
674 
675  $return = parent::initHeaderAction($a_sub_type, $a_sub_id);
676 
677  if ($this->creation_mode) {
678  return $return;
679  }
680 
681  $validator = new ilCertificateDownloadValidator();
682  if ($validator->isCertificateDownloadable($DIC->user()->getId(), $this->object->getId())) {
683  $certLink = $DIC->ctrl()->getLinkTargetByClass(
684  [ilObjLTIConsumerGUI::class, ilLTIConsumerSettingsGUI::class],
686  );
687 
688  $DIC->language()->loadLanguageModule('certificate');
689 
690  $return->addCustomCommand($certLink, 'download_certificate');
691 
692  $return->addHeaderIcon(
693  'cert_icon',
694  ilUtil::getImagePath('standard/icon_cert.svg'),
695  $DIC->language()->txt('download_certificate'),
696  null,
697  null,
698  $certLink
699  );
700  }
701 
702  return $return;
703  }
704 
705  public static function _goto(string $a_target): void
706  {
707  global $DIC;
708  $main_tpl = $DIC->ui()->mainTemplate();
709  /* @var \ILIAS\DI\Container $DIC */
710  $err = $DIC['ilErr'];
711  /* @var ilErrorHandling $err */
712  $ctrl = $DIC->ctrl();
713  $request = $DIC->http()->request();
714  $access = $DIC->access();
715  $lng = $DIC->language();
716 
717  $targetParameters = explode('_', $a_target);
718  $id = (int) $targetParameters[0];
719 
720  if ($id <= 0) {
721  $err->raiseError($lng->txt('msg_no_perm_read'), $err->FATAL);
722  }
723 
724  if ($access->checkAccess('read', '', $id)) {
725  $ctrl->setTargetScript('ilias.php');
726  $ctrl->setParameterByClass(ilObjLTIConsumerGUI::class, 'ref_id', $id);
727  $ctrl->redirectByClass([ilRepositoryGUI::class, ilObjLTIConsumerGUI::class]);
728  } elseif ($access->checkAccess('visible', '', $id)) {
729  ilObjectGUI::_gotoRepositoryNode($id, 'infoScreen');
730  } elseif ($access->checkAccess('read', '', ROOT_FOLDER_ID)) {
731  $main_tpl->setOnScreenMessage(
732  'info',
733  sprintf(
734  $DIC->language()->txt('msg_no_perm_read_item'),
736  ),
737  true
738  );
739 
741  }
742 
743  $err->raiseError($DIC->language()->txt("msg_no_perm_read_lm"), $err->FATAL);
744  }
745 
749  public function executeCommand(): void
750  {
751  global $DIC;
752  /* @var \ILIAS\DI\Container $DIC */
753 
754  // TODO: general access checks (!)
755 
757  $this->prepareOutput();
758  $this->addHeaderAction();
759  }
760 
761  if (!$this->creation_mode) {
762  $this->trackObjectReadEvent();
763 
764  if ($this->object->getProvider()->hasProviderIcon()) {
765  $DIC->ui()->mainTemplate()->setTitleIcon(
766  $this->object->getProvider()->getProviderIcon()->getAbsoluteFilePath(),
767  'Icon ' . $this->object->getProvider()->getTitle()
768  );
769  }
770 
771  $link = ilLink::_getLink($this->object->getRefId(), $this->object->getType());
772  $navigationHistory = $DIC['ilNavigationHistory'];
773  /* @var ilNavigationHistory $navigationHistory */
774  $navigationHistory->addItem($this->object->getRefId(), $link, $this->object->getType());
775  }
776 
778  $obj = $this->object;
779 
780  switch ($DIC->ctrl()->getNextClass()) {
781  case strtolower(ilObjectCopyGUI::class):
782 
783  $gui = new ilObjectCopyGUI($this);
784  $gui->setType($this->getType());
785  $DIC->ctrl()->forwardCommand($gui);
786  break;
787 
788  case strtolower(ilCommonActionDispatcherGUI::class):
789 
791  $DIC->ctrl()->forwardCommand($gui);
792  break;
793 
794  case strtolower(ilLearningProgressGUI::class):
795 
796  $DIC->tabs()->activateTab(self::TAB_ID_LEARNING_PROGRESS);
797 
798  $gui = new ilLearningProgressGUI(
800  $this->object->getRefId()
801  );
802 
803  $DIC->ctrl()->forwardCommand($gui);
804 
805  break;
806 
807  case strtolower(ilObjectMetaDataGUI::class):
808 
809  $DIC->tabs()->activateTab(self::TAB_ID_METADATA);
810 
811  $gui = new ilObjectMetaDataGUI($obj);
812  $DIC->ctrl()->forwardCommand($gui);
813  break;
814 
815  case strtolower(ilPermissionGUI::class):
816 
817  $DIC->tabs()->activateTab(self::TAB_ID_PERMISSIONS);
818 
819  $gui = new ilPermissionGUI($this);
820  $DIC->ctrl()->forwardCommand($gui);
821  break;
822 
823  case strtolower(ilLTIConsumerSettingsGUI::class):
824 
825  $DIC->tabs()->activateTab(self::TAB_ID_SETTINGS);
826 
827  $gui = new ilLTIConsumerSettingsGUI($obj, $this->ltiAccess);
828  $DIC->ctrl()->forwardCommand($gui);
829  break;
830 
831  case strtolower(ilLTIConsumerXapiStatementsGUI::class):
832 
833  $DIC->tabs()->activateTab(self::TAB_ID_STATEMENTS);
834 
835  $gui = new ilLTIConsumerXapiStatementsGUI($obj);
836  $DIC->ctrl()->forwardCommand($gui);
837 
838  break;
839 
840  case strtolower(ilLTIConsumerScoringGUI::class):
841 
842  $DIC->tabs()->activateTab(self::TAB_ID_SCORING);
843 
844  $gui = new ilLTIConsumerScoringGUI($obj);
845  $DIC->ctrl()->forwardCommand($gui);
846 
847  break;
848 
849  case strtolower(ilLTIConsumerGradeSynchronizationGUI::class):
850 
851  $DIC->tabs()->activateTab(self::TAB_ID_GRADE_SYNCHRONIZATION);
852 
853  $gui = new ilLTIConsumerGradeSynchronizationGUI($obj);
854  $DIC->ctrl()->forwardCommand($gui);
855 
856  break;
857 
858  case strtolower(ilLTIConsumerContentGUI::class):
859 
860  $DIC->tabs()->activateTab(self::TAB_ID_CONTENT);
861 
862  $gui = new ilLTIConsumerContentGUI($obj);
863  $DIC->ctrl()->forwardCommand($gui);
864 
865  break;
866 
867  case strtolower(ilInfoScreenGUI::class):
868 
869  $DIC->tabs()->activateTab(self::TAB_ID_INFO);
870  $info = new ilInfoScreenGUI($this);
871  $this->configureInfoScreen($info);
872  $this->ctrl->forwardCommand($info);
873  break;
874 
875  default:
876  if ($DIC->ctrl()->getCmd() === 'save') {
877  $this->checkContentSelection();
878  } else {
879  if (isset($this->object) && !$this->isContentTabAvailable()) {
880  $DIC->ctrl()->redirectToURL($this->ctrl->getLinkTargetByClass(ilInfoScreenGUI::class));
881  }
882  $command = $DIC->ctrl()->getCmd(self::DEFAULT_CMD);
883  $this->{$command}();
884  }
885  }
886  }
887 
888  protected function checkContentSelection(): void
889  {
890  global $DIC;
891  $providerId = $this->getRequestValue('provider_id');
892  $newType = $this->getRequestValue('new_type');
893  $refId = $this->getRequestValue('ref_id');
894  if ($providerId !== null && $newType == 'lti' && $refId != null) {
896  // check if post variables from contentSelectionResponse
897  if ($DIC->http()->wrapper()->post()->has('JWT')) {
898  // ToDo:
899  } else {
900  if ($provider->isContentItem() && !empty($provider->getContentItemUrl())) {
901  $this->contentSelection($providerId, $newType, $refId, $provider);
902  } else {
903  $this->saveObject();
904  }
905  }
906  } else {
907  $this->saveObject();
908  }
909  }
910 
911  public function isContentTabAvailable(): bool
912  {
913  if (!$this->object->getOfflineStatus() &&
914  $this->object->getProvider()->getAvailability() != ilLTIConsumeProvider::AVAILABILITY_NONE) {
915  return true;
916  }
917  return false;
918  }
919 
920  protected function setTabs(): void
921  {
922  global $DIC;
923 
924  /* @var \ILIAS\DI\Container $DIC */
925  $DIC->language()->loadLanguageModule('lti');
926 
927  if (isset($this->object) && $this->isContentTabAvailable()) {
928  $DIC->tabs()->addTab(
929  self::TAB_ID_CONTENT,
930  $DIC->language()->txt(self::TAB_ID_CONTENT),
931  $DIC->ctrl()->getLinkTargetByClass(ilLTIConsumerContentGUI::class)
932  );
933  }
934 
935  $DIC->tabs()->addTab(
936  self::TAB_ID_INFO,
937  $DIC->language()->txt(self::TAB_ID_INFO),
938  $this->ctrl->getLinkTargetByClass(ilInfoScreenGUI::class)
939  );
940 
941  if ($this->ltiAccess->hasWriteAccess()) {
942  $DIC->tabs()->addTab(
943  self::TAB_ID_SETTINGS,
944  $DIC->language()->txt(self::TAB_ID_SETTINGS),
945  $DIC->ctrl()->getLinkTargetByClass(ilLTIConsumerSettingsGUI::class)
946  );
947  }
948 
949  if ($this->ltiAccess->hasStatementsAccess()) {
950  $DIC->tabs()->addTab(
951  self::TAB_ID_STATEMENTS,
952  $DIC->language()->txt(self::TAB_ID_STATEMENTS),
953  $DIC->ctrl()->getLinkTargetByClass(ilLTIConsumerXapiStatementsGUI::class)
954  );
955  }
956 
957  if ($this->ltiAccess->hasHighscoreAccess()) {
958  //$DIC->language()->loadLanguageModule('lti');
959  $DIC->tabs()->addTab(
960  self::TAB_ID_SCORING,
961  $DIC->language()->txt(self::TAB_ID_SCORING),
962  $DIC->ctrl()->getLinkTargetByClass(ilLTIConsumerScoringGUI::class)
963  );
964  }
965 
966  if ($this->object->getProvider()->isGradeSynchronization()) {
967  $DIC->tabs()->addTab(
968  self::TAB_ID_GRADE_SYNCHRONIZATION,
969  $DIC->language()->txt(self::TAB_ID_GRADE_SYNCHRONIZATION),
970  $DIC->ctrl()->getLinkTargetByClass(ilLTIConsumerGradeSynchronizationGUI::class)
971  );
972  }
973 
974  if ($this->ltiAccess->hasLearningProgressAccess() && $this->object->getProvider()->getHasOutcome()) {
975  $DIC->tabs()->addTab(
976  self::TAB_ID_LEARNING_PROGRESS,
977  $DIC->language()->txt(self::TAB_ID_LEARNING_PROGRESS),
978  $DIC->ctrl()->getLinkTargetByClass(ilLearningProgressGUI::class)
979  );
980  }
981 
982  if ($this->ltiAccess->hasWriteAccess()) {
983  $gui = new ilObjectMetaDataGUI($this->object);
984  $link = $gui->getTab();
985 
986  if (strlen($link)) {
987  $DIC->tabs()->addTab(
988  self::TAB_ID_METADATA,
989  $DIC->language()->txt('meta_data'),
990  $link
991  );
992  }
993  }
994 
995  if ($this->ltiAccess->hasEditPermissionsAccess()) {
996  $DIC->tabs()->addTab(
997  self::TAB_ID_PERMISSIONS,
998  $DIC->language()->txt(self::TAB_ID_PERMISSIONS),
999  $DIC->ctrl()->getLinkTargetByClass(ilPermissionGUI::class, 'perm')
1000  );
1001  }
1002 
1003  // if (defined('DEVMODE') && DEVMODE) {
1004  // $DIC->tabs()->addTab(
1005  // 'debug',
1006  // 'DEBUG',
1007  // $DIC->ctrl()->getLinkTarget($this, 'debug')
1008  // );
1009  // }
1010  }
1011 
1012  // protected function debug(): void
1013  // {
1014  // global $DIC;
1015  // /* @var \ILIAS\DI\Container $DIC */
1016  //
1017  // $DIC->tabs()->activateTab('debug');
1018  //
1019  // $filter = new ilCmiXapiStatementsReportFilter();
1020  // $filter->setActivityId($this->object->getActivityId());
1021  //
1022  // $aggregateEndPointUrl = str_replace(
1023  // 'data/xAPI',
1024  // 'api/statements/aggregate',
1025  // $this->object->getProvider()->getXapiLaunchUrl() // should be named endpoint not launch url
1026  // );
1027  //
1028  // $linkBuilder = new ilCmiXapiHighscoreReportLinkBuilder(
1029  // $this->object->getId(),
1030  // $aggregateEndPointUrl,
1031  // $filter
1032  // );
1033  //
1034  // $basicAuth = ilCmiXapiLrsType::buildBasicAuth(
1035  // $this->object->getProvider()->getXapiLaunchKey(),
1036  // $this->object->getProvider()->getXapiLaunchSecret()
1037  // );
1038  //
1039  // $request = new ilCmiXapiHighscoreReportRequest(
1040  // $basicAuth,
1041  // $linkBuilder
1042  // );
1043  //
1044  // try {
1045  // $report = $request->queryReport($this->object->getId());
1046  //
1047  // $DIC->ui()->mainTemplate()->setContent(
1048  // $report->getResponseDebug()
1049  // );
1050  //
1051  // //ilUtil::sendSuccess('Object ID: '.$this->object->getId());
1052  // $DIC->ui()->mainTemplate()->setOnScreenMessage('info', $linkBuilder->getPipelineDebug());
1053  // $DIC->ui()->mainTemplate()->setOnScreenMessage('question', '<pre>' . print_r($report->getTableData(), true) . '</pre>');
1054  // } catch (Exception $e) {
1055  // $this->tpl->setOnScreenMessage('failure', $e->getMessage());
1056  // }
1057  // }
1058 
1059  protected function addLocatorItems(): void
1060  {
1061  global $DIC;
1062  /* @var \ILIAS\DI\Container $DIC */
1063 
1064  $locator = $DIC['ilLocator'];
1065  /* @var ilLocatorGUI $locator */
1066  $locator->addItem(
1067  $this->object->getTitle(),
1068  $this->ctrl->getLinkTarget($this, self::DEFAULT_CMD),
1069  "",
1070  $this->object->getRefId()
1071  );
1072  }
1073 
1074  protected function trackObjectReadEvent(): void
1075  {
1076  global $DIC;
1077  /* @var \ILIAS\DI\Container $DIC */
1078 
1080  $this->object->getType(),
1081  $this->object->getRefId(),
1082  $this->object->getId(),
1083  $DIC->user()->getId()
1084  );
1085 
1086  ilLPStatusWrapper::_updateStatus($this->object->getId(), $DIC->user()->getId());
1087  }
1088 
1089  protected function launch(): void
1090  {
1092  $obj = $this->object;
1093  $this->tabs_gui->activateTab(self::TAB_ID_CONTENT);
1094  $gui = new ilLTIConsumerContentGUI($obj);
1095  $this->ctrl->forwardCommand($gui);
1096  }
1097 
1098  protected function infoScreen(): void
1099  {
1100  $this->ctrl->redirectByClass(ilInfoScreenGUI::class, "showSummary");
1101  }
1102 
1103  protected function configureInfoScreen(ilInfoScreenGUI $info): void
1104  {
1105  global $DIC;
1106  /* @var \ILIAS\DI\Container $DIC */
1107  $ilErr = $DIC['ilErr'];
1108  /* @var ilErrorHandling $ilErr */
1109 
1110  if (!$this->checkPermissionBool("visible") && !$this->checkPermissionBool("read")) {
1111  $ilErr->raiseError($DIC->language()->txt("msg_no_perm_read"), $ilErr->MESSAGE);
1112  }
1113 
1114  $this->handleAvailablityMessage();
1115 
1116 
1117  $info->enablePrivateNotes();
1118 
1119  if ($this->checkPermissionBool("read")) {
1120  $info->enableNews();
1121  }
1122 
1123  $info->enableNewsEditing(false);
1124 
1125  if ($this->checkPermissionBool("write")) {
1126  $news_set = new ilSetting("news");
1127  $enable_internal_rss = $news_set->get("enable_rss_for_internal");
1128 
1129  if ($enable_internal_rss) {
1130  //todo check
1131  $info->setBlockProperty("news", "settings", "true");
1132  $info->setBlockProperty("news", "public_notifications_option", "true");
1133  }
1134  }
1135 
1136  // standard meta data
1137  $info->addMetaDataSections($this->object->getId(), 0, $this->object->getType());
1138 
1139  if (DEVMODE) {
1140  // Development Info
1141  $info->addSection('DEVMODE Info');
1142  $info->addProperty('Local Object ID', (string) $this->object->getId());
1143  $info->addProperty('Current User ID', (string) $DIC->user()->getId());
1144  }
1145  if ($this->object->getProvider()->getHasOutcome() && ilLPObjSettings::_lookupDBMode($this->object->getId()) != 0) {
1146  $info->addSection($DIC->language()->txt("lti_info_learning_progress_section"));
1147  $info->addProperty(
1148  $DIC->language()->txt("mastery_score"),
1149  ($this->object->getMasteryScorePercent()) . ' %'
1150  );
1151  }
1152 
1153  // LTI Ressource Info about privacy
1154  $info->addSection($DIC->language()->txt("lti_info_privacy_section"));
1155 
1156  $info->addProperty(
1157  $DIC->language()->txt("lti_con_prov_url"),
1158  $this->object->getProvider()->getProviderUrl()
1159  );
1160 
1161  $info->addProperty(
1162  $DIC->language()->txt("conf_privacy_name"),
1163  $DIC->language()->txt('conf_privacy_name_' . ilObjCmiXapiGUI::getPrivacyNameString($this->object->getProvider()->getPrivacyName()))
1164  );
1165 
1166  $info->addProperty(
1167  $DIC->language()->txt("conf_privacy_ident"),
1168  $DIC->language()->txt('conf_privacy_ident_' . ilObjCmiXapiGUI::getPrivacyIdentString($this->object->getProvider()->getPrivacyIdent()))
1169  );
1170  if ($this->object->getProvider()->isExternalProvider()) {
1171  $info->addProperty(
1172  $DIC->language()->txt("lti_info_external_provider_label"),
1173  $DIC->language()->txt('lti_info_external_provider_info')
1174  );
1175  }
1176 
1177  if ($this->object->getProvider()->getUseXapi()) {
1178  $info->addProperty(
1179  $DIC->language()->txt("lti_con_prov_xapi_launch_url"),
1180  $this->object->getProvider()->getXapiLaunchUrl()
1181  );
1182  }
1183 
1184  }
1185 
1186  protected function handleAvailablityMessage(): void
1187  {
1188  global $DIC;
1189  /* @var \ILIAS\DI\Container $DIC */
1190  if ($this->object->getProvider()->getProviderUrl() == '') {
1191  $this->tpl->setOnScreenMessage('failure', $DIC->language()->txt('lti_provider_not_set_msg'));
1192  } elseif ($this->object->getProvider()->getAvailability() == ilLTIConsumeProvider::AVAILABILITY_NONE) {
1193  $this->tpl->setOnScreenMessage('failure', $DIC->language()->txt('lti_provider_not_avail_msg'));
1194  }
1195  }
1196 
1197  protected function getRequestValue(string $key): ?string
1198  {
1199  if ($this->request_wrapper->has($key)) {
1200  return $this->request_wrapper->retrieve($key, $this->refinery->kindlyTo()->string());
1201  }
1202  return null;
1203  }
1204 }
static getIdentAsId(int $userIdentMode, ilObjUser $user)
static get(string $a_var)
Class ilObjectMetaDataGUI.
ilLTIConsumerAccess $ltiAccess
addMetaDataSections(int $a_rep_obj_id, int $a_obj_id, string $a_type)
redirectByClass( $a_class, string $a_cmd=null, string $a_anchor=null, bool $is_async=false)
ilErrorHandling $error
executeCommand()
execute command
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
enableNews(bool $a_enable=true)
New implementation of ilObjectGUI.
GUI class for the workflow of copying objects.
const ROOT_FOLDER_ID
Definition: constants.php:32
createNewObject(string $newType, string $title, string $description)
Interface Observer Contains several chained tasks and infos about them.
checkAccess(string $a_permission, string $a_cmd, int $a_ref_id, string $a_type="", ?int $a_obj_id=null, ?int $a_tree_id=null)
check access for an object (provide $a_type and $a_obj_id if available for better performance) ...
addProperty(string $a_name, string $a_value, string $a_link="")
add a property to current section
initHeaderAction(?string $a_sub_type=null, ?int $a_sub_id=null)
getDidacticTemplateVar(string $type)
Get didactic template setting from creation screen.
static _gotoRepositoryNode(int $ref_id, string $cmd="")
contentSelection(string $providerId, string $newType, string $refId, ilLTIConsumeProvider $provider)
setParameterByClass(string $a_class, string $a_parameter, $a_value)
$refId
Definition: xapitoken.php:56
prepareOutput(bool $show_sub_objects=true)
if(empty($clientId)) $providerId
Definition: ltitoken.php:79
setTitle(string $title)
enableNewsEditing(bool $a_enable=true)
createObject()
create new object form
static buildContentSelectionParameters(ilLTIConsumeProvider $provider, int $refId, string $returnUrl, string $nonce)
putObjectInTree(ilObject $obj, int $parent_node_id=null)
Add object to tree at given position.
saveContentSelection(ilLTIConsumeProvider $provider, string $token)
initShowToolConfig(string $a_new_type, int $a_provider_id)
configureInfoScreen(ilInfoScreenGUI $info)
$ilErr
Definition: raiseError.php:17
initNewForm(string $a_new_type)
static getProviderIdFromClientId(string $clientId)
static getTypeByRefId(int $ref_id, bool $stop_on_error=true)
get object type by reference id
static _lookupObjId(int $ref_id)
getCreationFormsHTML(StandardForm|ilPropertyFormGUI|array $forms)
$provider
Definition: ltitoken.php:80
checkPermissionBool(string $perm, string $cmd="", string $type="", ?int $node_id=null)
static _lookupTitle(int $obj_id)
static getPrivacyIdentString(int $ident)
buildProviderSelectionForm(string $a_new_type)
$token
Definition: xapitoken.php:67
static getPrivacyNameString(int $ident)
initCustomCreateForm(string $a_new_type)
ServerRequestInterface $request
setBlockProperty(string $a_block_type, string $a_property, string $a_value)
This function is supposed to be used for block type specific properties, that should be passed to ilB...
launch()
description: > Example for rendering a Launch Glyph.
Definition: launch.php:25
Validates if an active certificate is stored in the database and can be downloaded by the user...
const CLIENT_ID
Definition: constants.php:41
static _recordReadEvent(string $a_type, int $a_ref_id, int $obj_id, int $usr_id, bool $isCatchupWriteEvents=true, $a_ext_rc=null, $a_ext_time=null)
afterSave(\ilObject $newObject)
global $DIC
Definition: shib_login.php:25
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
addSection(string $a_title)
static has($a_var)
static _goto(string $a_target)
static _lookupDBMode(int $a_obj_id)
$ltiMessageHint
Definition: ltiauth.php:50
initDynRegForm(string $a_new_type)
setTargetScript(string $a_target_script)
__construct(Container $dic, ilPlugin $plugin)
ilLocatorGUI $locator
__construct(int $a_id=0, int $a_id_type=self::REPOSITORY_NODE_ID, int $a_parent_node_id=0)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addHeaderAction()
Add header action menu.
static clear(string $a_var)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getInstanceFromAjaxCall()
(Re-)Build instance from ajax call
static _gotoRepositoryRoot(bool $raise_error=false)
Goto repository root.
static _updateStatus(int $a_obj_id, int $a_usr_id, ?object $a_obj=null, bool $a_percentage=false, bool $a_force_raise=false)
initCreateForm(string $a_new_type)
enablePrivateNotes(bool $a_enable=true)
ilAccessHandler $access