ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
ilLTIToolProvider Class Reference

LTI provider for LTI launch. More...

+ Inheritance diagram for ilLTIToolProvider:
+ Collaboration diagram for ilLTIToolProvider:

Public Member Functions

 __construct (DataConnector $dataConnector)
 ilLTIToolProvider constructor. More...
 
 handleRequest ()
 Process an incoming request. More...
 

Data Fields

 $debugMode = true
 

Protected Member Functions

 onLaunch ()
 Process a valid launch request. More...
 
 onContentItem ()
 Process a valid content-item request. More...
 
 onRegister ()
 Process a valid tool proxy registration request. More...
 
 onError ()
 Process a response to an invalid request. More...
 

Protected Attributes

 $logger = null
 

Private Member Functions

 doCallback ($method=null)
 Call any callback function for the requested action. More...
 
 result ()
 Perform the result of an action. More...
 
 authenticate ()
 Check the authenticity of the LTI launch request. More...
 
 checkForShare ()
 Check if a share arrangement is in place. More...
 
 checkValue ($value, $values, $reason)
 Validate a parameter value from an array of permitted values. More...
 

Static Private Attributes

static $LTI_VERSIONS = array(self::LTI_VERSION1, self::LTI_VERSION2)
 Permitted LTI versions for messages. More...
 
static $MESSAGE_TYPES
 List of supported message types and associated class methods. More...
 
static $METHOD_NAMES
 List of supported message types and associated class methods. More...
 
static $LTI_CONSUMER_SETTING_NAMES = array('custom_tc_profile_url', 'custom_system_setting_url')
 Names of LTI parameters to be retained in the consumer settings property. More...
 
static $LTI_CONTEXT_SETTING_NAMES
 Names of LTI parameters to be retained in the context settings property. More...
 
static $LTI_RESOURCE_LINK_SETTING_NAMES
 Names of LTI parameters to be retained in the resource link settings property. More...
 
static $CUSTOM_SUBSTITUTION_VARIABLES
 Names of LTI custom parameter substitution variables (or capabilities) and their associated default message parameter names. More...
 

Detailed Description

Constructor & Destructor Documentation

◆ __construct()

ilLTIToolProvider::__construct ( DataConnector  $dataConnector)

ilLTIToolProvider constructor.

Parameters
DataConnector$dataConnector

Definition at line 122 of file class.ilLTIToolProvider.php.

123 {
124 global $DIC;
125
126 $this->logger = $DIC->logger()->lti();
127 parent::__construct($dataConnector);
128 }
global $DIC
Definition: saml.php:7

References $DIC.

Member Function Documentation

◆ authenticate()

ilLTIToolProvider::authenticate ( )
private

Check the authenticity of the LTI launch request.

The consumer, resource link and user objects will be initialised if the request is valid.

Returns
boolean True if the request has been successfully validated.

foreach ($this->constraints as $name => $constraint) { if ($constraint['required']) { if (!in_array($name, $capabilities) && !in_array($name, array_flip($capabilities))) { $missing[$name] = true; } } } if (!empty($missing)) { ksort($missing); $this->reason = 'Required capability not offered - \'' . implode('\', \'', array_keys($missing)) . '\''; $this->ok = false; }

Definition at line 302 of file class.ilLTIToolProvider.php.

