protected function parseHelper($numberToParse, $defaultRegion, $keepRawInput, $checkRegion, PhoneNumber $phoneNumber)
{
if ($numberToParse === null) {
throw new NumberParseException(NumberParseException::NOT_A_NUMBER, "The phone number supplied was null.");
}
$numberToParse = trim($numberToParse);
if (mb_strlen($numberToParse) > static::MAX_INPUT_STRING_LENGTH) {
throw new NumberParseException(NumberParseException::TOO_LONG, "The string supplied was too long to parse.");
}
$nationalNumber = '';
$this->buildNationalNumberForParsing($numberToParse, $nationalNumber);
if (!static::isViablePhoneNumber($nationalNumber)) {
throw new NumberParseException(NumberParseException::NOT_A_NUMBER, "The string supplied did not seem to be a phone number.");
}
// Check the region supplied is valid, or that the extracted number starts with some sort of +
// sign so the number's region can be determined.
if ($checkRegion && !$this->checkRegionForParsing($nationalNumber, $defaultRegion)) {
throw new NumberParseException(NumberParseException::INVALID_COUNTRY_CODE, "Missing or invalid default region.");
}
if ($keepRawInput) {
$phoneNumber->setRawInput($numberToParse);
}
// Attempt to parse extension first, since it doesn't require region-specific data and we want
// to have the non-normalised number here.
$extension = $this->maybeStripExtension($nationalNumber);
if (mb_strlen($extension) > 0) {
$phoneNumber->setExtension($extension);
}
$regionMetadata = $this->getMetadataForRegion($defaultRegion);
// Check to see if the number is given in international format so we know whether this number is
// from the default region or not.
$normalizedNationalNumber = "";
try {
// TODO: This method should really just take in the string buffer that has already
// been created, and just remove the prefix, rather than taking in a string and then
// outputting a string buffer.
$countryCode = $this->maybeExtractCountryCode($nationalNumber, $regionMetadata, $normalizedNationalNumber, $keepRawInput, $phoneNumber);
} catch (NumberParseException $e) {
$matcher = new Matcher(static::$PLUS_CHARS_PATTERN, $nationalNumber);
if ($e->getErrorType() == NumberParseException::INVALID_COUNTRY_CODE && $matcher->lookingAt()) {
// Strip the plus-char, and try again.
$countryCode = $this->maybeExtractCountryCode(substr($nationalNumber, $matcher->end()), $regionMetadata, $normalizedNationalNumber, $keepRawInput, $phoneNumber);
if ($countryCode == 0) {
throw new NumberParseException(NumberParseException::INVALID_COUNTRY_CODE, "Could not interpret numbers after plus-sign.");
}
} else {
throw new NumberParseException($e->getErrorType(), $e->getMessage(), $e);
}
}
if ($countryCode !== 0) {
$phoneNumberRegion = $this->getRegionCodeForCountryCode($countryCode);
if ($phoneNumberRegion != $defaultRegion) {
// Metadata cannot be null because the country calling code is valid.
$regionMetadata = $this->getMetadataForRegionOrCallingCode($countryCode, $phoneNumberRegion);
}
} else {
// If no extracted country calling code, use the region supplied instead. The national number
// is just the normalized version of the number we were given to parse.
$normalizedNationalNumber .= static::normalize($nationalNumber);
if ($defaultRegion !== null) {
$countryCode = $regionMetadata->getCountryCode();
$phoneNumber->setCountryCode($countryCode);
} elseif ($keepRawInput) {
$phoneNumber->clearCountryCodeSource();
}
}
if (mb_strlen($normalizedNationalNumber) < static::MIN_LENGTH_FOR_NSN) {
throw new NumberParseException(NumberParseException::TOO_SHORT_NSN, "The string supplied is too short to be a phone number.");
}
if ($regionMetadata !== null) {
$carrierCode = "";
$potentialNationalNumber = $normalizedNationalNumber;
$this->maybeStripNationalPrefixAndCarrierCode($potentialNationalNumber, $regionMetadata, $carrierCode);
// We require that the NSN remaining after stripping the national prefix and carrier code be
// long enough to be a possible length for the region. Otherwise, we don't do the stripping,
// since the original number could be a valid short number.
if ($this->testNumberLength($potentialNationalNumber, $regionMetadata->getGeneralDesc()) !== ValidationResult::TOO_SHORT) {
$normalizedNationalNumber = $potentialNationalNumber;
if ($keepRawInput && mb_strlen($carrierCode) > 0) {
$phoneNumber->setPreferredDomesticCarrierCode($carrierCode);
}
}
}
$lengthOfNationalNumber = mb_strlen($normalizedNationalNumber);
if ($lengthOfNationalNumber < static::MIN_LENGTH_FOR_NSN) {
throw new NumberParseException(NumberParseException::TOO_SHORT_NSN, "The string supplied is too short to be a phone number.");
}
if ($lengthOfNationalNumber > static::MAX_LENGTH_FOR_NSN) {
throw new NumberParseException(NumberParseException::TOO_LONG, "The string supplied is too long to be a phone number.");
}
static::setItalianLeadingZerosForPhoneNumber($normalizedNationalNumber, $phoneNumber);
/*
* We have to store the National Number as a string instead of a "long" as Google do
*
* Since PHP doesn't always support 64 bit INTs, this was a float, but that had issues
* with long numbers.
*
* We have to remove the leading zeroes ourself though
*/
if ((int) $normalizedNationalNumber == 0) {
$normalizedNationalNumber = "0";
} else {
$normalizedNationalNumber = ltrim($normalizedNationalNumber, '0');
}
$phoneNumber->setNationalNumber($normalizedNationalNumber);
}