From 666d3ae7524c3fc9ba786a5c7ee63e6ca80c66b7 Mon Sep 17 00:00:00 2001 From: 5baddi Date: Wed, 22 Nov 2023 12:13:23 +0100 Subject: [PATCH 1/8] wip: update .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d2a5712..04ee5f3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ vendor/ .phpunit.result.cache -index.php \ No newline at end of file +.idea/ From 3163809e5768de0f37731c2a1f663e7e27a36713 Mon Sep 17 00:00:00 2001 From: 5baddi Date: Wed, 22 Nov 2023 12:14:06 +0100 Subject: [PATCH 2/8] wip: require php 8.0 --- composer.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 864fc6f..87a08ce 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "baddiservices/vin-decoder", "type": "library", - "description": "Universal vin decoder to retrieve vehicle informations", + "description": "Universal vin decoder to retrieve vehicle information's", "keywords": ["vin","vin decoder","decoder","vehicle", "dealer", "dealership"], "homepage": "https://baddi.info", "license": "MIT", @@ -9,12 +9,11 @@ { "name": "Mohamed Baddi", "email": "project@baddi.info", - "homepage": "https://baddi.info", - "role": "Developer" + "homepage": "https://baddi.info" } ], "require": { - "php": "^7.2" + "php": ">=8.0" }, "require-dev": { "phpunit/phpunit": "^8" From 45a73b9de3068d57eee47686dac72624969750a2 Mon Sep 17 00:00:00 2001 From: 5baddi Date: Wed, 22 Nov 2023 12:14:25 +0100 Subject: [PATCH 3/8] wip: require ctype extension --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 87a08ce..70e4093 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,8 @@ } ], "require": { - "php": ">=8.0" + "php": ">=8.0", + "ext-ctype": "*" }, "require-dev": { "phpunit/phpunit": "^8" From e25a94a671b42c3b57444df169a65637c1143437 Mon Sep 17 00:00:00 2001 From: 5baddi Date: Wed, 22 Nov 2023 12:15:06 +0100 Subject: [PATCH 4/8] wip: update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 56e7fe1..ffba822 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # VIN Decoder -[![Build status](https://api.travis-ci.org/5baddi/vin-decoder.svg)](https://api.travis-ci.org/5baddi/vin-decoder) + +[![Licence](https://img.shields.io/github/license/5baddi/vin-decoder?logo=MIT)](./LICENSE) +![PHP Version](https://img.shields.io/packagist/php-v/baddiservices/safehtml) +[![Open issues](https://img.shields.io/github/issues-raw/5baddi/vin-decoder)](https://github.com/5baddi/vin-decoder/issues?q=is%3Aissue+is%3Aopen) +[![Stars](https://img.shields.io/github/stars/5baddi/vin-decoder)](https://github.com/5baddi/vin-decoder/stargazers) +[![Downloads](https://img.shields.io/packagist/dm/baddiservices/safehtml)](https://packagist.org/packages/baddiservices/safehtml) +[![Twitter Follow](https://img.shields.io/twitter/follow/5baddi?style=social)](https://twitter.com/intent/follow?screen_name=5baddi) PHP package provide VIN number decoding to retrieve vehicle informations From b5c761d59c4bfc91c88f6169f51ef68f49aa52c7 Mon Sep 17 00:00:00 2001 From: 5baddi Date: Wed, 22 Nov 2023 12:32:51 +0100 Subject: [PATCH 5/8] psr: coding style & typo --- src/VINConstants.php | 4 +- src/VINDecoder.php | 134 ++++++++++++++++----------------------- tests/VINDecoderTest.php | 9 +-- 3 files changed, 59 insertions(+), 88 deletions(-) diff --git a/src/VINConstants.php b/src/VINConstants.php index 6c43876..674c1c3 100644 --- a/src/VINConstants.php +++ b/src/VINConstants.php @@ -20,6 +20,7 @@ class VINConstants const CHECKSUM = 10; const CHECKSUM_FACTOR = 11; const CHECKSUM_POSITION = 8; + const TRANSLITERATION = [ 'A' => 1, 'J' => 1, 'B' => 2, 'K' => 2, 'S' => 2, @@ -31,7 +32,8 @@ class VINConstants 'H' => 8, 'Y' => 8, 'R' => 9, 'Z' => 9, ]; - const WEIGHTEDFACTORS = [ + + const WEIGHTED_FACTORS = [ 1 => 8, 10 => 9, 2 => 7, 11 => 8, 3 => 6, 12 => 7, diff --git a/src/VINDecoder.php b/src/VINDecoder.php index 2b99e7d..1d44aab 100644 --- a/src/VINDecoder.php +++ b/src/VINDecoder.php @@ -16,7 +16,7 @@ */ class VINDecoder { - public $vin; + public string $vin; private $checkDigit; @@ -24,44 +24,40 @@ class VINDecoder private $vds; private $vis; + private array $transliteration = []; - private $transliteration = []; - - private $weightedProduct = []; + private array $weightedProduct = []; private $calculatedWeightedProduct = 0; /** - * constructor - * - * @param string $vin + * @throws Exception */ public function __construct(string $vin) { - try{ - // Validate the VIN length - if(!$this->validate($vin)) - throw new Exception("Invalid VIN characters"); - - // Store the vin into this instance - $this->vin = strtoupper($vin); - - // Validate the VIN - if(!$this->checksum()) - throw new Exception("Invalid VIN"); - - // Parse the VIN details identifiers - $this->wmi = substr($this->vin, 0, 3); - $this->vds = substr($this->vin, 3, 6); - $this->vis = substr($this->vin, 9, 8); - }catch(Exception $ex){ - throw new Exception("Unknow error"); + // Validate the VIN length + if(! $this->validate($vin)) { + throw new Exception("Invalid VIN characters"); + } + + // Store the vin into this instance + $this->vin = strtoupper($vin); + + // Validate the VIN + if(! $this->checksum()) { + throw new Exception("Invalid VIN"); } + + // Parse the VIN details identifiers + $this->wmi = substr($this->vin, 0, 3); + $this->vds = substr($this->vin, 3, 6); + $this->vis = substr($this->vin, 9, 8); } /** * Check if the VIN is valid - * @return boolean + * + * @throws Exception */ public function isValid() : bool { @@ -70,8 +66,6 @@ public function isValid() : bool /** * Check digit getter - * - * @return int */ public function getCheckDigit() : int { @@ -80,59 +74,39 @@ public function getCheckDigit() : int /** * Extract the manufacturer brand name - * - * @return string|null */ public function getManufacturer() : ?string { // Load manufacturers list $manufactures = json_decode(file_get_contents(__DIR__ . "/data/manufacturers.json"), true); - // Get the manufacturers brand name - if(isset($manufactures[$this->wmi])) - return ucwords($manufactures[$this->wmi]); - - return null; + return ! empty($manufactures[$this->wmi]) ? ucwords($manufactures[$this->wmi]) : null; } /** * Get country by code - * - * @return string|null */ public function getCountry() : ?string { // Load countries list $countries = json_decode(file_get_contents(__DIR__ . "/data/countries.json"), true); - // Get country name by code - if(isset($countries[$this->getCountryCode()])) - return ucwords($countries[$this->getCountryCode()]); - - return null; + return ! empty($countries[$this->getCountryCode()]) ? ucwords($countries[$this->getCountryCode()]) : null; } /** * Get year by code - * - * @return string|null */ public function getYear() : ?int { // Load years list $years = json_decode(file_get_contents(__DIR__ . "/data/years.json"), true); - // Get year by code - if(isset($years[$this->vis[0]])) - return $years[$this->vis[0]]; - - return null; + return $years[$this->vis[0]] ?? null; } /** - * Extract serial numver - * - * @return string + * Extract serial number */ public function getSerialNumber() : string { @@ -141,8 +115,6 @@ public function getSerialNumber() : string /** * Extract security code - * - * @return char */ public function getSecurityCode() : string { @@ -152,24 +124,24 @@ public function getSecurityCode() : string /** * Check the vin length and regex * - * @param string $vin - * @return boolean + * @throws Exception */ private function validate(string $vin) : bool { // Verify if the vin corresponds to a vehicle manufactured before 1981 - if(strlen($vin) == 11) + if(strlen($vin) == 11) { throw new Exception("Information on vehicles manufactured before 1981 is limited"); - elseif(strlen($vin) != VINConstants::VIN_LENGTH) + } + + if(strlen($vin) != VINConstants::VIN_LENGTH) { throw new Exception("VIN number must be 17 characters"); + } return (bool)preg_match('/^[a-zA-Z0-9]+$/', $vin); } /** * Find and replace illegal characters - * - * @return void */ private function illegalCharacters() : void { @@ -180,15 +152,16 @@ private function illegalCharacters() : void // Replace the illegal characters foreach(VINConstants::EXCLUDED_LETTERS as $letter){ - if(strpos($this->vin, $letter) !== false) - $this->vin = str_replace($letter, ($letter === 'I' ? 1 : 0), $this->vin); + if(! str_contains($this->vin, $letter)) { + continue; + } + + $this->vin = str_replace($letter, ($letter === 'I' ? 1 : 0), $this->vin); } } /** * Check VIN sum and digit by transliteration and weighted product - * - * @return boolean */ private function checksum() : bool { @@ -198,37 +171,36 @@ private function checksum() : bool // Convert the VIN letters using the transliteration foreach(str_split($this->vin) as $letter){ // Unknown transliteration - if(ctype_alpha($letter) && isset(VINConstants::TRANSLITERATION[$letter])) + if(ctype_alpha($letter) && isset(VINConstants::TRANSLITERATION[$letter])) { $this->transliteration[] = VINConstants::TRANSLITERATION[$letter]; - else - $this->transliteration[] = $letter; + + continue; + } + + $this->transliteration[] = $letter; } - // Calculate the weighted product by wieghted factor + // Calculate the weighted product by weighted factor foreach($this->transliteration as $key => $trans){ - $this->weightedProduct[] = VINConstants::WEIGHTEDFACTORS[$key + 1]; - $this->calculatedWeightedProduct += $trans * VINConstants::WEIGHTEDFACTORS[$key + 1]; + $this->weightedProduct[] = VINConstants::WEIGHTED_FACTORS[$key + 1]; + $this->calculatedWeightedProduct += $trans * VINConstants::WEIGHTED_FACTORS[$key + 1]; } // Check digit $check = substr($this->vin, VINConstants::CHECKSUM_POSITION, 1); $this->checkDigit = $this->calculatedWeightedProduct % VINConstants::CHECKSUM_FACTOR; - // Verify the vin is valid - if($this->checkDigit == VINConstants::CHECKSUM && $check === VINConstants::CHECKSUM_LETTER) - return true; - elseif(isset(VINConstants::WEIGHTEDFACTORS[$check]) && ctype_alpha($check) && VINConstants::WEIGHTEDFACTORS[$check] == $mod) - return true; - elseif($this->checkDigit == $check) - return true; - - return false; + return ($this->checkDigit === VINConstants::CHECKSUM && $check === VINConstants::CHECKSUM_LETTER) + || ( + isset(VINConstants::WEIGHTED_FACTORS[$check]) + && ctype_alpha($check) + && VINConstants::WEIGHTED_FACTORS[$check] == $mod + ) + || ($this->checkDigit == $check); } /** * Get country code from the VIN number - * - * @return string */ private function getCountryCode() : string { diff --git a/tests/VINDecoderTest.php b/tests/VINDecoderTest.php index bf513a5..a1bde9d 100644 --- a/tests/VINDecoderTest.php +++ b/tests/VINDecoderTest.php @@ -16,16 +16,13 @@ class VINDecoderTest extends TestCase { /** - * Test the instance creation - * - * @return bool + * @throws Exception */ public function testInitInstance() { - // VIN example - $vin = "JTEHT05J542053195"; - + $vin = "JTEHT05J542053195"; // VIN example $vinDecoder = new VINDecoder($vin); + $this->assertInstanceOf(VINDecoder::class, $vinDecoder); } } \ No newline at end of file From 2cf4ebc42e7815f16be11b8cee6d15abf870a427 Mon Sep 17 00:00:00 2001 From: 5baddi Date: Wed, 22 Nov 2023 12:33:04 +0100 Subject: [PATCH 6/8] wip: remove travis action --- .travis.yml | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f65ac93..0000000 --- a/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -branches: - only: - - master -language: php -php: - - '7.2' -before_script: - - composer self-update -install: - - composer install --prefer-source --no-interaction -script: - - vendor/bin/phpunit \ No newline at end of file From bf5c2cf81a99774033e0dda9bb5b0c1d19ef4ec1 Mon Sep 17 00:00:00 2001 From: 5baddi Date: Wed, 22 Nov 2023 12:57:34 +0100 Subject: [PATCH 7/8] psr --- src/VINDecoder.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/VINDecoder.php b/src/VINDecoder.php index 1d44aab..f8993ed 100644 --- a/src/VINDecoder.php +++ b/src/VINDecoder.php @@ -18,17 +18,17 @@ class VINDecoder { public string $vin; - private $checkDigit; + private int $checkDigit; - private $wmi; - private $vds; - private $vis; + private string $wmi; + private string $vds; + private string $vis; private array $transliteration = []; private array $weightedProduct = []; - private $calculatedWeightedProduct = 0; + private int $calculatedWeightedProduct = 0; /** * @throws Exception @@ -190,11 +190,12 @@ private function checksum() : bool $check = substr($this->vin, VINConstants::CHECKSUM_POSITION, 1); $this->checkDigit = $this->calculatedWeightedProduct % VINConstants::CHECKSUM_FACTOR; - return ($this->checkDigit === VINConstants::CHECKSUM && $check === VINConstants::CHECKSUM_LETTER) + return + ($this->checkDigit === VINConstants::CHECKSUM && $check === VINConstants::CHECKSUM_LETTER) || ( - isset(VINConstants::WEIGHTED_FACTORS[$check]) - && ctype_alpha($check) - && VINConstants::WEIGHTED_FACTORS[$check] == $mod + ! ctype_alpha($check) + && isset(VINConstants::WEIGHTED_FACTORS[$check]) + && VINConstants::WEIGHTED_FACTORS[$check] === $this->checkDigit ) || ($this->checkDigit == $check); } From a08abacd1c35c7ad4bcdf0341305d53fe3e1ceb8 Mon Sep 17 00:00:00 2001 From: 5baddi Date: Wed, 22 Nov 2023 12:59:20 +0100 Subject: [PATCH 8/8] psr: coding style --- src/VINDecoder.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/VINDecoder.php b/src/VINDecoder.php index f8993ed..32714b6 100644 --- a/src/VINDecoder.php +++ b/src/VINDecoder.php @@ -61,7 +61,7 @@ public function __construct(string $vin) */ public function isValid() : bool { - return $this->validate($this->vin); + return @$this->validate($this->vin); } /** @@ -146,8 +146,7 @@ private function validate(string $vin) : bool private function illegalCharacters() : void { // Replace - and _ and whitespace - $this->vin = str_replace('-', '', $this->vin); - $this->vin = str_replace(' ', '', $this->vin); + $this->vin = str_replace(['-', ' '], '', $this->vin); $this->vin = str_replace('_', 0, $this->vin); // Replace the illegal characters