303 {
304
305// Get the consumer
306 $doSaveConsumer = false;
307 // Check all required launch parameters
308 $this->ok = isset($_POST['lti_message_type']) && array_key_exists($_POST['lti_message_type'], self::$MESSAGE_TYPES);
309 if (!$this->ok) {
310 $this->reason = 'Invalid or missing lti_message_type parameter.';
311 }
312 if ($this->ok) {
313 $this->ok = isset($_POST['lti_version']) && in_array($_POST['lti_version'], self::$LTI_VERSIONS);
314 if (!$this->ok) {
315 $this->reason = 'Invalid or missing lti_version parameter.';
316 }
317 }
318 if ($this->ok) {
319 if ($_POST['lti_message_type'] === 'basic-lti-launch-request') {
320 $this->ok = isset($_POST['resource_link_id']) && (strlen(trim($_POST['resource_link_id'])) > 0);
321 if (!$this->ok) {
322 $this->reason = 'Missing resource link ID.';
323 }
324 } elseif ($_POST['lti_message_type'] === 'ContentItemSelectionRequest') {
325 if (isset($_POST['accept_media_types']) && (strlen(trim($_POST['accept_media_types'])) > 0)) {
326 $mediaTypes = array_filter(explode(',', str_replace(' ', '', $_POST['accept_media_types'])), 'strlen');
327 $mediaTypes = array_unique($mediaTypes);
328 $this->ok = count($mediaTypes) > 0;
329 if (!$this->ok) {
330 $this->reason = 'No accept_media_types found.';
331 } else {
332 $this->mediaTypes = $mediaTypes;
333 }
334 } else {
335 $this->ok = false;
336 }
337 if ($this->ok && isset($_POST['accept_presentation_document_targets']) && (strlen(trim($_POST['accept_presentation_document_targets'])) > 0)) {
338 $documentTargets = array_filter(explode(',', str_replace(' ', '', $_POST['accept_presentation_document_targets'])), 'strlen');
339 $documentTargets = array_unique($documentTargets);
340 $this->ok = count($documentTargets) > 0;
341 if (!$this->ok) {
342 $this->reason = 'Missing or empty accept_presentation_document_targets parameter.';
343 } else {
344 foreach ($documentTargets as $documentTarget) {
345 $this->ok = $this->checkValue(
346 $documentTarget,
347 array('embed', 'frame', 'iframe', 'window', 'popup', 'overlay', 'none'),
348 'Invalid value in accept_presentation_document_targets parameter: %s.'
349 );
350 if (!$this->ok) {
351 break;
352 }
353 }
354 if ($this->ok) {
355 $this->documentTargets = $documentTargets;
356 }
357 }
358 } else {
359 $this->ok = false;
360 }
361 if ($this->ok) {
362 $this->ok = isset($_POST['content_item_return_url']) && (strlen(trim($_POST['content_item_return_url'])) > 0);
363 if (!$this->ok) {
364 $this->reason = 'Missing content_item_return_url parameter.';
365 }
366 }
367 } elseif ($_POST['lti_message_type'] == 'ToolProxyRegistrationRequest') {
368 $this->ok = ((isset($_POST['reg_key']) && (strlen(trim($_POST['reg_key'])) > 0)) &&
369 (isset($_POST['reg_password']) && (strlen(trim($_POST['reg_password'])) > 0)) &&
370 (isset($_POST['tc_profile_url']) && (strlen(trim($_POST['tc_profile_url'])) > 0)) &&
371 (isset($_POST['launch_presentation_return_url']) && (strlen(trim($_POST['launch_presentation_return_url'])) > 0)));
372 if ($this->debugMode && !$this->ok) {
373 $this->reason = 'Missing message parameters.';
374 }
375 }
376 }
377 $now = time();
378
379 $this->logger->debug('Checking consumer key...');
380
381 // Check consumer key
382 if ($this->ok && ($_POST['lti_message_type'] != 'ToolProxyRegistrationRequest')) {
383 $this->ok = isset($_POST['oauth_consumer_key']);
384 if (!$this->ok) {
385 $this->reason = 'Missing consumer key.';
386 }
387 if ($this->ok) {
388 // $this->consumer = new ToolConsumer($_POST['oauth_consumer_key'], $this->dataConnector);
389 $this->consumer = new ilLTIToolConsumer($_POST['oauth_consumer_key'], $this->dataConnector);
390 $this->ok = !is_null($this->consumer->created);
391 if (!$this->ok) {
392 $this->reason = 'Invalid consumer key.';
393 }
394 }
395 if ($this->ok) {
396 $today = date('Y-m-d', $now);
397 if (is_null($this->consumer->lastAccess)) {
398 $doSaveConsumer = true;
399 } else {
400 $last = date('Y-m-d', $this->consumer->lastAccess);
401 $doSaveConsumer = $doSaveConsumer || ($last !== $today);
402 }
403 $this->consumer->last_access = $now;
404 try {
405 $store = new OAuthDataStore($this);
406 $server = new OAuth\OAuthServer($store);
407 $method = new OAuth\OAuthSignatureMethod_HMAC_SHA1();
408 $server->add_signature_method($method);
409 $request = OAuth\OAuthRequest::from_request();
410 $res = $server->verify_request($request);
411 } catch (\Exception $e) {
412 $this->ok = false;
413 if (empty($this->reason)) {
414 if ($this->debugMode) {
415 $consumer = new OAuth\OAuthConsumer($this->consumer->getKey(), $this->consumer->secret);
416 $signature = $request->build_signature($method, $consumer, false);
417 $this->reason = $e->getMessage();
418 if (empty($this->reason)) {
419 $this->reason = 'OAuth exception';
420 }
421 $this->details[] = 'Timestamp: ' . time();
422 $this->details[] = "Signature: {$signature}";
423 $this->details[] = "Base string: {$request->base_string}]";
424 } else {
425 $this->reason = 'OAuth signature check failed - perhaps an incorrect secret or timestamp.';
426 }
427 }
428 }
429 }
430 // $this->ok = true; //ACHTUNG Problem Signature bei M.
431 if ($this->ok) {
432 $today = date('Y-m-d', $now);
433 if (is_null($this->consumer->lastAccess)) {
434 $doSaveConsumer = true;
435 } else {
436 $last = date('Y-m-d', $this->consumer->lastAccess);
437 $doSaveConsumer = $doSaveConsumer || ($last !== $today);
438 }
439 $this->consumer->last_access = $now;
440 if ($this->consumer->protected) {
441 if (!is_null($this->consumer->consumerGuid)) {
442 $this->ok = empty($_POST['tool_consumer_instance_guid']) ||
443 ($this->consumer->consumerGuid === $_POST['tool_consumer_instance_guid']);
444 if (!$this->ok) {
445 $this->reason = 'Request is from an invalid tool consumer.';
446 }
447 } else {
448 $this->ok = isset($_POST['tool_consumer_instance_guid']);
449 if (!$this->ok) {
450 $this->reason = 'A tool consumer GUID must be included in the launch request.';
451 }
452 }
453 }
454 if ($this->ok) {
455 $this->ok = $this->consumer->enabled;
456 if (!$this->ok) {
457 $this->reason = 'Tool consumer has not been enabled by the tool provider.';
458 }
459 }
460 if ($this->ok) {
461 $this->ok = is_null($this->consumer->enableFrom) || ($this->consumer->enableFrom <= $now);
462 if ($this->ok) {
463 $this->ok = is_null($this->consumer->enableUntil) || ($this->consumer->enableUntil > $now);
464 if (!$this->ok) {
465 $this->reason = 'Tool consumer access has expired.';
466 }
467 } else {
468 $this->reason = 'Tool consumer access is not yet available.';
469 }
470 }
471 }
472 // Validate other message parameter values
473 if ($this->ok) {
474 if ($_POST['lti_message_type'] === 'ContentItemSelectionRequest') {
475 if (isset($_POST['accept_unsigned'])) {
476 $this->ok = $this->checkValue($_POST['accept_unsigned'], array('true', 'false'), 'Invalid value for accept_unsigned parameter: %s.');
477 }
478 if ($this->ok && isset($_POST['accept_multiple'])) {
479 $this->ok = $this->checkValue($_POST['accept_multiple'], array('true', 'false'), 'Invalid value for accept_multiple parameter: %s.');
480 }
481 if ($this->ok && isset($_POST['accept_copy_advice'])) {
482 $this->ok = $this->checkValue($_POST['accept_copy_advice'], array('true', 'false'), 'Invalid value for accept_copy_advice parameter: %s.');
483 }
484 if ($this->ok && isset($_POST['auto_create'])) {
485 $this->ok = $this->checkValue($_POST['auto_create'], array('true', 'false'), 'Invalid value for auto_create parameter: %s.');
486 }
487 if ($this->ok && isset($_POST['can_confirm'])) {
488 $this->ok = $this->checkValue($_POST['can_confirm'], array('true', 'false'), 'Invalid value for can_confirm parameter: %s.');
489 }
490 } elseif (isset($_POST['launch_presentation_document_target'])) {
491 $this->ok = $this->checkValue(
492 $_POST['launch_presentation_document_target'],
493 array('embed', 'frame', 'iframe', 'window', 'popup', 'overlay'),
494 'Invalid value for launch_presentation_document_target parameter: %s.'
495 );
496 }
497 }
498 }
499
500 if ($this->ok && ($_POST['lti_message_type'] === 'ToolProxyRegistrationRequest')) {
501 $this->ok = $_POST['lti_version'] == self::LTI_VERSION2;
502 if (!$this->ok) {
503 $this->reason = 'Invalid lti_version parameter';
504 }
505 if ($this->ok) {
506 $http = new HTTPMessage($_POST['tc_profile_url'], 'GET', null, 'Accept: application/vnd.ims.lti.v2.toolconsumerprofile+json');
507 $this->ok = $http->send();
508 if (!$this->ok) {
509 $this->reason = 'Tool consumer profile not accessible.';
510 } else {
511 $tcProfile = json_decode($http->response);
512 $this->ok = !is_null($tcProfile);
513 if (!$this->ok) {
514 $this->reason = 'Invalid JSON in tool consumer profile.';
515 }
516 }
517 }
518 // Check for required capabilities
519 if ($this->ok) {
520 // $this->consumer = new ToolConsumer($_POST['reg_key'], $this->dataConnector);
521 $this->consumer = new ilLTIToolConsumer($_POST['oauth_consumer_key'], $this->dataConnector);
522 $this->consumer->profile = $tcProfile;
523 $capabilities = $this->consumer->profile->capability_offered;
524 $missing = array();
525 foreach ($this->resourceHandlers as $resourceHandler) {
526 foreach ($resourceHandler->requiredMessages as $message) {
527 if (!in_array($message->type, $capabilities)) {
528 $missing[$message->type] = true;
529 }
530 }
531 }
532 // smeyer: 21 Nov 2018 constraints are not supported in the moment and private in the base class.
547 }
548 // Check for required services
549 if ($this->ok) {
550 foreach ($this->requiredServices as $service) {
551 foreach ($service->formats as $format) {
552 if (!$this->findService($format, $service->actions)) {
553 if ($this->ok) {
554 $this->reason = 'Required service(s) not offered - ';
555 $this->ok = false;
556 } else {
557 $this->reason .= ', ';
558 }
559 $this->reason .= "'{$format}' [" . implode(', ', $service->actions) . ']';
560 }
561 }
562 }
563 }
564 if ($this->ok) {
565 if ($_POST['lti_message_type'] === 'ToolProxyRegistrationRequest') {
566 $this->consumer->profile = $tcProfile;
567 $this->consumer->secret = $_POST['reg_password'];
568 $this->consumer->ltiVersion = $_POST['lti_version'];
569 $this->consumer->name = $tcProfile->product_instance->service_owner->service_owner_name->default_value;
570 $this->consumer->consumerName = $this->consumer->name;
571 $this->consumer->consumerVersion = "{$tcProfile->product_instance->product_info->product_family->code}-{$tcProfile->product_instance->product_info->product_version}";
572 $this->consumer->consumerGuid = $tcProfile->product_instance->guid;
573 $this->consumer->enabled = true;
574 $this->consumer->protected = true;
575 $doSaveConsumer = true;
576 }
577 }
578 } elseif ($this->ok && !empty($_POST['custom_tc_profile_url']) && empty($this->consumer->profile)) {
579 $http = new HTTPMessage($_POST['custom_tc_profile_url'], 'GET', null, 'Accept: application/vnd.ims.lti.v2.toolconsumerprofile+json');
580 if ($http->send()) {
581 $tcProfile = json_decode($http->response);
582 if (!is_null($tcProfile)) {
583 $this->consumer->profile = $tcProfile;
584 $doSaveConsumer = true;
585 }
586 }
587 }
588 //ACHTUNG HIER TODO UWE
589 // Validate message parameter constraints
590 // if ($this->ok) {
591 // $invalidParameters = array();
592 // foreach ($this->constraints as $name => $constraint) {
593 // // if (empty($constraint['messages']) || in_array($_POST['lti_message_type'], $constraint['messages'])) {
594 // // $ok = true;
595 // // if ($constraint['required']) {
596 // // if (!isset($_POST[$name]) || (strlen(trim($_POST[$name])) <= 0)) {
597 // // $invalidParameters[] = "{$name} (missing)";
598 // // $ok = false;
599 // // }
600 // // }
601 // // if ($ok && !is_null($constraint['max_length']) && isset($_POST[$name])) {
602 // // if (strlen(trim($_POST[$name])) > $constraint['max_length']) {
603 // // $invalidParameters[] = "{$name} (too long)";
604 // // }
605 // // }
606 // // }
607 // }
608 // if (count($invalidParameters) > 0) {
609 // $this->ok = false;
610 // if (empty($this->reason)) {
611 // $this->reason = 'Invalid parameter(s): ' . implode(', ', $invalidParameters) . '.';
612 // }
613 // }
614 // }
615
616 $this->logger->debug('Still ok: ' . ($this->ok ? '1' : '0'));
617 if (!$this->ok) {
618 $this->logger->debug('Reason: ' . $this->reason);
619 }
620
621 if ($this->ok) {
622
623// Set the request context
624 if (isset($_POST['context_id'])) {
625 $this->context = Context::fromConsumer($this->consumer, trim($_POST['context_id']));
626 $title = '';
627 if (isset($_POST['context_title'])) {
628 $title = trim($_POST['context_title']);
629 }
630 if (empty($title)) {
631 $title = "Course {$this->context->getId()}";
632 }
633 $this->context->title = $title;
634 }
635
636 // Set the request resource link
637 if (isset($_POST['resource_link_id'])) {
638 $contentItemId = '';
639 if (isset($_POST['custom_content_item_id'])) {
640 $contentItemId = $_POST['custom_content_item_id'];
641 }
642 $this->resourceLink = ResourceLink::fromConsumer($this->consumer, trim($_POST['resource_link_id']), $contentItemId);
643 if (!empty($this->context)) {
644 $this->resourceLink->setContextId($this->context->getRecordId());
645 }
646 $title = '';
647 if (isset($_POST['resource_link_title'])) {
648 $title = trim($_POST['resource_link_title']);
649 }
650 if (empty($title)) {
651 $title = "Resource {$this->resourceLink->getId()}";
652 }
653 $this->resourceLink->title = $title;
654 // Delete any existing custom parameters
655 foreach ($this->consumer->getSettings() as $name => $value) {
656 if (strpos($name, 'custom_') === 0) {
657 $this->consumer->setSetting($name);
658 $doSaveConsumer = true;
659 }
660 }
661 if (!empty($this->context)) {
662 foreach ($this->context->getSettings() as $name => $value) {
663 if (strpos($name, 'custom_') === 0) {
664 $this->context->setSetting($name);
665 }
666 }
667 }
668 foreach ($this->resourceLink->getSettings() as $name => $value) {
669 if (strpos($name, 'custom_') === 0) {
670 $this->resourceLink->setSetting($name);
671 }
672 }
673 // Save LTI parameters
674 foreach (self::$LTI_CONSUMER_SETTING_NAMES as $name) {
675 if (isset($_POST[$name])) {
676 $this->consumer->setSetting($name, $_POST[$name]);
677 } else {
678 $this->consumer->setSetting($name);
679 }
680 }
681 if (!empty($this->context)) {
682 foreach (self::$LTI_CONTEXT_SETTING_NAMES as $name) {
683 if (isset($_POST[$name])) {
684 $this->context->setSetting($name, $_POST[$name]);
685 } else {
686 $this->context->setSetting($name);
687 }
688 }
689 }
690 foreach (self::$LTI_RESOURCE_LINK_SETTING_NAMES as $name) {
691 if (isset($_POST[$name])) {
692 $this->resourceLink->setSetting($name, $_POST[$name]);
693 } else {
694 $this->resourceLink->setSetting($name);
695 }
696 }
697 // Save other custom parameters
698 foreach ($_POST as $name => $value) {
699 if ((strpos($name, 'custom_') === 0) &&
700 !in_array($name, array_merge(self::$LTI_CONSUMER_SETTING_NAMES, self::$LTI_CONTEXT_SETTING_NAMES, self::$LTI_RESOURCE_LINK_SETTING_NAMES))) {
701 $this->resourceLink->setSetting($name, $value);
702 }
703 }
704 }
705
706 // Set the user instance
707 $userId = '';
708 if (isset($_POST['user_id'])) {
709 $userId = trim($_POST['user_id']);
710 }
711
712 $this->user = User::fromResourceLink($this->resourceLink, $userId);
713
714 // Set the user name
715 $firstname = (isset($_POST['lis_person_name_given'])) ? $_POST['lis_person_name_given'] : '';
716 $lastname = (isset($_POST['lis_person_name_family'])) ? $_POST['lis_person_name_family'] : '';
717 $fullname = (isset($_POST['lis_person_name_full'])) ? $_POST['lis_person_name_full'] : '';
718 $this->user->setNames($firstname, $lastname, $fullname);
719
720 // Set the user email
721 $email = (isset($_POST['lis_person_contact_email_primary'])) ? $_POST['lis_person_contact_email_primary'] : '';
722 $this->user->setEmail($email, $this->defaultEmail);
723
724 // Set the user image URI
725 if (isset($_POST['user_image'])) {
726 $this->user->image = $_POST['user_image'];
727 }
728
729 // Set the user roles
730 if (isset($_POST['roles'])) {
731 $this->user->roles = self::parseRoles($_POST['roles']);
732 }
733
734 // Initialise the consumer and check for changes
735 $this->consumer->defaultEmail = $this->defaultEmail;
736 if ($this->consumer->ltiVersion !== $_POST['lti_version']) {
737 $this->consumer->ltiVersion = $_POST['lti_version'];
738 $doSaveConsumer = true;
739 }
740 if (isset($_POST['tool_consumer_instance_name'])) {
741 if ($this->consumer->consumerName !== $_POST['tool_consumer_instance_name']) {
742 $this->consumer->consumerName = $_POST['tool_consumer_instance_name'];
743 $doSaveConsumer = true;
744 }
745 }
746 if (isset($_POST['tool_consumer_info_product_family_code'])) {
747 $version = $_POST['tool_consumer_info_product_family_code'];
748 if (isset($_POST['tool_consumer_info_version'])) {
749 $version .= "-{$_POST['tool_consumer_info_version']}";
750 }
751 // do not delete any existing consumer version if none is passed
752 if ($this->consumer->consumerVersion !== $version) {
753 $this->consumer->consumerVersion = $version;
754 $doSaveConsumer = true;
755 }
756 } elseif (isset($_POST['ext_lms']) && ($this->consumer->consumerName !== $_POST['ext_lms'])) {
757 $this->consumer->consumerVersion = $_POST['ext_lms'];
758 $doSaveConsumer = true;
759 }
760 if (isset($_POST['tool_consumer_instance_guid'])) {
761 if (is_null($this->consumer->consumerGuid)) {
762 $this->consumer->consumerGuid = $_POST['tool_consumer_instance_guid'];
763 $doSaveConsumer = true;
764 } elseif (!$this->consumer->protected) {
765 $doSaveConsumer = ($this->consumer->consumerGuid !== $_POST['tool_consumer_instance_guid']);
766 if ($doSaveConsumer) {
767 $this->consumer->consumerGuid = $_POST['tool_consumer_instance_guid'];
768 }
769 }
770 }
771 if (isset($_POST['launch_presentation_css_url'])) {
772 if ($this->consumer->cssPath !== $_POST['launch_presentation_css_url']) {
773 $this->consumer->cssPath = $_POST['launch_presentation_css_url'];
774 $doSaveConsumer = true;
775 }
776 } elseif (isset($_POST['ext_launch_presentation_css_url']) &&
777 ($this->consumer->cssPath !== $_POST['ext_launch_presentation_css_url'])) {
778 $this->consumer->cssPath = $_POST['ext_launch_presentation_css_url'];
779 $doSaveConsumer = true;
780 } elseif (!empty($this->consumer->cssPath)) {
781 $this->consumer->cssPath = null;
782 $doSaveConsumer = true;
783 }
784 }
785
786 // Persist changes to consumer
787 if ($doSaveConsumer) {
788 $this->consumer->save();
789 }
790 if ($this->ok && isset($this->context)) {
791 $this->context->save();//ACHTUNG TODO UWE
792 }
793
794 $this->logger->dump(get_class($this->context));
795
796
797 if ($this->ok && isset($this->resourceLink)) {
798
799// Check if a share arrangement is in place for this resource link
800 // $this->ok = $this->checkForShare();//ACHTUNG TODO UWE
801 // Persist changes to resource link
802 $this->resourceLink->save();
803
804 // Save the user instance
805 if (isset($_POST['lis_result_sourcedid'])) {
806 if ($this->user->ltiResultSourcedId !== $_POST['lis_result_sourcedid']) {
807 $this->user->ltiResultSourcedId = $_POST['lis_result_sourcedid'];
808 $this->user->save();
809 }
810 } elseif (!empty($this->user->ltiResultSourcedId)) {
811 $this->user->ltiResultSourcedId = '';
812 $this->user->save();
813 }
814 }
815 // die ($this->reason.'---'.$this->ok);//ACHTUNG WEG!
816 return $this->ok;
817 }
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
user()
Definition: user.php:4
$_POST["username"]
Class to represent an HTTP message.
Definition: HTTPMessage.php:15
Class to represent an OAuth Data Store.
LTI provider for LTI launch.
checkValue($value, $values, $reason)
Validate a parameter value from an array of permitted values.
$consumer
Definition: demo.php:30
if(! $oauthconfig->getBoolean('getUserInfo.enable', FALSE)) $store
Definition: getUserInfo.php:11
$server
Definition: getUserInfo.php:12
$service
Definition: login.php:15
if($format !==null) $name
Definition: metadata.php:146
$format
Definition: metadata.php:141
if( $orgName !==null) if($spconfig->hasValue('contacts')) $email
Definition: metadata.php:193
catch(Exception $e) $message
$http
Definition: raiseError.php:7
foreach($_POST as $key=> $value) $res

