PathParameterParser::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
1
<?php
2
3
namespace AlexWells\ApiDocsGenerator\Parsers;
4
5
use ReflectionParameter;
6
use Illuminate\Database\Eloquent\Model;
7
use AlexWells\ApiDocsGenerator\Exceptions\NoTypeSpecifiedException;
8
9
class PathParameterParser
10
{
11
    /**
12
     * Path parameter name.
13
     *
14
     * @var string
15
     */
16
    protected $name;
17
18
    /**
19
     * Should method parameters without type throw an exception.
20
     *
21
     * @var bool
22
     */
23
    protected $typeChecksEnabled;
24
25
    /**
26
     * A route wrapper object.
27
     *
28
     * @var RouteWrapper
29
     */
30
    protected $route;
31
32
    /**
33
     * Parsed parameter reflection.
34
     *
35
     * @var
36
     */
37
    protected $parameterReflection;
38
39
    /**
40
     * PathParameterParser constructor.
41
     *
42
     * @param RouteWrapper $route
43
     */
44
    public function __construct($name, $typeChecksEnabled, RouteWrapper $route)
45
    {
46
        $this->name = $name;
47
        $this->typeChecksEnabled = $typeChecksEnabled;
48
        $this->route = $route;
49
    }
50
51
    /**
52
     * Parse parameter.
53
     *
54
     * @return array
55
     */
56
    public function parse()
57
    {
58
        return [
59
            'name' => $this->getName(),
60
            'required' => $this->isRequired(),
61
            'type' => $this->getType(),
62
            'default' => $this->getDefaultValue(),
63
            'regex' => $this->getRegex(),
64
            'description' => $this->getDescription()
65
        ];
66
    }
67
68
    public function getName()
69
    {
70
        return rtrim($this->name, '?');
71
    }
72
73
    /**
74
     * Checks if the parameter is required.
75
     *
76
     * @return bool
77
     */
78
    public function isRequired()
79
    {
80
        return ! ends_with($this->name, '?');
81
    }
82
83
    /**
84
     * Returns parameter's type.
85
     *
86
     * @throws NoTypeSpecifiedException
87
     *
88
     * @return string
89
     */
90
    public function getType()
91
    {
92
        if(! ($reflection = $this->getParameterReflection())) {
93
            return null;
94
        }
95
96
        if(! ($parameterType = $reflection->getType())) {
97
            if($this->typeChecksEnabled) {
98
                throw new NoTypeSpecifiedException('No type specified for parameter ' . $this->getName());
99
            }
100
101
            return null;
102
        }
103
104
        if ($parameterType->isBuiltin()) {
105
            return strval($parameterType);
106
        }
107
108
        if (! ($parameterClass = $reflection->getClass())) {
109
            return null;
110
        }
111
112
        $type = $parameterClass->getShortName();
113
114
        if ($parameterClass->isSubclassOf(Model::class)) {
115
            //if (empty($description)) {
116
            //    $description = "`$type` id"; // TODO
117
            //}
118
            $type = 'model_id';
119
        }
120
121
        return $type;
122
    }
123
124
    /**
125
     * Returns parameter's default value.
126
     *
127
     * @return mixed
128
     */
129
    public function getDefaultValue()
130
    {
131
        $default = $this->route->getDefaultTagsParser()->get('path', $this->getName());
132
133
        if(! is_null($default)) {
134
            return $default;
135
        }
136
137
        if(! ($reflection = $this->getParameterReflection()) || ! $reflection->isDefaultValueAvailable()) {
138
            return null;
139
        }
140
141
        return strval($reflection->getDefaultValue());
142
    }
143
144
    /**
145
     * Returns parameter's regex pattern (from ->where() calls).
146
     *
147
     * @return string|null
148
     */
149
    public function getRegex()
150
    {
151
        return $this->route->getOriginalRoute()->wheres[$this->getName()] ?? null;
152
    }
153
154
    /**
155
     * Returns parameter's description.
156
     *
157
     * @return string
158
     */
159
    public function getDescription()
160
    {
161
        return $this->route->getDescribeTagsParser()->get('path', $this->getName());
162
    }
163
164
    /**
165
     * Returns parameter's reflection.
166
     *
167
     * @return ReflectionParameter
168
     */
169
    protected function getParameterReflection()
170
    {
171
        if (! $this->parameterReflection) {
172
            return $this->parameterReflection = $this->route->getMethodParameterByName($this->getName());
173
        }
174
175
        return $this->parameterReflection;
176
    }
177
}
178