LTI Integration Library  3.1.0
PHP class library for building LTI integrations
OAuthUtil.php
Go to the documentation of this file.
1 <?php
2 
3 namespace ceLTIc\LTI\OAuth;
4 
12 class OAuthUtil
13 {
14 
15  public static function urlencode_rfc3986($input)
16  {
17  if (is_array($input)) {
18  return array_map(array('ceLTIc\LTI\OAuth\OAuthUtil', 'urlencode_rfc3986'), $input);
19  } elseif (is_scalar($input)) {
20  return str_replace('+', ' ', str_replace('%7E', '~', rawurlencode($input)));
21  } else {
22  return '';
23  }
24  }
25 
26  // This decode function isn't taking into consideration the above
27  // modifications to the encoding process. However, this method doesn't
28  // seem to be used anywhere so leaving it as is.
29  public static function urldecode_rfc3986($string)
30  {
31  return urldecode($string);
32  }
33 
34  // Utility function for turning the Authorization: header into
35  // parameters, has to do some unescaping
36  // Can filter out any non-oauth parameters if needed (default behaviour)
37  // May 28th, 2010 - method updated to tjerk.meesters for a speed improvement.
38  // see http://code.google.com/p/oauth/issues/detail?id=163
39  public static function split_header($header, $only_allow_oauth_parameters = true)
40  {
41  $params = array();
42  if (preg_match_all('/(' . ($only_allow_oauth_parameters ? 'oauth_' : '') . '[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', $header,
43  $matches)) {
44  foreach ($matches[1] as $i => $h) {
45  $params[$h] = OAuthUtil::urldecode_rfc3986(empty($matches[3][$i]) ? $matches[4][$i] : $matches[3][$i]);
46  }
47  if (isset($params['realm'])) {
48  unset($params['realm']);
49  }
50  }
51 
52  return $params;
53  }
54 
55  // helper to try to sort out headers for people who aren't running apache
56  public static function get_headers()
57  {
58  if (function_exists('apache_request_headers')) {
59  // we need this to get the actual Authorization: header
60  // because apache tends to tell us it doesn't exist
61  $headers = apache_request_headers();
62 
63  // sanitize the output of apache_request_headers because
64  // we always want the keys to be Cased-Like-This and arh()
65  // returns the headers in the same case as they are in the
66  // request
67  $out = array();
68  foreach ($headers AS $key => $value) {
69  $key = str_replace(" ", "-", ucwords(strtolower(str_replace("-", " ", $key))));
70  $out[$key] = $value;
71  }
72  } else {
73  // otherwise we don't have apache and are just going to have to hope
74  // that $_SERVER actually contains what we need
75  $out = array();
76  if (isset($_SERVER['CONTENT_TYPE']))
77  $out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
78  if (isset($_ENV['CONTENT_TYPE']))
79  $out['Content-Type'] = $_ENV['CONTENT_TYPE'];
80 
81  foreach ($_SERVER as $key => $value) {
82  if (substr($key, 0, 5) == 'HTTP_') {
83  // this is chaos, basically it is just there to capitalize the first
84  // letter of every word that is not an initial HTTP and strip HTTP
85  // code from przemek
86  $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($key, 5)))));
87  $out[$key] = $value;
88  }
89  }
90  }
91  return $out;
92  }
93 
94  // This function takes a input like a=b&a=c&d=e and returns the parsed
95  // parameters like this
96  // array('a' => array('b','c'), 'd' => 'e')
97  public static function parse_parameters($input)
98  {
99  if (!isset($input) || !$input)
100  return array();
101 
102  $pairs = explode('&', $input);
103 
104  $parsed_parameters = array();
105  foreach ($pairs as $pair) {
106  $split = explode('=', $pair, 2);
107  $parameter = self::urldecode_rfc3986($split[0]);
108  $value = isset($split[1]) ? self::urldecode_rfc3986($split[1]) : '';
109 
110  if (isset($parsed_parameters[$parameter])) {
111  // We have already recieved parameter(s) with this name, so add to the list
112  // of parameters with this name
113 
114  if (is_scalar($parsed_parameters[$parameter])) {
115  // This is the first duplicate, so transform scalar (string) into an array
116  // so we can add the duplicates
117  $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
118  }
119 
120  $parsed_parameters[$parameter][] = $value;
121  } else {
122  $parsed_parameters[$parameter] = $value;
123  }
124  }
125 
126  return $parsed_parameters;
127  }
128 
129  public static function build_http_query($params)
130  {
131  if (!$params)
132  return '';
133 
134  // Urlencode both keys and values
135  $keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
136  $values = OAuthUtil::urlencode_rfc3986(array_values($params));
137  $params = array_combine($keys, $values);
138 
139  // Parameters are sorted by name, using lexicographical byte value ordering.
140  // Ref: Spec: 9.1.1 (1)
141  uksort($params, 'strcmp');
142 
143  $pairs = array();
144  foreach ($params as $parameter => $value) {
145  if (is_array($value)) {
146  // If two or more parameters share the same name, they are sorted by their value
147  // Ref: Spec: 9.1.1 (1)
148  // June 12th, 2010 - changed to sort because of issue 164 by hidetaka
149  sort($value, SORT_STRING);
150  foreach ($value as $duplicate_value) {
151  $pairs[] = $parameter . '=' . $duplicate_value;
152  }
153  } else {
154  $pairs[] = $parameter . '=' . $value;
155  }
156  }
157 
158  // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
159  // Each name-value pair is separated by an '&' character (ASCII code 38)
160  return implode('&', $pairs);
161  }
162 
163 }
static split_header($header, $only_allow_oauth_parameters=true)
Definition: OAuthUtil.php:39
static urlencode_rfc3986($input)
Definition: OAuthUtil.php:15
static build_http_query($params)
Definition: OAuthUtil.php:129
static urldecode_rfc3986($string)
Definition: OAuthUtil.php:29
Class to provide OAuth utility methods.
Definition: OAuthUtil.php:12
static parse_parameters($input)
Definition: OAuthUtil.php:97