Passed
Pull Request — master (#34)
by Anatoly
02:10
created

OpenApi::toArray()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 0
cts 3
cp 0
rs 10
cc 1
nc 1
nop 0
crap 2
1
<?php declare(strict_types=1);
2
3
/**
4
 * It's free open-source software released under the MIT License.
5
 *
6
 * @author Anatoly Fenric <[email protected]>
7
 * @copyright Copyright (c) 2018, Anatoly Fenric
8
 * @license https://github.com/sunrise-php/http-router/blob/master/LICENSE
9
 * @link https://github.com/sunrise-php/http-router
10
 */
11
12
namespace Sunrise\Http\Router\OpenApi;
13
14
/**
15
 * Import classes
16
 */
17
use Doctrine\Common\Annotations\SimpleAnnotationReader;
18
use Sunrise\Http\Router\RouteCollectionInterface;
19
use Sunrise\Http\Router\RouteInterface;
20
use Sunrise\Http\Router\OpenApi\Annotation\OpenApi\Operation;
21
use Sunrise\Http\Router\OpenApi\Annotation\OpenApi\Parameter;
22
use ReflectionClass;
23
24
/**
25
 * Import functions
26
 */
27
use function Sunrise\Http\Router\path_parse;
0 ignored issues
show
introduced by
The function Sunrise\Http\Router\path_parse was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
28
use function str_replace;
29
use function strtolower;
30
31
/**
32
 * OpenApi
33
 */
34
class OpenApi
35
{
36
37
    /**
38
     * @var RouteCollectionInterface
39
     */
40
    private $routes;
41
42
    /**
43
     * @var SimpleAnnotationReader
44
     */
45
    private $annotationReader;
46
47
    /**
48
     * @var array
49
     */
50
    private $schema = [];
51
52
    /**
53
     * Constructor of the class
54
     *
55
     * @param string $title
56
     * @param string $version
57
     * @param RouteCollectionInterface $routes
58
     */
59
    public function __construct(string $title, string $version, RouteCollectionInterface $routes)
60
    {
61
        $this->routes = $routes;
62
63
        $this->annotationReader = new SimpleAnnotationReader();
64
        $this->annotationReader->addNamespace('Sunrise\Http\Router\OpenApi\Annotation');
65
66
        $this->schema['openapi'] = '3.0.2';
67
        $this->schema['info']['title'] = $title;
68
        $this->schema['info']['version'] = $version;
69
70
        // auto build...
71
        $this->build();
72
    }
73
74
    /**
75
     * @return array
76
     */
77
    public function toArray() : array
78
    {
79
        return $this->schema;
80
    }
81
82
    /**
83
     * @return void
84
     */
85
    private function build() : void
86
    {
87
        foreach ($this->routes->all() as $route) {
88
            $path = $this->getPathFromRoute($route);
89
            $operation = $this->getOperationFromRoute($route);
90
91
            foreach ($route->getMethods() as $method) {
92
                $method = strtolower($method);
93
94
                $this->schema['paths'][$path][$method] = $operation->toArray();
95
            }
96
        }
97
    }
98
99
    /**
100
     * @param RouteInterface $route
101
     *
102
     * @return Operation
103
     */
104
    private function getOperationFromRoute(RouteInterface $route) : Operation
105
    {
106
        $source = new ReflectionClass($route->getRequestHandler());
107
108
        $operation = $this->annotationReader->getClassAnnotation($source, Operation::class);
109
        $operation = $operation ?? new Operation();
110
111
        $attributes = path_parse($route->getPath());
0 ignored issues
show
Bug introduced by
The function path_parse was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

111
        $attributes = /** @scrutinizer ignore-call */ path_parse($route->getPath());
Loading history...
112
113
        foreach ($attributes as $attribute) {
114
            $parameter = new Parameter();
115
            $parameter->in = 'path';
116
            $parameter->name = $attribute['name'];
117
            $parameter->required = $attribute['isOptional'];
118
119
            $operation->parameters[] = $parameter;
120
        }
121
122
        return $operation;
123
    }
124
125
    /**
126
     * @param RouteInterface $route
127
     *
128
     * @return string
129
     */
130
    private function getPathFromRoute(RouteInterface $route) : string
131
    {
132
        $path = $route->getPath();
133
        $attributes = path_parse($path);
0 ignored issues
show
Bug introduced by
The function path_parse was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

133
        $attributes = /** @scrutinizer ignore-call */ path_parse($path);
Loading history...
134
135
        foreach ($attributes as $attribute) {
136
            $path = str_replace($attribute['raw'], '{' . $attribute['name'] . '}', $path);
137
        }
138
139
        return str_replace(['(', ')'], '', $path);
140
    }
141
}
142