Completed
Pull Request — master (#11)
by
unknown
06:09
created

Dereferencer::dereference()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 1
nop 2
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace League\JsonReference;
4
5
use League\JsonReference\ReferenceSerializer\SafeReferenceSerializer;
6
use League\JsonReference\ScopeResolver\JsonSchemaScopeResolver;
7
use League\JsonReference\ScopeResolver\NullScopeResolver;
8
9
final class Dereferencer implements DereferencerInterface
10
{
11
    /**
12
     * @var LoaderManager
13
     */
14
    private $loaderManager;
15
16
    /**
17
     * @var ScopeResolverInterface
18
     */
19
    private $scopeResolver;
20
21
    /**
22
     * @var ReferenceSerializerInterface
23
     */
24
    private $referenceSerializer;
25
26
    /**
27
     * Create a new Dereferencer.
28
     *
29
     * @param ScopeResolverInterface                             $scopeResolver
30
     * @param \League\JsonReference\ReferenceSerializerInterface $referenceSerializer
31
     */
32 54
    public function __construct(
33
        ScopeResolverInterface $scopeResolver = null,
34
        ReferenceSerializerInterface $referenceSerializer = null
35
    ) {
36 54
        $this->scopeResolver       = $scopeResolver ?: new NullScopeResolver();
37 54
        $this->referenceSerializer = $referenceSerializer ?: new SafeReferenceSerializer();
38 54
        $this->loaderManager       = new LoaderManager();
39
40 54
        Reference::setDereferencerInstance($this);
41 54
    }
42
43
    /**
44
     * Create a new dereferencer configured for dereferencing JSON Schema Draft4 schemas.
45
     *
46
     * @return \League\JsonReference\Dereferencer
47
     */
48 2
    public static function draft4()
49
    {
50 2
        return new self(new JsonSchemaScopeResolver(JsonSchemaScopeResolver::KEYWORD_DRAFT_4));
51
    }
52
53
    /**
54
     * Create a new dereferencer configured for dereferencing JSON Schema Draft6 schemas.
55
     *
56
     * @return \League\JsonReference\Dereferencer
57
     */
58
    public static function draft6()
59
    {
60
        return new self(new JsonSchemaScopeResolver(JsonSchemaScopeResolver::KEYWORD_DRAFT_6));
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    public function dereference($schema, $uri = '')
67
    {
68 52
        return $this->crawl($schema, $uri, function ($schema, $pointer, $ref, $scope) {
69 48
            $resolved = new Reference($ref, $scope, is_internal_ref($ref) ? $schema : null);
70 48
            return merge_ref($schema, $resolved, $pointer);
71 52
        });
72
    }
73
74
    /**
75
     * @param object|string $schema
76
     * @param string        $uri
77
     *
78
     * @return array
79
     */
80 52
    private function prepareArguments($schema, $uri)
81
    {
82 52
        if (is_string($schema)) {
83 48
            $uri    = $schema;
84
            
85
            // Replace blackslashes
86 48
            $uri    = str_replace('\\', '/', $uri);
87
88
            // Fix Windows Path (file://C:/abc --> file:///C:/abc)
89 48
            $uri    = preg_replace("/^(file:\/\/)(\w:)/", "$1/$2", $uri);
90
            
91 48
            $schema = resolve_fragment($uri, $this->loadExternalRef($uri));
92 44
            $uri    = strip_fragment($uri);
93 22
        }
94
95 50
        return [$schema, $uri];
96
    }
97
98
    /**
99
     * @return LoaderManager
100
     */
101 10
    public function getLoaderManager()
102
    {
103 10
        return $this->loaderManager;
104
    }
105
106
    /**
107
     * @param \League\JsonReference\LoaderManager $loaderManager
108
     *
109
     * @return \League\JsonReference\Dereferencer
110
     */
111
    public function setLoaderManager(LoaderManager $loaderManager)
112
    {
113
        $this->loaderManager = $loaderManager;
114
115
        return $this;
116
    }
117
118
    /**
119
     * @return \League\JsonReference\ScopeResolverInterface
120
     */
121
    public function getScopeResolver()
122
    {
123
        return $this->scopeResolver;
124
    }
125
126
    /**
127
     * @param \League\JsonReference\ScopeResolverInterface $scopeResolver
128
     *
129
     * @return \League\JsonReference\Dereferencer
130
     */
131
    public function setScopeResolver(ScopeResolverInterface $scopeResolver)
132
    {
133
        $this->scopeResolver = $scopeResolver;
134
135
        return $this;
136
    }
137
138
    /**
139
     * @return \League\JsonReference\ReferenceSerializerInterface
140
     */
141 16
    public function getReferenceSerializer()
142
    {
143 16
        return $this->referenceSerializer;
144
    }
145
146
    /**
147
     * @param \League\JsonReference\ReferenceSerializerInterface $referenceSerializer
148
     *
149
     * @return \League\JsonReference\Dereferencer
150
     */
151 8
    public function setReferenceSerializer(ReferenceSerializerInterface $referenceSerializer)
152
    {
153 8
        $this->referenceSerializer = $referenceSerializer;
154
155 8
        return $this;
156
    }
157
158
    /**
159
     * @param string|object $schema
160
     * @param string        $uri
161
     * @param callable      $resolver
162
     *
163
     * @return object
164
     */
165 52
    private function crawl($schema, $uri, callable $resolver)
166
    {
167 52
        list($schema, $uri) = $this->prepareArguments($schema, $uri);
168
169 50
        foreach (schema_extract($schema, 'League\JsonReference\is_ref') as $pointer => $ref) {
170 48
            $scope = $this->scopeResolver->resolve($schema, $pointer, $uri);
171
172 48
            $schema = $resolver($schema, $pointer, $ref, $scope);
173 24
        }
174
175 48
        return $schema;
176
    }
177
178
    /**
179
     * Load an external ref and return the JSON object.
180
     *
181
     * @param string $reference
182
     *
183
     * @return object
184
     */
185 51
    private function loadExternalRef($reference)
186
    {
187 51
        list($prefix, $path) = parse_external_ref($reference);
188 46
        return $this->loaderManager->getLoader($prefix)->load($path);
189
    }
190
}
191