ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
ResourceLink.php
Go to the documentation of this file.
1 <?php
2 
4 
5 use DOMDocument;
6 use DOMElement;
11 
22 {
23 
27  const EXT_READ = 1;
31  const EXT_WRITE = 2;
35  const EXT_DELETE = 3;
39  const EXT_CREATE = 4;
43  const EXT_UPDATE = 5;
44 
48  const EXT_TYPE_DECIMAL = 'decimal';
52  const EXT_TYPE_PERCENTAGE = 'percentage';
56  const EXT_TYPE_RATIO = 'ratio';
60  const EXT_TYPE_LETTER_AF = 'letteraf';
64  const EXT_TYPE_LETTER_AF_PLUS = 'letterafplus';
68  const EXT_TYPE_PASS_FAIL = 'passfail';
72  const EXT_TYPE_TEXT = 'freetext';
73 
79  public $title = null;
85  public $ltiResourceLinkId = null;
91  public $groupSets = null;
97  public $groups = null;
103  public $extRequest = null;
109  public $extRequestHeaders = null;
115  public $extResponse = null;
121  public $extResponseHeaders = null;
127  public $primaryResourceLinkId = null;
133  public $shareApproved = null;
139  public $created = null;
145  public $updated = null;
146 
152  private $id = null;
158  private $consumer = null;
164  private $consumerId = null;
170  private $context = null;
176  private $contextId = null;
182  private $settings = null;
188  private $settingsChanged = false;
194  private $extDoc = null;
200  private $extNodes = null;
206  private $dataConnector = null;
207 
211  public function __construct()
212  {
213 
214  $this->initialize();
215 
216  }
217 
221  public function initialize()
222  {
223 
224  $this->title = '';
225  $this->settings = array();
226  $this->groupSets = null;
227  $this->groups = null;
228  $this->primaryResourceLinkId = null;
229  $this->shareApproved = null;
230  $this->created = null;
231  $this->updated = null;
232 
233  }
234 
240  public function initialise()
241  {
242 
243  $this->initialize();
244 
245  }
246 
252  public function save()
253  {
254 
255  $ok = $this->getDataConnector()->saveResourceLink($this);
256  if ($ok) {
257  $this->settingsChanged = false;
258  }
259 
260  return $ok;
261 
262  }
263 
269  public function delete()
270  {
271 
272  return $this->getDataConnector()->deleteResourceLink($this);
273 
274  }
275 
281  public function getConsumer()
282  {
283 
284  if (is_null($this->consumer)) {
285  // begin-patch ilias
286  #if (!is_null($this->context) || !is_null($this->contextId)) {
287  if($this->context || $this->contextId) {
288  $this->consumer = $this->getContext()->getConsumer();
289  } else {
290  $this->consumer = ToolConsumer::fromRecordId($this->consumerId, $this->getDataConnector());
291  }
292  }
293 
294  return $this->consumer;
295 
296  }
297 
303  public function setConsumerId($consumerId)
304  {
305 
306  $this->consumer = null;
307  $this->consumerId = $consumerId;
308 
309  }
310 
316  public function getContext()
317  {
318 
319  if (is_null($this->context) && !is_null($this->contextId)) {
320  $this->context = Context::fromRecordId($this->contextId, $this->getDataConnector());
321  }
322 
323  return $this->context;
324 
325  }
326 
332  public function getContextId()
333  {
334 
335  return $this->contextId;
336 
337  }
338 
344  public function setContextId($contextId)
345  {
346 
347  $this->context = null;
348  $this->contextId = $contextId;
349 
350  }
351 
357  public function getKey()
358  {
359 
360  return $this->getConsumer()->getKey();
361 
362  }
363 
369  public function getId()
370  {
371 
373 
374  }
375 
381  public function getRecordId()
382  {
383 
384  return $this->id;
385 
386  }
387 
393  public function setRecordId($id)
394  {
395 
396  $this->id = $id;
397 
398  }
399 
405  public function getDataConnector()
406  {
407 
408  return $this->dataConnector;
409 
410  }
411 
420  public function getSetting($name, $default = '')
421  {
422 
423  if (array_key_exists($name, $this->settings)) {
424  $value = $this->settings[$name];
425  } else {
426  $value = $default;
427  }
428 
429  return $value;
430 
431  }
432 
439  public function setSetting($name, $value = null)
440  {
441 
442  $old_value = $this->getSetting($name);
443  if ($value !== $old_value) {
444  if (!empty($value)) {
445  $this->settings[$name] = $value;
446  } else {
447  unset($this->settings[$name]);
448  }
449  $this->settingsChanged = true;
450  }
451 
452  }
453 
459  public function getSettings()
460  {
461 
462  return $this->settings;
463 
464  }
465 
471  public function setSettings($settings)
472  {
473 
474  $this->settings = $settings;
475 
476  }
477 
483  public function saveSettings()
484  {
485 
486  if ($this->settingsChanged) {
487  $ok = $this->save();
488  } else {
489  $ok = true;
490  }
491 
492  return $ok;
493 
494  }
495 
501  public function hasOutcomesService()
502  {
503 
504  $url = $this->getSetting('ext_ims_lis_basic_outcome_url') . $this->getSetting('lis_outcome_service_url');
505 
506  return !empty($url);
507 
508  }
509 
515  public function hasMembershipsService()
516  {
517 
518  $url = $this->getSetting('ext_ims_lis_memberships_url');
519 
520  return !empty($url);
521 
522  }
523 
529  public function hasSettingService()
530  {
531 
532  $url = $this->getSetting('ext_ims_lti_tool_setting_url');
533 
534  return !empty($url);
535 
536  }
537 
547  public function doOutcomesService($action, $ltiOutcome, $user)
548  {
549 
550  $response = false;
551  $this->extResponse = null;
552 
553 // Lookup service details from the source resource link appropriate to the user (in case the destination is being shared)
554  $sourceResourceLink = $user->getResourceLink();
555  $sourcedId = $user->ltiResultSourcedId;
556 
557 // Use LTI 1.1 service in preference to extension service if it is available
558  $urlLTI11 = $sourceResourceLink->getSetting('lis_outcome_service_url');
559  $urlExt = $sourceResourceLink->getSetting('ext_ims_lis_basic_outcome_url');
560  if ($urlExt || $urlLTI11) {
561  switch ($action) {
562  case self::EXT_READ:
563  if ($urlLTI11 && ($ltiOutcome->type === self::EXT_TYPE_DECIMAL)) {
564  $do = 'readResult';
565  } else if ($urlExt) {
566  $urlLTI11 = null;
567  $do = 'basic-lis-readresult';
568  }
569  break;
570  case self::EXT_WRITE:
571  if ($urlLTI11 && $this->checkValueType($ltiOutcome, array(self::EXT_TYPE_DECIMAL))) {
572  $do = 'replaceResult';
573  } else if ($this->checkValueType($ltiOutcome)) {
574  $urlLTI11 = null;
575  $do = 'basic-lis-updateresult';
576  }
577  break;
578  case self::EXT_DELETE:
579  if ($urlLTI11 && ($ltiOutcome->type === self::EXT_TYPE_DECIMAL)) {
580  $do = 'deleteResult';
581  } else if ($urlExt) {
582  $urlLTI11 = null;
583  $do = 'basic-lis-deleteresult';
584  }
585  break;
586  }
587  }
588  if (isset($do)) {
589  $value = $ltiOutcome->getValue();
590  if (is_null($value)) {
591  $value = '';
592  }
593  if ($urlLTI11) {
594  $xml = '';
595  if ($action === self::EXT_WRITE) {
596  $xml = <<<EOF
597 
598  <result>
599  <resultScore>
600  <language>{$ltiOutcome->language}</language>
601  <textString>{$value}</textString>
602  </resultScore>
603  </result>
604 EOF;
605  }
606  $sourcedId = htmlentities($sourcedId);
607  $xml = <<<EOF
608  <resultRecord>
609  <sourcedGUID>
610  <sourcedId>{$sourcedId}</sourcedId>
611  </sourcedGUID>{$xml}
612  </resultRecord>
613 EOF;
614  if ($this->doLTI11Service($do, $urlLTI11, $xml)) {
615  switch ($action) {
616  case self::EXT_READ:
617  if (!isset($this->extNodes['imsx_POXBody']["{$do}Response"]['result']['resultScore']['textString'])) {
618  break;
619  } else {
620  $ltiOutcome->setValue($this->extNodes['imsx_POXBody']["{$do}Response"]['result']['resultScore']['textString']);
621  }
622  case self::EXT_WRITE:
623  case self::EXT_DELETE:
624  $response = true;
625  break;
626  }
627  }
628  } else {
629  $params = array();
630  $params['sourcedid'] = $sourcedId;
631  $params['result_resultscore_textstring'] = $value;
632  if (!empty($ltiOutcome->language)) {
633  $params['result_resultscore_language'] = $ltiOutcome->language;
634  }
635  if (!empty($ltiOutcome->status)) {
636  $params['result_statusofresult'] = $ltiOutcome->status;
637  }
638  if (!empty($ltiOutcome->date)) {
639  $params['result_date'] = $ltiOutcome->date;
640  }
641  if (!empty($ltiOutcome->type)) {
642  $params['result_resultvaluesourcedid'] = $ltiOutcome->type;
643  }
644  if (!empty($ltiOutcome->data_source)) {
645  $params['result_datasource'] = $ltiOutcome->data_source;
646  }
647  if ($this->doService($do, $urlExt, $params)) {
648  switch ($action) {
649  case self::EXT_READ:
650  if (isset($this->extNodes['result']['resultscore']['textstring'])) {
651  $response = $this->extNodes['result']['resultscore']['textstring'];
652  }
653  break;
654  case self::EXT_WRITE:
655  case self::EXT_DELETE:
656  $response = true;
657  break;
658  }
659  }
660  }
661  if (is_array($response) && (count($response) <= 0)) {
662  $response = '';
663  }
664  }
665 
666  return $response;
667 
668  }
669 
679  public function doMembershipsService($withGroups = false)
680  {
681 
682  $users = array();
684  $this->extResponse = null;
685  $url = $this->getSetting('ext_ims_lis_memberships_url');
686  $params = array();
687  $params['id'] = $this->getSetting('ext_ims_lis_memberships_id');
688  $ok = false;
689  if ($withGroups) {
690  $ok = $this->doService('basic-lis-readmembershipsforcontextwithgroups', $url, $params);
691  }
692  if ($ok) {
693  $this->groupSets = array();
694  $this->groups = array();
695  } else {
696  $ok = $this->doService('basic-lis-readmembershipsforcontext', $url, $params);
697  }
698 
699  if ($ok) {
700  if (!isset($this->extNodes['memberships']['member'])) {
701  $members = array();
702  } else if (!isset($this->extNodes['memberships']['member'][0])) {
703  $members = array();
704  $members[0] = $this->extNodes['memberships']['member'];
705  } else {
706  $members = $this->extNodes['memberships']['member'];
707  }
708 
709  for ($i = 0; $i < count($members); $i++) {
710 
711  $user = User::fromResourceLink($this, $members[$i]['user_id']);
712 
713 // Set the user name
714  $firstname = (isset($members[$i]['person_name_given'])) ? $members[$i]['person_name_given'] : '';
715  $lastname = (isset($members[$i]['person_name_family'])) ? $members[$i]['person_name_family'] : '';
716  $fullname = (isset($members[$i]['person_name_full'])) ? $members[$i]['person_name_full'] : '';
717  $user->setNames($firstname, $lastname, $fullname);
718 
719 // Set the user email
720  $email = (isset($members[$i]['person_contact_email_primary'])) ? $members[$i]['person_contact_email_primary'] : '';
721  $user->setEmail($email, $this->getConsumer()->defaultEmail);
722 
724  if (isset($members[$i]['roles'])) {
725  $user->roles = ToolProvider::parseRoles($members[$i]['roles']);
726  }
727 
728 // Set the user groups
729  if (!isset($members[$i]['groups']['group'])) {
730  $groups = array();
731  } else if (!isset($members[$i]['groups']['group'][0])) {
732  $groups = array();
733  $groups[0] = $members[$i]['groups']['group'];
734  } else {
735  $groups = $members[$i]['groups']['group'];
736  }
737  for ($j = 0; $j < count($groups); $j++) {
738  $group = $groups[$j];
739  if (isset($group['set'])) {
740  $set_id = $group['set']['id'];
741  if (!isset($this->groupSets[$set_id])) {
742  $this->groupSets[$set_id] = array('title' => $group['set']['title'], 'groups' => array(),
743  'num_members' => 0, 'num_staff' => 0, 'num_learners' => 0);
744  }
745  $this->groupSets[$set_id]['num_members']++;
746  if ($user->isStaff()) {
747  $this->groupSets[$set_id]['num_staff']++;
748  }
749  if ($user->isLearner()) {
750  $this->groupSets[$set_id]['num_learners']++;
751  }
752  if (!in_array($group['id'], $this->groupSets[$set_id]['groups'])) {
753  $this->groupSets[$set_id]['groups'][] = $group['id'];
754  }
755  $this->groups[$group['id']] = array('title' => $group['title'], 'set' => $set_id);
756  } else {
757  $this->groups[$group['id']] = array('title' => $group['title']);
758  }
759  $user->groups[] = $group['id'];
760  }
761 
762 // If a result sourcedid is provided save the user
763  if (isset($members[$i]['lis_result_sourcedid'])) {
764  $user->ltiResultSourcedId = $members[$i]['lis_result_sourcedid'];
765  $user->save();
766  }
767  $users[] = $user;
768 
769 // Remove old user (if it exists)
770  unset($oldUsers[$user->getId(ToolProvider::ID_SCOPE_RESOURCE)]);
771  }
772 
773 // Delete any old users which were not in the latest list from the tool consumer
774  foreach ($oldUsers as $id => $user) {
775  $user->delete();
776  }
777  } else {
778  $users = false;
779  }
780 
781  return $users;
782 
783  }
784 
793  public function doSettingService($action, $value = null)
794  {
795 
796  $response = false;
797  $this->extResponse = null;
798  switch ($action) {
799  case self::EXT_READ:
800  $do = 'basic-lti-loadsetting';
801  break;
802  case self::EXT_WRITE:
803  $do = 'basic-lti-savesetting';
804  break;
805  case self::EXT_DELETE:
806  $do = 'basic-lti-deletesetting';
807  break;
808  }
809  if (isset($do)) {
810 
811  $url = $this->getSetting('ext_ims_lti_tool_setting_url');
812  $params = array();
813  $params['id'] = $this->getSetting('ext_ims_lti_tool_setting_id');
814  if (is_null($value)) {
815  $value = '';
816  }
817  $params['setting'] = $value;
818 
819  if ($this->doService($do, $url, $params)) {
820  switch ($action) {
821  case self::EXT_READ:
822  if (isset($this->extNodes['setting']['value'])) {
823  $response = $this->extNodes['setting']['value'];
824  if (is_array($response)) {
825  $response = '';
826  }
827  }
828  break;
829  case self::EXT_WRITE:
830  $this->setSetting('ext_ims_lti_tool_setting', $value);
831  $this->saveSettings();
832  $response = true;
833  break;
834  case self::EXT_DELETE:
835  $response = true;
836  break;
837  }
838  }
839  }
840 
841  return $response;
842 
843  }
844 
850  public function hasToolSettingsService()
851  {
852 
853  $url = $this->getSetting('custom_link_setting_url');
854 
855  return !empty($url);
856 
857  }
858 
867  public function getToolSettings($mode = Service\ToolSettings::MODE_CURRENT_LEVEL, $simple = true)
868  {
869 
870  $url = $this->getSetting('custom_link_setting_url');
871  $service = new Service\ToolSettings($this, $url, $simple);
872  $response = $service->get($mode);
873 
874  return $response;
875 
876  }
877 
885  public function setToolSettings($settings = array())
886  {
887 
888  $url = $this->getSetting('custom_link_setting_url');
889  $service = new Service\ToolSettings($this, $url);
890  $response = $service->set($settings);
891 
892  return $response;
893 
894  }
895 
901  public function hasMembershipService()
902  {
903 
904  $has = !empty($this->contextId);
905  if ($has) {
906  $has = !empty($this->getContext()->getSetting('custom_context_memberships_url'));
907  }
908 
909  return $has;
910 
911  }
912 
918  public function getMembership()
919  {
920 
921  $response = false;
922  if (!empty($this->contextId)) {
923  $url = $this->getContext()->getSetting('custom_context_memberships_url');
924  if (!empty($url)) {
925  $service = new Service\Membership($this, $url);
926  $response = $service->get();
927  }
928  }
929 
930  return $response;
931 
932  }
933 
945  public function getUserResultSourcedIDs($localOnly = false, $idScope = null)
946  {
947 
948  return $this->getDataConnector()->getUserResultSourcedIDsResourceLink($this, $localOnly, $idScope);
949 
950  }
951 
957  public function getShares()
958  {
959 
960  return $this->getDataConnector()->getSharesResourceLink($this);
961 
962  }
963 
972  public static function fromConsumer($consumer, $ltiResourceLinkId, $tempId = null)
973  {
974 
975  $resourceLink = new ResourceLink();
976  $resourceLink->consumer = $consumer;
977  $resourceLink->dataConnector = $consumer->getDataConnector();
978  $resourceLink->ltiResourceLinkId = $ltiResourceLinkId;
979  if (!empty($ltiResourceLinkId)) {
980  $resourceLink->load();
981  if (is_null($resourceLink->id) && !empty($tempId)) {
982  $resourceLink->ltiResourceLinkId = $tempId;
983  $resourceLink->load();
984  $resourceLink->ltiResourceLinkId = $ltiResourceLinkId;
985  }
986  }
987 
988  return $resourceLink;
989 
990  }
991 
1000  public static function fromContext($context, $ltiResourceLinkId, $tempId = null)
1001  {
1002 
1003  $resourceLink = new ResourceLink();
1004  $resourceLink->setContextId($context->getRecordId());
1005  $resourceLink->context = $context;
1006  $resourceLink->dataConnector = $context->getDataConnector();
1007  $resourceLink->ltiResourceLinkId = $ltiResourceLinkId;
1008  if (!empty($ltiResourceLinkId)) {
1009  $resourceLink->load();
1010  if (is_null($resourceLink->id) && !empty($tempId)) {
1011  $resourceLink->ltiResourceLinkId = $tempId;
1012  $resourceLink->load();
1013  $resourceLink->ltiResourceLinkId = $ltiResourceLinkId;
1014  }
1015  }
1016 
1017  return $resourceLink;
1018 
1019  }
1020 
1029  public static function fromRecordId($id, $dataConnector)
1030  {
1031  $resourceLink = new ResourceLink();
1032  $resourceLink->dataConnector = $dataConnector;
1033  $resourceLink->load($id);
1034 
1035  return $resourceLink;
1036 
1037  }
1038 
1039 ###
1040 ### PRIVATE METHODS
1041 ###
1042 
1050  private function load($id = null)
1051  {
1052 
1053  $this->initialize();
1054  $this->id = $id;
1055 
1056  return $this->getDataConnector()->loadResourceLink($this);
1057 
1058  }
1059 
1068  private function checkValueType($ltiOutcome, $supportedTypes = null)
1069  {
1070 
1071  if (empty($supportedTypes)) {
1072  $supportedTypes = explode(',', str_replace(' ', '', strtolower($this->getSetting('ext_ims_lis_resultvalue_sourcedids', self::EXT_TYPE_DECIMAL))));
1073  }
1074  $type = $ltiOutcome->type;
1075  $value = $ltiOutcome->getValue();
1076 // Check whether the type is supported or there is no value
1077  $ok = in_array($type, $supportedTypes) || (strlen($value) <= 0);
1078  if (!$ok) {
1079 // Convert numeric values to decimal
1080  if ($type === self::EXT_TYPE_PERCENTAGE) {
1081  if (substr($value, -1) === '%') {
1082  $value = substr($value, 0, -1);
1083  }
1084  $ok = is_numeric($value) && ($value >= 0) && ($value <= 100);
1085  if ($ok) {
1086  $ltiOutcome->setValue($value / 100);
1087  $ltiOutcome->type = self::EXT_TYPE_DECIMAL;
1088  }
1089  } else if ($type === self::EXT_TYPE_RATIO) {
1090  $parts = explode('/', $value, 2);
1091  $ok = (count($parts) === 2) && is_numeric($parts[0]) && is_numeric($parts[1]) && ($parts[0] >= 0) && ($parts[1] > 0);
1092  if ($ok) {
1093  $ltiOutcome->setValue($parts[0] / $parts[1]);
1094  $ltiOutcome->type = self::EXT_TYPE_DECIMAL;
1095  }
1096 // Convert letter_af to letter_af_plus or text
1097  } else if ($type === self::EXT_TYPE_LETTER_AF) {
1098  if (in_array(self::EXT_TYPE_LETTER_AF_PLUS, $supportedTypes)) {
1099  $ok = true;
1100  $ltiOutcome->type = self::EXT_TYPE_LETTER_AF_PLUS;
1101  } else if (in_array(self::EXT_TYPE_TEXT, $supportedTypes)) {
1102  $ok = true;
1103  $ltiOutcome->type = self::EXT_TYPE_TEXT;
1104  }
1105 // Convert letter_af_plus to letter_af or text
1106  } else if ($type === self::EXT_TYPE_LETTER_AF_PLUS) {
1107  if (in_array(self::EXT_TYPE_LETTER_AF, $supportedTypes) && (strlen($value) === 1)) {
1108  $ok = true;
1109  $ltiOutcome->type = self::EXT_TYPE_LETTER_AF;
1110  } else if (in_array(self::EXT_TYPE_TEXT, $supportedTypes)) {
1111  $ok = true;
1112  $ltiOutcome->type = self::EXT_TYPE_TEXT;
1113  }
1114 // Convert text to decimal
1115  } else if ($type === self::EXT_TYPE_TEXT) {
1116  $ok = is_numeric($value) && ($value >= 0) && ($value <=1);
1117  if ($ok) {
1118  $ltiOutcome->type = self::EXT_TYPE_DECIMAL;
1119  } else if (substr($value, -1) === '%') {
1120  $value = substr($value, 0, -1);
1121  $ok = is_numeric($value) && ($value >= 0) && ($value <=100);
1122  if ($ok) {
1123  if (in_array(self::EXT_TYPE_PERCENTAGE, $supportedTypes)) {
1124  $ltiOutcome->type = self::EXT_TYPE_PERCENTAGE;
1125  } else {
1126  $ltiOutcome->setValue($value / 100);
1127  $ltiOutcome->type = self::EXT_TYPE_DECIMAL;
1128  }
1129  }
1130  }
1131  }
1132  }
1133 
1134  return $ok;
1135 
1136  }
1137 
1147  private function doService($type, $url, $params)
1148  {
1149 
1150  $ok = false;
1151  $this->extRequest = null;
1152  $this->extRequestHeaders = '';
1153  $this->extResponse = null;
1154  $this->extResponseHeaders = '';
1155  if (!empty($url)) {
1156  $params = $this->getConsumer()->signParameters($url, $type, $this->getConsumer()->ltiVersion, $params);
1157 // Connect to tool consumer
1158  $http = new HTTPMessage($url, 'POST', $params);
1159 // Parse XML response
1160  if ($http->send()) {
1161  $this->extResponse = $http->response;
1162  $this->extResponseHeaders = $http->responseHeaders;
1163  try {
1164  $this->extDoc = new DOMDocument();
1165  $this->extDoc->loadXML($http->response);
1166  $this->extNodes = $this->domnodeToArray($this->extDoc->documentElement);
1167  if (isset($this->extNodes['statusinfo']['codemajor']) && ($this->extNodes['statusinfo']['codemajor'] === 'Success')) {
1168  $ok = true;
1169  }
1170  } catch (\Exception $e) {
1171  }
1172  }
1173  $this->extRequest = $http->request;
1174  $this->extRequestHeaders = $http->requestHeaders;
1175  }
1176 
1177  return $ok;
1178 
1179  }
1180 
1190  private function doLTI11Service($type, $url, $xml)
1191  {
1192 
1193  $ok = false;
1194  $this->extRequest = null;
1195  $this->extRequestHeaders = '';
1196  $this->extResponse = null;
1197  $this->extResponseHeaders = '';
1198  if (!empty($url)) {
1199  $id = uniqid();
1200  $xmlRequest = <<< EOD
1201 <?xml version = "1.0" encoding = "UTF-8"?>
1202 <imsx_POXEnvelopeRequest xmlns = "http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0">
1203  <imsx_POXHeader>
1204  <imsx_POXRequestHeaderInfo>
1205  <imsx_version>V1.0</imsx_version>
1206  <imsx_messageIdentifier>{$id}</imsx_messageIdentifier>
1207  </imsx_POXRequestHeaderInfo>
1208  </imsx_POXHeader>
1209  <imsx_POXBody>
1210  <{$type}Request>
1211 {$xml}
1212  </{$type}Request>
1213  </imsx_POXBody>
1214 </imsx_POXEnvelopeRequest>
1215 EOD;
1216 // Calculate body hash
1217  $hash = base64_encode(sha1($xmlRequest, true));
1218  $params = array('oauth_body_hash' => $hash);
1219 
1220 // Add OAuth signature
1221  $hmacMethod = new OAuth\OAuthSignatureMethod_HMAC_SHA1();
1222  $consumer = new OAuth\OAuthConsumer($this->getConsumer()->getKey(), $this->getConsumer()->secret, null);
1224  $req->sign_request($hmacMethod, $consumer, null);
1225  $params = $req->get_parameters();
1226  $header = $req->to_header();
1227  $header .= "\nContent-Type: application/xml";
1228 // Connect to tool consumer
1229  $http = new HTTPMessage($url, 'POST', $xmlRequest, $header);
1230 // Parse XML response
1231  if ($http->send()) {
1232  $this->extResponse = $http->response;
1233  $this->extResponseHeaders = $http->responseHeaders;
1234  try {
1235  $this->extDoc = new DOMDocument();
1236  $this->extDoc->loadXML($http->response);
1237  $this->extNodes = $this->domnodeToArray($this->extDoc->documentElement);
1238  if (isset($this->extNodes['imsx_POXHeader']['imsx_POXResponseHeaderInfo']['imsx_statusInfo']['imsx_codeMajor']) &&
1239  ($this->extNodes['imsx_POXHeader']['imsx_POXResponseHeaderInfo']['imsx_statusInfo']['imsx_codeMajor'] === 'success')) {
1240  $ok = true;
1241  }
1242  } catch (\Exception $e) {
1243  }
1244  }
1245  $this->extRequest = $http->request;
1246  $this->extRequestHeaders = $http->requestHeaders;
1247  }
1248 
1249  return $ok;
1250 
1251  }
1252 
1260  private function domnodeToArray($node)
1261  {
1262 
1263  $output = '';
1264  switch ($node->nodeType) {
1265  case XML_CDATA_SECTION_NODE:
1266  case XML_TEXT_NODE:
1267  $output = trim($node->textContent);
1268  break;
1269  case XML_ELEMENT_NODE:
1270  for ($i = 0; $i < $node->childNodes->length; $i++) {
1271  $child = $node->childNodes->item($i);
1272  $v = $this->domnodeToArray($child);
1273  if (isset($child->tagName)) {
1274  $t = $child->tagName;
1275  if (!isset($output[$t])) {
1276  $output[$t] = array();
1277  }
1278  $output[$t][] = $v;
1279  } else {
1280  $s = (string) $v;
1281  if (strlen($s) > 0) {
1282  $output = $s;
1283  }
1284  }
1285  }
1286  if (is_array($output)) {
1287  if ($node->attributes->length) {
1288  $a = array();
1289  foreach ($node->attributes as $attrName => $attrNode) {
1290  $a[$attrName] = (string) $attrNode->value;
1291  }
1292  $output['@attributes'] = $a;
1293  }
1294  foreach ($output as $t => $v) {
1295  if (is_array($v) && count($v)==1 && $t!='@attributes') {
1296  $output[$t] = $v[0];
1297  }
1298  }
1299  }
1300  break;
1301  }
1302 
1303  return $output;
1304 
1305  }
1306 
1307 }
$params
Definition: disable.php:11
if($orgName !==null) if($spconfig->hasValue('contacts')) $email
Definition: metadata.php:193
Add rich text string
static parseRoles($roles)
Get an array of fully qualified user roles.
static fromRecordId($id, $dataConnector)
Load the context from the database.
Definition: Context.php:407
const ID_SCOPE_RESOURCE
Prefix the ID with the consumer key and resource ID.
$action
$type
Class to implement the Membership service.
Definition: Membership.php:16
static fromRecordId($id, $dataConnector)
Load the tool consumer from the database by its record ID.
$s
Definition: pwgen.php:45
$service
Definition: login.php:15
$req
Definition: getUserInfo.php:20
static fromResourceLink($resourceLink, $ltiUserId)
Class constructor from resource link.
Definition: User.php:413
static from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=null)
pretty much a helper function to set up the request
$xml
Definition: metadata.php:240
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
if($format !==null) $name
Definition: metadata.php:146
const MODE_CURRENT_LEVEL
Settings at current level mode.
Class to represent an OAuth Consumer.
$http
Definition: raiseError.php:7
EOD
Definition: example_053.php:93
Create styles array
The data for the language used.
$users
Definition: authpage.php:44
Class to implement a service.
Definition: Service.php:17
settings()
Definition: settings.php:2
$i
Definition: disco.tpl.php:19
$url
$response
Class to implement the Tool Settings service.
Class to represent an HTTP message.
Definition: HTTPMessage.php:14
Class to represent an OAuth HMAC_SHA1 signature method.
const EOF
How fgetc() reports an End Of File.
Definition: JSMin_lib.php:92