diff --git a/src/ContainerRegistry.php b/src/ContainerRegistry.php index 694095bb3..8613d2928 100644 --- a/src/ContainerRegistry.php +++ b/src/ContainerRegistry.php @@ -11,6 +11,7 @@ namespace Respect\Validation; use DI\Container; +use libphonenumber\PhoneNumberUtil; use Psr\Container\ContainerInterface; use Respect\StringFormatter\BypassTranslator; use Respect\StringFormatter\Modifier; @@ -52,6 +53,7 @@ final class ContainerRegistry public static function createContainer(array $definitions = []): Container { return new Container($definitions + [ + PhoneNumberUtil::class => factory(static fn() => PhoneNumberUtil::getInstance()), Transformer::class => create(Prefix::class), TemplateResolver::class => create(TemplateResolver::class), TranslatorInterface::class => autowire(BypassTranslator::class), diff --git a/src/Validators/Phone.php b/src/Validators/Phone.php index 203031487..c5bd905f4 100644 --- a/src/Validators/Phone.php +++ b/src/Validators/Phone.php @@ -30,7 +30,6 @@ use Respect\Validation\Validator; use Sokil\IsoCodes\Database\Countries; -use function class_exists; use function is_scalar; #[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] @@ -53,9 +52,9 @@ final class Phone implements Validator public function __construct(string|null $countryCode = null, Countries|null $countries = null) { - if (!class_exists(PhoneNumberUtil::class)) { + if (!ContainerRegistry::getContainer()->has(PhoneNumberUtil::class)) { throw new MissingComposerDependencyException( - 'Phone rule libphonenumber for PHP', + 'Phone rule requires libphonenumber for PHP', 'giggsey/libphonenumber-for-php', ); } @@ -96,7 +95,7 @@ public function evaluate(mixed $input): Result private function isValidPhone(string $input): bool { try { - $phoneNumberUtil = PhoneNumberUtil::getInstance(); + $phoneNumberUtil = ContainerRegistry::getContainer()->get(PhoneNumberUtil::class); $phoneNumberObject = $phoneNumberUtil->parse($input, $this->country?->getAlpha2()); if ($this->country === null) { return $phoneNumberUtil->isValidNumber($phoneNumberObject); diff --git a/tests/unit/Validators/PhoneTest.php b/tests/unit/Validators/PhoneTest.php index f17792731..91de9efcb 100644 --- a/tests/unit/Validators/PhoneTest.php +++ b/tests/unit/Validators/PhoneTest.php @@ -18,6 +18,7 @@ namespace Respect\Validation\Validators; use DI; +use libphonenumber\PhoneNumberUtil; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; @@ -26,6 +27,7 @@ use Respect\Validation\Exceptions\InvalidValidatorException; use Respect\Validation\Exceptions\MissingComposerDependencyException; use Respect\Validation\Test\TestCase; +use Sokil\IsoCodes\Database\Countries; use stdClass; #[Group('validator')] @@ -70,10 +72,17 @@ public function itShouldThrowsExceptionWhenCountryCodeIsNotValid(): void } #[Test] - public function shouldThrowWhenMissingComponent(): void + public function shouldThrowWhenMissingIsocodesComponent(): void { $mainContainer = ContainerRegistry::getContainer(); - ContainerRegistry::setContainer((new DI\ContainerBuilder())->useAutowiring(false)->build()); + ContainerRegistry::setContainer( + (new DI\ContainerBuilder()) + ->addDefinitions([ + PhoneNumberUtil::class => DI\factory(static fn() => PhoneNumberUtil::getInstance()), + ]) + ->useAutowiring(false) + ->build(), + ); try { new Phone('US'); $this->fail('Expected MissingComposerDependencyException was not thrown.'); @@ -87,6 +96,31 @@ public function shouldThrowWhenMissingComponent(): void } } + #[Test] + public function shouldThrowWhenMissingPhonesComponent(): void + { + $mainContainer = ContainerRegistry::getContainer(); + ContainerRegistry::setContainer( + (new DI\ContainerBuilder()) + ->addDefinitions([ + Countries::class => DI\create(Countries::class), + ]) + ->useAutowiring(false) + ->build(), + ); + try { + new Phone('US'); + $this->fail('Expected MissingComposerDependencyException was not thrown.'); + } catch (MissingComposerDependencyException $e) { + $this->assertStringContainsString( + 'Phone rule requires libphonenumber for PHP.', + $e->getMessage(), + ); + } finally { + ContainerRegistry::setContainer($mainContainer); + } + } + /** @return array */ public static function providerForValidInputWithoutCountryCode(): array {