You are here

lti_tool_provider_outcomes.connect.inc in LTI Tool Provider 7

Functions for http xml requests to LTI Consumer services.

File

lti_tool_provider_outcomes/lti_tool_provider_outcomes.connect.inc
View source
<?php

/**
 * @file
 * Functions for http xml requests to LTI Consumer services.
 */

/**
 * Send single grade via http post.
 *
 * @param string $params
 *   An array containing the POST data, eg, lti_message_type etc.
 * @param string $key
 *   The consumer key.
 * @param string $url
 *   URL of the LTI service.
 *
 * @return string
 *   HTTP response.
 */
function lti_tool_provider_outcomes_lti_service_post($params, $key, $url) {
  $ext_response = NULL;
  if (!empty($url)) {

    // Check for query parameters which need to be included in the signature.
    $query_params = array();
    $query_string = parse_url($url, PHP_URL_QUERY);
    if (!is_null($query_string)) {
      $query_items = explode('&', $query_string);
      foreach ($query_items as $item) {
        if (strpos($item, '=') !== FALSE) {
          list($name, $value) = explode('=', $item);
          $query_params[$name] = $value;
        }
        else {
          $query_params[$name] = '';
        }
      }
    }
    $params = $params + $query_params;

    // Add standard parameters.
    $params['oauth_consumer_key'] = $key;
    $params['lti_version'] = 'LTI-1p0';
    $oauth_consumer_key = $key;
    $store = new LTIToolProviderOAuthDataStore();
    $consumer = $store
      ->lookup_consumer($oauth_consumer_key);
    $token = '';
    $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
    $request = OAuthRequest::from_consumer_and_token($consumer, $token, 'POST', $url, $params);
    $request
      ->sign_request($hmac_method, $consumer, $token);
    $params = $request
      ->get_parameters();

    // Remove parameters being passed on the query string.
    foreach (array_keys($query_params) as $name) {
      unset($params[$name]);
    }

    // Connect to tool consumer.
    // http_build_query($params).
    $options = array(
      'data' => http_build_query($params),
      'method' => 'POST',
      'max_redirects' => 5,
      'headers' => array(
        'Content-Type' => 'application/x-www-form-urlencoded',
      ),
    );
    $ext_response = drupal_http_request($url, $options);
  }
  return $ext_response;
}

/**
 * Constructs an array of parameters(READ) for the http post.
 *
 * @param string $sourcedid
 *   Sourece did of the incoming request.
 *
 * @return array
 *   Array of parameters.
 */
function lti_tool_provider_outcomes_construct_params_array_read($sourcedid) {
  $params = array();
  $params['lti_message_type'] = 'basic-lis-readresult';
  $params['sourcedid'] = $sourcedid;
  return $params;
}

/**
 * Constructs an array of parameters(UPDATE) for the http post.
 *
 * @param string $source_did
 *   Result Source DID.
 * @param string $grade
 *   Grade of the outcome record.
 * @param string $datatype
 *   Datatype of the resource.
 *
 * @return array
 *   Array of parameters.
 */
function lti_tool_provider_outcomes_construct_params_array_update($source_did, $grade, $base_no, $datatype) {
  $params = array();
  $params['lti_message_type'] = 'basic-lis-updateresult';
  $params['sourcedid'] = $source_did;

  // $params['result_resultscore_textstring'] =
  // lti_tool_provider_outcomes_format_raw_score($grade, $base_no, $datatype);
  $params['result_resultscore_textstring'] = $grade;
  $params['result_resultvaluesourcedid'] = 'decimal';
  return $params;
}

/**
 * Constructs an array of parameters(DELETE) for the http post.
 *
 * @param string $sourcedid
 *   Result Source DID.
 *
 * @return array
 *   Array of parameters.
 */
function lti_tool_provider_outcomes_construct_params_array_delete($sourcedid) {
  $params = array();
  $params['lti_message_type'] = 'basic-lis-deleteresult';
  $params['sourcedid'] = $sourcedid;
  return $params;
}

/**
 * Implements lti_tool_provider_outcomes_lti_service_xml().
 *
 * @param string $consumer
 *   Consumer entity.
 * @param string $url
 *   Endpoint URL.
 * @param string $message_type
 *   1 : UPDATE / replaceRESULT
 *   2 : READ / readRESULT
 *   3 : DELETE / deleteRESULT.
 * @param string $source_did
 *   lis_result_sourcedid.
 * @param string $grade
 *   OPTIONAL. Grade value to be updated.
 *
 * @return string
 *   HTTP response.
 */