References $_POST, $consumer, $email, $format, $http, $message, $name, $ok, $res, $server, $service, $store, $title, $version, checkValue(), date, and user().

Referenced by handleRequest().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ checkForShare()

ilLTIToolProvider::checkForShare ( )
private

Check if a share arrangement is in place.

Returns
boolean True if no error is reported

Definition at line 824 of file class.ilLTIToolProvider.php.

825 {
826 $ok = true;
827 $doSaveResourceLink = true;
828
829 $id = $this->resourceLink->primaryResourceLinkId;
830
831 $shareRequest = isset($_POST['custom_share_key']) && !empty($_POST['custom_share_key']);
832 if ($shareRequest) {
833 if (!$this->allowSharing) {
834 $ok = false;
835 $this->reason = 'Your sharing request has been refused because sharing is not being permitted.';
836 } else {
837 // Check if this is a new share key
838 $shareKey = new ResourceLinkShareKey($this->resourceLink, $_POST['custom_share_key']);
839 if (!is_null($shareKey->primaryConsumerKey) && !is_null($shareKey->primaryResourceLinkId)) {
840 // Update resource link with sharing primary resource link details
841 $key = $shareKey->primaryConsumerKey;
842 $id = $shareKey->primaryResourceLinkId;
843 $ok = ($key !== $this->consumer->getKey()) || ($id != $this->resourceLink->getId());
844 if ($ok) {
845 $this->resourceLink->primaryConsumerKey = $key;
846 $this->resourceLink->primaryResourceLinkId = $id;
847 $this->resourceLink->shareApproved = $shareKey->autoApprove;
848 $ok = $this->resourceLink->save();
849 if ($ok) {
850 $doSaveResourceLink = false;
851 $this->user->getResourceLink()->primaryConsumerKey = $key;
852 $this->user->getResourceLink()->primaryResourceLinkId = $id;
853 $this->user->getResourceLink()->shareApproved = $shareKey->autoApprove;
854 $this->user->getResourceLink()->updated = time();
855 // Remove share key
856 $shareKey->delete();
857 } else {
858 $this->reason = 'An error occurred initialising your share arrangement.';
859 }
860 } else {
861 $this->reason = 'It is not possible to share your resource link with yourself.';
862 }
863 }
864 if ($ok) {
865 $ok = !is_null($key);
866 if (!$ok) {
867 $this->reason = 'You have requested to share a resource link but none is available.';
868 } else {
869 $ok = (!is_null($this->user->getResourceLink()->shareApproved) && $this->user->getResourceLink()->shareApproved);
870 if (!$ok) {
871 $this->reason = 'Your share request is waiting to be approved.';
872 }
873 }
874 }
875 }
876 } else {
877 // Check no share is in place
878 $ok = is_null($id);
879 if (!$ok) {
880 $this->reason = 'You have not requested to share a resource link but an arrangement is currently in place.';
881 }
882 }
883 // Look up primary resource link
884 if ($ok && !is_null($id)) {
885 // $consumer = new ToolConsumer($key, $this->dataConnector);
886 $consumer = new ilLTIToolConsumer($_POST['oauth_consumer_key'], $this->dataConnector);
887 $ok = !is_null($consumer->created);
888 if ($ok) {
889 $resourceLink = ResourceLink::fromConsumer($consumer, $id);
890 $ok = !is_null($resourceLink->created);
891 }
892 if ($ok) {
893 if ($doSaveResourceLink) {
894 $this->resourceLink->save();
895 }
896 $this->resourceLink = $resourceLink;
897 } else {
898 $this->reason = 'Unable to load resource link being shared.';
899 }
900 }
901
902 return $ok;
903 }
Class to represent a tool consumer resource link share key.
$key
Definition: croninfo.php:18
if(!array_key_exists('StateId', $_REQUEST)) $id

