Completed
Push — master ( bb12d3...dcbb11 )
by Joao
02:11
created

SwaggerSchema   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 124
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 28
lcom 1
cbo 7
dl 0
loc 124
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getHttpSchema() 0 4 2
A getHost() 0 4 2
A getBasePath() 0 4 2
C getPathDefinition() 0 37 7
B validateArguments() 0 11 5
A getDefintion() 0 14 4
A getRequestParameters() 0 10 2
A getResponseParameters() 0 10 2
A isAllowNullValues() 0 4 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
    public function getPathDefinition($path, $method)
43
    {
44
        $method = strtolower($method);
45
46
        $path = preg_replace('~^' . $this->getBasePath() . '~', '', $path);
47
48
        // Try direct match
49
        if (isset($this->jsonFile['paths'][$path])) {
50
            if (isset($this->jsonFile['paths'][$path][$method])) {
51
                return $this->jsonFile['paths'][$path][$method];
52
            }
53
            throw new HttpMethodNotFoundException("The http method '$method' not found in '$path'");
54
        }
55
56
        // Try inline parameter
57
        foreach (array_keys($this->jsonFile['paths']) as $pathItem) {
58
            if (strpos($pathItem, '{') === false) {
59
                continue;
60
            }
61
62
            $pathItemPattern = '~^' . preg_replace('~\{(.*?)\}~', '(?<\1>[^/]+)', $pathItem) . '$~';
63
64
            $matches = [];
65
            if (preg_match($pathItemPattern, $path, $matches)) {
66
                $pathDef = $this->jsonFile['paths'][$pathItem];
67
                if (!isset($pathDef[$method])) {
68
                    throw new HttpMethodNotFoundException("The http method '$method' not found in '$path'");
69
                }
70
71
                $this->validateArguments('path', $pathDef[$method]['parameters'], $matches);
72
73
                return $pathDef[$method];
74
            }
75
        }
76
77
        throw new PathNotFoundException('Path "' . $path . '" not found');
78
    }
79
80
    private function validateArguments($parameterIn, $parameters, $arguments)
81
    {
82
        foreach ($parameters as $parameter) {
83
            if ($parameter['in'] === $parameterIn) {
84
                if ($parameter['type'] === "integer"
85
                    && filter_var($arguments[$parameter['name']], FILTER_VALIDATE_INT) === false) {
86
                    throw new NotMatchedException('Path expected an integer value');
87
                }
88
            }
89
        }
90
    }
91
92
    public function getDefintion($name)
93
    {
94
        $nameParts = explode('/', $name);
95
96
        if (count($nameParts) < 3 || $nameParts[0] != '#') {
97
            throw new InvalidDefinitionException('Invalid Definition');
98
        }
99
100
        if (!isset($this->jsonFile[$nameParts[1]][$nameParts[2]])) {
101
            throw new DefinitionNotFoundException("Definition '$name' not found");
102
        }
103
104
        return $this->jsonFile[$nameParts[1]][$nameParts[2]];
105
    }
106
107
    public function getRequestParameters($path, $method)
108
    {
109
        $structure = $this->getPathDefinition($path, $method);
110
111
        if (!isset($structure['parameters'])) {
112
            return new SwaggerRequestBody($this, "$method $path", []);
113
        }
114
115
        return new SwaggerRequestBody($this, "$method $path", $structure['parameters']);
116
    }
117
118
    public function getResponseParameters($path, $method, $status)
119
    {
120
        $structure = $this->getPathDefinition($path, $method);
121
122
        if (!isset($structure['responses'][$status])) {
123
            throw new InvalidDefinitionException("Could not found status code '$status' in '$path' and '$method'");
124
        }
125
126
        return new SwaggerResponseBody($this, "$method $status $path", $structure['responses'][$status]);
127
    }
128
129
    /**
130
     * OpenApi 2.0 doesn't describe null values, so this flag defines,
131
     * if match is ok when one of property
132
     *
133
     * @return bool
134
     */
135
    public function isAllowNullValues()
136
    {
137
        return $this->allowNullValues;
138
    }
139
}
140