function lti_tool_provider_outcomes_lti_service_xml($consumer, $url, $message_type, $source_did, $grade = NULL) {
  switch ($message_type) {

    // Create grades UPDATE xml service body.
    case 1:
      $body = lti_tool_provider_outcomes_create_grades_update_service_body($source_did, $grade);
      break;

    // Create grades READ xml service body.
    case 2:
      $body = lti_tool_provider_outcomes_create_grades_read_service_body($source_did);
      break;

    // Create grades DELETE xml service body.
    case 3:
      $body = lti_tool_provider_outcomes_create_grades_delete_service_body($source_did);
      break;
  }
  $response = lti_tool_provider_outcomes_send_oauth_xml_body_post('POST', $url, $consumer->lti_tool_provider_consumer_key, $consumer->lti_tool_provider_consumer_secret, 'application/xml', $body);
  return $response;
}

/**
 * Create a IMS POX body request for sync grades.
 *
 * @param string $source
 *   Source did required for the request.
 * @param float $grade
 *   User grade.
 *
 * @return string
 *   XML body.
 */
function lti_tool_provider_outcomes_create_grades_update_service_body($source, $grade) {
  return '<?xml version = "1.0" encoding = "UTF-8"?>
    <imsx_POXEnvelopeRequest xmlns = "http://www.imsglobal.org/lis/oms1p0/pox">
    <imsx_POXHeader>
    <imsx_POXRequestHeaderInfo>
    <imsx_version>V1.0</imsx_version>
    <imsx_messageIdentifier>' . REQUEST_TIME . '</imsx_messageIdentifier>
      </imsx_POXRequestHeaderInfo>
      </imsx_POXHeader>
      <imsx_POXBody>
      <replaceResultRequest>
      <resultRecord>
      <sourcedGUID>
      <sourcedId>' . $source . '</sourcedId>
        </sourcedGUID>
        <result>
        <resultScore>
        <language>en-us</language>
        <textString>' . $grade . '</textString>
          </resultScore>
          </result>
          </resultRecord>
          </replaceResultRequest>
          </imsx_POXBody>
          </imsx_POXEnvelopeRequest>';
}

/**
 * Create a IMS POX body request for reading grades.
 *
 * @param string $source
 *   Sourceid required for the request.
 *
 * @return string
 *   XML body.
 */
function lti_tool_provider_outcomes_create_grades_read_service_body($source) {
  return '<?xml version = "1.0" encoding = "UTF-8"?>
    <imsx_POXEnvelopeRequest xmlns = "http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0">
    <imsx_POXHeader>
    <imsx_POXRequestHeaderInfo>
    <imsx_version>V1.0</imsx_version>
    <imsx_messageIdentifier>' . REQUEST_TIME . '</imsx_messageIdentifier>
      </imsx_POXRequestHeaderInfo>
      </imsx_POXHeader>
      <imsx_POXBody>
      <readResultRequest>
      <resultRecord>
      <sourcedGUID>
      <sourcedId>' . $source . '</sourcedId>
        </sourcedGUID>
        </resultRecord>
        </readResultRequest>
        </imsx_POXBody>
        </imsx_POXEnvelopeRequest>';
}

/**
 * Create a IMS POX body request for deleting grades.
 *
 * @param string $source
 *   Source did required for the request.
 *
 * @return string
 *   XML body.
 */
function lti_tool_provider_outcomes_create_grades_delete_service_body($source) {
  return '<?xml version = "1.0" encoding = "UTF-8"?>
    <imsx_POXEnvelopeRequest xmlns = "http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0">
    <imsx_POXHeader>
    <imsx_POXRequestHeaderInfo>
    <imsx_version>V1.0</imsx_version>
    <imsx_messageIdentifier>' . REQUEST_TIME . '</imsx_messageIdentifier>
      </imsx_POXRequestHeaderInfo>
      </imsx_POXHeader>
      <imsx_POXBody>
      <deleteResultRequest>
      <resultRecord>
      <sourcedGUID>
      <sourcedId>' . $source . '</sourcedId>
        </sourcedGUID>
        </resultRecord>
        </deleteResultRequest>
        </imsx_POXBody>
        </imsx_POXEnvelopeRequest>';
}

