38    private static $LTI_VERSIONS = array(self::LTI_VERSION1, self::LTI_VERSION2);
 
   42    private static $MESSAGE_TYPES = array(
'basic-lti-launch-request' => 
'onLaunch',
 
   43                                          'ContentItemSelectionRequest' => 
'onContentItem',
 
   44                                          'ToolProxyRegistrationRequest' => 
'register');
 
   50    private static $METHOD_NAMES = array(
'basic-lti-launch-request' => 
'onLaunch',
 
   51                                         'ContentItemSelectionRequest' => 
'onContentItem',
 
   52                                         'ToolProxyRegistrationRequest' => 
'onRegister');
 
   65                                                      'custom_lineitems_url', 
'custom_results_url',
 
   66                                                      'custom_context_memberships_url');
 
   73                                                            'ext_ims_lis_basic_outcome_url', 
'ext_ims_lis_resultvalue_sourcedids',
 
   74                                                            'ext_ims_lis_memberships_id', 
'ext_ims_lis_memberships_url',
 
   75                                                            'ext_ims_lti_tool_setting', 
'ext_ims_lti_tool_setting_id', 
'ext_ims_lti_tool_setting_url',
 
   76                                                            'custom_link_setting_url',
 
   77                                                            'custom_lineitem_url', 
'custom_result_url');
 
   84                                                          'User.image' => 
'user_image',
 
   85                                                          'User.username' => 
'username',
 
   86                                                          'User.scope.mentor' => 
'role_scope_mentor',
 
   87                                                          'Membership.role' => 
'roles',
 
   88                                                          'Person.sourcedId' => 
'lis_person_sourcedid',
 
   89                                                          'Person.name.full' => 
'lis_person_name_full',
 
   90                                                          'Person.name.family' => 
'lis_person_name_family',
 
   91                                                          'Person.name.given' => 
'lis_person_name_given',
 
   92                                                          'Person.email.primary' => 
'lis_person_contact_email_primary',
 
   93                                                          'Context.id' => 
'context_id',
 
   94                                                          'Context.type' => 
'context_type',
 
   95                                                          'Context.title' => 
'context_title',
 
   96                                                          'Context.label' => 
'context_label',
 
   97                                                          'CourseOffering.sourcedId' => 
'lis_course_offering_sourcedid',
 
   98                                                          'CourseSection.sourcedId' => 
'lis_course_section_sourcedid',
 
   99                                                          'CourseSection.label' => 
'context_label',
 
  100                                                          'CourseSection.title' => 
'context_title',
 
  101                                                          'ResourceLink.id' => 
'resource_link_id',
 
  102                                                          'ResourceLink.title' => 
'resource_link_title',
 
  103                                                          'ResourceLink.description' => 
'resource_link_description',
 
  104                                                          'Result.sourcedId' => 
'lis_result_sourcedid',
 
  105                                                          'BasicOutcome.url' => 
'lis_outcome_service_url',
 
  106                                                          'ToolConsumerProfile.url' => 
'custom_tc_profile_url',
 
  107                                                          'ToolProxy.url' => 
'tool_proxy_url',
 
  108                                                          'ToolProxy.custom.url' => 
'custom_system_setting_url',
 
  109                                                          'ToolProxyBinding.custom.url' => 
'custom_context_setting_url',
 
  110                                                          'LtiLink.custom.url' => 
'custom_link_setting_url',
 
  111                                                          'LineItems.url' => 
'custom_lineitems_url',
 
  112                                                          'LineItem.url' => 
'custom_lineitem_url',
 
  113                                                          'Results.url' => 
'custom_results_url',
 
  114                                                          'Result.url' => 
'custom_result_url',
 
  115                                                          'ToolProxyBinding.memberships.url' => 
'custom_context_memberships_url');
 
  126        $this->logger = 
