ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
functions.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Sabre\Uri;
4 
23 function resolve($basePath, $newPath) {
24 
25  $base = parse($basePath);
26  $delta = parse($newPath);
27 
28  $pick = function($part) use ($base, $delta) {
29 
30  if ($delta[$part]) {
31  return $delta[$part];
32  } elseif ($base[$part]) {
33  return $base[$part];
34  }
35  return null;
36 
37  };
38 
39  // If the new path defines a scheme, it's absolute and we can just return
40  // that.
41  if ($delta['scheme']) {
42  return build($delta);
43  }
44 
45  $newParts = [];
46 
47  $newParts['scheme'] = $pick('scheme');
48  $newParts['host'] = $pick('host');
49  $newParts['port'] = $pick('port');
50 
51  $path = '';
52  if ($delta['path']) {
53  // If the path starts with a slash
54  if ($delta['path'][0] === '/') {
55  $path = $delta['path'];
56  } else {
57  // Removing last component from base path.
58  $path = $base['path'];
59  if (strpos($path, '/') !== false) {
60  $path = substr($path, 0, strrpos($path, '/'));
61  }
62  $path .= '/' . $delta['path'];
63  }
64  } else {
65  $path = $base['path'] ?: '/';
66  }
67  // Removing .. and .
68  $pathParts = explode('/', $path);
69  $newPathParts = [];
70  foreach ($pathParts as $pathPart) {
71 
72  switch ($pathPart) {
73  //case '' :
74  case '.' :
75  break;
76  case '..' :
77  array_pop($newPathParts);
78  break;
79  default :
80  $newPathParts[] = $pathPart;
81  break;
82  }
83  }
84 
85  $path = implode('/', $newPathParts);
86 
87  // If the source url ended with a /, we want to preserve that.
88  $newParts['path'] = $path;
89  if ($delta['query']) {
90  $newParts['query'] = $delta['query'];
91  } elseif (!empty($base['query']) && empty($delta['host']) && empty($delta['path'])) {
92  // Keep the old query if host and path didn't change
93  $newParts['query'] = $base['query'];
94  }
95  if ($delta['fragment']) {
96  $newParts['fragment'] = $delta['fragment'];
97  }
98  return build($newParts);
99 
100 }
101 
114 function normalize($uri) {
115 
116  $parts = parse($uri);
117 
118  if (!empty($parts['path'])) {
119  $pathParts = explode('/', ltrim($parts['path'], '/'));
120  $newPathParts = [];
121  foreach ($pathParts as $pathPart) {
122  switch ($pathPart) {
123  case '.':
124  // skip
125  break;
126  case '..' :
127  // One level up in the hierarchy
128  array_pop($newPathParts);
129  break;
130  default :
131  // Ensuring that everything is correctly percent-encoded.
132  $newPathParts[] = rawurlencode(rawurldecode($pathPart));
133  break;
134  }
135  }
136  $parts['path'] = '/' . implode('/', $newPathParts);
137  }
138 
139  if ($parts['scheme']) {
140  $parts['scheme'] = strtolower($parts['scheme']);
141  $defaultPorts = [
142  'http' => '80',
143  'https' => '443',
144  ];
145 
146  if (!empty($parts['port']) && isset($defaultPorts[$parts['scheme']]) && $defaultPorts[$parts['scheme']] == $parts['port']) {
147  // Removing default ports.
148  unset($parts['port']);
149  }
150  // A few HTTP specific rules.
151  switch ($parts['scheme']) {
152  case 'http' :
153  case 'https' :
154  if (empty($parts['path'])) {
155  // An empty path is equivalent to / in http.
156  $parts['path'] = '/';
157  }
158  break;
159  }
160  }
161 
162  if ($parts['host']) $parts['host'] = strtolower($parts['host']);
163 
164  return build($parts);
165 
166 }
167 
181 function parse($uri) {
182 
183  // Normally a URI must be ASCII, however. However, often it's not and
184  // parse_url might corrupt these strings.
185  //
186  // For that reason we take any non-ascii characters from the uri and
187  // uriencode them first.
188  $uri = preg_replace_callback(
189  '/[^[:ascii:]]/u',
190  function($matches) {
191  return rawurlencode($matches[0]);
192  },
193  $uri
194  );
195 
196  $result = parse_url($uri);
197  if (!$result) {
198  $result = _parse_fallback($uri);
199  }
200 
201  return
202  $result + [
203  'scheme' => null,
204  'host' => null,
205  'path' => null,
206  'port' => null,
207  'user' => null,
208  'query' => null,
209  'fragment' => null,
210  ];
211 
212 }
213 
221 function build(array $parts) {
222 
223  $uri = '';
224 
225  $authority = '';
226  if (!empty($parts['host'])) {
227  $authority = $parts['host'];
228  if (!empty($parts['user'])) {
229  $authority = $parts['user'] . '@' . $authority;
230  }
231  if (!empty($parts['port'])) {
232  $authority = $authority . ':' . $parts['port'];
233  }
234  }
235 
236  if (!empty($parts['scheme'])) {
237  // If there's a scheme, there's also a host.
238  $uri = $parts['scheme'] . ':';
239 
240  }
241  if ($authority || (!empty($parts['scheme']) && $parts['scheme'] === 'file')) {
242  // No scheme, but there is a host.
243  $uri .= '//' . $authority;
244 
245  }
246 
247  if (!empty($parts['path'])) {
248  $uri .= $parts['path'];
249  }
250  if (!empty($parts['query'])) {
251  $uri .= '?' . $parts['query'];
252  }
253  if (!empty($parts['fragment'])) {
254  $uri .= '#' . $parts['fragment'];
255  }
256 
257  return $uri;
258 
259 }
260 
279 function split($path) {
280 
281  $matches = [];
282  if (preg_match('/^(?:(?:(.*)(?:\/+))?([^\/]+))(?:\/?)$/u', $path, $matches)) {
283  return [$matches[1], $matches[2]];
284  }
285  return [null,null];
286 
287 }
288 
302 function _parse_fallback($uri) {
303 
304  // Normally a URI must be ASCII, however. However, often it's not and
305  // parse_url might corrupt these strings.
306  //
307  // For that reason we take any non-ascii characters from the uri and
308  // uriencode them first.
309  $uri = preg_replace_callback(
310  '/[^[:ascii:]]/u',
311  function($matches) {
312  return rawurlencode($matches[0]);
313  },
314  $uri
315  );
316 
317  $result = [
318  'scheme' => null,
319  'host' => null,
320  'port' => null,
321  'user' => null,
322  'path' => null,
323  'fragment' => null,
324  'query' => null,
325  ];
326 
327  if (preg_match('% ^([A-Za-z][A-Za-z0-9+-\.]+): %x', $uri, $matches)) {
328 
329  $result['scheme'] = $matches[1];
330  // Take what's left.
331  $uri = substr($uri, strlen($result['scheme']) + 1);
332 
333  }
334 
335  // Taking off a fragment part
336  if (strpos($uri, '#') !== false) {
337  list($uri, $result['fragment']) = explode('#', $uri, 2);
338  }
339  // Taking off the query part
340  if (strpos($uri, '?') !== false) {
341  list($uri, $result['query']) = explode('?', $uri, 2);
342  }
343 
344  if (substr($uri, 0, 3) === '
345  // The triple slash uris are a bit unusual, but we have special handling
346  // for them.
347  $result['path'] = substr($uri, 2);
348  $result['host'] = '';
349  } elseif (substr($uri, 0, 2) === '//') {
350  // Uris that have an authority part.
351  $regex = '
352  %^
353  //
354  (?: (?<user> [^:@]+) (: (?<pass> [^@]+)) @)?
355  (?<host> ( [^:/]* | \[ [^\]]+ \] ))
356  (?: : (?<port> [0-9]+))?
357  (?<path> / .*)?
358  $%x
359  ';
360  if (!preg_match($regex, $uri, $matches)) {
361  throw new InvalidUriException('Invalid, or could not parse URI');
362  }
363  if ($matches['host']) $result['host'] = $matches['host'];
364  if ($matches['port']) $result['port'] = (int)$matches['port'];
365  if (isset($matches['path'])) $result['path'] = $matches['path'];
366  if ($matches['user']) $result['user'] = $matches['user'];
367  if ($matches['pass']) $result['pass'] = $matches['pass'];
368  } else {
369  $result['path'] = $uri;
370  }
371 
372  return $result;
373 }
$path
Definition: aliased.php:25
resolve($basePath, $newPath)
This file contains all the uri handling functions.
Definition: functions.php:23
$result
split($path)
Returns the &#39;dirname&#39; and &#39;basename&#39; for a path.
Definition: functions.php:279
_parse_fallback($uri)
This function is another implementation of parse_url, except this one is fully written in PHP...
Definition: functions.php:302
$base
Definition: index.php:4
parse($uri)
Parses a URI and returns its individual components.
Definition: functions.php:181
build(array $parts)
This function takes the components returned from PHP&#39;s parse_url, and uses it to generate a new uri...
Definition: functions.php:221
$authority
normalize($uri)
Takes a URI or partial URI as its argument, and normalizes it.
Definition: functions.php:114