@@ -41,6 +41,11 @@ class RefResolver
4141 */
4242 protected $ uriRetriever = null ;
4343
44+ /**
45+ * @var object
46+ */
47+ protected $ rootSchema = null ;
48+
4449 /**
4550 * @param UriRetriever $retriever
4651 */
@@ -110,6 +115,10 @@ public function resolve($schema, $sourceUri = null)
110115 $ sourceUri = $ schema ->id ;
111116 }
112117
118+ if (null === $ this ->rootSchema ) {
119+ $ this ->rootSchema = $ schema ;
120+ }
121+
113122 // Resolve $ref first
114123 $ this ->resolveRef ($ schema , $ sourceUri );
115124
@@ -205,7 +214,30 @@ public function resolveRef($schema, $sourceUri)
205214 return ;
206215 }
207216
208- $ refSchema = $ this ->fetchRef ($ schema ->$ ref , $ sourceUri );
217+ $ splitRef = explode ('# ' , $ schema ->$ ref , 2 );
218+
219+ $ refDoc = $ splitRef [0 ];
220+ $ refPath = null ;
221+ if (count ($ splitRef ) === 2 ) {
222+ $ refPath = explode ('/ ' , $ splitRef [1 ]);
223+ array_shift ($ refPath );
224+ }
225+
226+ if (empty ($ refDoc ) && empty ($ refPath )) {
227+ // TODO: Not yet implemented - root pointer ref, causes recursion issues
228+ return ;
229+ }
230+
231+ if (!empty ($ refDoc )) {
232+ $ refSchema = $ this ->fetchRef ($ refDoc , $ sourceUri );
233+ } else {
234+ $ refSchema = $ this ->rootSchema ;
235+ }
236+
237+ if (null !== $ refPath ) {
238+ $ refSchema = $ this ->resolveRefSegment ($ refSchema , $ refPath );
239+ }
240+
209241 unset($ schema ->$ ref );
210242
211243 // Augment the current $schema object with properties fetched
@@ -226,4 +258,19 @@ public function setUriRetriever(UriRetriever $retriever)
226258
227259 return $ this ;
228260 }
261+
262+ protected function resolveRefSegment ($ data , $ pathParts )
263+ {
264+ foreach ($ pathParts as $ path ) {
265+ $ path = strtr ($ path , array ('~1 ' => '/ ' , '~0 ' => '~ ' , '%25 ' => '% ' ));
266+
267+ if (is_array ($ data )) {
268+ $ data = $ data [$ path ];
269+ } else {
270+ $ data = $ data ->{$ path };
271+ }
272+ }
273+
274+ return $ data ;
275+ }
229276}
0 commit comments