libphonenumber\PhoneNumberUtil::maybeExtractCountryCode PHP Method

maybeExtractCountryCode() public method

If the number is not considered possible for the numbering plan of the default region initially, but starts with the country calling code of this region, validation will be reattempted after stripping this country calling code. If this number is considered a possible number, then the first digits will be considered the country calling code and removed as such. It will throw a NumberParseException if the number starts with a '+' but the country calling code supplied after this does not match that of any known region.
public maybeExtractCountryCode ( string $number, PhoneMetadata $defaultRegionMetadata = null, string &$nationalNumber, boolean $keepRawInput, PhoneNumber $phoneNumber ) : integer
$number string non-normalized telephone number that we wish to extract a country calling code from - may begin with '+'
$defaultRegionMetadata PhoneMetadata metadata about the region this number may be from
$nationalNumber string a string buffer to store the national significant number in, in the case that a country calling code was extracted. The number is appended to any existing contents. If no country calling code was extracted, this will be left unchanged.
$keepRawInput boolean true if the country_code_source and preferred_carrier_code fields of phoneNumber should be populated.
$phoneNumber PhoneNumber the PhoneNumber object where the country_code and country_code_source need to be populated. Note the country_code is always populated, whereas country_code_source is only populated when keepCountryCodeSource is true.
return integer the country calling code extracted or 0 if none could be extracted
    public function maybeExtractCountryCode($number, PhoneMetadata $defaultRegionMetadata = null, &$nationalNumber, $keepRawInput, PhoneNumber $phoneNumber)
    {
        if (mb_strlen($number) == 0) {
            return 0;
        }
        $fullNumber = $number;
        // Set the default prefix to be something that will never match.
        $possibleCountryIddPrefix = "NonMatch";
        if ($defaultRegionMetadata !== null) {
            $possibleCountryIddPrefix = $defaultRegionMetadata->getInternationalPrefix();
        }
        $countryCodeSource = $this->maybeStripInternationalPrefixAndNormalize($fullNumber, $possibleCountryIddPrefix);
        if ($keepRawInput) {
            $phoneNumber->setCountryCodeSource($countryCodeSource);
        }
        if ($countryCodeSource != CountryCodeSource::FROM_DEFAULT_COUNTRY) {
            if (mb_strlen($fullNumber) <= static::MIN_LENGTH_FOR_NSN) {
                throw new NumberParseException(NumberParseException::TOO_SHORT_AFTER_IDD, "Phone number had an IDD, but after this was not long enough to be a viable phone number.");
            }
            $potentialCountryCode = $this->extractCountryCode($fullNumber, $nationalNumber);
            if ($potentialCountryCode != 0) {
                $phoneNumber->setCountryCode($potentialCountryCode);
                return $potentialCountryCode;
            }
            // If this fails, they must be using a strange country calling code that we don't recognize,
            // or that doesn't exist.
            throw new NumberParseException(NumberParseException::INVALID_COUNTRY_CODE, "Country calling code supplied was not recognised.");
        } elseif ($defaultRegionMetadata !== null) {
            // Check to see if the number starts with the country calling code for the default region. If
            // so, we remove the country calling code, and do some checks on the validity of the number
            // before and after.
            $defaultCountryCode = $defaultRegionMetadata->getCountryCode();
            $defaultCountryCodeString = (string) $defaultCountryCode;
            $normalizedNumber = (string) $fullNumber;
            if (strpos($normalizedNumber, $defaultCountryCodeString) === 0) {
                $potentialNationalNumber = substr($normalizedNumber, mb_strlen($defaultCountryCodeString));
                $generalDesc = $defaultRegionMetadata->getGeneralDesc();
                $validNumberPattern = $generalDesc->getNationalNumberPattern();
                // Don't need the carrier code.
                $carriercode = null;
                $this->maybeStripNationalPrefixAndCarrierCode($potentialNationalNumber, $defaultRegionMetadata, $carriercode);
                // If the number was not valid before but is valid now, or if it was too long before, we
                // consider the number with the country calling code stripped to be a better result and
                // keep that instead.
                if (preg_match('/^(' . $validNumberPattern . ')$/x', $fullNumber) == 0 && preg_match('/^(' . $validNumberPattern . ')$/x', $potentialNationalNumber) > 0 || $this->testNumberLength((string) $fullNumber, $generalDesc) === ValidationResult::TOO_LONG) {
                    $nationalNumber .= $potentialNationalNumber;
                    if ($keepRawInput) {
                        $phoneNumber->setCountryCodeSource(CountryCodeSource::FROM_NUMBER_WITHOUT_PLUS_SIGN);
                    }
                    $phoneNumber->setCountryCode($defaultCountryCode);
                    return $defaultCountryCode;
                }
            }
        }
        // No country calling code present.
        $phoneNumber->setCountryCode(0);
        return 0;
    }

