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 | * @author Saud bin Mohammed <[email protected]> |
||
8 | * @copyright Copyright (c) 2018, Anatoly Fenric |
||
9 | * @license https://github.com/sunrise-php/vin/blob/master/LICENSE |
||
10 | * @link https://github.com/sunrise-php/vin |
||
11 | */ |
||
12 | |||
13 | namespace Sunrise\Vin; |
||
14 | |||
15 | /** |
||
16 | * Import classes |
||
17 | */ |
||
18 | use InvalidArgumentException; |
||
19 | |||
20 | /** |
||
21 | * Import functions |
||
22 | */ |
||
23 | use function date; |
||
24 | use function preg_match; |
||
25 | use function sprintf; |
||
26 | use function strpbrk; |
||
27 | use function strtoupper; |
||
28 | |||
29 | /** |
||
30 | * Import constants |
||
31 | */ |
||
32 | use const Sunrise\Vin\MANUFACTURERS; |
||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||
33 | use const Sunrise\Vin\REGIONS; |
||
0 ignored issues
–
show
|
|||
34 | use const Sunrise\Vin\YEARS; |
||
0 ignored issues
–
show
|
|||
35 | |||
36 | /** |
||
37 | * Vehicle Identification Number |
||
38 | */ |
||
39 | class Vin implements VinInterface |
||
40 | { |
||
41 | |||
42 | /** |
||
43 | * Regular expression for a VIN parsing/validation (ISO 3779) |
||
44 | * |
||
45 | * @var string |
||
46 | * |
||
47 | * @link https://www.iso.org/standard/52200.html |
||
48 | */ |
||
49 | public const REGEX = '/^(?<wmi>[0-9A-HJ-NPR-Z]{3})(?<vds>[0-9A-HJ-NPR-Z]{6})(?<vis>[0-9A-HJ-NPR-Z]{8})$/'; |
||
50 | |||
51 | /** |
||
52 | * The VIN value |
||
53 | * |
||
54 | * @var string |
||
55 | */ |
||
56 | private $vin; |
||
57 | |||
58 | /** |
||
59 | * World manufacturer identifier |
||
60 | * |
||
61 | * @var string |
||
62 | */ |
||
63 | private $wmi; |
||
64 | |||
65 | /** |
||
66 | * Vehicle descriptor section |
||
67 | * |
||
68 | * @var string |
||
69 | */ |
||
70 | private $vds; |
||
71 | |||
72 | /** |
||
73 | * Vehicle identifier section |
||
74 | * |
||
75 | * @var string |
||
76 | */ |
||
77 | private $vis; |
||
78 | |||
79 | /** |
||
80 | * Vehicle region |
||
81 | * |
||
82 | * @var string|null |
||
83 | */ |
||
84 | private $region; |
||
85 | |||
86 | /** |
||
87 | * Vehicle country |
||
88 | * |
||
89 | * @var string|null |
||
90 | */ |
||
91 | private $country; |
||
92 | |||
93 | /** |
||
94 | * Vehicle manufacturer |
||
95 | * |
||
96 | * @var string|null |
||
97 | */ |
||
98 | private $manufacturer; |
||
99 | |||
100 | /** |
||
101 | * Vehicle model year |
||
102 | * |
||
103 | * @var list<int> |
||
0 ignored issues
–
show
The type
Sunrise\Vin\list was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||
104 | */ |
||
105 | private $modelYear; |
||
106 | |||
107 | /** |
||
108 | * Constructor of the class |
||
109 | * |
||
110 | * @param string $value |
||
111 | * |
||
112 | * @throws InvalidArgumentException |
||
113 | * If the given value isn't a valid VIN. |
||
114 | */ |
||
115 | 23 | public function __construct(string $value) |
|
116 | { |
||
117 | // VIN must be in uppercase... |
||
118 | 23 | $value = strtoupper($value); |
|
119 | |||
120 | 23 | if (!preg_match(self::REGEX, $value, $match)) { |
|
121 | 5 | throw new InvalidArgumentException(sprintf( |
|
122 | 5 | 'The value "%s" is not a valid VIN', |
|
123 | 5 | $value |
|
124 | 5 | )); |
|
125 | } |
||
126 | |||
127 | 18 | $this->vin = $value; |
|
128 | 18 | $this->wmi = $match['wmi']; |
|
129 | 18 | $this->vds = $match['vds']; |
|
130 | 18 | $this->vis = $match['vis']; |
|
131 | |||
132 | 18 | $this->region = $this->determineVehicleRegion(); |
|
133 | 18 | $this->country = $this->determineVehicleCountry(); |
|
134 | 18 | $this->manufacturer = $this->determineVehicleManufacturer(); |
|
135 | 18 | $this->modelYear = $this->determineVehicleModelYear(); |
|
0 ignored issues
–
show
It seems like
$this->determineVehicleModelYear() of type array or array is incompatible with the declared type Sunrise\Vin\list of property $modelYear .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
136 | } |
||
137 | |||
138 | /** |
||
139 | * {@inheritdoc} |
||
140 | */ |
||
141 | 1 | public function getVin() : string |
|
142 | { |
||
143 | 1 | return $this->vin; |
|
144 | } |
||
145 | |||
146 | /** |
||
147 | * {@inheritdoc} |
||
148 | */ |
||
149 | 1 | public function getWmi() : string |
|
150 | { |
||
151 | 1 | return $this->wmi; |
|
152 | } |
||
153 | |||
154 | /** |
||
155 | * {@inheritdoc} |
||
156 | */ |
||
157 | 1 | public function getVds() : string |
|
158 | { |
||
159 | 1 | return $this->vds; |
|
160 | } |
||
161 | |||
162 | /** |
||
163 | * {@inheritdoc} |
||
164 | */ |
||
165 | 1 | public function getVis() : string |
|
166 | { |
||
167 | 1 | return $this->vis; |
|
168 | } |
||
169 | |||
170 | /** |
||
171 | * {@inheritdoc} |
||
172 | */ |
||
173 | 2 | public function getRegion() : ?string |
|
174 | { |
||
175 | 2 | return $this->region; |
|
176 | } |
||
177 | |||
178 | /** |
||
179 | * {@inheritdoc} |
||
180 | */ |
||
181 | 2 | public function getCountry() : ?string |
|
182 | { |
||
183 | 2 | return $this->country; |
|
184 | } |
||
185 | |||
186 | /** |
||
187 | * {@inheritdoc} |
||
188 | */ |
||
189 | 2 | public function getManufacturer() : ?string |
|
190 | { |
||
191 | 2 | return $this->manufacturer; |
|
192 | } |
||
193 | |||
194 | /** |
||
195 | * {@inheritdoc} |
||
196 | */ |
||
197 | 5 | public function getModelYear() : array |
|
198 | { |
||
199 | 5 | return $this->modelYear; |
|
0 ignored issues
–
show
|
|||
200 | } |
||
201 | |||
202 | /** |
||
203 | * Converts the object to array |
||
204 | * |
||
205 | * @return array{ |
||
0 ignored issues
–
show
|
|||
206 | * vin: string, |
||
207 | * wmi: string, |
||
208 | * vds: string, |
||
209 | * vis: string, |
||
210 | * region: ?string, |
||
211 | * country: ?string, |
||
212 | * manufacturer: ?string, |
||
213 | * modelYear: list<int>, |
||
214 | * } |
||
215 | */ |
||
216 | 1 | public function toArray() : array |
|
217 | { |
||
218 | 1 | return [ |
|
219 | 1 | 'vin' => $this->vin, |
|
220 | 1 | 'wmi' => $this->wmi, |
|
221 | 1 | 'vds' => $this->vds, |
|
222 | 1 | 'vis' => $this->vis, |
|
223 | 1 | 'region' => $this->region, |
|
224 | 1 | 'country' => $this->country, |
|
225 | 1 | 'manufacturer' => $this->manufacturer, |
|
226 | 1 | 'modelYear' => $this->modelYear, |
|
227 | 1 | ]; |
|
228 | } |
||
229 | |||
230 | /** |
||
231 | * Converts the object to string |
||
232 | * |
||
233 | * @return string |
||
234 | */ |
||
235 | 1 | public function __toString() : string |
|
236 | { |
||
237 | 1 | return $this->vin; |
|
238 | } |
||
239 | |||
240 | /** |
||
241 | * Tries to determine vehicle region |
||
242 | * |
||
243 | * @return string|null |
||
244 | */ |
||
245 | 18 | private function determineVehicleRegion() : ?string |
|
246 | { |
||
247 | 18 | return REGIONS[$this->wmi[0]]['region'] ?? null; |
|
248 | } |
||
249 | |||
250 | /** |
||
251 | * Tries to determine vehicle country |
||
252 | * |
||
253 | * @return string|null |
||
254 | */ |
||
255 | 18 | private function determineVehicleCountry() : ?string |
|
256 | { |
||
257 | 18 | $countries = REGIONS[$this->wmi[0]]['countries'] ?? null; |
|
258 | 18 | if ($countries === null) { |
|
259 | 1 | return null; |
|
260 | } |
||
261 | |||
262 | 17 | foreach ($countries as $chars => $name) { |
|
263 | // there are keys that consist only of numbers... |
||
264 | 17 | $chars = (string) $chars; |
|
265 | |||
266 | 17 | if (strpbrk($this->wmi[1], $chars) !== false) { |
|
267 | 16 | return $name; |
|
268 | } |
||
269 | } |
||
270 | |||
271 | 1 | return null; |
|
272 | } |
||
273 | |||
274 | /** |
||
275 | * Tries to determine vehicle manufacturer |
||
276 | * |
||
277 | * @return string|null |
||
278 | */ |
||
279 | 18 | private function determineVehicleManufacturer() : ?string |
|
280 | { |
||
281 | 18 | return MANUFACTURERS[$this->wmi] ?? MANUFACTURERS[$this->wmi[0] . $this->wmi[1]] ?? null; |
|
282 | } |
||
283 | |||
284 | /** |
||
285 | * Tries to determine vehicle model year(s) |
||
286 | * |
||
287 | * @return list<int> |
||
288 | */ |
||
289 | 18 | private function determineVehicleModelYear() : array |
|
290 | { |
||
291 | 18 | $comingYear = date('Y') + 1; |
|
292 | 18 | $estimatedYears = []; |
|
293 | |||
294 | 18 | foreach (YEARS as $year => $char) { |
|
295 | 18 | if ($this->vis[0] === $char) { |
|
296 | 17 | $estimatedYears[] = $year; |
|
297 | } |
||
298 | |||
299 | 18 | if ($comingYear === $year) { |
|
300 | 18 | break; |
|
301 | } |
||
302 | } |
||
303 | |||
304 | 18 | return $estimatedYears; |
|
0 ignored issues
–
show
|
|||
305 | } |
||
306 | } |
||
307 |