References $_POST, $consumer, $id, $key, $ok, and user().

+ Here is the call graph for this function:

◆ checkValue()

ilLTIToolProvider::checkValue (   $value,
  $values,
  $reason 
)
private

Validate a parameter value from an array of permitted values.

Returns
boolean True if value is valid

Definition at line 909 of file class.ilLTIToolProvider.php.

910 {
911 $ok = in_array($value, $values);
912 if (!$ok && !empty($reason)) {
913 $this->reason = sprintf($reason, $value);
914 }
915
916 return $ok;
917 }
sprintf('%.4f', $callTime)

References $ok, and sprintf.

Referenced by authenticate().

+ Here is the caller graph for this function:

◆ doCallback()

ilLTIToolProvider::doCallback (   $method = null)
private

Call any callback function for the requested action.

This function may set the redirect_url and output properties.

Returns
boolean True if no error reported

Definition at line 216 of file class.ilLTIToolProvider.php.

217 {
218 $callback = $method;
219 if (is_null($callback)) {
220 $callback = self::$METHOD_NAMES[$_POST['lti_message_type']];
221 }
222 if (method_exists($this, $callback)) {
223 $result = $this->$callback(); // ACHTUNG HIER PROBLEM UK
224 } elseif (is_null($method) && $this->ok) {
225 $this->ok = false;
226 $this->reason = "Message type not supported: {$_POST['lti_message_type']}";
227 }
228 if ($this->ok && ($_POST['lti_message_type'] == 'ToolProxyRegistrationRequest')) {
229 $this->consumer->save();
230 }
231 }
$result