Usage Example

 public function testMaybeExtractCountryCode()
 {
     $number = new PhoneNumber();
     $metadata = $this->phoneUtil->getMetadataForRegion(RegionCode::US);
     // Note that for the US, the IDD is 011.
     try {
         $phoneNumber = "011112-3456789";
         $strippedNumber = "123456789";
         $countryCallingCode = 1;
         $numberToFill = "";
         $this->assertEquals($countryCallingCode, $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number), "Did not extract country calling code " . $countryCallingCode . " correctly.");
         $this->assertEquals(CountryCodeSource::FROM_NUMBER_WITH_IDD, $number->getCountryCodeSource(), "Did not figure out CountryCodeSource correctly");
         // Should strip and normalize national significant number.
         $this->assertEquals($strippedNumber, $numberToFill, "Did not strip off the country calling code correctly.");
     } catch (NumberParseException $e) {
         $this->fail("Should not have thrown an exception: " . $e->getMessage());
     }
     $number->clear();
     try {
         $phoneNumber = "+6423456789";
         $countryCallingCode = 64;
         $numberToFill = "";
         $this->assertEquals($countryCallingCode, $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number), "Did not extract country calling code " . $countryCallingCode . " correctly.");
         $this->assertEquals(CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN, $number->getCountryCodeSource(), "Did not figure out CountryCodeSource correctly");
     } catch (NumberParseException $e) {
         $this->fail("Should not have thrown an exception: " . $e->getMessage());
     }
     $number->clear();
     try {
         $phoneNumber = "+80012345678";
         $countryCallingCode = 800;
         $numberToFill = "";
         $this->assertEquals($countryCallingCode, $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number), "Did not extract country calling code " . $countryCallingCode . " correctly.");
         $this->assertEquals(CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN, $number->getCountryCodeSource(), "Did not figure out CountryCodeSource correctly");
     } catch (NumberParseException $e) {
         $this->fail("Should not have thrown an exception: " . $e->getMessage());
     }
     $number->clear();
     try {
         $phoneNumber = "2345-6789";
         $numberToFill = "";
         $this->assertEquals(0, $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number), "Should not have extracted a country calling code - no international prefix present.");
         $this->assertEquals(CountryCodeSource::FROM_DEFAULT_COUNTRY, $number->getCountryCodeSource(), "Did not figure out CountryCodeSource correctly");
     } catch (NumberParseException $e) {
         $this->fail("Should not have thrown an exception: " . $e->getMessage());
     }
     $number->clear();
     try {
         $phoneNumber = "0119991123456789";
         $numberToFill = "";
         $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number);
         $this->fail("Should have thrown an exception, no valid country calling code present.");
     } catch (NumberParseException $e) {
         // Expected.
         $this->assertEquals(NumberParseException::INVALID_COUNTRY_CODE, $e->getErrorType(), "Wrong error type stored in exception.");
     }
     $number->clear();
     try {
         $phoneNumber = "(1 610) 619 4466";
         $countryCallingCode = 1;
         $numberToFill = "";
         $this->assertEquals($countryCallingCode, $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number), "Should have extracted the country calling code of the region passed in");
         $this->assertEquals(CountryCodeSource::FROM_NUMBER_WITHOUT_PLUS_SIGN, $number->getCountryCodeSource(), "Did not figure out CountryCodeSource correctly");
     } catch (NumberParseException $e) {
         $this->fail("Should not have thrown an exception: " . $e->getMessage());
     }
     $number->clear();
     try {
         $phoneNumber = "(1 610) 619 4466";
         $countryCallingCode = 1;
         $numberToFill = "";
         $this->assertEquals($countryCallingCode, $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, false, $number), "Should have extracted the country calling code of the region passed in");
         $this->assertFalse($number->hasCountryCodeSource(), "Should not contain CountryCodeSource");
     } catch (NumberParseException $e) {
         $this->fail("Should not have thrown an exception: " . $e->getMessage());
     }
     $number->clear();
     try {
         $phoneNumber = "(1 610) 619 446";
         $numberToFill = "";
         $this->assertEquals(0, $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, false, $number), "Should not have extracted a country calling code - invalid number after extraction of uncertain country calling code.");
         $this->assertFalse($number->hasCountryCodeSource(), "Should not contain CountryCodeSource");
     } catch (NumberParseException $e) {
         $this->fail("Should not have thrown an exception: " . $e->getMessage());
     }
     $number->clear();
     try {
         $phoneNumber = "(1 610) 619";
         $numberToFill = "";
         $this->assertEquals(0, $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number), "Should not have extracted a country calling code - too short number both before and after extraction of uncertain country calling code.");
         $this->assertEquals(CountryCodeSource::FROM_DEFAULT_COUNTRY, $number->getCountryCodeSource(), "Did not figure out CountryCodeSource correctly");
     } catch (NumberParseException $e) {
         $this->fail("Should not have thrown an exception: " . $e->getMessage());
     }
 }
PhoneNumberUtil