226 $this->groupSets = null;
227 $this->groups = null;
228 $this->primaryResourceLinkId = null;
229 $this->shareApproved = null;
230 $this->created = null;
231 $this->updated = null;
257 $this->settingsChanged =
false;
269 public function delete()
284 if (is_null($this->consumer)) {
286 #if (!is_null($this->context) || !is_null($this->contextId)) { 287 if($this->context || $this->contextId) {
288 $this->consumer = $this->
getContext()->getConsumer();
306 $this->consumer = null;
319 if (is_null($this->context) && !is_null($this->contextId)) {
347 $this->context = null;
443 if ($value !== $old_value) {
444 if (!empty($value)) {
449 $this->settingsChanged =
true;
486 if ($this->settingsChanged) {
550 $logger = $DIC->logger()->lti();
553 $this->extResponse = null;
556 $sourceResourceLink =
$user->getResourceLink();
557 $sourcedId =
$user->ltiResultSourcedId;
560 $urlLTI11 = $sourceResourceLink->getSetting(
'lis_outcome_service_url');
561 $urlExt = $sourceResourceLink->getSetting(
'ext_ims_lis_basic_outcome_url');
562 if ($urlExt || $urlLTI11) {
565 if ($urlLTI11 && ($ltiOutcome->type === self::EXT_TYPE_DECIMAL)) {
567 }
else if ($urlExt) {
569 $do =
'basic-lis-readresult';
572 case self::EXT_WRITE:
573 if ($urlLTI11 && $this->
checkValueType($ltiOutcome, array(self::EXT_TYPE_DECIMAL))) {
574 $do =
'replaceResult';
577 $do =
'basic-lis-updateresult';
580 case self::EXT_DELETE:
581 if ($urlLTI11 && ($ltiOutcome->type === self::EXT_TYPE_DECIMAL)) {
582 $do =
'deleteResult';
583 }
else if ($urlExt) {
585 $do =
'basic-lis-deleteresult';
591 $logger->debug(
'Command is: ' . $do);
594 $value = $ltiOutcome->getValue();
595 if (is_null($value)) {
600 if (
$action === self::EXT_WRITE) {
606 <textString>{$value}</textString>
611 $sourcedId = htmlentities($sourcedId);
615 <sourcedId>{$sourcedId}</sourcedId>
620 $logger->debug($urlLTI11);
621 $logger->debug(
'xml for doLTI11Service: ' .
$xml);
626 if (!isset($this->extNodes[
'imsx_POXBody'][
"{$do}Response"][
'result'][
'resultScore'][
'textString'])) {
629 $ltiOutcome->setValue($this->extNodes[
'imsx_POXBody'][
"{$do}Response"][
'result'][
'resultScore'][
'textString']);
631 case self::EXT_WRITE:
632 case self::EXT_DELETE:
639 $params[
'sourcedid'] = $sourcedId;
640 $params[
'result_resultscore_textstring'] = $value;
641 if (!empty($ltiOutcome->language)) {
642 $params[
'result_resultscore_language'] = $ltiOutcome->language;
644 if (!empty($ltiOutcome->status)) {
645 $params[
'result_statusofresult'] = $ltiOutcome->status;
647 if (!empty($ltiOutcome->date)) {
648 $params[
'result_date'] = $ltiOutcome->date;
650 if (!empty($ltiOutcome->type)) {
651 $params[
'result_resultvaluesourcedid'] = $ltiOutcome->type;
653 if (!empty($ltiOutcome->data_source)) {
654 $params[
'result_datasource'] = $ltiOutcome->data_source;
657 $logger->debug($urlExt);
664 if (isset($this->extNodes[
'result'][
'resultscore'][
'textstring'])) {
665 $response = $this->extNodes[
'result'][
'resultscore'][
'textstring'];
668 case self::EXT_WRITE:
669 case self::EXT_DELETE:
698 $this->extResponse = null;
707 $this->groupSets = array();
708 $this->groups = array();
714 if (!isset($this->extNodes[
'memberships'][
'member'])) {
716 }
else if (!isset($this->extNodes[
'memberships'][
'member'][0])) {
718 $members[0] = $this->extNodes[
'memberships'][
'member'];
720 $members = $this->extNodes[
'memberships'][
'member'];
723 for (
$i = 0;
$i < count($members);
$i++) {
728 $firstname = (isset($members[$i][
'person_name_given'])) ? $members[$i][
'person_name_given'] :
'';
729 $lastname = (isset($members[$i][
'person_name_family'])) ? $members[$i][
'person_name_family'] :
'';
730 $fullname = (isset($members[$i][
'person_name_full'])) ? $members[$i][
'person_name_full'] :
'';
731 $user->setNames($firstname, $lastname, $fullname);
734 $email = (isset($members[$i][
'person_contact_email_primary'])) ? $members[$i][
'person_contact_email_primary'] :
'';
738 if (isset($members[$i][
'roles'])) {
743 if (!isset($members[$i][
'groups'][
'group'])) {
745 }
else if (!isset($members[$i][
'groups'][
'group'][0])) {
747 $groups[0] = $members[
$i][
'groups'][
'group'];
749 $groups = $members[
$i][
'groups'][
'group'];
751 for ($j = 0; $j < count(
$groups); $j++) {
753 if (isset($group[
'set'])) {
754 $set_id = $group[
'set'][
'id'];
755 if (!isset($this->groupSets[$set_id])) {
756 $this->groupSets[$set_id] = array(
'title' => $group[
'set'][
'title'],
'groups' => array(),
757 'num_members' => 0,
'num_staff' => 0,
'num_learners' => 0);
759 $this->groupSets[$set_id][
'num_members']++;
760 if (
$user->isStaff()) {
761 $this->groupSets[$set_id][
'num_staff']++;
763 if (
$user->isLearner()) {
764 $this->groupSets[$set_id][
'num_learners']++;
766 if (!in_array($group[
'id'], $this->groupSets[$set_id][
'groups'])) {
767 $this->groupSets[$set_id][
'groups'][] = $group[
'id'];
769 $this->groups[$group[
'id']] = array(
'title' => $group[
'title'],
'set' => $set_id);
771 $this->groups[$group[
'id']] = array(
'title' => $group[
'title']);
773 $user->groups[] = $group[
'id'];
777 if (isset($members[$i][
'lis_result_sourcedid'])) {
778 $user->ltiResultSourcedId = $members[
$i][
'lis_result_sourcedid'];
788 foreach ($oldUsers as
$id =>
$user) {
811 $this->extResponse = null;
814 $do =
'basic-lti-loadsetting';
816 case self::EXT_WRITE:
817 $do =
'basic-lti-savesetting';
819 case self::EXT_DELETE:
820 $do =
'basic-lti-deletesetting';
828 if (is_null($value)) {
836 if (isset($this->extNodes[
'setting'][
'value'])) {
837 $response = $this->extNodes[
'setting'][
'value'];
843 case self::EXT_WRITE:
844 $this->
setSetting(
'ext_ims_lti_tool_setting', $value);
848 case self::EXT_DELETE:
918 $has = !empty($this->contextId);
936 if (!empty($this->contextId)) {
937 $url = $this->
getContext()->getSetting(
'custom_context_memberships_url');
962 return $this->
getDataConnector()->getUserResultSourcedIDsResourceLink($this, $localOnly, $idScope);
991 $resourceLink->dataConnector =
$consumer->getDataConnector();
994 $resourceLink->load();
995 if (is_null($resourceLink->id) && !empty($tempId)) {
996 $resourceLink->ltiResourceLinkId = $tempId;
997 $resourceLink->load();
1002 return $resourceLink;
1018 $resourceLink->setContextId(
$context->getRecordId());
1020 $resourceLink->dataConnector =
$context->getDataConnector();
1023 $resourceLink->load();
1024 if (is_null($resourceLink->id) && !empty($tempId)) {
1025 $resourceLink->ltiResourceLinkId = $tempId;
1026 $resourceLink->load();
1031 return $resourceLink;
1047 $resourceLink->load(
$id);
1049 return $resourceLink;
1085 if (empty($supportedTypes)) {
1086 $supportedTypes = explode(
',', str_replace(
' ',
'', strtolower($this->
getSetting(
'ext_ims_lis_resultvalue_sourcedids', self::EXT_TYPE_DECIMAL))));
1088 $type = $ltiOutcome->type;
1089 $value = $ltiOutcome->getValue();
1091 $ok = in_array(
$type, $supportedTypes) || (strlen($value) <= 0);
1094 if (
$type === self::EXT_TYPE_PERCENTAGE) {
1095 if (substr($value, -1) ===
'%') {
1096 $value = substr($value, 0, -1);
1098 $ok = is_numeric($value) && ($value >= 0) && ($value <= 100);
1100 $ltiOutcome->setValue($value / 100);
1101 $ltiOutcome->type = self::EXT_TYPE_DECIMAL;
1103 }
else if (
$type === self::EXT_TYPE_RATIO) {
1104 $parts = explode(
'/', $value, 2);
1105 $ok = (count($parts) === 2) && is_numeric($parts[0]) && is_numeric($parts[1]) && ($parts[0] >= 0) && ($parts[1] > 0);
1107 $ltiOutcome->setValue($parts[0] / $parts[1]);
1108 $ltiOutcome->type = self::EXT_TYPE_DECIMAL;
1111 }
else if (
$type === self::EXT_TYPE_LETTER_AF) {
1112 if (in_array(self::EXT_TYPE_LETTER_AF_PLUS, $supportedTypes)) {
1114 $ltiOutcome->type = self::EXT_TYPE_LETTER_AF_PLUS;
1115 }
else if (in_array(self::EXT_TYPE_TEXT, $supportedTypes)) {
1117 $ltiOutcome->type = self::EXT_TYPE_TEXT;
1120 }
else if (
$type === self::EXT_TYPE_LETTER_AF_PLUS) {
1121 if (in_array(self::EXT_TYPE_LETTER_AF, $supportedTypes) && (strlen($value) === 1)) {
1123 $ltiOutcome->type = self::EXT_TYPE_LETTER_AF;
1124 }
else if (in_array(self::EXT_TYPE_TEXT, $supportedTypes)) {
1126 $ltiOutcome->type = self::EXT_TYPE_TEXT;
1129 }
else if (
$type === self::EXT_TYPE_TEXT) {
1130 $ok = is_numeric($value) && ($value >= 0) && ($value <=1);
1132 $ltiOutcome->type = self::EXT_TYPE_DECIMAL;
1133 }
else if (substr($value, -1) ===
'%') {
1134 $value = substr($value, 0, -1);
1135 $ok = is_numeric($value) && ($value >= 0) && ($value <=100);
1137 if (in_array(self::EXT_TYPE_PERCENTAGE, $supportedTypes)) {
1138 $ltiOutcome->type = self::EXT_TYPE_PERCENTAGE;
1140 $ltiOutcome->setValue($value / 100);
1141 $ltiOutcome->type = self::EXT_TYPE_DECIMAL;
1165 $this->extRequest = null;
1166 $this->extRequestHeaders =
'';
1167 $this->extResponse = null;
1168 $this->extResponseHeaders =
'';
1177 if (
$http->send()) {
1178 $this->extResponse =
$http->response;
1179 $this->extResponseHeaders =
$http->responseHeaders;
1186 $this->extDoc->loadXML(
$http->response);
1187 $this->extNodes = $this->
domnodeToArray($this->extDoc->documentElement);
1188 if (isset($this->extNodes[
'statusinfo'][
'codemajor']) && ($this->extNodes[
'statusinfo'][
'codemajor'] ===
'Success')) {
1195 $this->extRequest =
$http->request;
1196 $this->extRequestHeaders =
$http->requestHeaders;
1219 $this->extRequest = null;
1220 $this->extRequestHeaders =
'';
1221 $this->extResponse = null;
1222 $this->extResponseHeaders =
'';
1225 $xmlRequest = <<<
EOD 1226 <?xml version =
"1.0" encoding =
"UTF-8"?>
1227 <imsx_POXEnvelopeRequest xmlns =
"http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0">
1229 <imsx_POXRequestHeaderInfo>
1230 <imsx_version>V1.0</imsx_version>
1231 <imsx_messageIdentifier>{
$id}</imsx_messageIdentifier>
1232 </imsx_POXRequestHeaderInfo>
1239 </imsx_POXEnvelopeRequest>
1242 $hash = base64_encode(sha1($xmlRequest,
true));
1243 $params = array(
'oauth_body_hash' => $hash);
1252 $header .=
"\nContent-Type: application/xml";
1260 if (
$http->send()) {
1261 $this->extResponse =
$http->response;
1262 $this->extResponseHeaders =
$http->responseHeaders;
1267 $this->extDoc->loadXML(
$http->response);
1268 $this->extNodes = $this->
domnodeToArray($this->extDoc->documentElement);
1269 if (isset($this->extNodes[
'imsx_POXHeader'][
'imsx_POXResponseHeaderInfo'][
'imsx_statusInfo'][
'imsx_codeMajor']) &&
1270 ($this->extNodes[
'imsx_POXHeader'][
'imsx_POXResponseHeaderInfo'][
'imsx_statusInfo'][
'imsx_codeMajor'] ===
'success')) {
1281 $this->extRequest =
$http->request;
1282 $this->extRequestHeaders =
$http->requestHeaders;
1300 switch ($node->nodeType) {
1301 case XML_CDATA_SECTION_NODE:
1303 $output = trim($node->textContent);
1305 case XML_ELEMENT_NODE:
1306 for (
$i = 0;
$i < $node->childNodes->length;
$i++) {
1307 $child = $node->childNodes->item(
$i);
1309 if (isset($child->tagName)) {
1310 $t = $child->tagName;
1317 if (strlen(
$s) > 0) {
1323 if ($node->attributes->length) {
1325 foreach ($node->attributes as $attrName => $attrNode) {
1326 $a[$attrName] = (string) $attrNode->value;
1331 if (is_array($v) && count($v)==1 &&
$t!=
'@attributes') {
static fromRecordId($id, $dataConnector)
Load the context from the database.
static from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=null)
pretty much a helper function to set up the request
Class to represent an OAuth Consumer.
static getLogger($a_component_id)
Get component logger.
Class to represent an HTTP message.
Class to represent an OAuth HMAC_SHA1 signature method.
const EOF
How fgetc() reports an End Of File.