References $_POST, and $result.

Referenced by handleRequest().

+ Here is the caller graph for this function:

◆ handleRequest()

ilLTIToolProvider::handleRequest ( )

Process an incoming request.

Definition at line 134 of file class.ilLTIToolProvider.php.

135 {
136 if ($this->ok) {
137 if ($this->authenticate()) {
138 $this->doCallback();
139 }
140 }
141 // if return url is given, this redirects in case of errors
142 $this->result();
143 return $this->ok;
144 }
authenticate()
Check the authenticity of the LTI launch request.
doCallback($method=null)
Call any callback function for the requested action.
result()
Perform the result of an action.

References $ok, authenticate(), doCallback(), and result().

+ Here is the call graph for this function:

◆ onContentItem()

ilLTIToolProvider::onContentItem ( )
protected

Process a valid content-item request.

Returns
boolean True if no error

Definition at line 176 of file class.ilLTIToolProvider.php.

177 {
178 $this->onError();
179 }
onError()
Process a response to an invalid request.

References onError().

+ Here is the call graph for this function:

◆ onError()

ilLTIToolProvider::onError ( )
protected

Process a response to an invalid request.

Returns
boolean True if no further error processing required

Definition at line 196 of file class.ilLTIToolProvider.php.

197 {
198 // only return error status
199 return $this->ok;
200
201 //$this->doCallback('onError');
202 // return parent::onError(); //Stefan M.
203 }

