/**
  * Helper method to check a number against a particular pattern and determine whether it matches,
  * or is too short or too long. Currently, if a number pattern suggests that numbers of length 7
  * and 10 are possible, and a number in between these possible lengths is entered, such as of
  * length 8, this will return TOO_LONG.
  * @param string $numberPattern
  * @param string $number
  * @return int ValidationResult
  */
 private function testNumberLengthAgainstPattern($numberPattern, $number)
 {
     $numberMatcher = new Matcher($numberPattern, $number);
     if ($numberMatcher->matches()) {
         return ValidationResult::IS_POSSIBLE;
     }
     if ($numberMatcher->lookingAt()) {
         return ValidationResult::TOO_LONG;
     } else {
         return ValidationResult::TOO_SHORT;
     }
 }
 /**
  * Returns whether the given national number (a string containing only decimal digits) matches
  * the national number pattern defined in the given {@code PhoneNumberDesc} message.
  *
  * @param string $nationalNumber
  * @param PhoneNumberDesc $numberDesc
  * @param boolean $allowPrefixMatch
  * @return boolean
  */
 public function matchesNationalNumber($nationalNumber, PhoneNumberDesc $numberDesc, $allowPrefixMatch)
 {
     $nationalNumberPatternMatcher = new Matcher($numberDesc->getNationalNumberPattern(), $nationalNumber);
     return $nationalNumberPatternMatcher->matches() || $allowPrefixMatch && $nationalNumberPatternMatcher->lookingAt();
 }
 public function formatNsnUsingPattern($nationalNumber, NumberFormat $formattingPattern, $numberFormat, $carrierCode = NULL)
 {
     $numberFormatRule = $formattingPattern->getFormat();
     $m = new Matcher($formattingPattern->getPattern(), $nationalNumber);
     if ($numberFormat == PhoneNumberFormat::NATIONAL && $carrierCode !== NULL && strlen($carrierCode) > 0 && strlen($formattingPattern->getDomesticCarrierCodeFormattingRule()) > 0) {
         // Replace the $CC in the formatting rule with the desired carrier code.
         $carrierCodeFormattingRule = $formattingPattern->getDomesticCarrierCodeFormattingRule();
         $ccPatternMatcher = new Matcher(self::CC_PATTERN, $carrierCodeFormattingRule);
         $carrierCodeFormattingRule = $ccPatternMatcher->replaceFirst($carrierCode);
         // Now replace the $FG in the formatting rule with the first group and the carrier code
         // combined in the appropriate way.
         $firstGroupMatcher = new Matcher(self::FIRST_GROUP_PATTERN, $numberFormatRule);
         $numberFormatRule = $firstGroupMatcher->replaceFirst($carrierCodeFormattingRule);
         $formattedNationalNumber = $m->replaceAll($numberFormatRule);
     } else {
         // Use the national prefix formatting rule instead.
         $nationalPrefixFormattingRule = $formattingPattern->getNationalPrefixFormattingRule();
         if ($numberFormat == PhoneNumberFormat::NATIONAL && $nationalPrefixFormattingRule !== NULL && strlen($nationalPrefixFormattingRule) > 0) {
             $firstGroupMatcher = new Matcher(self::FIRST_GROUP_PATTERN, $numberFormatRule);
             $formattedNationalNumber = $m->replaceAll($firstGroupMatcher->replaceFirst($nationalPrefixFormattingRule));
         } else {
             $formattedNationalNumber = $m->replaceAll($numberFormatRule);
         }
     }
     if ($numberFormat == PhoneNumberFormat::RFC3966) {
         // Strip any leading punctuation.
         $matcher = new Matcher(self::$SEPARATOR_PATTERN, $formattedNationalNumber);
         if ($matcher->lookingAt()) {
             $formattedNationalNumber = $matcher->replaceFirst("");
         }
         // Replace the rest with a dash between each number group.
         $formattedNationalNumber = $matcher->reset($formattedNationalNumber)->replaceAll("-");
     }
     return $formattedNationalNumber;
 }
 private function matchesEmergencyNumberHelper($number, $regionCode, $allowPrefixMatch)
 {
     $number = PhoneNumberUtil::extractPossibleNumber($number);
     $matcher = new Matcher(PhoneNumberUtil::$PLUS_CHARS_PATTERN, $number);
     if ($matcher->lookingAt()) {
         // Returns false if the number starts with a plus sign. WE don't believe dialling the country
         // code before emergency numbers (e.g. +1911) works, but later, if that proves to work, we can
         // add additional logic here to handle it.
         return false;
     }
     $metadata = $this->getMetadataForRegion($regionCode);
     if ($metadata === null || !$metadata->hasEmergency()) {
         return false;
     }
     $emergencyNumberPattern = $metadata->getEmergency()->getNationalNumberPattern();
     $normalizedNumber = PhoneNumberUtil::normalizeDigitsOnly($number);
     $emergencyMatcher = new Matcher($emergencyNumberPattern, $normalizedNumber);
     return !$allowPrefixMatch || in_array($regionCode, self::$regionsWhereEmergencyNumbersMustBeExact) ? $emergencyMatcher->matches() : $emergencyMatcher->lookingAt();
 }
 /**
  * Strips any national prefix (such as 0, 1) present in the number provided.
  *
  * @param string $number the normalized telephone number that we wish to strip any national
  *     dialing prefix from
  * @param PhoneMetadata $metadata the metadata for the region that we think this number is from
  * @param string $carrierCode a place to insert the carrier code if one is extracted
  * @return bool true if a national prefix or carrier code (or both) could be extracted.
  */
 public function maybeStripNationalPrefixAndCarrierCode(&$number, PhoneMetadata $metadata, &$carrierCode)
 {
     $numberLength = mb_strlen($number);
     $possibleNationalPrefix = $metadata->getNationalPrefixForParsing();
     if ($numberLength == 0 || $possibleNationalPrefix === null || mb_strlen($possibleNationalPrefix) == 0) {
         // Early return for numbers of zero length.
         return false;
     }
     // Attempt to parse the first digits as a national prefix.
     $prefixMatcher = new Matcher($possibleNationalPrefix, $number);
     if ($prefixMatcher->lookingAt()) {
         $nationalNumberRule = $metadata->getGeneralDesc()->getNationalNumberPattern();
         // Check if the original number is viable.
         $nationalNumberRuleMatcher = new Matcher($nationalNumberRule, $number);
         $isViableOriginalNumber = $nationalNumberRuleMatcher->matches();
         // $prefixMatcher->group($numOfGroups) === null implies nothing was captured by the capturing
         // groups in $possibleNationalPrefix; therefore, no transformation is necessary, and we just
         // remove the national prefix
         $numOfGroups = $prefixMatcher->groupCount();
         $transformRule = $metadata->getNationalPrefixTransformRule();
         if ($transformRule === null || mb_strlen($transformRule) == 0 || $prefixMatcher->group($numOfGroups - 1) === null) {
             // If the original number was viable, and the resultant number is not, we return.
             $matcher = new Matcher($nationalNumberRule, substr($number, $prefixMatcher->end()));
             if ($isViableOriginalNumber && !$matcher->matches()) {
                 return false;
             }
             if ($carrierCode !== null && $numOfGroups > 0 && $prefixMatcher->group($numOfGroups) !== null) {
                 $carrierCode .= $prefixMatcher->group(1);
             }
             $number = substr($number, $prefixMatcher->end());
             return true;
         } else {
             // Check that the resultant number is still viable. If not, return. Check this by copying
             // the string and making the transformation on the copy first.
             $transformedNumber = $number;
             $transformedNumber = substr_replace($transformedNumber, $prefixMatcher->replaceFirst($transformRule), 0, $numberLength);
             $matcher = new Matcher($nationalNumberRule, $transformedNumber);
             if ($isViableOriginalNumber && !$matcher->matches()) {
                 return false;
             }
             if ($carrierCode !== null && $numOfGroups > 1) {
                 $carrierCode .= $prefixMatcher->group(1);
             }
             $number = substr_replace($number, $transformedNumber, 0, mb_strlen($number));
             return true;
         }
     }
     return false;
 }