Test Failed
Push — master ( ebee1f...045b1b )
by Anatoly
08:32 queued 05:52
created

Vin::determineManufacturer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 1
cts 1
cp 1
crap 1
rs 10
c 0
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
 * Vehicle Identification Number
31
 */
32
class Vin implements VinInterface
33
{
34
35
    /**
36
     * Regular expression for a VIN parsing/validation (ISO 3779)
37
     *
38
     * @var string
39
     */
40
    public const REGEX = '/^(?<wmi>[0-9A-HJ-NPR-Z]{3})(?<vds>[0-9A-HJ-NPR-Z]{6})(?<vis>[0-9A-HJ-NPR-Z]{8})$/';
41
42
    /**
43
     * The VIN code
44
     *
45
     * @var string
46
     */
47
    private $vin;
48
49
    /**
50
     * World manufacturer identifier
51
     *
52
     * @var string
53
     */
54
    private $wmi;
55
56
    /**
57
     * Vehicle descriptor section
58
     *
59
     * @var string
60
     */
61
    private $vds;
62
63
    /**
64
     * Vehicle identifier section
65
     *
66
     * @var string
67
     */
68
    private $vis;
69
70
    /**
71
     * Vehicle region
72
     *
73
     * @var null|string
74
     */
75
    private $region;
76
77
    /**
78
     * Vehicle country
79
     *
80
     * @var null|string
81
     */
82
    private $country;
83
84
    /**
85
     * Vehicle manufacturer
86
     *
87
     * @var null|string
88
     */
89 22
    private $manufacturer;
90
91
    /**
92 22
     * Vehicle model year
93
     *
94 22
     * @var int[]
95 5
     */
96 5
    private $modelYear;
97
98
    /**
99
     * Constructor of the class
100
     *
101 17
     * @param string $value
102 17
     *
103 17
     * @throws InvalidArgumentException If the given string is not a valid VIN.
104 17
     */
105
    public function __construct(string $value)
106
    {
107 17
        // The given VIN must be in upper case...
108 17
        $value = strtoupper($value);
109 17
110 17
        if (!preg_match(self::REGEX, $value, $match)) {
111 17
            throw new InvalidArgumentException(
112
                sprintf('The value "%s" is not a valid VIN', $value)
113
            );
114
        }
115
116 1
        // Base values
117
        $this->vin = $value;
118 1
        $this->wmi = $match['wmi'];
119
        $this->vds = $match['vds'];
120
        $this->vis = $match['vis'];
121
122
        // Parsed values
123
        $this->region = $this->determineRegion();
124 1
        $this->country = $this->determineCountry();
125
        $this->manufacturer = $this->determineManufacturer();
126 1
        $this->modelYear = $this->determineModelYear();
127
    }
128
129
    /**
130
     * {@inheritDoc}
131
     */
132 1
    public function getVin() : string
133
    {
134 1
        return $this->vin;
135
    }
136
137
    /**
138
     * {@inheritDoc}
139
     */
140 1
    public function getWmi() : string
141
    {
142 1
        return $this->wmi;
143
    }
144
145
    /**
146
     * {@inheritDoc}
147
     */
148 2
    public function getVds() : string
149
    {
150 2
        return $this->vds;
151
    }
152
153
    /**
154
     * {@inheritDoc}
155
     */
156 2
    public function getVis() : string
157
    {
158 2
        return $this->vis;
159
    }
160
161
    /**
162
     * {@inheritDoc}
163
     */
164 2
    public function getRegion() : ?string
165
    {
166 2
        return $this->region;
167
    }
168
169
    /**
170
     * {@inheritDoc}
171
     */
172 5
    public function getCountry() : ?string
173
    {
174 5
        return $this->country;
175
    }
176
177
    /**
178
     * {@inheritDoc}
179
     */
180 1
    public function getManufacturer() : ?string
181
    {
182
        return $this->manufacturer;
183 1
    }
184 1
185 1
    /**
186 1
     * {@inheritDoc}
187 1
     */
188 1
    public function getModelYear() : array
189 1
    {
190 1
        return $this->modelYear;
191
    }
192
193
    /**
194
     * Converts the object to array
195
     *
196
     * @return array
197 17
     */
198
    public function toArray() : array
199
    {
200 17
        return [
201 1
            'vin' => $this->vin,
202
            'wmi' => $this->wmi,
203
            'vds' => $this->vds,
204 16
            'vis' => $this->vis,
205
            'region' => $this->region,
206
            'country' => $this->country,
207
            'manufacturer' => $this->manufacturer,
208
            'modelYear' => $this->modelYear,
209
        ];
210 17
    }
211
212
    /**
213 17
     * Tries to determine vehicle region
214 1
     *
215
     * @return null|string
216
     */
217 16
    private function determineRegion() : ?string
218 16
    {
219 16
        return REGIONS[$this->wmi[0]]['region'] ?? null;
220
    }
221
222
    /**
223 1
     * Tries to determine vehicle country
224
     *
225
     * @return null|string
226
     */
227
    private function determineCountry() : ?string
228
    {
229 17
        $countries = REGIONS[$this->wmi[0]]['countries'] ?? null;
230
        if (null === $countries) {
231 17
            return null;
232
        }
233
234
        foreach ($countries as $chars => $name) {
235
            if (!(false === strpbrk($this->wmi[1], (string) $chars))) {
236
                return $name;
237 17
            }
238
        }
239 17
240 17
        return null;
241
    }
242 17
243 17
    /**
244 16
     * Tries to determine vehicle manufacturer
245
     *
246
     * @return null|string
247 17
     */
248 17
    private function determineManufacturer() : ?string
249
    {
250
        return MANUFACTURERS[$this->wmi] ?? MANUFACTURERS[$this->wmi[0] . $this->wmi[1]] ?? null;
251
    }
252 17
253
    /**
254
     * Tries to determine vehicle model year(s)
255
     *
256
     * @return int[]
257
     */
258
    private function determineModelYear() : array
259
    {
260
        $comingYear = (int) date('Y') + 1;
261
        $estimatedYears = [];
262
263
        foreach (YEARS as $year => $char) {
264
            if ($this->vis[0] === $char) {
265
                $estimatedYears[] = $year;
266
            }
267
268
            if ($comingYear === $year) {
269
                break;
270
            }
271
        }
272
273
        return $estimatedYears;
274
    }
275
}
276