| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | namespace League\JsonGuard; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | use League\JsonGuard\Loaders\CurlWebLoader; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | use League\JsonGuard\Loaders\FileGetContentsWebLoader; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | use League\JsonGuard\Loaders\FileLoader; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  |  * The Dereferencer resolves all external $refs and replaces | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |  * internal references with Reference objects. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | class Dereferencer | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |     private $loaders; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |      * Create a new Dereferencer. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 | 158 |  |     public function __construct() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 | 158 |  |         $this->registerFileLoader(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 | 158 |  |         $this->registerDefaultWebLoaders(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 | 158 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |      * Return the schema with all references resolved. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |      * @param string|object $schema Either a valid path like "http://json-schema.org/draft-03/schema#" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |      *                              or the object resulting from a json_decode call. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |      * @return object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 | 158 |  |     public function dereference($schema) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 | 158 |  |         if (is_string($schema)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 | 24 |  |             $uri    = $schema; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 | 24 |  |             $schema = $this->loadExternalRef($uri); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 | 24 |  |             $schema = $this->resolveFragment($uri, $schema); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 | 24 |  |             return $this->crawl($schema, strip_fragment($uri)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 | 134 |  |         return $this->crawl($schema); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |      * Register a Loader for the given prefix. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |      * @param Loader $loader | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |      * @param string $prefix | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 | 122 |  |     public function registerLoader(Loader $loader, $prefix) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 | 122 |  |         $this->loaders[$prefix] = $loader; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 | 122 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |      * Get all registered loaders, keyed by the prefix they are registered to load schemas for. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |      * @return Loader[] | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 65 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 66 |  |  |     public function getLoaders() | 
            
                                                                        
                            
            
                                    
            
            
                | 67 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 68 |  |  |         return $this->loaders; | 
            
                                                                        
                            
            
                                    
            
            
                | 69 | 38 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 | 38 |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |      * Get the loader for the given prefix. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |      * @param $prefix | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 | 38 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |      * @return Loader | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |      * @throws \InvalidArgumentException | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |     private function getLoader($prefix) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 | 158 |  |         if (!array_key_exists($prefix, $this->loaders)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |             throw new \InvalidArgumentException(sprintf('A loader is not registered for the prefix "%s"', $prefix)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 | 158 |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 | 158 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |         return $this->loaders[$prefix]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |      * Register the default file loader. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |     private function registerFileLoader() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 | 158 |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |         $this->loaders['file'] = new FileLoader(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 | 158 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 | 158 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 | 158 |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 | 158 |  |      * Register the default web loaders.  If the curl extension is loaded, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |      * the CurlWebLoader will be used.  Otherwise the FileGetContentsWebLoader | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |      * will be used.  You can override this by registering your own loader | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |      * for the 'http' and 'https' protocols. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 | 158 |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |     private function registerDefaultWebLoaders() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |         if (function_exists('curl_init')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |             $this->loaders['https'] = new CurlWebLoader('https://'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |             $this->loaders['http']  = new CurlWebLoader('http://'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |             $this->loaders['https'] = new FileGetContentsWebLoader('https://'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |             $this->loaders['http']  = new FileGetContentsWebLoader('http://'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 | 158 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 | 158 |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |      * Crawl the schema and resolve any references. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 | 158 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |      * @param object      $schema | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 | 48 |  |      * @param string|null $currentUri | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 | 20 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 | 18 |  |      * @return object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 | 42 |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |     private function crawl($schema, $currentUri = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |         $references = $this->getReferences($schema); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 | 46 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |         foreach ($references as $path => $ref) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |             // resolve | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 | 46 |  |             if ($this->isExternalRef($ref)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 | 156 |  |                 $resolved = new Reference(function () use ($schema, $path, $ref, $currentUri) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |                     return $this->resolveExternalReference($schema, $path, $ref, $currentUri); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 | 156 |  |                 }, $ref); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |                 $resolved = new Reference($schema, $ref); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |             // handle any fragments | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |             $resolved = $this->resolveFragment($ref, $resolved); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |             // merge | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |             $this->mergeResolvedReference($schema, $resolved, $path); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 | 20 |  |         return $schema; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 | 20 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 | 20 |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |      * Resolve the external reference at the given path. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 | 18 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |      * @param  object      $schema     The JSON Schema | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |      * @param  string      $path       A JSON pointer to the $ref's location in the schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |      * @param  string      $ref        The JSON reference | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |      * @param  string|null $currentUri The URI of the schema, or null if the schema was loaded from an object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |      * @return object                  The schema with the reference resolved. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |     private function resolveExternalReference($schema, $path, $ref, $currentUri) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |         $ref      = $this->makeReferenceAbsolute($schema, $path, $ref, $currentUri); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 | 46 |  |         $resolved = $this->loadExternalRef($ref); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 | 46 |  |         return $this->crawl($resolved, strip_fragment($ref)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 | 16 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 | 8 |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 | 8 |  |      * Merge the resolved reference with the schema, at the given path. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 | 16 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 | 16 |  |      * @param  object $schema   The schema to merge the resolved reference with | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 | 44 |  |      * @param  object $resolved The resolved schema | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 | 44 |  |      * @param  string $path     A JSON pointer to the path where the reference should be merged. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 | 44 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 | 44 |  |      * @return void | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 | 46 |  |     private function mergeResolvedReference($schema, $resolved, $path) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  |         if ($path === '') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  |             // Immediately resolve any root references. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |             while ($resolved instanceof Reference) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  |                 $resolved = $resolved->resolve(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |             $this->mergeRootRef($schema, $resolved); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  |             $pointer = new Pointer($schema); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 | 48 |  |             if ($pointer->has($path)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |                 $pointer->set($path, $resolved); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 | 48 |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 | 48 |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 | 10 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 | 10 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |      * Check if the reference contains a fragment and resolve | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 | 48 |  |      * the pointer.  Otherwise returns the original schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  |      * @param  string $ref | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  |      * @param  object $schema | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 |  |  |      * @return object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  |     private function resolveFragment($ref, $schema) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 |  |  |         $fragment = parse_url($ref, PHP_URL_FRAGMENT); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |         if ($this->isExternalRef($ref) && is_string($fragment)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |             if ($schema instanceof Reference) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |                 $schema = $schema->resolve(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  |             $pointer  = new Pointer($schema); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  |             return $pointer->get($fragment); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 | 158 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  |         return $schema; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 | 158 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 | 158 |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 | 40 |  |      * Recursively get all of the references for the given schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 |  |  |      * Returns an associative array like [path => reference]. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  |      * Example: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 | 158 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 | 158 |  |      * ['/properties' => '#/definitions/b'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 | 158 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 | 48 |  |      * The path does NOT include the $ref. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 | 48 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 | 156 |  |      * @param object $schema The schema to resolve references for. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 | 90 |  |      * @param string $path   The current schema path. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 | 90 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 | 154 |  |      * @return array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 | 62 |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 | 58 |  |     private function getReferences($schema, $path = '') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 | 58 |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 | 58 |  |         $refs = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 | 58 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 | 62 |  |         if (!is_array($schema) && !is_object($schema)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 | 62 |  |             return $refs; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 | 158 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 |  |  |         foreach ($schema as $attribute => $parameter) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 | 158 |  |             switch (true) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  |                 case $this->isRef($attribute, $parameter): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  |                     $refs[$path] = $parameter; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 |  |  |                 case is_object($parameter): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 |  |  |                     $refs = array_merge($refs, $this->getReferences($parameter, $this->pathPush($path, $attribute))); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 |  |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  |                 case is_array($parameter): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  |                     foreach ($parameter as $k => $v) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 |  |  |                         $refs = array_merge( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  |                             $refs, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 | 104 |  |                             $this->getReferences($v, $this->pathPush($this->pathPush($path, $attribute), $k)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 246 |  |  |                         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 | 104 |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 |  |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 250 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 251 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 252 |  |  |         return $refs; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 253 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 254 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 255 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 256 | 158 |  |      * Push a segment onto the given path. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 257 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 258 | 158 |  |      * @param string $path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 |  |  |      * @param string $segment | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 261 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 262 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 263 |  |  |     private function pathPush($path, $segment) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 264 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 265 |  |  |         return $path . '/' . escape_pointer($segment); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 266 | 50 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 267 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 268 | 50 |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 269 |  |  |      * @param string $attribute | 
            
                                                                                                            
                            
            
                                    
            
            
                | 270 |  |  |      * @param mixed  $attributeValue | 
            
                                                                                                            
                            
            
                                    
            
            
                | 271 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 272 |  |  |      * @return bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 273 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 274 |  |  |     private function isRef($attribute, $attributeValue) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 275 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 276 | 50 |  |         return $attribute === '$ref' && is_string($attributeValue); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 277 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 278 | 50 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 279 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 280 |  |  |      * @param string $value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 281 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 |  |  |      * @return bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 283 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 284 |  |  |     private function isInternalRef($value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 285 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 286 |  |  |         return is_string($value) && substr($value, 0, 1) === '#'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 287 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 288 | 40 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 289 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 290 | 40 |  |      * @param string $value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 291 | 38 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 292 |  |  |      * @return bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 293 | 38 |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 294 |  |  |     private function isExternalRef($value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 295 | 38 |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 296 |  |  |         return !$this->isInternalRef($value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 297 | 38 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 298 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 299 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 300 |  |  |      * Load an external ref and return the JSON object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 301 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 302 |  |  |      * @param string $reference | 
            
                                                                                                            
                            
            
                                    
            
            
                | 303 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 304 |  |  |      * @return object | 
            
                                                                                                            
                            
            
                                    
            
            
                | 305 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 306 | 16 |  |     private function loadExternalRef($reference) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 307 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 308 | 16 |  |         $this->validateAbsolutePath($reference); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 309 | 16 |  |         list($prefix, $path) = explode('://', $reference, 2); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 310 | 16 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 311 | 16 |  |         $loader = $this->getLoader($prefix); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 312 | 16 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 313 | 16 |  |         $schema = $loader->load($path); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 314 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 315 |  |  |         return $schema; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 316 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 317 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 318 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 319 |  |  |      * Merge a resolved reference into the root of the given schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 320 | 40 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 321 |  |  |      * @param object $rootSchema | 
            
                                                                                                            
                            
            
                                    
            
            
                | 322 | 40 |  |      * @param object $resolvedRef | 
            
                                                                                                            
                            
            
                                    
            
            
                | 323 | 2 |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 324 | 2 |  |     private function mergeRootRef($rootSchema, $resolvedRef) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 325 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 326 | 2 |  |         $ref = '$ref'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 327 |  |  |         unset($rootSchema->$ref); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 328 | 2 |  |         foreach (get_object_vars($resolvedRef) as $prop => $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 329 | 2 |  |             $rootSchema->$prop = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 330 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 331 | 38 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 332 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 333 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 334 |  |  |      * Validate an absolute path is valid. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 335 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 336 |  |  |      * @param string $path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 337 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 338 |  |  |     private function validateAbsolutePath($path) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 339 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 340 |  |  |         if (!preg_match('#^.+\:\/\/.*#', $path)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 341 | 20 |  |             throw new \InvalidArgumentException( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 342 |  |  |                 sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 343 | 20 |  |                     'Your path  "%s" is missing a valid prefix.  ' . | 
            
                                                                                                            
                            
            
                                    
            
            
                | 344 |  |  |                     'The schema path should start with a prefix i.e. "file://".', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 345 |  |  |                     $path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 346 |  |  |                 ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 347 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 348 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 349 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 350 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 351 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 352 |  |  |      * Take a relative reference, and prepend the id of the schema and any | 
            
                                                                                                            
                            
            
                                    
            
            
                | 353 |  |  |      * sub schemas to get the absolute url. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 354 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 355 |  |  |      * @param object      $schema | 
            
                                                                                                            
                            
            
                                    
            
            
                | 356 |  |  |      * @param string      $path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 357 | 20 |  |      * @param string      $ref | 
            
                                                                                                            
                            
            
                                    
            
            
                | 358 |  |  |      * @param string|null $currentUri | 
            
                                                                                                            
                            
            
                                    
            
            
                | 359 | 20 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 360 | 14 |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 361 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 362 |  |  |     private function makeReferenceAbsolute($schema, $path, $ref, $currentUri = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 363 | 12 |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 364 | 12 |  |         // If the reference is absolute, we can just return it without walking the schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 365 |  |  |         if (!is_relative_ref($ref)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 366 | 12 |  |             return $ref; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 367 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 368 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 369 |  |  |         $scope = $currentUri ?: ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 370 |  |  |         $scope = $this->getResolvedResolutionScope($schema, $path, $scope); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 371 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 372 |  |  |         return resolve_uri($ref, $scope); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 373 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 374 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 375 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 376 |  |  |      * Get the resolved resolution scope by walking the schema and resolving | 
            
                                                                                                            
                            
            
                                    
            
            
                | 377 |  |  |      * every `id` against the most immediate parent scope. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 378 | 12 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 379 |  |  |      * @see  http://json-schema.org/latest/json-schema-core.html#anchor27 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 380 | 12 |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 381 |  |  |      * @param  object $schema | 
            
                                                                                                            
                            
            
                                    
            
            
                | 382 |  |  |      * @param  string $path | 
            
                                                                                                            
                            
            
                                    
            
            
                | 383 |  |  |      * @param  string $scope | 
            
                                                                                                            
                            
            
                                    
            
            
                | 384 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 385 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 386 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 387 |  |  |     private function getResolvedResolutionScope($schema, $path, $scope) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 388 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 389 |  |  |         $pointer     = new Pointer($schema); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 390 |  |  |         $currentPath = ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 391 | 12 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 392 |  |  |         foreach (explode('/', $path) as $segment) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 393 | 12 |  |             if (!empty($segment)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 394 |  |  |                 $currentPath .= '/' . $segment; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 395 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 396 |  |  |             if ($pointer->has($currentPath . '/id')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 397 |  |  |                 $id = $pointer->get($currentPath . '/id'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 398 |  |  |                 if (is_string($id)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 399 | 12 |  |                     $scope = resolve_uri($id, $scope); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 400 | 12 |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 401 | 12 |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 402 | 8 |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 403 | 8 |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 404 | 12 |  |         return $scope; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 405 | 6 |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 406 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 407 |  |  |  |