Completed
Push — master ( a1155a...fee9e9 )
by Veaceslav
06:30 queued 04:35
created

Schema::getResponseBodySchema()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1
Metric Value
dl 0
loc 12
ccs 6
cts 6
cp 1
rs 9.4285
cc 1
eloc 9
nc 1
nop 3
crap 1
1
<?php
2
/**
3
 * This file is part of Rebilly.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @see http://rebilly.com
9
 */
10
11
namespace Rebilly\OpenAPI;
12
13
/**
14
 * Schema representation.
15
 */
16
final class Schema
17
{
18
    /**
19
     * Schema definition.
20
     *
21
     * @var object
22
     */
23
    private $schema;
24
25
    /**
26
     * @param object $schema
27
     */
28 13
    public function __construct($schema)
29
    {
30 13
        if (!(isset($schema->swagger) && $schema->swagger === '2.0')) {
31 1
            throw new UnexpectedValueException('Unsupported OpenAPI Specification schema');
32
        }
33
34 12
        $this->schema = $schema;
35
    }
36
37
    /**
38
     * @return string
39
     */
40 5
    public function getHost()
41
    {
42 5
        return $this->fetch($this->schema, 'host');
43
    }
44
45
    /**
46
     * @return string
47
     */
48 4
    public function getBasePath()
49
    {
50 4
        return $this->fetch($this->schema, 'basePath');
51
    }
52
53
    /**
54
     * @param string $name
55
     *
56
     * @return object
57
     */
58 1
    public function getDefinition($name)
59
    {
60 1
        return $this->fetch($this->schema, 'definitions', $name);
61
    }
62
63
    /**
64
     * @return string[]
65
     */
66 1
    public function getDefinitionNames()
67
    {
68 1
        return array_keys((array) $this->fetch($this->schema, 'definitions'));
69
    }
70
71
    /**
72
     * @param string $template
73
     *
74
     * @return object
75
     */
76 6
    public function getPathSchema($template)
77
    {
78 6
        return $this->fetch($this->schema, 'paths', $template);
79
    }
80
81
    /**
82
     * @return string[]
83
     */
84 1
    public function getAvailablePaths()
85
    {
86 1
        return array_keys((array) $this->fetch($this->schema, 'paths'));
87
    }
88
89
    /**
90
     * @param string $template Schema path template.
91
     *
92
     * @return string[]
93
     */
94 6
    public function getAllowedMethods($template)
95
    {
96 6
        $schema = $this->getPathSchema($template);
97
        $methods = [
98 6
            'OPTIONS' => true,
99 6
            'HEAD' => isset($schema->get),
100 6
            'GET' => isset($schema->get),
101 6
            'POST' => isset($schema->post),
102 6
            'PUT' => isset($schema->put),
103 6
            'DELETE' => isset($schema->delete),
104 6
            'PATCH' => isset($schema->patch),
105
        ];
106
107 6
        return array_keys(array_filter($methods));
108
    }
109
110
    /**
111
     * The transfer protocol for the operation.
112
     * The value overrides the top-level schemes definition.
113
     *
114
     * @see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#operationObject
115
     *
116
     * @param string $template
117
     * @param string $method
118
     *
119
     * @return string[]
120
     */
121 4 View Code Duplication
    public function getSupportedSchemes($template, $method)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
122
    {
123 4
        $schemes = $this->fetch(
124 4
            $this->schema,
125 4
            'paths',
126
            $template,
127
            $method,
128 4
            'schemes'
129
        );
130
131 4
        if (!$schemes) {
132 4
            $schemes = $this->fetch($this->schema, 'schemes');
133
        }
134
135 4
        return (array) $schemes;
136
    }
137
138
    /**
139
     * @param string $template
140
     * @param string $method
141
     *
142
     * @return object[]
143
     */
144 5
    public function getRequestHeaderSchemas($template, $method)
145
    {
146 5
        return $this->getRequestParameters($template, $method, 'header');
147
    }
148
149
    /**
150
     * @param string $template
151
     * @param string $method
152
     *
153
     * @return object|null
154
     */
155 5
    public function getRequestBodySchema($template, $method)
156
    {
157 5
        $parameters = $this->getRequestParameters($template, $method, 'body');
158 5
        $count = count($parameters);
159
160 5
        if ($count === 0) {
161 2
            return null;
162
        }
163
164 3
        if ($count > 1) {
165 1
            throw new UnexpectedValueException('Multiple body parameters found');
166
        }
167
168 2
        $body = reset($parameters);
169
170 2
        if (!isset($body->schema)) {
171 1
            throw new UnexpectedValueException('Invalid body parameter definition');
172
        }
173
174 1
        return $body->schema;
175
    }
176
177
    /**
178
     * @param string $template
179
     * @param string $method
180
     *
181
     * @return object[]
182
     */
183 4
    public function getRequestPathParameters($template, $method)
184
    {
185 4
        return $this->getRequestParameters($template, $method, 'path');
186
    }
187
188
    /**
189
     * @param string $template
190
     * @param string $method
191
     *
192
     * @return object[]
193
     */
194 4
    public function getRequestQueryParameters($template, $method)
195
    {
196 4
        return $this->getRequestParameters($template, $method, 'query');
197
    }
198
199
    /**
200
     * @param string $template
201
     * @param string $method
202
     *
203
     * @return string[]
204
     */
205 4 View Code Duplication
    public function getRequestContentTypes($template, $method)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
206
    {
207 4
        $items = $this->fetch($this->schema, 'paths', $template, $method, 'consumes');
208
209 4
        if (!$items) {
210 4
            $items = $this->fetch($this->schema, 'consumes');
211
        }
212
213 4
        return (array) $items;
214
    }
215
216
    /**
217
     * @param string $template
218
     * @param string $method
219
     *
220
     * @return string[]
221
     */
222 4
    public function getResponseCodes($template, $method)
223
    {
224 4
        return array_filter(
225 4
            array_keys((array) $this->fetch($this->schema, 'paths', $template, $method, 'responses')),
226 4
            'is_numeric'
227
        );
228
    }
229
230
    /**
231
     * @param string $template
232
     * @param string $method
233
     *
234
     * @return string[]
235
     */
236 4 View Code Duplication
    public function getResponseContentTypes($template, $method)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
237
    {
238 4
        $items = $this->fetch($this->schema, 'paths', $template, $method, 'produces');
239
240 4
        if (!$items) {
241 4
            $items = $this->fetch($this->schema, 'produces');
242
        }
243
244 4
        return (array) $items;
245
    }
246
247
    /**
248
     * @param string $template
249
     * @param string $method
250
     * @param string $status
251
     *
252
     * TODO: Normalize headers list to JSON schema (seems it is validator deals)
253
     * TODO: If status does not defined, check default response declaration
254
     *
255
     * @return object[]
256
     */
257 4
    public function getResponseHeaderSchemas($template, $method, $status)
258
    {
259 4
        return (array) $this->fetch(
260 4
            $this->schema,
261 4
            'paths',
262
            $template,
263
            $method,
264 4
            'responses',
265
            $status,
266 4
            'headers'
267
        );
268
    }
269
270
    /**
271
     * Returns body schema.
272
     *
273
     * @param string $template
274
     * @param string $method
275
     * @param string $status
276
     *
277
     * @return object|null
278
     */
279 4
    public function getResponseBodySchema($template, $method, $status)
280
    {
281 4
        return $this->fetch(
282 4
            $this->schema,
283 4
            'paths',
284
            $template,
285
            $method,
286 4
            'responses',
287
            $status,
288 4
            'schema'
289
        );
290
    }
291
292
    /**
293
     * @param $schema
294
     * @param array ...$paths
295
     *
296
     * @return mixed
297
     */
298 12
    private static function fetch($schema, ...$paths)
299
    {
300 12
        foreach ($paths as $path) {
301 12
            if (!isset($schema->{$path})) {
302 10
                return null;
303
            }
304
305 12
            $schema = $schema->{$path};
306
        }
307
308 12
        return $schema;
309
    }
310
311
    /**
312
     * A list of parameters that are applicable for this operation.
313
     * If a parameter is already defined at the Path Item,
314
     * the new definition will override it, but can never remove it.
315
     *
316
     * @param string $template
317
     * @param string $method
318
     * @param string $location
319
     *
320
     * @return object[]
321
     */
322 7
    private function getRequestParameters($template, $method, $location)
323
    {
324 7
        $path = $this->fetch($this->schema, 'paths', $template);
325
326 7
        $parameters = $this->fetch($path, $method, 'parameters') ?: $this->fetch($path, 'parameters');
327 7
        $schemas = [];
328
329 7
        foreach ((array) $parameters as $parameter) {
330 7
            if ($parameter->in !== $location) {
331 4
                continue;
332
            }
333
334 7
            if (isset($schemas[$parameter->name])) {
335 1
                throw new UnexpectedValueException('Multiple parameters found');
336
            }
337
338 7
            $schemas[$parameter->name] = clone $parameter;
339 7
            unset($schemas[$parameter->name]->name, $schemas[$parameter->name]->in);
340
        }
341
342 6
        return $schemas;
343
    }
344
}
345