Passed
Pull Request — master (#67)
by Joao
07:03
created

OpenApiSchema   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 128
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 28
eloc 44
dl 0
loc 128
c 1
b 0
f 0
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getServerUrl() 0 20 6
A getDefinition() 0 13 4
A setServerVariable() 0 3 1
B validateArguments() 0 21 11
A getBasePath() 0 4 1
A __construct() 0 11 3
A getRequestParameters() 0 8 2
1
<?php
2
3
namespace ByJG\ApiTools\OpenApi;
4
5
use ByJG\ApiTools\Base\Schema;
6
use ByJG\ApiTools\Exception\DefinitionNotFoundException;
7
use ByJG\ApiTools\Exception\HttpMethodNotFoundException;
8
use ByJG\ApiTools\Exception\InvalidDefinitionException;
9
use ByJG\ApiTools\Exception\NotMatchedException;
10
use ByJG\ApiTools\Exception\PathNotFoundException;
11
use ByJG\Util\Uri;
12
use InvalidArgumentException;
13
14
class OpenApiSchema extends Schema
15
{
16
17
    protected $serverVariables = [];
18
19
    /**
20
     * Initialize with schema data, which can be a PHP array or encoded as JSON.
21
     *
22
     * @param array|string $data
23
     */
24
    public function __construct($data)
25
    {
26
        // when given a string, decode from JSON
27
        if (is_string($data)) {
28
            $data = json_decode($data, true);
29
        }
30
        // make sure we got an array
31
        if (!is_array($data)) {
32
            throw new InvalidArgumentException('schema must be given as array or JSON string');
33
        }
34
        $this->jsonFile = $data;
35
    }
36
37
    public function getServerUrl()
38
    {
39
        if (!isset($this->jsonFile['servers'])) {
40
            return '';
41
        }
42
        $serverUrl = $this->jsonFile['servers'][0]['url'];
43
44
        if (isset($this->jsonFile['servers'][0]['variables'])) {
45
            foreach ($this->jsonFile['servers'][0]['variables'] as $var => $value) {
46
                if (!isset($this->serverVariables[$var])) {
47
                    $this->serverVariables[$var] = $value['default'];
48
                }
49
            }
50
        }
51
52
        foreach ($this->serverVariables as $var => $value) {
53
            $serverUrl = preg_replace("/\{$var\}/", $value, $serverUrl);
54
        }
55
56
        return $serverUrl;
57
    }
58
59
    public function getBasePath()
60
    {
61
        $uriServer = new Uri($this->getServerUrl());
62
        return $uriServer->getPath();
63
    }
64
65
    /**
66
     * @param $parameterIn
67
     * @param $parameters
68
     * @param $arguments
69
     * @throws DefinitionNotFoundException
70
     * @throws InvalidDefinitionException
71
     * @throws NotMatchedException
72
     */
73
    protected function validateArguments($parameterIn, $parameters, $arguments)
74
    {
75
        foreach ($parameters as $parameter) {
76
            if (isset($parameter['$ref'])) {
77
                $paramParts = explode("/", $parameter['$ref']);
78
                if (count($paramParts) != 4 || $paramParts[0] != "#" || $paramParts[1] != self::SWAGGER_COMPONENTS || $paramParts[2] != self::SWAGGER_PARAMETERS) {
79
                    throw new InvalidDefinitionException(
80
                        "Not get the reference in the expected format #/components/parameters/<NAME>"
81
                    );
82
                }
83
                if (!isset($this->jsonFile[self::SWAGGER_COMPONENTS][self::SWAGGER_PARAMETERS][$paramParts[3]])) {
84
                    throw new DefinitionNotFoundException(
85
                        "Not find reference #/components/parameters/${paramParts[3]}"
86
                    );
87
                }
88
                $parameter = $this->jsonFile[self::SWAGGER_COMPONENTS][self::SWAGGER_PARAMETERS][$paramParts[3]];
89
            }
90
            if ($parameter['in'] === $parameterIn &&
91
                $parameter['schema']['type'] === "integer"
92
                && filter_var($arguments[$parameter['name']], FILTER_VALIDATE_INT) === false) {
93
                throw new NotMatchedException('Path expected an integer value');
94
            }
95
        }
96
    }
97
98
    /**
99
     * @param $name
100
     * @return mixed
101
     * @throws DefinitionNotFoundException
102
     * @throws InvalidDefinitionException
103
     */
104
    public function getDefinition($name)
105
    {
106
        $nameParts = explode('/', $name);
107
108
        if (count($nameParts) < 4 || $nameParts[0] !== '#') {
109
            throw new InvalidDefinitionException('Invalid Component');
110
        }
111
112
        if (!isset($this->jsonFile[$nameParts[1]][$nameParts[2]][$nameParts[3]])) {
113
            throw new DefinitionNotFoundException("Component'$name' not found");
114
        }
115
116
        return $this->jsonFile[$nameParts[1]][$nameParts[2]][$nameParts[3]];
117
    }
118
119
    /**
120
     * @param $path
121
     * @param $method
122
     * @return OpenApiRequestBody
123
     * @throws DefinitionNotFoundException
124
     * @throws HttpMethodNotFoundException
125
     * @throws InvalidDefinitionException
126
     * @throws NotMatchedException
127
     * @throws PathNotFoundException
128
     */
129
    public function getRequestParameters($path, $method)
130
    {
131
        $structure = $this->getPathDefinition($path, $method);
132
133
        if (!isset($structure['requestBody'])) {
134
            return new OpenApiRequestBody($this, "$method $path", []);
135
        }
136
        return new OpenApiRequestBody($this, "$method $path", $structure['requestBody']);
137
    }
138
139
    public function setServerVariable($var, $value)
140
    {
141
        $this->serverVariables[$var] = $value;
142
    }
143
}
144