Skip to content
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ return [
| 38 | [ValidUsername](https://github.com/milwad-dev/laravel-validate/blob/1.x/docs/1.x/valid-username.md) | Validate username for ex (milwad) |
| 39 | [ValidUuid](https://github.com/milwad-dev/laravel-validate/blob/1.x/docs/1.x/valid-uuid.md) | Validate uuid for ex (123e4567-e89b-12d3-a456-426655440000) |
| 40 | [ValidVatId](https://github.com/milwad-dev/laravel-validate/blob/1.x/docs/1.x/valid-vatid.md) | Validate european VAT ID ex (EL123456789123) |
| 41 | [ValidLandlineNumber](https://github.com/milwad-dev/laravel-validate/blob/1.x/docs/1.x/valid-landline-number.md) | Validate landline number |

<a name="support-languages"></a>

Expand Down
13 changes: 13 additions & 0 deletions config/laravel-validate.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use Milwad\LaravelValidate\Utils\CountryPhoneValidator\SEPhoneValidator;
use Milwad\LaravelValidate\Utils\CountryPhoneValidator\TRPhoneValidator;
use Milwad\LaravelValidate\Utils\CountryPhoneValidator\ZHPhoneValidator;
use \Milwad\LaravelValidate\Utils\CountryLandlineValidator\IRLandlineValidator;
use \Milwad\LaravelValidate\Utils\CountryLandlineValidator\DELandlineValidator;

return [
/*
Expand Down Expand Up @@ -47,6 +49,17 @@
'ZH' => ZHPhoneValidator::class, // China
],

/*
* Mapping of country codes to their respective landline number validator classes.
* Each validator enforces country-specific landline number formatting and validation rules.
*
* You can add custom country landline validator.
*/
'landline-country' => [
'DE' => DELandlineValidator::class, // Germany
'IR' => IRLandlineValidator::class, // Iran
],

/*
* If you want to use rules like 'required|ValidPhone' in your validations, you can change it to true.
*/
Expand Down
33 changes: 33 additions & 0 deletions docs/1.x/valid-landline-number.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## ValidLandlineNumber

If you want to validate the landline number, you can use the `ValidLandlineNumber` rule:

```php
use Milwad\LaravelValidate\Rules\ValidLandlineNumber;

return [
'landline-number' => ['required', new ValidLandlineNumber()], // landline-number => 09120000000
];
```

Also `ValidLandlineNumber` have the ability to validate landline number with specific country code:

```php
use Milwad\LaravelValidate\Rules\ValidLandlineNumber;
use Milwad\LaravelValidate\Utils\Country;

return [
'landline-number' => ['required', new ValidLandlineNumber(Country::GERMANY)], // landline-number => 09120000000
];
```

> **Note**
> If you want to know which country's codes are supported by the `ValidLandlineNumber` Rule, you can search your country
> on this [Countries Landline Number](#support-countries-landline-number) list.

<a name="support-countries-landline-number"></a>
## Support Countries Landline Number

- ✅ IRAN
- ✅ GERMANY

7 changes: 7 additions & 0 deletions src/LaravelValidateServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
use Milwad\LaravelValidate\Utils\CountryLandlineCallback;
use Milwad\LaravelValidate\Utils\CountryPhoneCallback;

class LaravelValidateServiceProvider extends ServiceProvider
Expand Down Expand Up @@ -65,6 +66,12 @@ public function boot(): void
CountryPhoneCallback::addValidator($code, $country);
}

$landlineCountries = config('laravel-validate.landline-country', []);

foreach ($landlineCountries as $code => $country) {
CountryLandlineCallback::addValidator($code, $country);
}

// Register rules in container
if (config('laravel-validate.using_container', false)) {
$rules = File::files(__DIR__.'/Rules');
Expand Down
33 changes: 33 additions & 0 deletions src/Rules/ValidLandlineNumber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Milwad\LaravelValidate\Rules;

use Illuminate\Contracts\Validation\Rule;
use Milwad\LaravelValidate\Utils\CountryLandlineCallback;

class ValidLandlineNumber implements Rule
{
public function __construct(protected ?string $code = null) {}

/**
* Check phone number is valid.
*/
public function passes($attribute, $value): bool
{
if (is_string($this->code)) {
$passes = CountryLandlineCallback::callLandlineValidator($this->code, $value);

return collect($passes)->some(fn ($passe) => $passe);
}

return preg_match('/^(?:\+|00)(?:[1-9]\d{0,2})(?:[ .\-]?\(?\d+\)?)+$/', $value);
}

/**
* Get the validation error message.
*/
public function message(): string
{
return __('validate.landline-number');
}
}
40 changes: 40 additions & 0 deletions src/Utils/CountryLandlineCallback.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Milwad\LaravelValidate\Utils;

use Milwad\LaravelValidate\Utils\CountryLandlineValidator\CountryLandlineValidator;
use RuntimeException;

class CountryLandlineCallback
{
/**
* Country Validate classes.
*/
protected static array $validators = [];

/**
* Add new country validator.
*
* @throws \Throwable
*/
public static function addValidator(string $code, string $validator): void
{
if (! new $validator instanceof CountryLandlineValidator) {
throw new RuntimeException('The validator is not instance of CountryLandlineValidator');
}

self::$validators[$code] = $validator;
}

/**
* Call country validate class.
*/
public static function callLandlineValidator(string $code, $value)
{
if (isset(self::$validators[$code])) {
return (new self::$validators[$code])->validate($value);
} else {
throw new \BadMethodCallException("Validator method for '$code' does not exist.");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Milwad\LaravelValidate\Utils\CountryLandlineValidator;

interface CountryLandlineValidator
{
public function validate($value): bool;
}
14 changes: 14 additions & 0 deletions src/Utils/CountryLandlineValidator/DELandlineValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Milwad\LaravelValidate\Utils\CountryLandlineValidator;

class DELandlineValidator implements CountryLandlineValidator
{
/**
* Validate Germany landline numbers.
*/
public function validate($value): bool
{
return preg_match('/^(?:(?:\+49|0049)[\s\-]?[2-9]\d{1,4}[\s\-]?\d{3,8}|0[2-9]\d{1,4}[\s\-]?\d{3,8})$/', $value);
}
}
14 changes: 14 additions & 0 deletions src/Utils/CountryLandlineValidator/IRLandlineValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Milwad\LaravelValidate\Utils\CountryLandlineValidator;

class IRLandlineValidator implements CountryLandlineValidator
{
/**
* Validate Iran landline numbers.
*/
public function validate($value): bool
{
return preg_match('/^(?:98|\+98|0098|0)?[1-8]{1}\d{9}$/', $value);
}
}
1 change: 1 addition & 0 deletions src/lang/de/validate.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@
'url' => ':attribute kein gültiger.',
'username' => ':attribute kein gültiger.',
'uuid' => ':attribute kein gültiger.',
'landline-number' => ':attribute kein gültiger.',
];
1 change: 1 addition & 0 deletions src/lang/fa/validate.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@
'url' => 'مقدار :attribute صحیح نمی باشد.',
'username' => 'مقدار :attribute صحیح نمی باشد.',
'uuid' => 'مقدار :attribute صحیح نمی باشد.',
'landline-number' => 'مقدار :attribute صحیح نمی باشد.',
];
79 changes: 79 additions & 0 deletions tests/Rules/ValidLandlineNumberTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

namespace Milwad\LaravelValidate\Tests\Rules;

use BadMethodCallException;
use Milwad\LaravelValidate\Rules\ValidLandlineNumber;
use Milwad\LaravelValidate\Tests\TestCase;
use Milwad\LaravelValidate\Utils\Country;

class ValidLandlineNumberTest extends TestCase
{
/**
* Test landline number is valid.
*/
public function test_landline_number_is_valid()
{
$rules = [
'landline_number' => [new ValidLandlineNumber],
'landline_de' => [new ValidLandlineNumber(Country::GERMANY)],
];
$data = [
'landline_number' => '+98212223343',
'landline_de' => '+49301234567',
];
$passes = $this->app['validator']->make($data, $rules)->passes();

$this->assertTrue($passes);
}

/**
* Test landline number is not valid.
*/
public function test_landline_number_is_not_valid()
{
$rules = [
'landline_number' => [new ValidLandlineNumber],
'landline_ir' => [new ValidLandlineNumber(Country::IRAN)],
];
$data = [
'landline_number' => '123456789',
'landline_ir' => '09120000000',
];
$passes = $this->app['validator']->make($data, $rules)->passes();

$this->assertFalse($passes);
}

/**
* Test all landline number is valid by specific code.
*/
public function test_all_landline_number_is_valid_by_specific_code()
{
$rules = [
'landline_ir' => [new ValidLandlineNumber(Country::IRAN)],
'landline_de' => [new ValidLandlineNumber(Country::GERMANY)],
];
$data = [
'landline_ir' => '02132223343',
'landline_de' => '+49301234567',
];
$passes = $this->app['validator']->make($data, $rules)->passes();

$this->assertTrue($passes);
}

/**
* Test if landline number validate method is not exists, will be thrown an exception.
*/
public function test_if_landline_number_validate_method_is_not_exists()
{
$this->expectException(BadMethodCallException::class);
$this->expectExceptionMessage("Validator method for 'AZ' does not exist.");

$rules = ['landline' => [new ValidLandlineNumber(Country::AZERBAIJAN)]];
$data = ['landline' => '+62812345678'];

$this->app['validator']->make($data, $rules)->passes();
}
}