Skip to content

Commit

Permalink
Refactoring + add number type constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
Propaganistas committed May 9, 2015
1 parent 5d632bd commit 0c88083
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 23 deletions.
22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Adds a phone validator to Laravel 4 and 5 based on the [PHP port](https://github
$ composer update
```

3. In your `app/config/app.php` add `'Propaganistas\LaravelPhone\LaravelPhoneServiceProvider',` to the end of the `$providers` array
3. In your app config, add `'Propaganistas\LaravelPhone\LaravelPhoneServiceProvider'` to the end of the `$providers` array

```php
'providers' => [
Expand All @@ -30,7 +30,7 @@ Adds a phone validator to Laravel 4 and 5 based on the [PHP port](https://github
4. In your languages directory, add for each language an extra language line for the validator:

```php
"phone" => "The :attribute field contains an invalid number.",
"phone" => "The :attribute field contains an invalid number.",
```

### Usage
Expand All @@ -40,20 +40,16 @@ To validate a field using the phone validator, use the `phone` keyword in your v
- You either specify *ISO 3166-1 compliant* country codes yourself as parameters for the validator, e.g.:

```php
public static $rules = [
'phonefield' => 'phone:US,BE',
];
'phonefield' => 'phone:US,BE',
```

The validator will check if the number is valid in at least one of provided countries, so feel free to add as many country codes as you like.

- Or you don't specify any parameters but you plug in a dedicated country input field (keyed by *ISO 3166-1 compliant* country codes) to allow end users to supply a country on their own. The easiest method by far is to install the [CountryList package by monarobase](https://github.com/Monarobase/country-list). The country field has to be named similar to the phone field but with `_country` appended:

```php
public static $rules = [
'phonefield' => 'phone',
'phonefield_country' => 'required_with:phonefield',
];
'phonefield' => 'phone',
'phonefield_country' => 'required_with:phonefield',
```

If using the CountryList package, you could then use the following in the form view:
Expand All @@ -63,6 +59,14 @@ To validate a field using the phone validator, use the `phone` keyword in your v
{{ Form::select('phonefield_country', Countries::getList(App::getLocale(), 'php', 'cldr')) }}
```

To specify constraints on the number type, just append the allowed types to the end of the parameters, e.g.:

```php
'phonefield' => 'phone:US,BE,mobile,landline',
```

Supported types include `mobile`, `landline`, `voip`, `pager`, `uan`, `voicemail` and `emergency`.

### Display
Format a fetched phone value using the helper function:

Expand Down
64 changes: 50 additions & 14 deletions src/Propaganistas/LaravelPhone/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use libphonenumber\PhoneNumberUtil;
use libphonenumber\NumberParseException;
use libphonenumber\PhoneNumberType;

class Validator
{
Expand All @@ -11,21 +12,55 @@ class Validator
public function phone($attribute, $value, $parameters, $validator)
{
$data = $validator->getData();
// Check if we should validate using a default country or a *_country field.
if (!empty($parameters)) {
$countries = $parameters;
}
elseif (isset($data[$attribute.'_country'])) {
$countries = array($data[$attribute.'_country']);
}
else {
return FALSE;
$countries = array();
$types = array();

// Explode the parameters in appropriate arrays.
foreach ($parameters as $parameter) {
if ($this->phone_country($parameter)) {
// Extract countries.
$countries[] = $parameter;
}
else {
// Check if we should only allow specific phone number types.
switch ($parameter) {
case 'landline':
$types[] = PhoneNumberType::FIXED_LINE;
$types[] = PhoneNumberType::FIXED_LINE_OR_MOBILE;
break;
case 'mobile':
$types[] = PhoneNumberType::MOBILE;
$types[] = PhoneNumberType::FIXED_LINE_OR_MOBILE;
break;
case 'voip':
$types[] = PhoneNumberType::VOIP;
break;
case 'pager':
$types[] = PhoneNumberType::PAGER;
break;
case 'uan':
$types[] = PhoneNumberType::UAN;
break;
case 'emergency':
$types[] = PhoneNumberType::EMERGENCY;
break;
case 'voicemail':
$types[] = PhoneNumberType::VOICEMAIL;
break;
default:
break;
}
}
}

// Filter out invalid countries.
foreach ($countries as $key => $country) {
if (!$this->phone_country($country)) {
unset($countries[$key]);
if (empty($countries)) {
// Check for the existence of a country field.
if (isset($data[$attribute.'_country']) && $this->phone_country($data[$attribute.'_country'])) {
$countries = array($data[$attribute.'_country']);
}
else {
// No phone country found; validation cannot proceed.
return FALSE;
}
}

Expand All @@ -34,7 +69,8 @@ public function phone($attribute, $value, $parameters, $validator)
$phoneUtil = PhoneNumberUtil::getInstance();
try {
$phoneProto = $phoneUtil->parse($value, $country);
if ($phoneUtil->isValidNumberForRegion($phoneProto, $country)) {
if ($phoneUtil->isValidNumberForRegion($phoneProto, $country)
&& (empty($types) || in_array($phoneUtil->getNumberType($phoneProto), $types))) {
return TRUE;
}
}
Expand Down

0 comments on commit 0c88083

Please sign in to comment.