Remove backwards compatibility break from Phone rule

In version 2.3, the Phone rule started to require
"giggly/libphonenumber-for-php" as a dependency. That was a backward
compatibility break, but the validation also became stricter, and phone
numbers without country codes would not be considered valid.

This commit will revert the backward compatibility break. That way, when
validating a phone number without a country code (the behaviour from
version 2.2), the Phone will not use an external library.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
Henrique Moody 2024-03-11 22:06:55 +01:00
parent fb322df1da
commit 788939e359
No known key found for this signature in database
GPG key ID: 221E9281655813A6
3 changed files with 109 additions and 22 deletions

View file

@ -1,10 +1,9 @@
# Phone
- `Phone()`
- `Phone(string $countyCode)`
Validates whether the input is a valid phone number. This rule requires
the `giggsey/libphonenumber-for-php-lite` package.
Validates whether the input is a valid phone number.
```php
v::phone()->validate('+1 650 253 00 00'); // true
@ -12,16 +11,20 @@ v::phone('BR')->validate('+55 11 91111 1111'); // true
v::phone('BR')->validate('11 91111 1111'); // false
```
## Note
When validating with `$countryCode`, this rule will require the `giggsey/libphonenumber-for-php-lite` package.
## Categorization
- Strings
## Changelog
Version | Description
--------|-------------
2.3.0 | Updated to use external validator
0.5.0 | Created
| Version | Description |
|--------:|-------------------------------------|
| 2.3.0 | Introduced a validation per country |
| 0.5.0 | Created |
***
See also:

View file

