Completed
Push — master ( fd8391...5bac92 )
by Joao
18:40 queued 31s
created

SwaggerSchema::setAllowNullValues()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
/**
3
 * User: jg
4
 * Date: 22/05/17
5
 * Time: 09:29
6
 */
7
8
namespace ByJG\Swagger;
9
10
use ByJG\Swagger\Exception\DefinitionNotFoundException;
11
use ByJG\Swagger\Exception\HttpMethodNotFoundException;
12
use ByJG\Swagger\Exception\InvalidDefinitionException;
13
use ByJG\Swagger\Exception\NotMatchedException;
14
use ByJG\Swagger\Exception\PathNotFoundException;
15
16
class SwaggerSchema
17
{
18
    protected $jsonFile;
19
    protected $allowNullValues;
20
21
    public function __construct($jsonFile, $allowNullValues = false)
22
    {
23
        $this->jsonFile = json_decode($jsonFile, true);
24
        $this->allowNullValues = (bool) $allowNullValues;
25
    }
26
27
    public function getHttpSchema()
28
    {
29
        return isset($this->jsonFile['schemes']) ? $this->jsonFile['schemes'][0] : '';
30
    }
31
32
    public function getHost()
33
    {
34
        return isset($this->jsonFile['host']) ? $this->jsonFile['host'] : '';
35
    }
36
37
    public function getBasePath()
38
    {
39
        return isset($this->jsonFile['basePath']) ? $this->jsonFile['basePath'] : '';
40
    }
41
42
    /**
43
     * @param $path
44
     * @param $method
45
     * @return mixed
46
     * @throws \ByJG\Swagger\Exception\HttpMethodNotFoundException
47
     * @throws \ByJG\Swagger\Exception\NotMatchedException
48
     * @throws \ByJG\Swagger\Exception\PathNotFoundException
49
     */
50
    public function getPathDefinition($path, $method)
51
    {
52
        $method = strtolower($method);
53
54
        $path = preg_replace('~^' . $this->getBasePath() . '~', '', $path);
55
56
        // Try direct match
57
        if (isset($this->jsonFile['paths'][$path])) {
58
            if (isset($this->jsonFile['paths'][$path][$method])) {
59
                return $this->jsonFile['paths'][$path][$method];
60
            }
61
            throw new HttpMethodNotFoundException("The http method '$method' not found in '$path'");
62
        }
63
64
        // Try inline parameter
65
        foreach (array_keys($this->jsonFile['paths']) as $pathItem) {
66
            if (strpos($pathItem, '{') === false) {
67
                continue;
68
            }
69
70
            $pathItemPattern = '~^' . preg_replace('~\{(.*?)\}~', '(?<\1>[^/]+)', $pathItem) . '$~';
71
72
            $matches = [];
73
            if (preg_match($pathItemPattern, $path, $matches)) {
74
                $pathDef = $this->jsonFile['paths'][$pathItem];
75
                if (!isset($pathDef[$method])) {
76
                    throw new HttpMethodNotFoundException("The http method '$method' not found in '$path'");
77
                }
78
79
                $this->validateArguments('path', $pathDef[$method]['parameters'], $matches);
80
81
                return $pathDef[$method];
82
            }
83
        }
84
85
        throw new PathNotFoundException('Path "' . $path . '" not found');
86
    }
87
88
    /**
89
     * @param $parameterIn
90
     * @param $parameters
91
     * @param $arguments
92
     * @throws \ByJG\Swagger\Exception\NotMatchedException
93
     */
94
    private function validateArguments($parameterIn, $parameters, $arguments)
95
    {
96
        foreach ($parameters as $parameter) {
97
            if ($parameter['in'] === $parameterIn) {
98
                if ($parameter['type'] === "integer"
99
                    && filter_var($arguments[$parameter['name']], FILTER_VALIDATE_INT) === false) {
100
                    throw new NotMatchedException('Path expected an integer value');
101
                }
102
            }
103
        }
104
    }
105
106
    /**
107
     * @param $name
108
     * @return mixed
109
     * @throws \ByJG\Swagger\Exception\DefinitionNotFoundException
110
     * @throws \ByJG\Swagger\Exception\InvalidDefinitionException
111
     */
112
    public function getDefintion($name)
113
    {
114
        $nameParts = explode('/', $name);
115
116
        if (count($nameParts) < 3 || $nameParts[0] != '#') {
117
            throw new InvalidDefinitionException('Invalid Definition');
118
        }
119
120
        if (!isset($this->jsonFile[$nameParts[1]][$nameParts[2]])) {
121
            throw new DefinitionNotFoundException("Definition '$name' not found");
122
        }
123
124
        return $this->jsonFile[$nameParts[1]][$nameParts[2]];
125
    }
126
127
    /**
128
     * @param $path
129
     * @param $method
130
     * @return \ByJG\Swagger\SwaggerRequestBody
131
     * @throws \ByJG\Swagger\Exception\HttpMethodNotFoundException
132
     * @throws \ByJG\Swagger\Exception\NotMatchedException
133
     * @throws \ByJG\Swagger\Exception\PathNotFoundException
134
     */
135
    public function getRequestParameters($path, $method)
136
    {
137
        $structure = $this->getPathDefinition($path, $method);
138
139
        if (!isset($structure['parameters'])) {
140
            return new SwaggerRequestBody($this, "$method $path", []);
141
        }
142
143
        return new SwaggerRequestBody($this, "$method $path", $structure['parameters']);
144
    }
145
146
    /**
147
     * @param $path
148
     * @param $method
149
     * @param $status
150
     * @return \ByJG\Swagger\SwaggerResponseBody
151
     * @throws \ByJG\Swagger\Exception\HttpMethodNotFoundException
152
     * @throws \ByJG\Swagger\Exception\InvalidDefinitionException
153
     * @throws \ByJG\Swagger\Exception\NotMatchedException
154
     * @throws \ByJG\Swagger\Exception\PathNotFoundException
155
     */
156
    public function getResponseParameters($path, $method, $status)
157
    {
158
        $structure = $this->getPathDefinition($path, $method);
159
160
        if (!isset($structure['responses'][$status])) {
161
            throw new InvalidDefinitionException("Could not found status code '$status' in '$path' and '$method'");
162
        }
163
164
        return new SwaggerResponseBody($this, "$method $status $path", $structure['responses'][$status]);
165
    }
166
167
    /**
168
     * OpenApi 2.0 doesn't describe null values, so this flag defines,
169
     * if match is ok when one of property
170
     *
171
     * @return bool
172
     */
173
    public function isAllowNullValues()
174
    {
175
        return $this->allowNullValues;
176
    }
177
178
    /**
179
     * OpenApi 2.0 doesn't describe null values, so this flag defines,
180
     * if match is ok when one of property
181
     *
182
     * @param $value
183
     */
184
    public function setAllowNullValues($value)
185
    {
186
        $this->allowNullValues = (bool) $value;
187
    }
188
}
189