$DIC->logger()->lti();
 
  127        parent::__construct($dataConnector);
 
  147    ###    PROTECTED METHODS 
  162        if ($this->context instanceof 
Context) {
 
  163            $this->context->save();
 
  167            $this->resourceLink->save();
 
  219        if (is_null($callback)) {
 
  220            $callback = self::$METHOD_NAMES[
$_POST[
'lti_message_type']];
 
  222        if (method_exists($this, $callback)) {
 
  224        } elseif (is_null($method) && $this->ok) {
 
  226            $this->reason = 
"Message type not supported: {$_POST['lti_message_type']}";
 
  228        if ($this->ok && (
$_POST[
'lti_message_type'] == 
'ToolProxyRegistrationRequest')) {
 
  229            $this->consumer->save();
 
  249                if (!empty($this->returnUrl)) {
 
  250                    $errorUrl = $this->returnUrl;
 
  251                    if (strpos($errorUrl, 
'?') === 
false) {
 
  256                    if ($this->debugMode && !is_null($this->reason)) {
 
  257                        $errorUrl .= 
'lti_errormsg=' . urlencode(
"Debug error: $this->reason");
 
  259                        $errorUrl .= 
'lti_errormsg=' . urlencode($this->message);
 
  260                        if (!is_null($this->reason)) {
 
  261                            $errorUrl .= 
'<i_errorlog=' . urlencode(
"Debug error: $this->reason");
 
  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'];
 
  270                        $formParams = $this->consumer->signParameters($errorUrl, 
'ContentItemSelection', 
$version, $formParams);
 
  271                        $page = self::sendForm($errorUrl, $formParams);
 
  274                        header(
"Location: {$errorUrl}");
 
  278                    if (!is_null($this->errorOutput)) {
 
  279                        echo $this->errorOutput;
 
  280                    } elseif ($this->debugMode && !empty($this->reason)) {
 
  281                        echo 
"Debug error: {$this->reason}";
 
  283                        echo 
"Error: {$this->message}";
 
  286            } elseif (!is_null($this->redirectUrl)) {
 
  287                header(
"Location: {$this->redirectUrl}");
 
  289            } elseif (!is_null($this->output)) {
 
  306        $doSaveConsumer = 
false;
 
  308        $this->ok = isset(
$_POST[
'lti_message_type']) && array_key_exists(
$_POST[
'lti_message_type'], self::$MESSAGE_TYPES);
 
  310            $this->reason = 
'Invalid or missing lti_message_type parameter.';
 
  313            $this->ok = isset(
$_POST[
'lti_version']) && in_array(
$_POST[
'lti_version'], self::$LTI_VERSIONS);
 
  315                $this->reason = 
'Invalid or missing lti_version parameter.';
 
  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);
 
  322                    $this->reason = 
'Missing resource link ID.';
 
  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;
 
  330                        $this->reason = 
'No accept_media_types found.';
 
  332                        $this->mediaTypes = $mediaTypes;
 
  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;
 
  342                        $this->reason = 
'Missing or empty accept_presentation_document_targets parameter.';
 
  344                        foreach ($documentTargets as $documentTarget) {
 
  347                                array(
'embed', 
'frame', 
'iframe', 
'window', 
'popup', 
'overlay', 
'none'),
 
  348                                'Invalid value in accept_presentation_document_targets parameter: %s.' 
  355                            $this->documentTargets = $documentTargets;
 
  362                    $this->ok = isset(
$_POST[
'content_item_return_url']) && (strlen(trim(
$_POST[
'content_item_return_url'])) > 0);
 
  364                        $this->reason = 
'Missing content_item_return_url parameter.';
 
  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.';
 
  379        $this->logger->debug(
'Checking consumer key...');
 
  382        if ($this->ok && (
$_POST[
'lti_message_type'] != 
'ToolProxyRegistrationRequest')) {
 
  383            $this->ok = isset(
$_POST[
'oauth_consumer_key']);
 
  385                $this->reason = 
'Missing consumer key.';
 
  390                $this->ok = !is_null($this->consumer->created);
 
  392                    $this->reason = 
'Invalid consumer key.';
 
  396                $today = date(
'Y-m-d', $now);
 
  397                if (is_null($this->consumer->lastAccess)) {
 
  398                    $doSaveConsumer = 
true;
 
  400                    $last = date(
'Y-m-d', $this->consumer->lastAccess);
 
  401                    $doSaveConsumer = $doSaveConsumer || ($last !== $today);
 
  403                $this->consumer->last_access = $now;
 
  408                    $server->add_signature_method($method);
 
  409                    $request = OAuth\OAuthRequest::from_request();
 
  411                } 
catch (\Exception $e) {
 
  413                    if (empty($this->reason)) {
 
  414                        if ($this->debugMode) {
 
  416                            $signature = 
$request->build_signature($method, $consumer, 
false);
 
  417                            $this->reason = $e->getMessage();
 
  418                            if (empty($this->reason)) {
 
  419                                $this->reason = 
'OAuth exception';
 
  421                            $this->details[] = 
'Timestamp: ' . time();
 
  422                            $this->details[] = 
"Signature: {$signature}";
 
  423                            $this->details[] = 
"Base string: {$request->base_string}]";
 
  425                            $this->reason = 
'OAuth signature check failed - perhaps an incorrect secret or timestamp.';
 
  432                $today = date(
'Y-m-d', $now);
 
  433                if (is_null($this->consumer->lastAccess)) {
 
  434                    $doSaveConsumer = 
true;
 
  436                    $last = date(
'Y-m-d', $this->consumer->lastAccess);
 
  437                    $doSaveConsumer = $doSaveConsumer || ($last !== $today);
 
  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']);
 
  445                            $this->reason = 
'Request is from an invalid tool consumer.';
 
  448                        $this->ok = isset(
$_POST[
'tool_consumer_instance_guid']);
 
  450                            $this->reason = 
'A tool consumer GUID must be included in the launch request.';
 
  455                    $this->ok = $this->consumer->enabled;
 
  457                        $this->reason = 
'Tool consumer has not been enabled by the tool provider.';
 
  461                    $this->ok = is_null($this->consumer->enableFrom) || ($this->consumer->enableFrom <= $now);
 
  463                        $this->ok = is_null($this->consumer->enableUntil) || ($this->consumer->enableUntil > $now);
 
  465                            $this->reason = 
'Tool consumer access has expired.';
 
  468                        $this->reason = 
'Tool consumer access is not yet available.';
 
  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.');
 
  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.');
 
  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.');
 
  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.');
 
  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.');
 
  490                } elseif (isset(
$_POST[
'launch_presentation_document_target'])) {
 
  492                        $_POST[
'launch_presentation_document_target'],
 
  493                        array(
'embed', 
'frame', 
'iframe', 
'window', 
'popup', 
'overlay'),
 
  494                        'Invalid value for launch_presentation_document_target parameter: %s.' 
  500        if ($this->ok && (
$_POST[
'lti_message_type'] === 
'ToolProxyRegistrationRequest')) {
 
  501            $this->ok = 
$_POST[
'lti_version'] == self::LTI_VERSION2;
 
  503                $this->reason = 
'Invalid lti_version parameter';
 
  506                $http = 
new HTTPMessage(
$_POST[
'tc_profile_url'], 
'GET', 
null, 
'Accept: application/vnd.ims.lti.v2.toolconsumerprofile+json');
 
  507                $this->ok = 
$http->send();
 
  509                    $this->reason = 
'Tool consumer profile not accessible.';
 
  511                    $tcProfile = json_decode(
$http->response);
 
  512                    $this->ok = !is_null($tcProfile);
 
  514                        $this->reason = 
'Invalid JSON in tool consumer profile.';
 
  522                $this->consumer->profile = $tcProfile;
 
  523                $capabilities = $this->consumer->profile->capability_offered;
 
  525                foreach ($this->resourceHandlers as $resourceHandler) {
 
  526                    foreach ($resourceHandler->requiredMessages as 
$message) {
 
  527                        if (!in_array(
$message->type, $capabilities)) {
 
  532                foreach ($this->constraints as 
$name => $constraint) {
 
  533                    if ($constraint[
'required']) {
 
  534                        if (!in_array(
$name, $capabilities) && !in_array(
$name, array_flip($capabilities))) {
 
  535                            $missing[
$name] = 
true;
 
  539                if (!empty($missing)) {
 
  541                    $this->reason = 
'Required capability not offered - \'' . implode(
'\', \
'', array_keys($missing)) . 
'\'';
 
  547                foreach ($this->requiredServices as $service) {
 
  548                    foreach ($service->formats as 
$format) {
 
  549                        if (!$this->findService(
$format, $service->actions)) {
 
  551                                $this->reason = 
'Required service(s) not offered - ';
 
  554                                $this->reason .= 
', ';
 
  556                            $this->reason .= 
"'{$format}' [" . implode(
', ', $service->actions) . 
']';
 
  562                if (
$_POST[
'lti_message_type'] === 
'ToolProxyRegistrationRequest') {
 
  563                    $this->consumer->profile = $tcProfile;
 
  564                    $this->consumer->secret = 
$_POST[
'reg_password'];
 
  565                    $this->consumer->ltiVersion = 
$_POST[
'lti_version'];
 
  566                    $this->consumer->name = $tcProfile->product_instance->service_owner->service_owner_name->default_value;
 
  567                    $this->consumer->consumerName = $this->consumer->name;
 
  568                    $this->consumer->consumerVersion = 
"{$tcProfile->product_instance->product_info->product_family->code}-{$tcProfile->product_instance->product_info->product_version}";
 
  569                    $this->consumer->consumerGuid = $tcProfile->product_instance->guid;
 
  570                    $this->consumer->enabled = 
true;
 
  571                    $this->consumer->protected = 
true;
 
  572                    $doSaveConsumer = 
true;
 
  575        } elseif ($this->ok && !empty(
$_POST[
'custom_tc_profile_url']) && empty($this->consumer->profile)) {
 
  576            $http = 
new HTTPMessage(
$_POST[
'custom_tc_profile_url'], 
'GET', 
null, 
'Accept: application/vnd.ims.lti.v2.toolconsumerprofile+json');
 
  578                $tcProfile = json_decode(
$http->response);
 
  579                if (!is_null($tcProfile)) {
 
  580                    $this->consumer->profile = $tcProfile;
 
  581                    $doSaveConsumer = 
true;
 
  613        $this->logger->debug(
'Still ok: ' . ($this->ok ? 
'1' : 
'0'));
 
  615            $this->logger->debug(
'Reason: ' . $this->reason);
 
  621            if (isset(
$_POST[
'context_id'])) {
 
  622                $this->context = Context::fromConsumer($this->consumer, trim(
$_POST[
'context_id']));
 
  624                if (isset(
$_POST[
'context_title'])) {
 
  628                    $title = 
"Course {$this->context->getId()}";
 
  630                $this->context->title = 
$title;
 
  634            if (isset(
$_POST[
'resource_link_id'])) {
 
  636                if (isset(
$_POST[
'custom_content_item_id'])) {
 
  637                    $contentItemId = 
$_POST[
'custom_content_item_id'];
 
  639                $this->resourceLink = ResourceLink::fromConsumer($this->consumer, trim(
$_POST[
'resource_link_id']), $contentItemId);
 
  640                if (!empty($this->context)) {
 
  641                    $this->resourceLink->setContextId($this->context->getRecordId());
 
  644                if (isset(
$_POST[
'resource_link_title'])) {
 
  648                    $title = 
"Resource {$this->resourceLink->getId()}";
 
  650                $this->resourceLink->title = 
$title;
 
  652                foreach ($this->consumer->getSettings() as 
$name => $value) {
 
  653                    if (strpos(
$name, 
'custom_') === 0) {
 
  654                        $this->consumer->setSetting(
$name);
 
  655                        $doSaveConsumer = 
true;
 
  658                if (!empty($this->context)) {
 
  659                    foreach ($this->context->getSettings() as 
$name => $value) {
 
  660                        if (strpos(
$name, 
'custom_') === 0) {
 
  661                            $this->context->setSetting(
$name);
 
  665                foreach ($this->resourceLink->getSettings() as 
$name => $value) {
 
  666                    if (strpos(
$name, 
'custom_') === 0) {
 
  667                        $this->resourceLink->setSetting(
$name);
 
  671                foreach (self::$LTI_CONSUMER_SETTING_NAMES as 
$name) {
 
  675                        $this->consumer->setSetting(
$name);
 
  678                if (!empty($this->context)) {
 
  679                    foreach (self::$LTI_CONTEXT_SETTING_NAMES as 
$name) {
 
  683                            $this->context->setSetting(
$name);
 
  687                foreach (self::$LTI_RESOURCE_LINK_SETTING_NAMES as 
$name) {
 
  691                        $this->resourceLink->setSetting(
$name);
 
  696                    if ((strpos(
$name, 
'custom_') === 0) &&
 
  697                        !in_array(
$name, array_merge(self::$LTI_CONSUMER_SETTING_NAMES, self::$LTI_CONTEXT_SETTING_NAMES, self::$LTI_RESOURCE_LINK_SETTING_NAMES))) {
 
  698                        $this->resourceLink->setSetting(
$name, $value);
 
  705            if (isset(
$_POST[
'user_id'])) {
 
  706                $userId = trim(
$_POST[
'user_id']);
 
  709            $this->
user = User::fromResourceLink($this->resourceLink, $userId);
 
  712            $firstname = (isset(
$_POST[
'lis_person_name_given'])) ? 
$_POST[
'lis_person_name_given'] : 
'';
 
  713            $lastname = (isset(
$_POST[
'lis_person_name_family'])) ? 
$_POST[
'lis_person_name_family'] : 
'';
 
  714            $fullname = (isset(
$_POST[
'lis_person_name_full'])) ? 
$_POST[
'lis_person_name_full'] : 
'';
 
  715            $this->
user->setNames($firstname, $lastname, $fullname);
 
  718            $email = (isset(
$_POST[
'lis_person_contact_email_primary'])) ? 
$_POST[
'lis_person_contact_email_primary'] : 
'';
 
  719            $this->
user->setEmail(
$email, $this->defaultEmail);
 
  722            if (isset(
$_POST[
'user_image'])) {
 
  727            if (isset(
$_POST[
'roles'])) {
 
  728                $this->
user->roles = self::parseRoles(
$_POST[
'roles']);
 
  732            $this->consumer->defaultEmail = $this->defaultEmail;
 
  733            if ($this->consumer->ltiVersion !== 
$_POST[
'lti_version']) {
 
  734                $this->consumer->ltiVersion = 
$_POST[
'lti_version'];
 
  735                $doSaveConsumer = 
true;
 
  737            if (isset(
$_POST[
'tool_consumer_instance_name'])) {
 
  738                if ($this->consumer->consumerName !== 
$_POST[
'tool_consumer_instance_name']) {
 
  739                    $this->consumer->consumerName = 
$_POST[
'tool_consumer_instance_name'];
 
  740                    $doSaveConsumer = 
true;
 
  743            if (isset(
$_POST[
'tool_consumer_info_product_family_code'])) {
 
  745                if (isset(
$_POST[
'tool_consumer_info_version'])) {
 
  746                    $version .= 
"-{$_POST['tool_consumer_info_version']}";
 
  749                if ($this->consumer->consumerVersion !== 
$version) {
 
  750                    $this->consumer->consumerVersion = 
$version;
 
  751                    $doSaveConsumer = 
true;
 
  753            } elseif (isset(
$_POST[
'ext_lms']) && ($this->consumer->consumerName !== 
$_POST[
'ext_lms'])) {
 
  754                $this->consumer->consumerVersion = 
$_POST[
'ext_lms'];
 
  755                $doSaveConsumer = 
true;
 
  757            if (isset(
$_POST[
'tool_consumer_instance_guid'])) {
 
  758                if (is_null($this->consumer->consumerGuid)) {
 
  759                    $this->consumer->consumerGuid = 
$_POST[
'tool_consumer_instance_guid'];
 
  760                    $doSaveConsumer = 
true;
 
  761                } elseif (!$this->consumer->protected) {
 
  762                    $doSaveConsumer = ($this->consumer->consumerGuid !== 
$_POST[
'tool_consumer_instance_guid']);
 
  763                    if ($doSaveConsumer) {
 
  764                        $this->consumer->consumerGuid = 
$_POST[
'tool_consumer_instance_guid'];
 
  768            if (isset(
$_POST[
'launch_presentation_css_url'])) {
 
  769                if ($this->consumer->cssPath !== 
$_POST[
'launch_presentation_css_url']) {
 
  770                    $this->consumer->cssPath = 
$_POST[
'launch_presentation_css_url'];
 
  771                    $doSaveConsumer = 
true;
 
  773            } elseif (isset(
$_POST[
'ext_launch_presentation_css_url']) &&
 
  774                 ($this->consumer->cssPath !== 
$_POST[
'ext_launch_presentation_css_url'])) {
 
  775                $this->consumer->cssPath = 
$_POST[
'ext_launch_presentation_css_url'];
 
  776                $doSaveConsumer = 
true;
 
  777            } elseif (!empty($this->consumer->cssPath)) {
 
  778                $this->consumer->cssPath = 
null;
 
  779                $doSaveConsumer = 
true;
 
  784        if ($doSaveConsumer) {
 
  785            $this->consumer->save();
 
  787        if ($this->ok && isset($this->context)) {
 
  788            $this->context->save();
 
  794        if ($this->ok && isset($this->resourceLink)) {
 
  799            $this->resourceLink->save();
 
  802            if (isset(
$_POST[
'lis_result_sourcedid'])) {
 
  803                if ($this->
user->ltiResultSourcedId !== 
$_POST[
'lis_result_sourcedid']) {
 
  804                    $this->
user->ltiResultSourcedId = 
$_POST[
'lis_result_sourcedid'];
 
  807            } elseif (!empty($this->
user->ltiResultSourcedId)) {
 
  808                $this->
user->ltiResultSourcedId = 
'';
 
  824        $doSaveResourceLink = 
true;
 
  826        $id = $this->resourceLink->primaryResourceLinkId;
 
  828        $shareRequest = isset(
$_POST[
'custom_share_key']) && !empty(
$_POST[
'custom_share_key']);
 
  830            if (!$this->allowSharing) {
 
  832                $this->reason = 
'Your sharing request has been refused because sharing is not being permitted.';
 
  836                if (!is_null($shareKey->primaryConsumerKey) && !is_null($shareKey->primaryResourceLinkId)) {
 
  838                    $key = $shareKey->primaryConsumerKey;
 
  839                    $id = $shareKey->primaryResourceLinkId;
 
  840                    $ok = (
$key !== $this->consumer->getKey()) || (
$id != $this->resourceLink->getId());
 
  842                        $this->resourceLink->primaryConsumerKey = 
$key;
 
  843                        $this->resourceLink->primaryResourceLinkId = 
$id;
 
  844                        $this->resourceLink->shareApproved = $shareKey->autoApprove;
 
  845                        $ok = $this->resourceLink->save();
 
  847                            $doSaveResourceLink = 
false;
 
  848                            $this->
user->getResourceLink()->primaryConsumerKey = 
$key;
 
  849                            $this->
user->getResourceLink()->primaryResourceLinkId = 
$id;
 
  850                            $this->
user->getResourceLink()->shareApproved = $shareKey->autoApprove;
 
  851                            $this->
user->getResourceLink()->updated = time();
 
  855                            $this->reason = 
'An error occurred initialising your share arrangement.';
 
  858                        $this->reason = 
'It is not possible to share your resource link with yourself.';
 
  864                        $this->reason = 
'You have requested to share a resource link but none is available.';
 
  866                        $ok = (!is_null($this->
user->getResourceLink()->shareApproved) && $this->
user->getResourceLink()->shareApproved);
 
  868                            $this->reason = 
'Your share request is waiting to be approved.';
 
  877                $this->reason = 
'You have not requested to share a resource link but an arrangement is currently in place.';
 
  881        if (
$ok && !is_null(
$id)) {
 
  884            $ok = !is_null($consumer->created);
 
  886                $resourceLink = ResourceLink::fromConsumer($consumer, 
$id);
 
  887                $ok = !is_null($resourceLink->created);
 
  890                if ($doSaveResourceLink) {
 
  891                    $this->resourceLink->save();
 
  893                $this->resourceLink = $resourceLink;
 
  895                $this->reason = 
'Unable to load resource link being shared.';
 
  909        if (!
$ok && !empty($reason)) {
 
  910            $this->reason = sprintf($reason, $value);
 
foreach($paths as $path) $request
An exception for terminatinating execution or to throw for unit testing.
Class to represent an HTTP message.
Class to represent an OAuth Consumer.
Class to represent an OAuth Data Store.
Class to represent an OAuth Server.
Class to represent an OAuth HMAC_SHA1 signature method.
Class to represent a generic item object.
Class to represent a tool consumer context.
if(!array_key_exists('StateId', $_REQUEST)) $id
if(! $oauthconfig->getBoolean('getUserInfo.enable', FALSE)) $store
catch(Exception $e) $message
foreach($_POST as $key=> $value) $res