/** * Perform an Outcomes service request. * * @param int $action The action type constant * @param Outcome $ltiOutcome Outcome object * @param User $user User object * * @return boolean True if the request was successfully processed */ public function doOutcomesService($action, $ltiOutcome, $user) { $response = false; $this->extResponse = null; // Lookup service details from the source resource link appropriate to the user (in case the destination is being shared) $sourceResourceLink = $user->getResourceLink(); $sourcedId = $user->ltiResultSourcedId; // Use LTI 1.1 service in preference to extension service if it is available $urlLTI11 = $sourceResourceLink->getSetting('lis_outcome_service_url'); $urlExt = $sourceResourceLink->getSetting('ext_ims_lis_basic_outcome_url'); if ($urlExt || $urlLTI11) { switch ($action) { case self::EXT_READ: if ($urlLTI11 && $ltiOutcome->type === self::EXT_TYPE_DECIMAL) { $do = 'readResult'; } else { if ($urlExt) { $urlLTI11 = null; $do = 'basic-lis-readresult'; } } break; case self::EXT_WRITE: if ($urlLTI11 && $this->checkValueType($ltiOutcome, array(self::EXT_TYPE_DECIMAL))) { $do = 'replaceResult'; } else { if ($this->checkValueType($ltiOutcome)) { $urlLTI11 = null; $do = 'basic-lis-updateresult'; } } break; case self::EXT_DELETE: if ($urlLTI11 && $ltiOutcome->type === self::EXT_TYPE_DECIMAL) { $do = 'deleteResult'; } else { if ($urlExt) { $urlLTI11 = null; $do = 'basic-lis-deleteresult'; } } break; } } if (isset($do)) { $value = $ltiOutcome->getValue(); if (is_null($value)) { $value = ''; } if ($urlLTI11) { $xml = ''; if ($action === self::EXT_WRITE) { $xml = <<<EOF <result> <resultScore> <language>{$ltiOutcome->language}</language> <textString>{$value}</textString> </resultScore> </result> EOF; } $sourcedId = htmlentities($sourcedId); $xml = <<<EOF <resultRecord> <sourcedGUID> <sourcedId>{$sourcedId}</sourcedId> </sourcedGUID>{$xml} </resultRecord> EOF; if ($this->doLTI11Service($do, $urlLTI11, $xml)) { switch ($action) { case self::EXT_READ: if (!isset($this->extNodes['imsx_POXBody']["{$do}Response"]['result']['resultScore']['textString'])) { break; } else { $ltiOutcome->setValue($this->extNodes['imsx_POXBody']["{$do}Response"]['result']['resultScore']['textString']); } case self::EXT_WRITE: case self::EXT_DELETE: $response = true; break; } } } else { $params = array(); $params['sourcedid'] = $sourcedId; $params['result_resultscore_textstring'] = $value; if (!empty($ltiOutcome->language)) { $params['result_resultscore_language'] = $ltiOutcome->language; } if (!empty($ltiOutcome->status)) { $params['result_statusofresult'] = $ltiOutcome->status; } if (!empty($ltiOutcome->date)) { $params['result_date'] = $ltiOutcome->date; } if (!empty($ltiOutcome->type)) { $params['result_resultvaluesourcedid'] = $ltiOutcome->type; } if (!empty($ltiOutcome->data_source)) { $params['result_datasource'] = $ltiOutcome->data_source; } if ($this->doService($do, $urlExt, $params)) { switch ($action) { case self::EXT_READ: if (isset($this->extNodes['result']['resultscore']['textstring'])) { $response = $this->extNodes['result']['resultscore']['textstring']; } break; case self::EXT_WRITE: case self::EXT_DELETE: $response = true; break; } } } if (is_array($response) && count($response) <= 0) { $response = ''; } } return $response; }
/** * Save user object. * * @param User $user User object * * @return boolean True if the user object was successfully saved */ public function saveUser($user) { $time = time(); $now = date("{$this->dateFormat} {$this->timeFormat}", $time); if (is_null($user->created)) { $sql = sprintf("INSERT INTO {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' (resource_link_pk, ' . 'lti_user_id, lti_result_sourcedid, created, updated) ' . 'VALUES (%d, %s, %s, %s, %s)', $user->getResourceLink()->getRecordId(), DataConnector::quoted($user->getId(ToolProvider\ToolProvider::ID_SCOPE_ID_ONLY)), DataConnector::quoted($user->ltiResultSourcedId), DataConnector::quoted($now), DataConnector::quoted($now)); } else { $sql = sprintf("UPDATE {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' ' . 'SET lti_result_sourcedid = %s, updated = %s ' . 'WHERE (user_pk = %d)', DataConnector::quoted($user->ltiResultSourcedId), DataConnector::quoted($now), $user->getRecordId()); } $ok = mysql_query($sql); if ($ok) { if (is_null($user->created)) { $user->setRecordId(mysql_insert_id()); $user->created = $time; } $user->updated = $time; } return $ok; }
/** * Save user object. * * @param User $user User object * @return boolean True if the user object was successfully saved */ public function saveUser($user) { global $DB; $now = time(); $isinsert = is_null($user->created); $user->updated = $now; $params = ['ltiresultsourcedid' => $user->ltiResultSourcedId, 'updated' => $user->updated]; if ($isinsert) { $params['resourcelinkid'] = $user->getResourceLink()->getRecordId(); $params['ltiuserkey'] = $user->getId(ToolProvider\ToolProvider::ID_SCOPE_ID_ONLY); $user->created = $now; $params['created'] = $user->created; $id = $DB->insert_record($this->userresulttable, (object) $params); if ($id) { $user->setRecordId($id); return true; } } else { $params['id'] = $user->getRecordId(); return $DB->update_record($this->userresulttable, (object) $params); } return false; }
/** * Check if a share arrangement is in place. * * @return boolean True if no error is reported */ private function checkForShare() { $ok = true; $doSaveResourceLink = true; $id = $this->resourceLink->primaryResourceLinkId; $shareRequest = isset($_POST['custom_share_key']) && !empty($_POST['custom_share_key']); if ($shareRequest) { if (!$this->allowSharing) { $ok = false; $this->reason = 'Your sharing request has been refused because sharing is not being permitted.'; } else { // Check if this is a new share key $shareKey = new ResourceLinkShareKey($this->resourceLink, $_POST['custom_share_key']); if (!is_null($shareKey->primaryConsumerKey) && !is_null($shareKey->primaryResourceLinkId)) { // Update resource link with sharing primary resource link details $key = $shareKey->primaryConsumerKey; $id = $shareKey->primaryResourceLinkId; $ok = $key !== $this->consumer->getKey() || $id != $this->resourceLink->getId(); if ($ok) { $this->resourceLink->primaryConsumerKey = $key; $this->resourceLink->primaryResourceLinkId = $id; $this->resourceLink->shareApproved = $shareKey->autoApprove; $ok = $this->resourceLink->save(); if ($ok) { $doSaveResourceLink = false; $this->user->getResourceLink()->primaryConsumerKey = $key; $this->user->getResourceLink()->primaryResourceLinkId = $id; $this->user->getResourceLink()->shareApproved = $shareKey->autoApprove; $this->user->getResourceLink()->updated = time(); // Remove share key $shareKey->delete(); } else { $this->reason = 'An error occurred initialising your share arrangement.'; } } else { $this->reason = 'It is not possible to share your resource link with yourself.'; } } if ($ok) { $ok = !is_null($key); if (!$ok) { $this->reason = 'You have requested to share a resource link but none is available.'; } else { $ok = !is_null($this->user->getResourceLink()->shareApproved) && $this->user->getResourceLink()->shareApproved; if (!$ok) { $this->reason = 'Your share request is waiting to be approved.'; } } } } } else { // Check no share is in place $ok = is_null($id); if (!$ok) { $this->reason = 'You have not requested to share a resource link but an arrangement is currently in place.'; } } // Look up primary resource link if ($ok && !is_null($id)) { $consumer = new ToolConsumer($key, $this->dataConnector); $ok = !is_null($consumer->created); if ($ok) { $resourceLink = ResourceLink::fromConsumer($consumer, $id); $ok = !is_null($resourceLink->created); } if ($ok) { if ($doSaveResourceLink) { $this->resourceLink->save(); } $this->resourceLink = $resourceLink; } else { $this->reason = 'Unable to load resource link being shared.'; } } return $ok; }
/** * Save user object. * * @param User $user User object * * @return boolean True if the user object was successfully saved */ public function saveUser($user) { $time = time(); $now = date("{$this->dateFormat} {$this->timeFormat}", $time); if (is_null($user->created)) { $sql = "INSERT INTO {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' (resource_link_pk, ' . 'lti_user_id, lti_result_sourcedid, created, updated) ' . 'VALUES (:rlid, :uid, :sourcedid, :created, :updated)'; $query = $this->db->prepare($sql); $query->bindValue('rlid', $user->getResourceLink()->getRecordId(), PDO::PARAM_INT); $query->bindValue('uid', $user->getId(ToolProvider\ToolProvider::ID_SCOPE_ID_ONLY), PDO::PARAM_STR); $query->bindValue('sourcedid', $user->ltiResultSourcedId, PDO::PARAM_STR); $query->bindValue('created', $now, PDO::PARAM_STR); $query->bindValue('updated', $now, PDO::PARAM_STR); } else { $sql = "UPDATE {$this->dbTableNamePrefix}" . DataConnector::USER_RESULT_TABLE_NAME . ' ' . 'SET lti_result_sourcedid = :sourcedid, updated = :updated ' . 'WHERE (user_pk = :id)'; $query = $this->db->prepare($sql); $query->bindValue('sourcedid', $user->ltiResultSourcedId, PDO::PARAM_STR); $query->bindValue('updated', $now, PDO::PARAM_STR); $query->bindValue('id', $user->getRecordId(), PDO::PARAM_INT); } $ok = $query->execute(); if ($ok) { if (is_null($user->created)) { $user->setRecordId(intval($this->db->lastInsertId())); $user->created = $time; } $user->updated = $time; } return $ok; }