References $ok.

Referenced by onContentItem(), onRegister(), and result().

+ Here is the caller graph for this function:

◆ onLaunch()

ilLTIToolProvider::onLaunch ( )
protected

Process a valid launch request.

Returns
boolean True if no error

Definition at line 155 of file class.ilLTIToolProvider.php.

156 {
157 // save/update current user
158 if ($this->user instanceof User) {
159 $this->user->save();
160 }
161
162 if ($this->context instanceof Context) {
163 $this->context->save();
164 }
165
166 if ($this->resourceLink instanceof ResourceLink) {
167 $this->resourceLink->save();
168 }
169 }
Class to represent a tool consumer context.
Definition: Context.php:18
Class to represent a tool consumer user.
Definition: User.php:16

References user().

+ Here is the call graph for this function:

◆ onRegister()

ilLTIToolProvider::onRegister ( )
protected

Process a valid tool proxy registration request.

Returns
boolean True if no error

Definition at line 186 of file class.ilLTIToolProvider.php.

187 {
188 $this->onError();
189 }

References onError().

+ Here is the call graph for this function:

◆ result()

ilLTIToolProvider::result ( )
private

Perform the result of an action.

This function may redirect the user to another URL rather than returning a value.

Returns
string Output to be displayed (redirection, or display HTML or message)

