374 lines
11 KiB
PHP
374 lines
11 KiB
PHP
<?php
|
||
|
||
namespace App\Rules;
|
||
|
||
use Closure;
|
||
use Illuminate\Contracts\Validation\ValidationRule;
|
||
|
||
class PhoneNumber implements ValidationRule
|
||
{
|
||
/**
|
||
* Run the validation rule.
|
||
*/
|
||
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||
{
|
||
if (!is_string($value)) {
|
||
$fail('شماره تلفن نامعتبر است.');
|
||
return;
|
||
}
|
||
|
||
$phone = $this->normalizePhone($value);
|
||
|
||
if (!$this->isValidFormat($phone)) {
|
||
$fail('شماره تلفن نامعتبر است.');
|
||
session()->flash('error', 'شماره تلفن نامعتبر است.');
|
||
return;
|
||
}
|
||
|
||
if (!$this->isValidCountryCode($phone)) {
|
||
$fail('کد کشور نامعتبر است.');
|
||
session()->flash('error', 'کد کشور نامعتبر است.');
|
||
return;
|
||
}
|
||
|
||
if (!$this->isValidLength($phone)) {
|
||
$fail('شماره تلفن نامعتبر است.');
|
||
session()->flash('error', 'شماره تلفن نامعتبر است.');
|
||
return;
|
||
}
|
||
}
|
||
|
||
private function normalizePhone(string $phone): string
|
||
{
|
||
$phone = $this->convertPersianToEnglish($phone);
|
||
return preg_replace('/[^0-9+]/', '', $phone);
|
||
}
|
||
|
||
private function isValidFormat(string $phone): bool
|
||
{
|
||
return str_starts_with($phone, '+') || ctype_digit($phone);
|
||
}
|
||
|
||
private function isValidCountryCode(string $phone): bool
|
||
{
|
||
if (!str_starts_with($phone, '+')) {
|
||
return true;
|
||
}
|
||
|
||
$phoneWithoutPlus = substr($phone, 1);
|
||
$countryCodes = $this->getValidCountryCodes();
|
||
|
||
foreach ($countryCodes as $code) {
|
||
if (str_starts_with($phoneWithoutPlus, $code)) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
private function isValidLength(string $phone): bool
|
||
{
|
||
if (str_starts_with($phone, '+')) {
|
||
$phoneWithoutPlus = substr($phone, 1);
|
||
return strlen($phoneWithoutPlus) >= 7 && strlen($phoneWithoutPlus) <= 15;
|
||
}
|
||
|
||
$phone = ltrim($phone, '0');
|
||
return strlen($phone) >= 7 && strlen($phone) <= 12;
|
||
}
|
||
|
||
private function convertPersianToEnglish(string $text): string
|
||
{
|
||
$persianNumbers = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
|
||
$englishNumbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||
|
||
return str_replace($persianNumbers, $englishNumbers, $text);
|
||
}
|
||
|
||
/**
|
||
* Get valid country codes
|
||
*/
|
||
private function getValidCountryCodes(): array
|
||
{
|
||
return [
|
||
// Middle East
|
||
'98', // Iran
|
||
'966', // Saudi Arabia
|
||
'971', // UAE
|
||
'965', // Kuwait
|
||
'974', // Qatar
|
||
'968', // Oman
|
||
'973', // Bahrain
|
||
'962', // Jordan
|
||
'961', // Lebanon
|
||
'963', // Syria
|
||
'964', // Iraq
|
||
'967', // Yemen
|
||
'970', // Palestine
|
||
'972', // Israel
|
||
|
||
// Europe
|
||
'44', // UK
|
||
'33', // France
|
||
'49', // Germany
|
||
'39', // Italy
|
||
'34', // Spain
|
||
'31', // Netherlands
|
||
'32', // Belgium
|
||
'41', // Switzerland
|
||
'43', // Austria
|
||
'46', // Sweden
|
||
'47', // Norway
|
||
'45', // Denmark
|
||
'358', // Finland
|
||
'48', // Poland
|
||
'420', // Czech Republic
|
||
'36', // Hungary
|
||
'40', // Romania
|
||
'380', // Ukraine
|
||
'7', // Russia
|
||
'375', // Belarus
|
||
'371', // Latvia
|
||
'372', // Estonia
|
||
'370', // Lithuania
|
||
'90', // Turkey
|
||
'994', // Azerbaijan
|
||
'374', // Armenia
|
||
'995', // Georgia
|
||
|
||
// Asia
|
||
'86', // China
|
||
'81', // Japan
|
||
'82', // South Korea
|
||
'91', // India
|
||
'92', // Pakistan
|
||
'880', // Bangladesh
|
||
'93', // Afghanistan
|
||
'992', // Tajikistan
|
||
'993', // Turkmenistan
|
||
'996', // Kyrgyzstan
|
||
'998', // Uzbekistan
|
||
'65', // Singapore
|
||
'60', // Malaysia
|
||
'66', // Thailand
|
||
'84', // Vietnam
|
||
'62', // Indonesia
|
||
'63', // Philippines
|
||
'977', // Nepal
|
||
'975', // Bhutan
|
||
'976', // Mongolia
|
||
'855', // Cambodia
|
||
'856', // Laos
|
||
'95', // Myanmar
|
||
'94', // Sri Lanka
|
||
'960', // Maldives
|
||
'886', // Taiwan
|
||
'852', // Hong Kong
|
||
'853', // Macau
|
||
'850', // North Korea
|
||
|
||
// Americas
|
||
'1', // USA/Canada
|
||
'52', // Mexico
|
||
'55', // Brazil
|
||
'54', // Argentina
|
||
'56', // Chile
|
||
'57', // Colombia
|
||
'51', // Peru
|
||
'58', // Venezuela
|
||
'598', // Uruguay
|
||
'595', // Paraguay
|
||
'591', // Bolivia
|
||
'593', // Ecuador
|
||
'592', // Guyana
|
||
'597', // Suriname
|
||
|
||
// Africa
|
||
'20', // Egypt
|
||
'212', // Morocco
|
||
'213', // Algeria
|
||
'216', // Tunisia
|
||
'218', // Libya
|
||
'249', // Sudan
|
||
'27', // South Africa
|
||
'234', // Nigeria
|
||
'254', // Kenya
|
||
'251', // Ethiopia
|
||
'255', // Tanzania
|
||
'256', // Uganda
|
||
'233', // Ghana
|
||
'225', // Ivory Coast
|
||
'237', // Cameroon
|
||
'236', // Central African Republic
|
||
'235', // Chad
|
||
'241', // Gabon
|
||
'242', // Republic of the Congo
|
||
'243', // Democratic Republic of the Congo
|
||
'244', // Angola
|
||
'245', // Guinea-Bissau
|
||
'250', // Rwanda
|
||
'257', // Burundi
|
||
'258', // Mozambique
|
||
'260', // Zambia
|
||
'261', // Madagascar
|
||
'263', // Zimbabwe
|
||
'264', // Namibia
|
||
'265', // Malawi
|
||
'266', // Lesotho
|
||
'267', // Botswana
|
||
'268', // Eswatini
|
||
'269', // Comoros
|
||
'291', // Eritrea
|
||
'252', // Somalia
|
||
'253', // Djibouti
|
||
|
||
// Oceania
|
||
'61', // Australia
|
||
'64', // New Zealand
|
||
'679', // Fiji
|
||
'675', // Papua New Guinea
|
||
'685', // Samoa
|
||
'676', // Tonga
|
||
'677', // Solomon Islands
|
||
'678', // Vanuatu
|
||
'680', // Palau
|
||
'681', // Wallis and Futuna
|
||
'682', // Cook Islands
|
||
'683', // Niue
|
||
'686', // Kiribati
|
||
'687', // New Caledonia
|
||
'688', // Tuvalu
|
||
'689', // French Polynesia
|
||
'690', // Tokelau
|
||
'691', // Micronesia
|
||
'692', // Marshall Islands
|
||
|
||
// Additional countries from JavaScript file
|
||
'355', // Albania
|
||
'376', // Andorra
|
||
'1268', // Antigua and Barbuda
|
||
'1242', // Bahamas
|
||
'1246', // Barbados
|
||
'501', // Belize
|
||
'229', // Benin
|
||
'1767', // Dominica
|
||
'1809', // Dominican Republic
|
||
'503', // El Salvador
|
||
'240', // Equatorial Guinea
|
||
'291', // Eritrea
|
||
'372', // Estonia
|
||
'679', // Fiji
|
||
'220', // Gambia
|
||
'995', // Georgia
|
||
'1473', // Grenada
|
||
'502', // Guatemala
|
||
'224', // Guinea
|
||
'245', // Guinea-Bissau
|
||
'509', // Haiti
|
||
'504', // Honduras
|
||
'354', // Iceland
|
||
'353', // Ireland
|
||
'1876', // Jamaica
|
||
'962', // Jordan
|
||
'254', // Kenya
|
||
'686', // Kiribati
|
||
'965', // Kuwait
|
||
'996', // Kyrgyzstan
|
||
'856', // Laos
|
||
'371', // Latvia
|
||
'961', // Lebanon
|
||
'266', // Lesotho
|
||
'231', // Liberia
|
||
'218', // Libya
|
||
'423', // Liechtenstein
|
||
'370', // Lithuania
|
||
'352', // Luxembourg
|
||
'261', // Madagascar
|
||
'265', // Malawi
|
||
'223', // Mali
|
||
'356', // Malta
|
||
'692', // Marshall Islands
|
||
'222', // Mauritania
|
||
'230', // Mauritius
|
||
'52', // Mexico
|
||
'691', // Micronesia
|
||
'373', // Moldova
|
||
'377', // Monaco
|
||
'976', // Mongolia
|
||
'382', // Montenegro
|
||
'212', // Morocco
|
||
'258', // Mozambique
|
||
'95', // Myanmar
|
||
'264', // Namibia
|
||
'674', // Nauru
|
||
'977', // Nepal
|
||
'505', // Nicaragua
|
||
'227', // Niger
|
||
'234', // Nigeria
|
||
'47', // Norway
|
||
'968', // Oman
|
||
'92', // Pakistan
|
||
'680', // Palau
|
||
'507', // Panama
|
||
'675', // Papua New Guinea
|
||
'595', // Paraguay
|
||
'51', // Peru
|
||
'63', // Philippines
|
||
'48', // Poland
|
||
'351', // Portugal
|
||
'974', // Qatar
|
||
'40', // Romania
|
||
'250', // Rwanda
|
||
'1869', // Saint Kitts and Nevis
|
||
'1758', // Saint Lucia
|
||
'1784', // Saint Vincent and the Grenadines
|
||
'685', // Samoa
|
||
'378', // San Marino
|
||
'239', // Sao Tome and Principe
|
||
'966', // Saudi Arabia
|
||
'221', // Senegal
|
||
'381', // Serbia
|
||
'248', // Seychelles
|
||
'232', // Sierra Leone
|
||
'421', // Slovakia
|
||
'386', // Slovenia
|
||
'677', // Solomon Islands
|
||
'252', // Somalia
|
||
'27', // South Africa
|
||
'82', // South Korea
|
||
'94', // Sri Lanka
|
||
'249', // Sudan
|
||
'597', // Suriname
|
||
'268', // Eswatini
|
||
'46', // Sweden
|
||
'41', // Switzerland
|
||
'963', // Syria
|
||
'886', // Taiwan
|
||
'992', // Tajikistan
|
||
'255', // Tanzania
|
||
'66', // Thailand
|
||
'670', // Timor-Leste
|
||
'228', // Togo
|
||
'676', // Tonga
|
||
'1868', // Trinidad and Tobago
|
||
'216', // Tunisia
|
||
'993', // Turkmenistan
|
||
'688', // Tuvalu
|
||
'256', // Uganda
|
||
'380', // Ukraine
|
||
'971', // United Arab Emirates
|
||
'44', // United Kingdom
|
||
'1', // United States
|
||
'598', // Uruguay
|
||
'998', // Uzbekistan
|
||
'678', // Vanuatu
|
||
'379', // Vatican City
|
||
'58', // Venezuela
|
||
'967', // Yemen
|
||
'260', // Zambia
|
||
'263', // Zimbabwe
|
||
];
|
||
}
|
||
}
|