|
5 | 5 | use Yaoi\Schema\Constraint\Properties;
|
6 | 6 | use Yaoi\Schema\Constraint\Ref;
|
7 | 7 | use Yaoi\Schema\Constraint\Type;
|
| 8 | +use Yaoi\Schema\RemoteRef\BasicFetcher; |
8 | 9 |
|
9 | 10 | class SchemaLoader extends Base
|
10 | 11 | {
|
@@ -51,6 +52,25 @@ class SchemaLoader extends Base
|
51 | 52 | /** @var Ref[] */
|
52 | 53 | private $refs = array();
|
53 | 54 |
|
| 55 | + /** @var SchemaLoader[] */ |
| 56 | + private $remoteSchemaLoaders = array(); |
| 57 | + |
| 58 | + /** @var RemoteRefProvider */ |
| 59 | + private $refProvider; |
| 60 | + |
| 61 | + public function setRemoteRefProvider(RemoteRefProvider $provider) |
| 62 | + { |
| 63 | + $this->refProvider = $provider; |
| 64 | + return $this; |
| 65 | + } |
| 66 | + |
| 67 | + private function getRefProvider() |
| 68 | + { |
| 69 | + if (null === $this->refProvider) { |
| 70 | + $this->refProvider = new BasicFetcher(); |
| 71 | + } |
| 72 | + return $this->refProvider; |
| 73 | + } |
54 | 74 |
|
55 | 75 | public function readSchema($schemaData)
|
56 | 76 | {
|
@@ -230,35 +250,41 @@ private function resolveReference($referencePath)
|
230 | 250 | {
|
231 | 251 | $ref = &$this->refs[$referencePath];
|
232 | 252 | if (null === $ref) {
|
233 |
| - if ($referencePath === 'http://json-schema.org/draft-04/schema#') { |
234 |
| - $ref = new Ref( |
235 |
| - $referencePath, |
236 |
| - SchemaLoader::create()->readSchema(json_decode(file_get_contents(__DIR__ . '/../spec/json-schema.json'))) |
237 |
| - ); |
238 |
| - } elseif ($referencePath === '#') { |
239 |
| - $ref = new Ref($referencePath, $this->rootSchema); |
240 |
| - } elseif ($referencePath[0] === '#') { |
241 |
| - $path = explode('/', trim($referencePath, '#/')); |
242 |
| - $branch = &$this->rootData; |
243 |
| - while ($path) { |
244 |
| - $folder = array_shift($path); |
245 |
| - |
246 |
| - // unescaping special characters |
247 |
| - // https://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07#section-4 |
248 |
| - // https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues/130 |
249 |
| - $folder = str_replace(array('~0','~1', '%25'), array('~', '/', '%'), $folder); |
250 |
| - |
251 |
| - if ($branch instanceof \stdClass && isset($branch->$folder)) { |
252 |
| - $branch = &$branch->$folder; |
253 |
| - } elseif (is_array($branch) && isset($branch[$folder])) { |
254 |
| - $branch = &$branch[$folder]; |
255 |
| - } else { |
256 |
| - throw new \Exception('Could not resolve ' . $referencePath . ': ' . $folder); |
| 253 | + if ($referencePath[0] === '#') { |
| 254 | + if ($referencePath === '#') { |
| 255 | + $ref = new Ref($referencePath, $this->rootSchema); |
| 256 | + } else { |
| 257 | + $path = explode('/', trim($referencePath, '#/')); |
| 258 | + $branch = &$this->rootData; |
| 259 | + while ($path) { |
| 260 | + $folder = array_shift($path); |
| 261 | + |
| 262 | + // unescaping special characters |
| 263 | + // https://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07#section-4 |
| 264 | + // https://github.com/json-schema-org/JSON-Schema-Test-Suite/issues/130 |
| 265 | + $folder = str_replace(array('~0', '~1', '%25'), array('~', '/', '%'), $folder); |
| 266 | + |
| 267 | + if ($branch instanceof \stdClass && isset($branch->$folder)) { |
| 268 | + $branch = &$branch->$folder; |
| 269 | + } elseif (is_array($branch) && isset($branch[$folder])) { |
| 270 | + $branch = &$branch[$folder]; |
| 271 | + } else { |
| 272 | + throw new \Exception('Could not resolve ' . $referencePath . ': ' . $folder); |
| 273 | + } |
257 | 274 | }
|
| 275 | + $ref = new Ref($referencePath, $this->readSchema($branch)); |
258 | 276 | }
|
259 |
| - $ref = new Ref($referencePath, $this->readSchema($branch)); |
260 | 277 | } else {
|
261 |
| - throw new \Exception('Could not resolve ' . $referencePath); |
| 278 | + $refParts = explode('#', $referencePath); |
| 279 | + $url = $refParts[0]; |
| 280 | + $refLocalPath = isset($refParts[1]) ? '#' . $refParts[1] : '#'; |
| 281 | + $schemaLoader = &$this->remoteSchemaLoaders[$url]; |
| 282 | + if (null === $schemaLoader) { |
| 283 | + $schemaLoader = SchemaLoader::create(); |
| 284 | + $schemaLoader->readSchema($this->getRefProvider()->getSchemaData($url)); |
| 285 | + } |
| 286 | + |
| 287 | + $ref = $schemaLoader->resolveReference($refLocalPath); |
262 | 288 | }
|
263 | 289 | }
|
264 | 290 |
|
|
0 commit comments