/**
 * Use Oauth to sign the XML body.
 *
 * @param string $method
 *   HTTP method.
 * @param string $endpoint
 *   Endpoint Service URL.
 * @param string $oauth_consumer_key
 *   Consumer Key.
 * @param string $content_type
 *   HTTP request content type.
 * @param string $body
 *   XML body.
 *
 * @return string
 *   HTTP Response.
 */
function lti_tool_provider_outcomes_send_oauth_xml_body_post($method, $endpoint, $oauth_consumer_key, $oauth_consumer_secret, $content_type, $body) {
  $hash = base64_encode(sha1($body, TRUE));
  $parms = array(
    'oauth_body_hash' => $hash,
  );
  $test_token = '';
  $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
  $test_consumer = new OAuthConsumer($oauth_consumer_key, $oauth_consumer_secret, NULL);
  $acc_req = OAuthRequest::from_consumer_and_token($test_consumer, $test_token, $method, $endpoint, $parms);
  $acc_req
    ->sign_request($hmac_method, $test_consumer, $test_token);
  $header = $acc_req
    ->to_header();
  $header = $header . "\r\nContent-type: " . $content_type . "\r\n";
  $params = array(
    'http' => array(
      'method' => 'POST',
      'content' => $body,
      'header' => $header,
    ),
  );
  $ctx = stream_context_create($params);
  $fp = @fopen($endpoint, 'rb', FALSE, $ctx);
  $response = @stream_get_contents($fp);
  return $response;
}

/**
 * Decode XML for extension services.
 *
 * @param string $data
 *   HTTP Response.
 *
 * @return boolean
 *   TRUE if success / FALSE if not successful.
 */
function lti_tool_provider_outcomes_decode_ext_xml_reply($data) {
  if ($data->code != 200) {
    drupal_set_message(t('Request failed with code @code.', array(
      '@code' => $data->code,
    )), 'info');
    return FALSE;
  }
  if ($data->status_message != 'OK') {
    drupal_set_message(t('Request failed with status @message.', array(
      '@message' => $data->status_message,
    )), 'info');
    return FALSE;
  }
  $reader = new XMLReader();
  $reader
    ->XML($data->data);
  $result = array();

  // Default XML elements.
  $codemajor = 'codemajor';
  $severity = 'severity';
  $codeminor = 'codeminor';
  while ($reader
    ->read()) {

    // Codemajor    Success / Failure / Unsupported.
    // Severity     Status / Warning / Error.
    // Codeminor    fullsuccess / reason for failure.
    // Value        Value of the setting.
    if ($reader->nodeType == XMLReader::ELEMENT && ($reader->name == $codemajor || $reader->name == $severity || $reader->name == $codeminor)) {
      $str = $reader
        ->readInnerXml();
      $codemajor_check = strcasecmp($str, 'success');
      $severity_check = strcasecmp($str, 'status');
      $codeminor_check = strcasecmp($str, 'fullsuccess');
      if ($codemajor_check == 0 || $severity_check == 0 || $codeminor_check == 0) {
        $result[] = $str;
      }
    }
  }
  $reader
    ->close();
  if (count($result) == 3) {
    return TRUE;
  }
  else {
    return FALSE;
  }
}

/**
 * Decode xml reply from lis outcome service.
 *
 * @param string $data
 *   HTTP Response.
 *
 * @return boolean
 *   TRUE if success / FALSE if not successful.
 */
function lti_tool_provider_outcomes_decode_xml_reply($data) {
  if ($data->code != 200) {
    drupal_set_message(t('Request failed with code @code.', array(
      '@code' => $data->code,
    )), 'info');
    return FALSE;
  }
  if ($data->status_message != 'OK') {
    drupal_set_message(t('Request failed with status @message.', array(
      '@message' => $data->status_message,
    )), 'info');
    return FALSE;
  }
  $reader = new XMLReader();
  $reader
    ->XML($data);
  $result = array();

  // Default XML elements.
  $imsx_codemajor = 'imsx_codeMajor';
  $imsx_severity = 'imsx_severity';
  $imsx_description = 'imsx_description';
  while ($reader
    ->read()) {

    // Codemajor    Success / Failure / Unsupported.
    // Severity     Status / Warning / Error.
    // Codeminor    fullsuccess / reason for failure.
    // Value        Value of the setting.
    if ($reader->nodeType == XMLReader::ELEMENT && ($reader->name == $imsx_codemajor || $reader->name == $imsx_severity)) {
      $str = $reader
        ->readInnerXml();
      $codemajor_check = strcasecmp($str, 'success');
      $severity_check = strcasecmp($str, 'status');
      if ($codemajor_check == 0 || $severity_check == 0) {
        $result[] = $str;
      }
    }
  }
  $reader
    ->close();
  if (count($result) == 2) {
    return TRUE;
  }
  else {
    return FALSE;
  }
}

