Issues (182)

src/OptionsMethodRequest.php (6 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Resource;
6
7
use ReflectionException;
8
use ReflectionMethod;
9
use ReflectionNamedType;
10
use ReflectionParameter;
11
12
use function assert;
13
use function is_array;
14
use function is_string;
15
use function method_exists;
16
17
/**
18
 * @psalm-import-type OptionsResponse from Types
19
 * @psalm-import-type InsMap from Types
20
 * @psalm-import-type ParameterMetadata from Types
21
 * @psalm-import-type ParametersMap from Types
22
 * @psalm-import-type RequiredParameterList from Types
23
 * @psalm-import-type ReflectionParameterList from Types
24
 */
25
final class OptionsMethodRequest
26
{
27
    /**
28
     * @param ParametersMap $paramDoc
29
     * @param InsMap        $ins
30
     *
31
     * @return OptionsResponse
32
     */
33
    public function __invoke(ReflectionMethod $method, array $paramDoc, array $ins): array
34
    {
35
        return $this->getParamMetas($method->getParameters(), $paramDoc, $ins);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getParamMe...ers(), $paramDoc, $ins) returns the type array which is incompatible with the documented return type BEAR\Resource\OptionsResponse.
Loading history...
36
    }
37
38
    /**
39
     * @param ParametersMap $paramDoc
40
     *
41
     * @psalm-suppress RedundantCondition for BC
42
     */
43
    private function getParameterType(ReflectionParameter $parameter, array $paramDoc, string $name): string|null
44
    {
45
        /** @phpstan-ignore function.alreadyNarrowedType */
46
        $hasType = method_exists($parameter, 'getType') && $parameter->getType();
47
        if ($hasType) {
48
            return $this->getType($parameter);
49
        }
50
51
        return $paramDoc[$name]['type'] ?? null;
52
    }
53
54
    /**
55
     * @param ReflectionParameterList $parameters
56
     * @param ParametersMap           $paramDoc
57
     * @param InsMap                  $ins
58
     *
59
     * @return OptionsResponse
60
     */
61
    private function getParamMetas(array $parameters, array $paramDoc, array $ins): array
62
    {
63
        foreach ($parameters as $parameter) {
64
            $name = (string) $parameter->name;
65
            if (isset($ins[$name])) {
66
                $paramDoc[$name]['in'] = $ins[$parameter->name];
67
            }
68
69
            if (! isset($paramDoc[$parameter->name])) {
70
                $paramDoc[$name] = [];
71
            }
72
73
            $paramDoc = $this->paramType($paramDoc, $parameter);
74
            $paramDoc = $this->paramDefault($paramDoc, $parameter);
75
        }
76
77
        $required = $this->getRequired($parameters);
78
79
        return $this->setParamMetas($paramDoc, $required);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->setParamMetas($paramDoc, $required) returns the type array which is incompatible with the documented return type BEAR\Resource\OptionsResponse.
Loading history...
80
    }
81
82
    /**
83
     * @param ReflectionParameterList $parameters
84
     *
85
     * @return RequiredParameterList
86
     */
87
    private function getRequired(array $parameters): array
88
    {
89
        $required = [];
90
        foreach ($parameters as $parameter) {
91
            if ($parameter->isOptional()) {
92
                continue;
93
            }
94
95
            $required[] = $parameter->name;
96
        }
97
98
        return $required;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $required returns the type array which is incompatible with the documented return type BEAR\Resource\RequiredParameterList.
Loading history...
99
    }
100
101
    /**
102
     * @param ParametersMap $paramDoc
103
     *
104
     * @return ParametersMap
105
     *
106
     * @throws ReflectionException
107
     */
108
    private function paramDefault(array $paramDoc, ReflectionParameter $parameter): array
109
    {
110
        $hasDefault = $parameter->isDefaultValueAvailable() && $parameter->getDefaultValue() !== null;
111
        if ($hasDefault) {
112
            $default = $parameter->getDefaultValue();
113
            $paramDoc[(string) $parameter->name]['default'] = is_array($default) ? '[]' : (string) $parameter->getDefaultValue(); // @phpstan-ignore-lines
114
        }
115
116
        return $paramDoc;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $paramDoc returns the type array which is incompatible with the documented return type BEAR\Resource\ParametersMap.
Loading history...
117
    }
118
119
    /**
120
     * @param ParametersMap $paramDoc
121
     *
122
     * @return ParametersMap
123
     */
124
    private function paramType(array $paramDoc, ReflectionParameter $parameter): array
125
    {
126
        $type = $this->getParameterType($parameter, $paramDoc, $parameter->name);
127
        if (is_string($type)) {
128
            $paramDoc[(string) $parameter->name]['type'] = $type; // override type parameter by reflection over phpdoc param type
129
        }
130
131
        return $paramDoc;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $paramDoc returns the type array which is incompatible with the documented return type BEAR\Resource\ParametersMap.
Loading history...
132
    }
133
134
    private function getType(ReflectionParameter $parameter): string
135
    {
136
        $namedType = $parameter->getType();
137
        assert($namedType instanceof ReflectionNamedType);
138
        $type = $namedType->getName();
139
        if ($type === 'int') {
140
            $type = 'integer';
141
        }
142
143
        return $type;
144
    }
145
146
    /**
147
     * @param ParametersMap         $paramDoc
148
     * @param RequiredParameterList $required
149
     *
150
     * @return OptionsResponse
151
     */
152
    private function setParamMetas(array $paramDoc, array $required): array
153
    {
154
        $paramMetas = [];
155
        if ((bool) $paramDoc) {
156
            $paramMetas['parameters'] = $paramDoc;
157
        }
158
159
        if ((bool) $required) {
160
            $paramMetas['required'] = $required;
161
        }
162
163
        return $paramMetas;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $paramMetas returns the type array which is incompatible with the documented return type BEAR\Resource\OptionsResponse.
Loading history...
164
    }
165
}
166