Passed
Push — master ( 251ad7...1f2d7e )
by Anatoly
09:33 queued 10s
created

Vin::identifyManufacturer()   A

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 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 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 (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
     * @var string
44
     */
45
    private $vin;
46
47
    /**
48
     * @var string
49
     */
50
    private $wmi;
51
52
    /**
53
     * @var string
54
     */
55
    private $vds;
56
57
    /**
58
     * @var string
59
     */
60
    private $vis;
61
62
    /**
63
     * @var null|string
64
     */
65
    private $region;
66
67
    /**
68
     * @var null|string
69
     */
70
    private $country;
71
72
    /**
73
     * @var null|string
74
     */
75
    private $manufacturer;
76
77
    /**
78
     * @var int[]
79
     */
80
    private $modelYear;
81
82
    /**
83
     * Constructor of the class
84
     *
85
     * @param string $value
86
     *
87
     * @throws InvalidArgumentException If the given string is not a valid VIN.
88
     */
89 22
    public function __construct(string $value)
90
    {
91
        // The given VIN must be in upper case...
92 22
        $value = strtoupper($value);
93
94 22
        if (! preg_match(self::REGEX, $value, $match)) {
95 5
            throw new InvalidArgumentException(
96 5
                sprintf('The value "%s" is not a valid VIN', $value)
97
            );
98
        }
99
100
        // Base values
101 17
        $this->vin = $value;
102 17
        $this->wmi = $match['wmi'];
103 17
        $this->vds = $match['vds'];
104 17
        $this->vis = $match['vis'];
105
106
        // Parsed values
107 17
        $this->region = $this->identifyRegion();
108 17
        $this->country = $this->identifyCountry();
109 17
        $this->manufacturer = $this->identifyManufacturer();
110 17
        $this->modelYear = $this->identifyModelYear();
111 17
    }
112
113
    /**
114
     * {@inheritDoc}
115
     */
116 1
    public function getVin() : string
117
    {
118 1
        return $this->vin;
119
    }
120
121
    /**
122
     * {@inheritDoc}
123
     */
124 1
    public function getWmi() : string
125
    {
126 1
        return $this->wmi;
127
    }
128
129
    /**
130
     * {@inheritDoc}
131
     */
132 1
    public function getVds() : string
133
    {
134 1
        return $this->vds;
135
    }
136
137
    /**
138
     * {@inheritDoc}
139
     */
140 1
    public function getVis() : string
141
    {
142 1
        return $this->vis;
143
    }
144
145
    /**
146
     * {@inheritDoc}
147
     */
148 2
    public function getRegion() : ?string
149
    {
150 2
        return $this->region;
151
    }
152
153
    /**
154
     * {@inheritDoc}
155
     */
156 2
    public function getCountry() : ?string
157
    {
158 2
        return $this->country;
159
    }
160
161
    /**
162
     * {@inheritDoc}
163
     */
164 2
    public function getManufacturer() : ?string
165
    {
166 2
        return $this->manufacturer;
167
    }
168
169
    /**
170
     * {@inheritDoc}
171
     */
172 5
    public function getModelYear() : array
173
    {
174 5
        return $this->modelYear;
175
    }
176
177
    /**
178
     * {@inheritDoc}
179
     */
180 1
    public function toArray() : array
181
    {
182
        return [
183 1
            'vin' => $this->vin,
184 1
            'wmi' => $this->wmi,
185 1
            'vds' => $this->vds,
186 1
            'vis' => $this->vis,
187 1
            'region' => $this->region,
188 1
            'country' => $this->country,
189 1
            'manufacturer' => $this->manufacturer,
190 1
            'modelYear' => $this->modelYear,
191
        ];
192
    }
193
194
    /**
195
     * @return null|string
196
     */
197 17
    private function identifyRegion() : ?string
198
    {
199
        // undefined region...
200 17
        if (! isset(REGIONS[$this->wmi[0]])) {
201 1
            return null;
202
        }
203
204 16
        return REGIONS[$this->wmi[0]]['region'] ?? null;
205
    }
206
207
    /**
208
     * @return null|string
209
     */
210 17
    private function identifyCountry() : ?string
211
    {
212
        // undefined region...
213 17
        if (! isset(REGIONS[$this->wmi[0]])) {
214 1
            return null;
215
        }
216
217 16
        foreach (REGIONS[$this->wmi[0]]['countries'] as $chars => $title) {
218 16
            if (! (false === strpbrk($this->wmi[1], $chars))) {
219 16
                return $title;
220
            }
221
        }
222
223 1
        return null;
224
    }
225
226
    /**
227
     * @return null|string
228
     */
229 17
    private function identifyManufacturer() : ?string
230
    {
231 17
        return MANUFACTURERS[$this->wmi] ?? MANUFACTURERS[$this->wmi[0] . $this->wmi[1]] ?? null;
232
    }
233
234
    /**
235
     * @return int[]
236
     */
237 17
    private function identifyModelYear() : array
238
    {
239 17
        $comingYear = (int) date('Y') + 1;
240 17
        $certainYears = [];
241
242 17
        foreach (YEARS as $year => $char) {
243 17
            if ($this->vis[0] === $char) {
244 16
                $certainYears[] = $year;
245
            }
246
247 17
            if ($comingYear === $year) {
248 17
                break;
249
            }
250
        }
251
252 17
        return $certainYears;
253
    }
254
}
255