Vin::getWmi()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 1
b 0
f 0
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
The constant Sunrise\Vin\MANUFACTURERS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
33
use const Sunrise\Vin\REGIONS;
0 ignored issues
show
Bug introduced by
The constant Sunrise\Vin\REGIONS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
34
use const Sunrise\Vin\YEARS;
0 ignored issues
show
Bug introduced by
The constant Sunrise\Vin\YEARS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
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
Bug introduced by
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. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
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
Documentation Bug introduced by
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..

Loading history...
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
Bug Best Practice introduced by
The expression return $this->modelYear returns the type Sunrise\Vin\list which is incompatible with the type-hinted return array.
Loading history...
200
    }
201
202
    /**
203
     * Converts the object to array
204
     *
205
     * @return array{
0 ignored issues
show
Documentation Bug introduced by
The doc comment array{ at position 2 could not be parsed: the token is null at position 2.
Loading history...
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
Bug Best Practice introduced by
The expression return $estimatedYears returns the type array which is incompatible with the documented return type Sunrise\Vin\list.
Loading history...
305
    }
306
}
307