Definition at line 240 of file class.ilLTIToolProvider.php.

241 {
242 $ok = false;
243 if (!$this->ok) {
244 $ok = $this->onError();
245 }
246 if (!$ok) {
247 if (!$this->ok) {
248 // If not valid, return an error message to the tool consumer if a return URL is provided
249 if (!empty($this->returnUrl)) {
250 $errorUrl = $this->returnUrl;
251 if (strpos($errorUrl, '?') === false) {
252 $errorUrl .= '?';
253 } else {
254 $errorUrl .= '&';
255 }
256 if ($this->debugMode && !is_null($this->reason)) {
257 $errorUrl .= 'lti_errormsg=' . urlencode("Debug error: $this->reason");
258 } else {
259 $errorUrl .= 'lti_errormsg=' . urlencode($this->message);
260 if (!is_null($this->reason)) {
261 $errorUrl .= '&lti_errorlog=' . urlencode("Debug error: $this->reason");
262 }
263 }
264 if (!is_null($this->consumer) && isset($_POST['lti_message_type']) && ($_POST['lti_message_type'] === 'ContentItemSelectionRequest')) {
265 $formParams = array();
266 if (isset($_POST['data'])) {
267 $formParams['data'] = $_POST['data'];
268 }
269 $version = (isset($_POST['lti_version'])) ? $_POST['lti_version'] : self::LTI_VERSION1;
270 $formParams = $this->consumer->signParameters($errorUrl, 'ContentItemSelection', $version, $formParams);
271 $page = self::sendForm($errorUrl, $formParams);
272 echo $page;
273 } else {
274 header("Location: {$errorUrl}");
275 }
276 exit; //ACHTUNG HIER PROBLEM UK
277 } else {
278 if (!is_null($this->errorOutput)) {
279 echo $this->errorOutput;
280 } elseif ($this->debugMode && !empty($this->reason)) {
281 echo "Debug error: {$this->reason}";
282 } else {
283 echo "Error: {$this->message}";
284 }
285 }
286 } elseif (!is_null($this->redirectUrl)) {
287 header("Location: {$this->redirectUrl}");
288 exit;
289 } elseif (!is_null($this->output)) {
290 echo $this->output;
291 }
292 }
293 }
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\s+" &#(? foreach( $entity_files as $file) $output

