Passed
Push — master ( 76b039...f6fc8d )
by Alex
04:36
created

PathParameterParser::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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