Skip to content

Commit 4257bc6

Browse files
committed
Adjust relative URLs for externalValue Example Object
Adjust relative URLs for externalValue fields in Example Objects when inlining references. https://spec.openapis.org/oas/v3.0.3#example-object fixes #95
1 parent 54d9d01 commit 4257bc6

File tree

4 files changed

+52
-1
lines changed

4 files changed

+52
-1
lines changed

src/spec/Reference.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,9 @@ private function resolveTransitiveReference(Reference $referencedObject, Referen
289289
return $transitiveRefResult;
290290
}
291291

292-
// adjust relative refernces inside of the file to match the context of the base file
292+
/**
293+
* Adjust relative references inside of the file to match the context of the base file
294+
*/
293295
private function adjustRelativeReferences($referencedDocument, $basePath, $baseDocument = null, $oContext = null)
294296
{
295297
$context = new ReferenceContext(null, $basePath);
@@ -298,6 +300,7 @@ private function adjustRelativeReferences($referencedDocument, $basePath, $baseD
298300
}
299301

300302
foreach ($referencedDocument as $key => $value) {
303+
// adjust reference URLs
301304
if ($key === '$ref' && is_string($value)) {
302305
if (isset($value[0]) && $value[0] === '#') {
303306
// direcly inline references in the same document,
@@ -309,16 +312,38 @@ private function adjustRelativeReferences($referencedDocument, $basePath, $baseD
309312
$parts = explode('#', $referencedDocument[$key], 2);
310313
if ($parts[0] === $oContext->getUri()) {
311314
$referencedDocument[$key] = '#' . ($parts[1] ?? '');
315+
} else {
316+
$referencedDocument[$key] = $this->makeRelativePath($oContext->getUri(), $referencedDocument[$key]);
312317
}
313318
continue;
314319
}
320+
// adjust URLs for 'externalValue' references in Example Objects
321+
// https://spec.openapis.org/oas/v3.0.3#example-object
322+
if ($key === 'externalValue' && is_string($value)) {
323+
$referencedDocument[$key] = $this->makeRelativePath($oContext->getUri(), $context->resolveRelativeUri($value));
324+
continue;
325+
}
315326
if (is_array($value)) {
316327
$referencedDocument[$key] = $this->adjustRelativeReferences($value, $basePath, $baseDocument, $oContext);
317328
}
318329
}
319330
return $referencedDocument;
320331
}
321332

333+
/**
334+
* If $path can be expressed relative to $base, make it a relative path, otherwise $path is returned.
335+
* @param string $base
336+
* @param string $path
337+
*/
338+
private function makeRelativePath($base, $path)
339+
{
340+
if (strpos($path, dirname($base)) === 0) {
341+
return '.' . DIRECTORY_SEPARATOR . substr($path, strlen(dirname($base) . DIRECTORY_SEPARATOR));
342+
}
343+
344+
return $path;
345+
}
346+
322347
/**
323348
* Resolves all Reference Objects in this object and replaces them with their resolution.
324349
* @throws UnresolvableReferenceException

tests/spec/ReferenceTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,16 @@ public function testReferencedCommonParamsInReferencedPath()
484484
responses:
485485
'200':
486486
description: 'OK if common params can be references'
487+
request:
488+
content:
489+
application/json:
490+
examples:
491+
user:
492+
summary: 'User Example'
493+
externalValue: ./paths/examples/user-example.json
494+
userex:
495+
summary: 'External User Example'
496+
externalValue: 'https://api.example.com/examples/user-example.json'
487497
parameters:
488498
-
489499
name: test

tests/spec/data/reference/paths/ReferencesCommonParams.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,13 @@ get:
55
responses:
66
200:
77
description: OK if common params can be references
8+
request:
9+
content:
10+
application/json:
11+
examples:
12+
"user":
13+
"summary": "User Example"
14+
"externalValue": "./examples/user-example.json"
15+
"userex":
16+
"summary": "External User Example"
17+
"externalValue": "https://api.example.com/examples/user-example.json"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "user",
3+
"properties": {
4+
"name": "John"
5+
}
6+
}

0 commit comments

Comments
 (0)