diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php index 13b84e2..2a51171 100644 --- a/src/Validator/Validator.php +++ b/src/Validator/Validator.php @@ -79,6 +79,20 @@ public function validate($value): Resolution ]); } + foreach ($this->config->getAIConstraints() as $code => $constraint) { + if ($barcode->hasAI((string) $code) + && !$constraint($ai = $barcode->ai((string) $code)) + ) { + return Resolution::createInvalid([ + ErrorCodes::INVALID_VALUE => sprintf( + 'AI is invalid: code=%s, value=%s', + $code, + $ai + ), + ]); + } + } + return Resolution::createValid(); } diff --git a/src/Validator/ValidatorConfig.php b/src/Validator/ValidatorConfig.php index 2a17d10..04a90df 100644 --- a/src/Validator/ValidatorConfig.php +++ b/src/Validator/ValidatorConfig.php @@ -8,6 +8,7 @@ final class ValidatorConfig { private $requiredAIs = []; private $forbiddenAIs = []; + private $aiConstraints = []; private $allowEmpty = false; public function getRequiredAIs(): array @@ -42,4 +43,15 @@ public function setAllowEmpty(bool $allowEmpty): self $this->allowEmpty = $allowEmpty; return $this; } -} \ No newline at end of file + + public function setAIConstraints(array $aiConstraints): self + { + $this->aiConstraints = $aiConstraints; + return $this; + } + + public function getAIConstraints(): array + { + return $this->aiConstraints; + } +} diff --git a/tests/Validator/ValidatorConfigTest.php b/tests/Validator/ValidatorConfigTest.php index 97d9b65..dab8540 100644 --- a/tests/Validator/ValidatorConfigTest.php +++ b/tests/Validator/ValidatorConfigTest.php @@ -18,6 +18,7 @@ public function testConfigDefaults(): void self::assertEmpty($config->getRequiredAIs()); self::assertEmpty($config->getForbiddenAIs()); + self::assertEmpty($config->getAIConstraints()); self::assertFalse($config->isAllowEmpty()); } @@ -26,10 +27,12 @@ public function testGettersSetters(): void $config = (new ValidatorConfig()) ->setAllowEmpty(true) ->setRequiredAIs(['10']) - ->setForbiddenAIs(['01']); + ->setForbiddenAIs(['01']) + ->setAIConstraints(['01' => fn(string $ai) => true]); self::assertTrue($config->isAllowEmpty()); self::assertEquals(['10'], $config->getRequiredAIs()); self::assertEquals(['01'], $config->getForbiddenAIs()); + self::assertEquals(['01' => fn(string $ai) => true], $config->getAIConstraints()); } } diff --git a/tests/Validator/ValidatorTest.php b/tests/Validator/ValidatorTest.php index ed71927..ca88eb6 100644 --- a/tests/Validator/ValidatorTest.php +++ b/tests/Validator/ValidatorTest.php @@ -62,6 +62,10 @@ public function dataValidate(): array ->setRequiredAIs(['10']); $forbiddenAI = (new ValidatorConfig()) ->setForbiddenAIs(['01']); + $aiConstraintReturnTrue = (new ValidatorConfig()) + ->setAIConstraints(['01' => fn (string $ai) => true]); + $aiConstraintReturnFalse = (new ValidatorConfig()) + ->setAIConstraints(['01' => fn (string $ai) => false]); return [ 'valid' => [ @@ -114,6 +118,18 @@ public function dataValidate(): array ErrorCodes::FORBIDDEN_AIS => '', ]), ], + 'ai constraint return true' => [ + $aiConstraintReturnTrue, + ']d201034531200000111719112511ABCD1234', + Resolution::createValid(), + ], + 'ai constraint return false' => [ + $aiConstraintReturnFalse, + ']d201034531200000111719112511ABCD1234', + Resolution::createInvalid([ + ErrorCodes::INVALID_VALUE => 'AI is invalid: code=01, value=03453120000011', + ]), + ], ]; }