49 $this->phoneNumberStartPattern =
'[' . $this->plusChar . $this->validDigits .
']';
50 $this->afterPhoneNumberEndPattern =
'[^' . $this->validDigits . $this->extensionSeparators . $this->extensionSymbols .
']+$';
51 $this->minLengthPhoneNumberPattern =
'[' . $this->validDigits .
']{' . static::MIN_LENGTH_FOR_NSN .
'}';
52 $this->validPunctuation = $this->dashes . $this->slashes . $this->dot . $this->whitespace . $this->brackets . $this->tildes . $this->extensionSeparators .
$this->extensionSymbols;
53 $this->validPhoneNumber =
54 '[' . $this->plusChar .
']{0,1}' .
56 '[' . $this->validPunctuation .
']*' .
57 '[' . $this->validDigits .
']' .
60 $this->validPunctuation .
64 $this->validPhoneNumberPattern =
67 '^' . $this->minLengthPhoneNumberPattern .
'$' .
69 '|' .
'^' . $this->validPhoneNumber .
'$' .
94 $defaultCountryId = Option::get(
'main', static::DEFAULT_COUNTRY_OPTION);
96 if(!$defaultCountryId)
98 $detectedCountry = static::detectCountry();
99 $detectedCountryId = GetCountryIdByCode($detectedCountry);
100 if($detectedCountryId > 0)
102 Option::set(
'main', static::DEFAULT_COUNTRY_OPTION, $detectedCountryId);
103 $defaultCountryId = $detectedCountryId;
107 return $defaultCountryId ? GetCountryCodeById($defaultCountryId) :
"";
124 $defaultCountry = Option::get(
"bitrix24",
"REG_COUNTRY",
"");
128 $portalZone = \CBitrix24::getPortalZone();
130 if(in_array($portalZone, array(
'br',
'cn',
'de',
'in',
'ru',
'ua',
'by',
'kz',
'fr',
'pl')))
132 $defaultCountry = $portalZone;
140 if(in_array($currentLanguage, array(
'br',
'cn',
'de',
'in',
'ru',
'ua',
'by',
'kz',
'fr',
'pl')))
142 $defaultCountry = $currentLanguage;
149 $defaultCountry = \Bitrix\Main\Service\GeoIp\Manager::getCountryCode();
152 return mb_strtoupper($defaultCountry);
170 public function parse($phoneNumber, $defaultCountry =
'')
172 if($defaultCountry ==
'')
174 $defaultCountry = static::getDefaultCountry();
177 $result->setRawNumber($phoneNumber);
185 list($extensionSeparator, $extension) = $this->
stripExtension($formattedPhoneNumber);
186 $result->setNationalNumber($formattedPhoneNumber);
187 $result->setExtensionSeparator($extensionSeparator);
188 $result->setExtension($extension);
191 if($parseResult ===
false)
196 $countryCode = $parseResult[
'countryCode'];
197 $localNumber = $parseResult[
'localNumber'];
203 $isInternational =
true;
206 if(!$countryMetadata)
221 $country = $defaultCountry;
223 if(!$countryMetadata)
228 $countryCode = $countryMetadata[
'countryCode'];
239 $country = $this->
findCountry($countryCode, $localNumber);
249 if(mb_strlen($localNumber) > static::MAX_LENGTH_FOR_NSN)
254 $nationalNumberRegex =
'/^(?:' . $countryMetadata[
'generalDesc'][
'nationalNumberPattern'] .
')$/';
255 if(!preg_match($nationalNumberRegex, $localNumber))
261 $result->setHasPlus($hasPlus);
262 $result->setCountry($country);
263 $result->setCountryCode($countryCode);
264 $result->setNumberType($numberType);
265 $result->setValid($numberType !==
false);
267 if($result->isValid())
269 $result->setNationalNumber($localNumber);
270 $result->setInternational($isInternational);
271 $result->setNationalPrefix($nationalPrefix);
285 $extensionSeparator =
"";
287 if(preg_match(
"/[" . $this->extensionSeparators .
"]/", $phoneNumber, $matches, PREG_OFFSET_CAPTURE))
289 $extensionSeparator = $matches[0][0];
290 $separatorPosition = $matches[0][1];
291 $extension = mb_substr($phoneNumber, $separatorPosition + 1);
292 $phoneNumber = mb_substr($phoneNumber, 0, $separatorPosition);
294 return [$extensionSeparator, $extension];
304 if (!$phoneNumber || mb_strlen($phoneNumber) > static::MAX_INPUT_STRING_LENGTH)
309 if(!preg_match(
'/'.$this->phoneNumberStartPattern.
'/', $phoneNumber, $matches, PREG_OFFSET_CAPTURE))
315 $startsAt = $matches[0][1];
321 $result = mb_substr($phoneNumber, $startsAt);
322 $result = preg_replace(
'/'.$this->afterPhoneNumberEndPattern.
'/',
'', $result);
349 if ($phoneNumber[0] !== $this->plusChar)
353 'localNumber' => $phoneNumber
358 $phoneNumber = mb_substr($phoneNumber, 1);
361 if ($phoneNumber[0] ===
'0')
366 for ($i = static::MAX_LENGTH_COUNTRY_CODE; $i > 0; $i--)
368 $countryCode = mb_substr($phoneNumber, 0, $i);
372 'countryCode' => $countryCode,
373 'localNumber' => mb_substr($phoneNumber, $i)
425 if(!$countryCode || !$localNumber)
429 if(count($possibleCountries) === 1)
431 return $possibleCountries[0];
434 foreach($possibleCountries as $possibleCountry)
439 if(isset($countryMetadata[
'leadingDigits']))
441 $leadingDigitsRegex =
'/^('.$countryMetadata[
'leadingDigits'].
')/';
442 if(preg_match($leadingDigitsRegex, $localNumber))
444 return $possibleCountry;
448 else if($this->
getNumberType($localNumber, $possibleCountry))
450 return $possibleCountry;
467 if(!$countryMetadata)
470 if(isset($countryMetadata[
'generalDesc'][
'nationalNumberPattern']))
472 $nationalNumberRegex =
'/^(?:' . $countryMetadata[
'generalDesc'][
'nationalNumberPattern'] .
')$/';
473 if(!preg_match($nationalNumberRegex, $localNumber))
477 $possibleTypes = array(
'noInternationalDialling',
'areaCodeOptional',
'fixedLine',
'mobile',
'pager',
'tollFree',
'premiumRate',
'sharedCost',
'personalNumber',
'voip',
'uan',
'voicemail');
478 foreach ($possibleTypes as $possibleType)
480 if(isset($countryMetadata[$possibleType][
'nationalNumberPattern']))
484 $numberTypeRegex =
'/^' . $countryMetadata[$possibleType][
'nationalNumberPattern'] .
'$/';
485 if(preg_match($numberTypeRegex, $localNumber))
487 return $possibleType;
503 $nationalPrefixForParsing = $countryMetadata[
'nationalPrefixForParsing'] ?? ($countryMetadata[
'nationalPrefix'] ??
'');
505 if($phoneNumber ==
'' || $nationalPrefixForParsing ==
'')
508 $nationalPrefixRegex =
'/^(?:' . $nationalPrefixForParsing .
')/';
509 if(!preg_match($nationalPrefixRegex, $phoneNumber, $nationalPrefixMatches))
515 $nationalPrefixTransformRule = $countryMetadata[
'nationalPrefixTransformRule'] ??
'';
516 if($nationalPrefixTransformRule && count($nationalPrefixMatches) > 1)
518 $nationalSignificantNumber = preg_replace($nationalPrefixRegex, $nationalPrefixTransformRule, $phoneNumber);
523 $nationalSignificantNumber = mb_substr($phoneNumber, mb_strlen($nationalPrefixMatches[0]));
525 $nationalPrefix = mb_substr($phoneNumber, 0, mb_strlen($phoneNumber) - mb_strlen($nationalSignificantNumber));
527 $nationalNumberRegex =
'/^(?:' . $countryMetadata[
'generalDesc'][
'nationalNumberPattern'] .
')$/';
528 if(preg_match($nationalNumberRegex, $phoneNumber) && !preg_match($nationalNumberRegex, $nationalSignificantNumber))
539 $phoneNumber = $nationalSignificantNumber;
540 return $nationalPrefix;
551 $countryCode = $countryMetadata[
'countryCode'];
552 if(mb_strpos($phoneNumber, $countryCode) !== 0)
555 $possibleLocalNumber = mb_substr($phoneNumber, mb_strlen($countryCode));
556 $nationalNumberRegex =
'/^(?:' . $countryMetadata[
'generalDesc'][
'nationalNumberPattern'] .
')$/';
558 if(!preg_match($nationalNumberRegex, $phoneNumber) && preg_match($nationalNumberRegex, $possibleLocalNumber))
566 $phoneNumber = $possibleLocalNumber;