References $_POST, $ok, $output, $version, exit, and onError().

Referenced by handleRequest().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $CUSTOM_SUBSTITUTION_VARIABLES

array ilLTIToolProvider::$CUSTOM_SUBSTITUTION_VARIABLES
staticprivate

Names of LTI custom parameter substitution variables (or capabilities) and their associated default message parameter names.

Definition at line 83 of file class.ilLTIToolProvider.php.

◆ $debugMode

ilLTIToolProvider::$debugMode = true

Definition at line 34 of file class.ilLTIToolProvider.php.

◆ $logger

ilLTIToolProvider::$logger = null
protected

Definition at line 31 of file class.ilLTIToolProvider.php.

◆ $LTI_CONSUMER_SETTING_NAMES

array ilLTIToolProvider::$LTI_CONSUMER_SETTING_NAMES = array('custom_tc_profile_url', 'custom_system_setting_url')
staticprivate

Names of LTI parameters to be retained in the consumer settings property.

Definition at line 58 of file class.ilLTIToolProvider.php.

◆ $LTI_CONTEXT_SETTING_NAMES

array ilLTIToolProvider::$LTI_CONTEXT_SETTING_NAMES
staticprivate
Initial value:
= array('custom_context_setting_url',
'custom_lineitems_url', 'custom_results_url',
'custom_context_memberships_url')

Names of LTI parameters to be retained in the context settings property.

Definition at line 64 of file class.ilLTIToolProvider.php.

◆ $LTI_RESOURCE_LINK_SETTING_NAMES

array ilLTIToolProvider::$LTI_RESOURCE_LINK_SETTING_NAMES
staticprivate
Initial value:
= array('lis_result_sourcedid', 'lis_outcome_service_url',
'ext_ims_lis_basic_outcome_url', 'ext_ims_lis_resultvalue_sourcedids',
'ext_ims_lis_memberships_id', 'ext_ims_lis_memberships_url',
'ext_ims_lti_tool_setting', 'ext_ims_lti_tool_setting_id', 'ext_ims_lti_tool_setting_url',
'custom_link_setting_url',
'custom_lineitem_url', 'custom_result_url')

Names of LTI parameters to be retained in the resource link settings property.

Definition at line 72 of file class.ilLTIToolProvider.php.

◆ $LTI_VERSIONS

ilLTIToolProvider::$LTI_VERSIONS = array(self::LTI_VERSION1, self::LTI_VERSION2)
staticprivate

Permitted LTI versions for messages.

Definition at line 38 of file class.ilLTIToolProvider.php.

◆ $MESSAGE_TYPES

ilLTIToolProvider::$MESSAGE_TYPES
staticprivate
Initial value:
= array('basic-lti-launch-request' => 'onLaunch',
'ContentItemSelectionRequest' => 'onContentItem',
'ToolProxyRegistrationRequest' => 'register')

List of supported message types and associated class methods.

Definition at line 42 of file class.ilLTIToolProvider.php.

◆ $METHOD_NAMES

array ilLTIToolProvider::$METHOD_NAMES
staticprivate
Initial value:
= array('basic-lti-launch-request' => 'onLaunch',
'ContentItemSelectionRequest' => 'onContentItem',
'ToolProxyRegistrationRequest' => 'onRegister')

List of supported message types and associated class methods.

Definition at line 50 of file class.ilLTIToolProvider.php.


The documentation for this class was generated from the following file: