diff --git a/composer.json b/composer.json index c786f53..5d1fb7d 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ ], "require": { "php": ">=7.1", - "illuminate/support": "^5.5" + "illuminate/support": "^5.5|^6.0" }, "require-dev": { "roave/security-advisories": "dev-master", @@ -43,7 +43,7 @@ "MarvinLabs\\Luhn\\LuhnServiceProvider" ], "aliases": { - "Menu": "MarvinLabs\\Luhn\\Facades\\Luhn" + "Luhn": "MarvinLabs\\Luhn\\Facades\\Luhn" } } }, diff --git a/src/Luhn/Algorithm/LuhnAlgorithm.php b/src/Luhn/Algorithm/LuhnAlgorithm.php index 5600b54..37fbad4 100644 --- a/src/Luhn/Algorithm/LuhnAlgorithm.php +++ b/src/Luhn/Algorithm/LuhnAlgorithm.php @@ -2,6 +2,7 @@ namespace MarvinLabs\Luhn\Algorithm; +use InvalidArgumentException; use MarvinLabs\Luhn\Contracts\LuhnAlgorithm as LuhnAlgorithmContract; /** @@ -12,7 +13,11 @@ class LuhnAlgorithm implements LuhnAlgorithmContract public function isValid(string $input): bool { - [$number, $lastDigit] = $this->cleanAndSplitInput($input); + try { + [$number, $lastDigit] = $this->cleanAndSplitInput($input); + } catch (InvalidArgumentException $e) { + return false; + } $checksum = $this->computeCheckSum($number); $sum = $checksum + $lastDigit; @@ -59,6 +64,11 @@ protected function cleanAndSplitInput(string $input): array // Remove everything not a digit, then extract check digit $input = \preg_replace('/\D/', '', $input); $inputLength = \strlen($input); + + if ($inputLength === 0) { + throw new InvalidArgumentException; + } + return [ \substr($input, 0, $inputLength - 1), (int)$input[$inputLength - 1], diff --git a/src/Luhn/LuhnServiceProvider.php b/src/Luhn/LuhnServiceProvider.php index e30a3fb..79efddc 100644 --- a/src/Luhn/LuhnServiceProvider.php +++ b/src/Luhn/LuhnServiceProvider.php @@ -16,6 +16,7 @@ class LuhnServiceProvider extends ServiceProvider public function boot() { $this->registerValidationRules(); + $this->registerTranslationsPath(); } public function register() @@ -36,4 +37,9 @@ protected function registerBindings(): void $this->app->singleton(LuhnAlgorithmContract::class, LuhnAlgorithm::class); $this->app->singleton('luhn', LuhnAlgorithmContract::class); } + + protected function registerTranslationsPath(): void + { + $this->loadTranslationsFrom(__DIR__ . '/../../translations', 'luhn'); + } } diff --git a/src/Luhn/Rules/LuhnRule.php b/src/Luhn/Rules/LuhnRule.php index 870bc5d..45369bb 100644 --- a/src/Luhn/Rules/LuhnRule.php +++ b/src/Luhn/Rules/LuhnRule.php @@ -21,6 +21,8 @@ public function passes($attribute, $value) public function message() { - return trans('validation.luhn'); + return trans('validation.luhn') != 'validation.luhn' + ? trans('validation.luhn') + : trans('luhn::validation.luhn'); } } diff --git a/tests/AlgorithmTest.php b/tests/AlgorithmTest.php index 95e6e0d..3f1a8ff 100644 --- a/tests/AlgorithmTest.php +++ b/tests/AlgorithmTest.php @@ -21,11 +21,13 @@ public function provideIsValidTestInput(): array { return [ 'default' => ['837668185', true], + 'zero' => ['0', true], 'with_spaces' => ['837 668 185', true], '123455' => ['123455', true], '4103219202' => ['4103219202', true], '31997233700020' => ['31997233700020', true], 'large' => ['89148000003974165685', true], + 'empty' => ['', false], 'invalid' => ['123456789', false], '123' => ['123', false], ]; diff --git a/tests/ValidationTest.php b/tests/ValidationTest.php index cf0e00a..2a11215 100644 --- a/tests/ValidationTest.php +++ b/tests/ValidationTest.php @@ -26,4 +26,11 @@ public function can_use_shorthand_notation() $validator = Validator::make(['number' => TestCase::INVALID_LUHN_NUMBER], ['number' => 'luhn']); $this->assertTrue($validator->fails()); } + + /** @test */ + public function does_not_throw_on_edge_cases() + { + $validator = Validator::make(['number' => 'notanumber'], ['number' => 'luhn']); + $this->assertTrue($validator->fails()); + } } diff --git a/translations/en/validation.php b/translations/en/validation.php new file mode 100644 index 0000000..b9971fe --- /dev/null +++ b/translations/en/validation.php @@ -0,0 +1,5 @@ + 'The :attribute checksum is invalid.', +];