/**
 * Extract score from extension service.
 *
 * @param string $data
 *   HTTP Response,
 *
 * @return boolean
 *   TRUE if success / FALSE if not successful
 */
function lti_tool_provider_outcomes_extract_ext_xml_score_reply($data) {
  if (isset($data)) {
    $reader = new XMLReader();
    $reader
      ->XML($data->data);
    $result = array();

    // Default XML elements.
    $codemajor = 'codemajor';
    $severity = 'severity';
    $codeminor = 'codeminor';
    while ($reader
      ->read()) {

      // Codemajor    Success / Failure / Unsupported.
      // Severity     Status / Warning / Error.
      // Codeminor    fullsuccess / reason for failure.
      // Value        Value of the setting.
      if ($reader->nodeType == XMLReader::ELEMENT && ($reader->name == $codemajor || $reader->name == $severity || $reader->name == $codeminor)) {
        $str = $reader
          ->readInnerXml();
        $codemajor_check = strcasecmp($str, 'success');
        $severity_check = strcasecmp($str, 'status');
        $codeminor_check = strcasecmp($str, 'fullsuccess');
        if ($codemajor_check == 0 || $severity_check == 0 || $codeminor_check == 0) {
          $result[] = $str;
        }
      }
      if (count($result) == 3) {
        if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'textstring') {
          $score = $reader
            ->readInnerXml();
          break;
        }
      }
    }
    $reader
      ->close();
    if (isset($score)) {
      return $score;
    }
  }
}

/**
 * Extract score from lis outcome services.
 *
 * @param string $data
 *   HTTP Response.
 *
 * @return boolean
 *   TRUE if success / FALSE if not successful.
 */
function lti_tool_provider_outcomes_extract_xml_score_reply($data) {
  if (isset($data)) {
    $reader = new XMLReader();
    $reader
      ->XML($data);
    $result = array();

    // Default XML elements.
    $imsx_codemajor = 'imsx_codeMajor';
    $imsx_severity = 'imsx_severity';
    $imsx_description = 'imsx_description';
    while ($reader
      ->read()) {

      // Codemajor    Success / Failure / Unsupported.
      // Severity     Status / Warning / Error.
      // Codeminor    fullsuccess / reason for failure.
      // Value        Value of the setting.
      if ($reader->nodeType == XMLReader::ELEMENT && ($reader->name == $imsx_codemajor || $reader->name == $imsx_severity)) {
        $str = $reader
          ->readInnerXml();
        $codemajor_check = strcasecmp($str, 'success');
        $severity_check = strcasecmp($str, 'status');
        if ($codemajor_check == 0 || $severity_check == 0) {
          $result[] = $str;
        }
      }
      if (count($result) == 2) {
        if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'textString') {
          $score = $reader
            ->readInnerXml();
          break;
        }
      }
    }
    $reader
      ->close();
    if (isset($score)) {
      return $score;
    }
  }
}

Functions

Namesort descending Description
lti_tool_provider_outcomes_construct_params_array_delete Constructs an array of parameters(DELETE) for the http post.
lti_tool_provider_outcomes_construct_params_array_read Constructs an array of parameters(READ) for the http post.
lti_tool_provider_outcomes_construct_params_array_update Constructs an array of parameters(UPDATE) for the http post.
lti_tool_provider_outcomes_create_grades_delete_service_body Create a IMS POX body request for deleting grades.
lti_tool_provider_outcomes_create_grades_read_service_body Create a IMS POX body request for reading grades.
lti_tool_provider_outcomes_create_grades_update_service_body Create a IMS POX body request for sync grades.
lti_tool_provider_outcomes_decode_ext_xml_reply Decode XML for extension services.
lti_tool_provider_outcomes_decode_xml_reply Decode xml reply from lis outcome service.
lti_tool_provider_outcomes_extract_ext_xml_score_reply Extract score from extension service.
lti_tool_provider_outcomes_extract_xml_score_reply Extract score from lis outcome services.
lti_tool_provider_outcomes_lti_service_post Send single grade via http post.
lti_tool_provider_outcomes_lti_service_xml Implements lti_tool_provider_outcomes_lti_service_xml().
lti_tool_provider_outcomes_send_oauth_xml_body_post Use Oauth to sign the XML body.