OpenApiPhpTypeSchemaResolverManager   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 158
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 59
c 0
b 0
f 0
dl 0
loc 158
ccs 70
cts 70
cp 1
rs 10
wmc 21

9 Methods

Rating   Name   Duplication   Size   Complexity  
A resolvePhpTypeSchema() 0 28 6
A setPhpTypeSchemaResolvers() 0 10 4
A __construct() 0 6 1
A getDefaultPhpTypeSchemaResolvers() 0 16 1
A findPhpTypeSchemaResolver() 0 11 3
A enrichDocumentWithDefinitions() 0 4 2
A createPhpTypeSchemaReference() 0 4 1
A completePhpTypeSchema() 0 14 2
A sortPhpTypeSchemaResolvers() 0 6 1
1
<?php
2
3
/**
4
 * It's free open-source software released under the MIT License.
5
 *
6
 * @author Anatoly Nekhay <[email protected]>
7
 * @copyright Copyright (c) 2018, Anatoly Nekhay
8
 * @license https://github.com/sunrise-php/http-router/blob/master/LICENSE
9
 * @link https://github.com/sunrise-php/http-router
10
 */
11
12
declare(strict_types=1);
13
14
namespace Sunrise\Http\Router\OpenApi;
15
16
use Reflector;
17
use Sunrise\Http\Router\OpenApi\PhpTypeSchemaResolver\ArrayAccessPhpTypeSchemaResolver;
18
use Sunrise\Http\Router\OpenApi\PhpTypeSchemaResolver\ArrayPhpTypeSchemaResolver;
19
use Sunrise\Http\Router\OpenApi\PhpTypeSchemaResolver\BackedEnumPhpTypeSchemaResolver;
20
use Sunrise\Http\Router\OpenApi\PhpTypeSchemaResolver\BoolPhpTypeSchemaResolver;
21
use Sunrise\Http\Router\OpenApi\PhpTypeSchemaResolver\FloatPhpTypeSchemaResolver;
22
use Sunrise\Http\Router\OpenApi\PhpTypeSchemaResolver\IntPhpTypeSchemaResolver;
23
use Sunrise\Http\Router\OpenApi\PhpTypeSchemaResolver\ObjectPhpTypeSchemaResolver;
24
use Sunrise\Http\Router\OpenApi\PhpTypeSchemaResolver\RamseyUuidPhpTypeSchemaResolver;
25
use Sunrise\Http\Router\OpenApi\PhpTypeSchemaResolver\StreamPhpTypeSchemaResolver;
26
use Sunrise\Http\Router\OpenApi\PhpTypeSchemaResolver\StringPhpTypeSchemaResolver;
27
use Sunrise\Http\Router\OpenApi\PhpTypeSchemaResolver\SymfonyUidPhpTypeSchemaResolver;
28
use Sunrise\Http\Router\OpenApi\PhpTypeSchemaResolver\TimestampPhpTypeSchemaResolver;
29
use Sunrise\Http\Router\OpenApi\PhpTypeSchemaResolver\TimezonePhpTypeSchemaResolver;
30
31
use function sprintf;
32
use function usort;
33
34
/**
35
 * @since 3.0.0
36
 */
