forked from cebe/php-openapi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJsonReference.php
More file actions
133 lines (119 loc) · 4.58 KB
/
JsonReference.php
File metadata and controls
133 lines (119 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
/**
* @copyright Copyright (c) 2018 Carsten Brandt <mail@cebe.cc> and contributors
* @license https://github.com/cebe/php-openapi/blob/master/LICENSE
*/
namespace cebe\openapi\json;
use JsonSerializable;
/**
* Represents a JSON Reference (IETF draft-pbryan-zyp-json-ref-03)
*
* Includes the URI to another JSON document and the JSON Pointer as
* the fragment section of the URI.
*
* @link https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03
* @see JsonPointer
*/
final class JsonReference implements JsonSerializable
{
/**
* @var string
*/
private $_uri = '';
/**
* @var JsonPointer
*/
private $_pointer;
/**
* Create a JSON Reference instance from a JSON document.
* @param string $json the JSON object, e.g. `{ "$ref": "http://example.com/example.json#/foo/bar" }`.
* @return JsonReference
* @throws MalformedJsonReferenceObjectException
* @throws InvalidJsonPointerSyntaxException if an invalid JSON pointer string is passed as part of the fragment section.
*/
public static function createFromJson(string $json): JsonReference
{
$refObject = json_decode($json, true);
if (!isset($refObject['$ref'])) {
throw new MalformedJsonReferenceObjectException('JSON Reference Object must contain the "$ref" member.');
}
return static::createFromReference($refObject['$ref']);
}
/**
* Create a JSON Reference instance from an URI and a JSON Pointer.
* If no JSON Pointer is given this will be interpreted as an empty string JSON pointer, which
* references the whole document.
* @param string $uri the URI to the document without a fragment part.
* @param JsonPointer $jsonPointer
* @return JsonReference
*/
public static function createFromUri(string $uri, ?JsonPointer $jsonPointer = null): JsonReference
{
$jsonReference = static::createFromReference($uri);
$jsonReference->_pointer = $jsonPointer ?: new JsonPointer('');
return $jsonReference;
}
/**
* Create a JSON Reference instance from a reference URI.
* @param string $referenceURI the JSON Reference URI, e.g. `"http://example.com/example.json#/foo/bar"`.
* @return JsonReference
* @throws InvalidJsonPointerSyntaxException if an invalid JSON pointer string is passed as part of the fragment section.
*/
public static function createFromReference(string $referenceURI): JsonReference
{
$jsonReference = new JsonReference();
if (strpos($referenceURI, '#') !== false) {
list($uri, $fragment) = explode('#', $referenceURI, 2);
$jsonReference->_uri = $uri;
$jsonReference->_pointer = new JsonPointer(rawurldecode($fragment));
} else {
$jsonReference->_uri = $referenceURI;
$jsonReference->_pointer = new JsonPointer('');
}
return $jsonReference;
}
private function __construct()
{
}
public function __clone()
{
$this->_pointer = clone $this->_pointer;
}
public function getJsonPointer(): JsonPointer
{
return $this->_pointer;
}
/**
* @return string returns the URI of the referenced JSON document without the fragment (JSON Pointer) part.
*/
public function getDocumentUri(): string
{
return $this->_uri;
}
/**
* @return string returns the JSON Pointer in URI format.
*/
public function getReference(): string
{
// https://tools.ietf.org/html/rfc6901#section-6
// A JSON Pointer can be represented in a URI fragment identifier by
// encoding it into octets using UTF-8 [RFC3629], while percent-encoding
// those characters not allowed by the fragment rule in [RFC3986].
// https://tools.ietf.org/html/rfc3986#page-25
// The characters slash ("/") and question mark ("?") are allowed to
// represent data within the fragment identifier.
// https://tools.ietf.org/html/rfc3986#section-2.4
// the "%7E" can be replaced by "~" without changing its interpretation.
return $this->_uri . '#' . strtr(rawurlencode($this->_pointer->getPointer()), ['%2F' => '/', '%3F' => '?', '%7E' => '~']);
}
/**
* Specify data which should be serialized to JSON
* @link https://php.net/manual/en/jsonserializable.jsonserialize.php
* @return mixed data which can be serialized by <b>json_encode</b>,
* which is a value of any type other than a resource.
*/
public function jsonSerialize()
{
return (object)['$ref' => $this->getReference()];
}
}