@ -14,8 +14,8 @@ use libphonenumber\PhoneNumberUtil;
use Respect\Validation\Exceptions\ComponentException;
use function class_exists;
use function is_null;
use function is_scalar;
use function preg_match;
use function sprintf;
/**
@ -24,6 +24,9 @@ use function sprintf;
* Validates an international or country-specific telephone number
*
* @author Alexandre Gomes Gaigalas <alganet@gmail.com>
* @author Danilo Correa <danilosilva87@gmail.com>
* @author Graham Campbell <graham@mineuk.com>
* @author Henrique Moody <henriquemoody@gmail.com>
*/
final class Phone extends AbstractRule
{
@ -32,20 +35,15 @@ final class Phone extends AbstractRule
*/
private $countryCode;
/**
* {@inheritDoc}
*/
public function __construct(?string $countryCode = null)
{
$this->countryCode = $countryCode;
if ($countryCode === null) {
return;
}
if (!is_null($countryCode) && !(new CountryCode())->validate($countryCode)) {
throw new ComponentException(
sprintf(
'Invalid country code %s',
$countryCode
)
);
if (!(new CountryCode())->validate($countryCode)) {
throw new ComponentException(sprintf('Invalid country code %s', $countryCode));
}
if (!class_exists(PhoneNumberUtil::class)) {
@ -53,21 +51,32 @@ final class Phone extends AbstractRule
}
}
/**
* {@inheritDoc}
*/
public function validate($input): bool
{
if (!is_scalar($input)) {
return false;
}
if ($this->countryCode === null) {
return preg_match($this->getPregFormat(), (string) $input) > 0;
}
try {
return PhoneNumberUtil::getInstance()->isValidNumber(
PhoneNumberUtil::getInstance()->parse((string) $input, $this->countryCode)
);
} catch (NumberParseException $e) {
} catch (NumberParseException) {
return false;
}
}
private function getPregFormat(): string
{
return sprintf(
'/^\+?(%1$s)? ?(?(?=\()(\(%2$s\) ?%3$s)|([. -]?(%2$s[. -]*)?%3$s))$/',
'\d{0,3}',
'\d{1,3}',
'((\d{3,5})[. -]?(\d{2}[. -]?\d{2})|(\d{2}[. -]?){4})'
);
}
}

View file

@ -55,6 +55,52 @@ final class PhoneTest extends RuleTestCase
[new Phone(), '+7 (999) 999-99-99'],
[new Phone(), '+7(999)999-99-99'],
[new Phone(), '+7(999)999-9999'],
[new Phone(), '+5-555-555-5555'],
[new Phone(), '+5 555 555 5555'],
[new Phone(), '+5.555.555.5555'],
[new Phone(), '5-555-555-5555'],
[new Phone(), '5.555.555.5555'],
[new Phone(), '5 555 555 5555'],
[new Phone(), '555.555.5555'],
[new Phone(), '555 555 5555'],
[new Phone(), '555-555-5555'],
[new Phone(), '555-5555555'],
[new Phone(), '5(555)555.5555'],
[new Phone(), '+5(555)555.5555'],
[new Phone(), '+5(555)555 5555'],
[new Phone(), '+5(555)555-5555'],
[new Phone(), '+5(555)5555555'],
[new Phone(), '(555)5555555'],
[new Phone(), '(555)555.5555'],
[new Phone(), '(555)555-5555'],
[new Phone(), '(555) 555 5555'],
[new Phone(), '55555555555'],
[new Phone(), '5555555555'],
[new Phone(), '+33(1)2222222'],
[new Phone(), '+33(1)222 2222'],
[new Phone(), '+33(1)222.2222'],
[new Phone(), '+33(1)22 22 22 22'],
[new Phone(), '33(1)2222222'],
[new Phone(), '33(1)22222222'],
[new Phone(), '33(1)22 22 22 22'],
[new Phone(), '(020) 7476 4026'],
[new Phone(), '33(020) 7777 7777'],
[new Phone(), '33(020)7777 7777'],
[new Phone(), '+33(020) 7777 7777'],
[new Phone(), '+33(020)7777 7777'],
[new Phone(), '03-6106666'],
[new Phone(), '036106666'],
[new Phone(), '+33(11) 97777 7777'],
[new Phone(), '+3311977777777'],
[new Phone(), '11977777777'],
[new Phone(), '11 97777 7777'],
[new Phone(), '(11) 97777 7777'],
[new Phone(), '(11) 97777-7777'],
[new Phone(), '555-5555'],
[new Phone(), '5555555'],
[new Phone(), '555.5555'],
[new Phone(), '555 5555'],
[new Phone(), '+1 (555) 555 5555'],
[new Phone('BR'), '+55 11 91111 1111'],
[new Phone('BR'), '11 91111 1111'], // no international prefix
[new Phone('BR'), '+5511911111111'], // no whitespace
@ -68,6 +114,35 @@ final class PhoneTest extends RuleTestCase
public static function providerForInvalidInput(): array
{
return [
[new Phone(), ''],
[new Phone(), '123'],
[new Phone(), '(11- 97777-7777'],
[new Phone(), '-11) 97777-7777'],
[new Phone(), 's555-5555'],
[new Phone(), '555-555'],
[new Phone(), '555555'],
[new Phone(), '555+5555'],
[new Phone(), '(555)555555'],
[new Phone(), '(555)55555'],
[new Phone(), '+(555)555 555'],
[new Phone(), '+5(555)555 555'],
[new Phone(), '+5(555)555 555 555'],
[new Phone(), '555)555 555'],
[new Phone(), '+5(555)5555 555'],
[new Phone(), '(555)55 555'],
[new Phone(), '(555)5555 555'],
[new Phone(), '+5(555)555555'],
[new Phone(), '5(555)55 55555'],
[new Phone(), '(5)555555'],
[new Phone(), '+55(5)55 5 55 55'],
[new Phone(), '+55(5)55 55 55 5'],
[new Phone(), '+55(5)55 55 55'],
[new Phone(), '+55(5)5555 555'],
[new Phone(), '+55()555 5555'],
[new Phone(), '03610666-5'],
[new Phone(), 'text'],
[new Phone(), "555\n5555"],
[new Phone(), []],
[new Phone(), '+1-650-253-00-0'],
[new Phone('BR'), '+1 11 91111 1111'], // invalid + code for BR
];