37
final class OpenApiPhpTypeSchemaResolverManager implements OpenApiPhpTypeSchemaResolverManagerInterface
38
{
39
    /**
40
     * @var array<array-key, OpenApiPhpTypeSchemaResolverInterface>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<array-key, OpenApi...chemaResolverInterface> at position 2 could not be parsed: Unknown type name 'array-key' at position 2 in array<array-key, OpenApiPhpTypeSchemaResolverInterface>.
Loading history...
41
     */
42
    private array $phpTypeSchemaResolvers = [];
43
44
    /**
45
     * @var array<string, array<array-key, mixed>>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string, array<array-key, mixed>> at position 6 could not be parsed: Unknown type name 'array-key' at position 6 in array<string, array<array-key, mixed>>.
Loading history...
46
     */
47
    private array $namedPhpTypeSchemas = [];
48
49
    private bool $isPhpTypeSchemaResolversSorted = false;
50
51
    /**
52
     * @param array<array-key, OpenApiPhpTypeSchemaResolverInterface> $phpTypeSchemaResolvers
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<array-key, OpenApi...chemaResolverInterface> at position 2 could not be parsed: Unknown type name 'array-key' at position 2 in array<array-key, OpenApiPhpTypeSchemaResolverInterface>.
Loading history...
53
     */
54 5
    public function __construct(
55
        private readonly OpenApiConfiguration $openApiConfiguration,
56
        array $phpTypeSchemaResolvers = [],
57
    ) {
58 5
        $this->setPhpTypeSchemaResolvers(self::getDefaultPhpTypeSchemaResolvers());
59 5
        $this->setPhpTypeSchemaResolvers($phpTypeSchemaResolvers);
60
    }
61
62
    /**
63
     * @inheritDoc
64
     */
65 3
    public function resolvePhpTypeSchema(Type $phpType, Reflector $phpTypeHolder): array
66
    {
67 3
        $this->isPhpTypeSchemaResolversSorted or $this->sortPhpTypeSchemaResolvers();
68
69 3
        $phpTypeSchemaResolver = $this->findPhpTypeSchemaResolver($phpType, $phpTypeHolder);
70 3
        if ($phpTypeSchemaResolver === null) {
71 3
            return [];
72
        }
73
74 3
        $phpTypeSchemaName = null;
75 3
        if ($phpTypeSchemaResolver instanceof OpenApiPhpTypeSchemaNameResolverInterface) {
76 3
            $phpTypeSchemaName = $phpTypeSchemaResolver->resolvePhpTypeSchemaName($phpType, $phpTypeHolder);
77
        }
78
79 3
        if (isset($phpTypeSchemaName, $this->namedPhpTypeSchemas[$phpTypeSchemaName])) {
80 3
            $phpTypeSchemaReference = self::createPhpTypeSchemaReference($phpTypeSchemaName);
81 3
            return self::completePhpTypeSchema($phpType, $phpTypeSchemaReference);
82
        }
83
84 3
        $phpTypeSchema = $phpTypeSchemaResolver->resolvePhpTypeSchema($phpType, $phpTypeHolder);
85
86 3
        if (isset($phpTypeSchemaName)) {
87 3
            $this->namedPhpTypeSchemas[$phpTypeSchemaName] = $phpTypeSchema;
88 3
            $phpTypeSchemaReference = self::createPhpTypeSchemaReference($phpTypeSchemaName);
89 3
            return self::completePhpTypeSchema($phpType, $phpTypeSchemaReference);
90
        }
91
92 3
        return self::completePhpTypeSchema($phpType, $phpTypeSchema);
93
    }
94
95
    /**
96
     * @inheritDoc
97
     *
98
     * @see self::createPhpTypeSchemaReference()
99
     */
100 3
    public function enrichDocumentWithDefinitions(array &$document): void
101
    {
102 3
        foreach ($this->namedPhpTypeSchemas as $phpTypeSchemaName => $phpTypeSchema) {
103 3
            $document['components']['schemas'][$phpTypeSchemaName] = $phpTypeSchema;
104
        }
105
    }
106
107
    /**
108
     * @param array<array-key, OpenApiPhpTypeSchemaResolverInterface> $phpTypeSchemaResolvers
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<array-key, OpenApi...chemaResolverInterface> at position 2 could not be parsed: Unknown type name 'array-key' at position 2 in array<array-key, OpenApiPhpTypeSchemaResolverInterface>.
Loading history...
109
     */
110 5
    private function setPhpTypeSchemaResolvers(array $phpTypeSchemaResolvers): void
111
    {
112 5
        foreach ($phpTypeSchemaResolvers as $phpTypeSchemaResolver) {
113 5
            $this->phpTypeSchemaResolvers[] = $phpTypeSchemaResolver;
114
115 5
            if ($phpTypeSchemaResolver instanceof OpenApiConfigurationAwareInterface) {
116 5
                $phpTypeSchemaResolver->setOpenApiConfiguration($this->openApiConfiguration);
117
            }
118 5
            if ($phpTypeSchemaResolver instanceof OpenApiPhpTypeSchemaResolverManagerAwareInterface) {
119 5
                $phpTypeSchemaResolver->setOpenApiPhpTypeSchemaResolverManager($this);
120
            }
121
        }
122
    }
123
124 3
    private function findPhpTypeSchemaResolver(
125
        Type $phpType,
126
        Reflector $phpTypeHolder,
127
    ): ?OpenApiPhpTypeSchemaResolverInterface {
128 3
        foreach ($this->phpTypeSchemaResolvers as $phpTypeSchemaResolver) {
129 3
            if ($phpTypeSchemaResolver->supportsPhpType($phpType, $phpTypeHolder)) {
130 3
                return $phpTypeSchemaResolver;
131
            }
132
        }
133
134 3
        return null;
135
    }
136
137 3
    private function sortPhpTypeSchemaResolvers(): void
138
    {
139 3
        $this->isPhpTypeSchemaResolversSorted = usort($this->phpTypeSchemaResolvers, static fn(
140 3
            OpenApiPhpTypeSchemaResolverInterface $a,
141 3
            OpenApiPhpTypeSchemaResolverInterface $b
142 3
        ): int => $b->getWeight() <=> $a->getWeight());
143
    }
144
145
    /**
146
     * @return array<array-key, mixed>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<array-key, mixed> at position 2 could not be parsed: Unknown type name 'array-key' at position 2 in array<array-key, mixed>.
Loading history...
147
     */
148 3
    private static function createPhpTypeSchemaReference(string $phpTypeSchemaName): array
149
    {
150 3
        return [
151 3
            '$ref' => sprintf('#/components/schemas/%s', $phpTypeSchemaName),
152 3
        ];
153
    }
154
155
    /**
156
     * @param array<array-key, mixed> $phpTypeSchema
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<array-key, mixed> at position 2 could not be parsed: Unknown type name 'array-key' at position 2 in array<array-key, mixed>.
Loading history...
157
     *
158
     * @return array<array-key, mixed>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<array-key, mixed> at position 2 could not be parsed: Unknown type name 'array-key' at position 2 in array<array-key, mixed>.
Loading history...
159
     */
160 3
    private static function completePhpTypeSchema(Type $phpType, array $phpTypeSchema): array
161
    {
162 3
        if ($phpType->allowsNull) {
163 3
            $phpTypeSchema = [
164 3
                'anyOf' => [
165 3
                    $phpTypeSchema,
166 3
                    [
167 3
                        'type' => Type::OAS_TYPE_NAME_NULL,
168 3
                    ],
169 3
                ],
170 3
            ];
171
        }
172
173 3
        return $phpTypeSchema;
174
    }
175
176
    /**
177
     * @return array<array-key, OpenApiPhpTypeSchemaResolverInterface>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<array-key, OpenApi...chemaResolverInterface> at position 2 could not be parsed: Unknown type name 'array-key' at position 2 in array<array-key, OpenApiPhpTypeSchemaResolverInterface>.
Loading history...
178
     */
179 5
    private static function getDefaultPhpTypeSchemaResolvers(): array
180
    {
181 5
        return [
182 5
            new ArrayAccessPhpTypeSchemaResolver(),
183 5
            new ArrayPhpTypeSchemaResolver(),
184 5
            new BackedEnumPhpTypeSchemaResolver(),
185 5
            new BoolPhpTypeSchemaResolver(),
186 5
            new FloatPhpTypeSchemaResolver(),
187 5
            new IntPhpTypeSchemaResolver(),
188 5
            new ObjectPhpTypeSchemaResolver(),
189 5
            new RamseyUuidPhpTypeSchemaResolver(),
190 5
            new StreamPhpTypeSchemaResolver(),
191 5
            new StringPhpTypeSchemaResolver(),
192 5
            new SymfonyUidPhpTypeSchemaResolver(),
193 5
            new TimestampPhpTypeSchemaResolver(),
194 5
            new TimezonePhpTypeSchemaResolver(),
195 5
        ];
196
    }
197
}
198