]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / vendor / justinrainbow / json-schema / src / JsonSchema / Uri / UriResolver.php
1 <?php
2
3 /*
4  * This file is part of the JsonSchema package.
5  *
6  * For the full copyright and license information, please view the LICENSE
7  * file that was distributed with this source code.
8  */
9
10 namespace JsonSchema\Uri;
11
12 use JsonSchema\Exception\UriResolverException;
13 use JsonSchema\UriResolverInterface;
14
15 /**
16  * Resolves JSON Schema URIs
17  *
18  * @author Sander Coolen <sander@jibber.nl>
19  */
20 class UriResolver implements UriResolverInterface
21 {
22     /**
23      * Parses a URI into five main components
24      *
25      * @param string $uri
26      *
27      * @return array
28      */
29     public function parse($uri)
30     {
31         preg_match('|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|', $uri, $match);
32
33         $components = array();
34         if (5 < count($match)) {
35             $components =  array(
36                 'scheme'    => $match[2],
37                 'authority' => $match[4],
38                 'path'      => $match[5]
39             );
40         }
41         if (7 < count($match)) {
42             $components['query'] = $match[7];
43         }
44         if (9 < count($match)) {
45             $components['fragment'] = $match[9];
46         }
47
48         return $components;
49     }
50
51     /**
52      * Builds a URI based on n array with the main components
53      *
54      * @param array $components
55      *
56      * @return string
57      */
58     public function generate(array $components)
59     {
60         $uri = $components['scheme'] . '://'
61              . $components['authority']
62              . $components['path'];
63
64         if (array_key_exists('query', $components)) {
65             $uri .= $components['query'];
66         }
67         if (array_key_exists('fragment', $components)) {
68             $uri .= '#' . $components['fragment'];
69         }
70
71         return $uri;
72     }
73
74     /**
75      * {@inheritdoc}
76      */
77     public function resolve($uri, $baseUri = null)
78     {
79         if ($uri == '') {
80             return $baseUri;
81         }
82
83         $components = $this->parse($uri);
84         $path = $components['path'];
85
86         if (!empty($components['scheme'])) {
87             return $uri;
88         }
89         $baseComponents = $this->parse($baseUri);
90         $basePath = $baseComponents['path'];
91
92         $baseComponents['path'] = self::combineRelativePathWithBasePath($path, $basePath);
93         if (isset($components['fragment'])) {
94             $baseComponents['fragment'] = $components['fragment'];
95         }
96
97         return $this->generate($baseComponents);
98     }
99
100     /**
101      * Tries to glue a relative path onto an absolute one
102      *
103      * @param string $relativePath
104      * @param string $basePath
105      *
106      * @throws UriResolverException
107      *
108      * @return string Merged path
109      */
110     public static function combineRelativePathWithBasePath($relativePath, $basePath)
111     {
112         $relativePath = self::normalizePath($relativePath);
113         if ($relativePath == '') {
114             return $basePath;
115         }
116         if ($relativePath[0] == '/') {
117             return $relativePath;
118         }
119
120         $basePathSegments = explode('/', $basePath);
121
122         preg_match('|^/?(\.\./(?:\./)*)*|', $relativePath, $match);
123         $numLevelUp = strlen($match[0]) /3 + 1;
124         if ($numLevelUp >= count($basePathSegments)) {
125             throw new UriResolverException(sprintf("Unable to resolve URI '%s' from base '%s'", $relativePath, $basePath));
126         }
127
128         $basePathSegments = array_slice($basePathSegments, 0, -$numLevelUp);
129         $path = preg_replace('|^/?(\.\./(\./)*)*|', '', $relativePath);
130
131         return implode('/', $basePathSegments) . '/' . $path;
132     }
133
134     /**
135      * Normalizes a URI path component by removing dot-slash and double slashes
136      *
137      * @param string $path
138      *
139      * @return string
140      */
141     private static function normalizePath($path)
142     {
143         $path = preg_replace('|((?<!\.)\./)*|', '', $path);
144         $path = preg_replace('|//|', '/', $path);
145
146         return $path;
147     }
148
149     /**
150      * @param string $uri
151      *
152      * @return bool
153      */
154     public function isValid($uri)
155     {
156         $components = $this->parse($uri);
157
158         return !empty($components);
159     }
160 }