| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | namespace libphonenumber\buildtools; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | use libphonenumber\NumberFormat; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | use libphonenumber\PhoneMetadata; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | use libphonenumber\PhoneNumberDesc; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  |  * Library to build phone number metadata from the XML format. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |  * @author Davide Mendolia | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |  * @internal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | class BuildMetadataFromXml | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |     // String constants used to fetch the XML nodes and attributes. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |     const CARRIER_CODE_FORMATTING_RULE = 'carrierCodeFormattingRule'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |     const COUNTRY_CODE = 'countryCode'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |     const EMERGENCY = 'emergency'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |     const EXAMPLE_NUMBER = 'exampleNumber'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |     const FIXED_LINE = 'fixedLine'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |     const FORMAT = 'format'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |     const GENERAL_DESC = 'generalDesc'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |     const INTERNATIONAL_PREFIX = 'internationalPrefix'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |     const INTL_FORMAT = 'intlFormat'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |     const LEADING_DIGITS = 'leadingDigits'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |     const MOBILE_NUMBER_PORTABLE_REGION = 'mobileNumberPortableRegion'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |     const MAIN_COUNTRY_FOR_CODE = 'mainCountryForCode'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |     const MOBILE = 'mobile'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |     const NATIONAL_NUMBER_PATTERN = 'nationalNumberPattern'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |     const NATIONAL_PREFIX = 'nationalPrefix'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |     const NATIONAL_PREFIX_FORMATTING_RULE = 'nationalPrefixFormattingRule'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |     const NATIONAL_PREFIX_OPTIONAL_WHEN_FORMATTING = 'nationalPrefixOptionalWhenFormatting'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |     const NATIONAL_PREFIX_FOR_PARSING = 'nationalPrefixForParsing'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |     const NATIONAL_PREFIX_TRANSFORM_RULE = 'nationalPrefixTransformRule'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |     const NO_INTERNATIONAL_DIALLING = 'noInternationalDialling'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |     const NUMBER_FORMAT = 'numberFormat'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |     const PAGER = 'pager'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |     const CARRIER_SPECIFIC = 'carrierSpecific'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |     const PATTERN = 'pattern'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |     const PERSONAL_NUMBER = 'personalNumber'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |     const POSSIBLE_LENGTHS = 'possibleLengths'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |     const NATIONAL = 'national'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |     const LOCAL_ONLY = 'localOnly'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |     const PREFERRED_EXTN_PREFIX = 'preferredExtnPrefix'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |     const PREFERRED_INTERNATIONAL_PREFIX = 'preferredInternationalPrefix'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |     const PREMIUM_RATE = 'premiumRate'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |     const SHARED_COST = 'sharedCost'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |     const SHORT_CODE = 'shortCode'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |     const SMS_SERVICES = 'smsServices'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |     const STANDARD_RATE = 'standardRate'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |     const TOLL_FREE = 'tollFree'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |     const UAN = 'uan'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |     const VOICEMAIL = 'voicemail'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |     const VOIP = 'voip'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |     private static $phoneNumberDescsWithoutMatchingTypes = array( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |         self::NO_INTERNATIONAL_DIALLING | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |     ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |      * @internal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |      * @param string $regex | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |      * @param bool $removeWhitespace | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |     public static function validateRE($regex, $removeWhitespace = false) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |         $compressedRegex = $removeWhitespace ? \preg_replace('/\\s/', '', $regex) : $regex; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |         // Match regex against an empty string to check the regex is valid | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |         if (\preg_match('/' . $compressedRegex . '/', '') === false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |             throw new \RuntimeException('Regex error: ' . \preg_last_error()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |         // We don't ever expect to see | followed by a ) in our metadata - this would be an indication | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |         // of a bug. If one wants to make something optional, we prefer ? to using an empty group. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |         $errorIndex = \strpos($compressedRegex, '|)'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |         if ($errorIndex !== false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |             throw new \RuntimeException('| followed by )'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |         // return the regex if it is of correct syntax, i.e. compile did not fail with a | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |         return $compressedRegex; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |      * @param string $inputXmlFile | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |      * @param boolean $liteBuild | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |      * @param boolean $specialBuild | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |      * @param bool $isShortNumberMetadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |      * @param bool $isAlternateFormatsMetadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |      * @return PhoneMetadata[] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |     public static function buildPhoneMetadataCollection($inputXmlFile, $liteBuild, $specialBuild, $isShortNumberMetadata = false, $isAlternateFormatsMetadata = false) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |         if ($inputXmlFile instanceof \DOMElement) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |             $document = $inputXmlFile; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |             $document = new \DOMDocument(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |             $document->load($inputXmlFile); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |             $document->normalizeDocument(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |             $isShortNumberMetadata = \strpos($inputXmlFile, 'ShortNumberMetadata'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |             $isAlternateFormatsMetadata = \strpos($inputXmlFile, 'PhoneNumberAlternateFormats'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |         $territories = $document->getElementsByTagName('territory'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |         $metadataCollection = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |         $metadataFilter = self::getMetadataFilter($liteBuild, $specialBuild); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |         foreach ($territories as $territoryElement) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |             /** @var $territoryElement \DOMElement */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |             // For the main metadata file this should always be set, but for other supplementary data | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |             // files the country calling code may be all that is needed. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |             if ($territoryElement->hasAttribute('id')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |                 $regionCode = $territoryElement->getAttribute('id'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |                 $regionCode = ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |             $metadata = self::loadCountryMetadata($regionCode, $territoryElement, $isShortNumberMetadata, $isAlternateFormatsMetadata); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |             $metadataFilter->filterMetadata($metadata); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |             $metadataCollection[] = $metadata; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |         return $metadataCollection; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |      * @param string $regionCode | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |      * @param \DOMElement $element | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |      * @param string $isShortNumberMetadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |      * @param string $isAlternateFormatsMetadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |      * @return PhoneMetadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |     public static function loadCountryMetadata($regionCode, \DOMElement $element, $isShortNumberMetadata, $isAlternateFormatsMetadata) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |         $nationalPrefix = self::getNationalPrefix($element); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |         $metadata = self::loadTerritoryTagMetadata($regionCode, $element, $nationalPrefix); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |         $nationalPrefixFormattingRule = self::getNationalPrefixFormattingRuleFromElement($element, $nationalPrefix); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |         self::loadAvailableFormats($metadata, $element, $nationalPrefix, $nationalPrefixFormattingRule, $element->hasAttribute(self::NATIONAL_PREFIX_OPTIONAL_WHEN_FORMATTING)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |         if (!$isAlternateFormatsMetadata) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |             // The alternate formats metadata does not need most of the patterns to be set. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |             self::setRelevantDescPatterns($metadata, $element, $isShortNumberMetadata); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |         return $metadata; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |      * Processes the custom build flags and gets a MetadataFilter which may be used to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |      * filter PhoneMetadata objects. Incompatible flag combinations throw RuntimeException. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |      * @param bool $liteBuild | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |      * @param bool $specialBuild | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |      * @return MetadataFilter | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |     public static function getMetadataFilter($liteBuild, $specialBuild) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |         if ($specialBuild) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |             if ($liteBuild) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |                 throw new \RuntimeException('liteBuild and specialBuild may not both be set'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |             return MetadataFilter::forSpecialBuild(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  |         if ($liteBuild) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |             return MetadataFilter::forLiteBuild(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |         return MetadataFilter::emptyFilter(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |      * Returns the national prefix of the provided country element. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  |      * @internal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  |      * @param \DOMElement $element | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  |     public static function getNationalPrefix(\DOMElement $element) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |         return $element->hasAttribute(self::NATIONAL_PREFIX) ? $element->getAttribute(self::NATIONAL_PREFIX) : ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |      * @internal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 |  |  |      * @param \DOMElement $element | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 |  |  |      * @param string $nationalPrefix | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |     public static function getNationalPrefixFormattingRuleFromElement(\DOMElement $element, $nationalPrefix) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 |  |  |         $nationalPrefixFormattingRule = $element->getAttribute(self::NATIONAL_PREFIX_FORMATTING_RULE); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  |         // Replace $NP with national prefix and $FG with the first group ($1). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  |         $nationalPrefixFormattingRule = \str_replace( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  |             array('$NP', '$FG'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 |  |  |             array($nationalPrefix, '$1'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  |             $nationalPrefixFormattingRule | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 |  |  |         return $nationalPrefixFormattingRule; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |      * @internal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  |      * @param string $regionCode | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  |      * @param \DOMElement $element | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |      * @param string $nationalPrefix | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  |      * @return PhoneMetadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  |     public static function loadTerritoryTagMetadata( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  |         $regionCode, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 |  |  |         \DOMElement $element, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 |  |  |         $nationalPrefix | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 |  |  |     ) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  |         $metadata = new PhoneMetadata(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 |  |  |         $metadata->setId($regionCode); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 |  |  |         $metadata->setCountryCode((int)$element->getAttribute(self::COUNTRY_CODE)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 |  |  |         if ($element->hasAttribute(self::LEADING_DIGITS)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 |  |  |             $metadata->setLeadingDigits(self::validateRE($element->getAttribute(self::LEADING_DIGITS))); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 |  |  |         $metadata->setInternationalPrefix(self::validateRE($element->getAttribute(self::INTERNATIONAL_PREFIX))); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 |  |  |         if ($element->hasAttribute(self::PREFERRED_INTERNATIONAL_PREFIX)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 |  |  |             $preferredInternationalPrefix = $element->getAttribute(self::PREFERRED_INTERNATIONAL_PREFIX); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 |  |  |             $metadata->setPreferredInternationalPrefix($preferredInternationalPrefix); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 |  |  |         if ($element->hasAttribute(self::NATIONAL_PREFIX_FOR_PARSING)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 |  |  |             $metadata->setNationalPrefixForParsing( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 |  |  |                 self::validateRE($element->getAttribute(self::NATIONAL_PREFIX_FOR_PARSING), true) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 |  |  |             if ($element->hasAttribute(self::NATIONAL_PREFIX_TRANSFORM_RULE)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 |  |  |                 $metadata->setNationalPrefixTransformRule(self::validateRE($element->getAttribute(self::NATIONAL_PREFIX_TRANSFORM_RULE))); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 |  |  |         if ($nationalPrefix != '') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 |  |  |             $metadata->setNationalPrefix($nationalPrefix); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 |  |  |             if (!$metadata->hasNationalPrefixForParsing()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  |                 $metadata->setNationalPrefixForParsing($nationalPrefix); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 |  |  |         if ($element->hasAttribute(self::PREFERRED_EXTN_PREFIX)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 |  |  |             $metadata->setPreferredExtnPrefix($element->getAttribute(self::PREFERRED_EXTN_PREFIX)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  |         if ($element->hasAttribute(self::MAIN_COUNTRY_FOR_CODE)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 |  |  |             $metadata->setMainCountryForCode(true); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  |         if ($element->hasAttribute(self::MOBILE_NUMBER_PORTABLE_REGION)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 246 |  |  |             $metadata->setMobileNumberPortableRegion(true); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 |  |  |         return $metadata; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 250 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 251 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 252 |  |  |      * Extracts the available formats from the provided DOM element. If it does not contain any | 
            
                                                                                                            
                            
            
                                    
            
            
                | 253 |  |  |      * nationalPrefixFormattingRule, the one passed-in is retained; similarly for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 254 |  |  |      * nationalPrefixOptionalWhenFormatting. The nationalPrefix, nationalPrefixFormattingRule and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 255 |  |  |      * nationalPrefixOptionalWhenFormatting values are provided from the parent (territory) element. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 256 |  |  |      * @internal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 257 |  |  |      * @param PhoneMetadata $metadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 258 |  |  |      * @param \DOMElement $element | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 |  |  |      * @param string $nationalPrefix | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 |  |  |      * @param string $nationalPrefixFormattingRule | 
            
                                                                                                            
                            
            
                                    
            
            
                | 261 |  |  |      * @param bool $nationalPrefixOptionalWhenFormatting | 
            
                                                                                                            
                            
            
                                    
            
            
                | 262 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 263 |  |  |     public static function loadAvailableFormats( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 264 |  |  |         PhoneMetadata $metadata, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 265 |  |  |         \DOMElement $element, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 266 |  |  |         $nationalPrefix, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 267 |  |  |         $nationalPrefixFormattingRule, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 268 |  |  |         $nationalPrefixOptionalWhenFormatting | 
            
                                                                                                            
                            
            
                                    
            
            
                | 269 |  |  |     ) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 270 |  |  |         $carrierCodeFormattingRule = ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 271 |  |  |         if ($element->hasAttribute(self::CARRIER_CODE_FORMATTING_RULE)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 272 |  |  |             $carrierCodeFormattingRule = self::validateRE(self::getDomesticCarrierCodeFormattingRuleFromElement($element, $nationalPrefix)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 273 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 274 |  |  |         $numberFormatElements = $element->getElementsByTagName(self::NUMBER_FORMAT); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 275 |  |  |         $hasExplicitIntlFormatDefined = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 276 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 277 |  |  |         $numOfFormatElements = $numberFormatElements->length; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 278 |  |  |         if ($numOfFormatElements > 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 279 |  |  |             for ($i = 0; $i < $numOfFormatElements; $i++) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 280 |  |  |                 /** @var \DOMElement $numberFormatElement */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 281 |  |  |                 $numberFormatElement = $numberFormatElements->item($i); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 |  |  |                 $format = new NumberFormat(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 283 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 284 |  |  |                 if ($numberFormatElement->hasAttribute(self::NATIONAL_PREFIX_FORMATTING_RULE)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 285 |  |  |                     $format->setNationalPrefixFormattingRule( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 286 |  |  |                         self::getNationalPrefixFormattingRuleFromElement($numberFormatElement, $nationalPrefix) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 287 |  |  |                     ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 288 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 289 |  |  |                     $format->setNationalPrefixFormattingRule($nationalPrefixFormattingRule); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 290 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 291 |  |  |                 if ($numberFormatElement->hasAttribute(self::NATIONAL_PREFIX_OPTIONAL_WHEN_FORMATTING)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 292 |  |  |                     $format->setNationalPrefixOptionalWhenFormatting($numberFormatElement->getAttribute(self::NATIONAL_PREFIX_OPTIONAL_WHEN_FORMATTING) === 'true' ? true : false); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 293 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 294 |  |  |                     $format->setNationalPrefixOptionalWhenFormatting($nationalPrefixOptionalWhenFormatting); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 295 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 296 |  |  |                 if ($numberFormatElement->hasAttribute(self::CARRIER_CODE_FORMATTING_RULE)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 297 |  |  |                     $format->setDomesticCarrierCodeFormattingRule( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 298 |  |  |                         self::validateRE(self::getDomesticCarrierCodeFormattingRuleFromElement($numberFormatElement, $nationalPrefix)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 299 |  |  |                     ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 300 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 301 |  |  |                     $format->setDomesticCarrierCodeFormattingRule($carrierCodeFormattingRule); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 302 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 303 |  |  |                 self::loadNationalFormat($metadata, $numberFormatElement, $format); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 304 |  |  |                 $metadata->addNumberFormat($format); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 305 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 306 |  |  |                 if (self::loadInternationalFormat($metadata, $numberFormatElement, $format)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 307 |  |  |                     $hasExplicitIntlFormatDefined = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 308 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 309 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 310 |  |  |             // Only a small number of regions need to specify the intlFormats in the xml. For the majority | 
            
                                                                                                            
                            
            
                                    
            
            
                | 311 |  |  |             // of countries the intlNumberFormat metadata is an exact copy of the national NumberFormat | 
            
                                                                                                            
                            
            
                                    
            
            
                | 312 |  |  |             // metadata. To minimize the size of the metadata file, we only keep intlNumberFormats that | 
            
                                                                                                            
                            
            
                                    
            
            
                | 313 |  |  |             // actually differ in some way to the national formats. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 314 |  |  |             if (!$hasExplicitIntlFormatDefined) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 315 |  |  |                 $metadata->clearIntlNumberFormat(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 316 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 317 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 318 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 319 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 320 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 321 |  |  |      * @internal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 322 |  |  |      * @param \DOMElement $element | 
            
                                                                                                            
                            
            
                                    
            
            
                | 323 |  |  |      * @param string $nationalPrefix | 
            
                                                                                                            
                            
            
                                    
            
            
                | 324 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 325 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 326 |  |  |     public static function getDomesticCarrierCodeFormattingRuleFromElement(\DOMElement $element, $nationalPrefix) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 327 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 328 |  |  |         $carrierCodeFormattingRule = $element->getAttribute(self::CARRIER_CODE_FORMATTING_RULE); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 329 |  |  |         // Replace $FG with the first group ($1) and $NP with the national prefix. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 330 |  |  |         $carrierCodeFormattingRule = \str_replace( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 331 |  |  |             array('$NP', '$FG'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 332 |  |  |             array($nationalPrefix, '$1'), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 333 |  |  |             $carrierCodeFormattingRule | 
            
                                                                                                            
                            
            
                                    
            
            
                | 334 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 335 |  |  |         return $carrierCodeFormattingRule; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 336 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 337 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 338 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 339 |  |  |      * Extracts the pattern for the national format. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 340 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 341 |  |  |      * @internal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 342 |  |  |      * @param PhoneMetadata $metadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 343 |  |  |      * @param \DOMElement $numberFormatElement | 
            
                                                                                                            
                            
            
                                    
            
            
                | 344 |  |  |      * @param NumberFormat $format | 
            
                                                                                                            
                            
            
                                    
            
            
                | 345 |  |  |      * @throws \RuntimeException if multiple or no formats have been encountered. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 346 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 347 |  |  |     public static function loadNationalFormat( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 348 |  |  |         PhoneMetadata $metadata, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 349 |  |  |         \DOMElement $numberFormatElement, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 350 |  |  |         NumberFormat $format | 
            
                                                                                                            
                            
            
                                    
            
            
                | 351 |  |  |     ) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 352 |  |  |         self::setLeadingDigitsPatterns($numberFormatElement, $format); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 353 |  |  |         $format->setPattern(self::validateRE($numberFormatElement->getAttribute(self::PATTERN))); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 354 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 355 |  |  |         $formatPattern = $numberFormatElement->getElementsByTagName(self::FORMAT); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 356 |  |  |         if ($formatPattern->length != 1) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 357 |  |  |             $countryId = $metadata->getId() != '' ? $metadata->getId() : $metadata->getCountryCode(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 358 |  |  |             throw new \RuntimeException('Invalid number of format patterns for country: ' . $countryId); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 359 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 360 |  |  |         $nationalFormat = $formatPattern->item(0)->firstChild->nodeValue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 361 |  |  |         $format->setFormat($nationalFormat); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 362 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 363 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 364 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 365 |  |  |      * @internal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 366 |  |  |      * @param \DOMElement $numberFormatElement | 
            
                                                                                                            
                            
            
                                    
            
            
                | 367 |  |  |      * @param NumberFormat $format | 
            
                                                                                                            
                            
            
                                    
            
            
                | 368 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 369 |  |  |     public static function setLeadingDigitsPatterns(\DOMElement $numberFormatElement, NumberFormat $format) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 370 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 371 |  |  |         $leadingDigitsPatternNodes = $numberFormatElement->getElementsByTagName(self::LEADING_DIGITS); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 372 |  |  |         $numOfLeadingDigitsPatterns = $leadingDigitsPatternNodes->length; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 373 |  |  |         if ($numOfLeadingDigitsPatterns > 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 374 |  |  |             for ($i = 0; $i < $numOfLeadingDigitsPatterns; $i++) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 375 |  |  |                 $format->addLeadingDigitsPattern(self::validateRE($leadingDigitsPatternNodes->item($i)->firstChild->nodeValue, true)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 376 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 377 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 378 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 379 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 380 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 381 |  |  |      * Extracts the pattern for international format. If there is no intlFormat, default to using the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 382 |  |  |      * national format. If the intlFormat is set to "NA" the intlFormat should be ignored. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 383 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 384 |  |  |      * @internal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 385 |  |  |      * @param PhoneMetadata $metadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 386 |  |  |      * @param \DOMElement $numberFormatElement | 
            
                                                                                                            
                            
            
                                    
            
            
                | 387 |  |  |      * @param NumberFormat $nationalFormat | 
            
                                                                                                            
                            
            
                                    
            
            
                | 388 |  |  |      * @throws \RuntimeException if multiple intlFormats have been encountered. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 389 |  |  |      * @return bool whether an international number format is defined. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 390 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 391 |  |  |     public static function loadInternationalFormat( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 392 |  |  |         PhoneMetadata $metadata, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 393 |  |  |         \DOMElement $numberFormatElement, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 394 |  |  |         NumberFormat $nationalFormat | 
            
                                                                                                            
                            
            
                                    
            
            
                | 395 |  |  |     ) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 396 |  |  |         $intlFormat = new NumberFormat(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 397 |  |  |         $intlFormatPattern = $numberFormatElement->getElementsByTagName(self::INTL_FORMAT); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 398 |  |  |         $hasExplicitIntlFormatDefined = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 399 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 400 |  |  |         if ($intlFormatPattern->length > 1) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 401 |  |  |             $countryId = $metadata->getId() != '' ? $metadata->getId() : $metadata->getCountryCode(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 402 |  |  |             throw new \RuntimeException('Invalid number of intlFormat patterns for country: ' . $countryId); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 403 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 404 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 405 |  |  |         if ($intlFormatPattern->length === 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 406 |  |  |             // Default to use the same as the national pattern if none is defined. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 407 |  |  |             $intlFormat->mergeFrom($nationalFormat); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 408 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 409 |  |  |             $intlFormat->setPattern($numberFormatElement->getAttribute(self::PATTERN)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 410 |  |  |             self::setLeadingDigitsPatterns($numberFormatElement, $intlFormat); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 411 |  |  |             $intlFormatPatternValue = $intlFormatPattern->item(0)->firstChild->nodeValue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 412 |  |  |             if ($intlFormatPatternValue !== 'NA') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 413 |  |  |                 $intlFormat->setFormat($intlFormatPatternValue); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 414 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 415 |  |  |             $hasExplicitIntlFormatDefined = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 416 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 417 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 418 |  |  |         if ($intlFormat->hasFormat()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 419 |  |  |             $metadata->addIntlNumberFormat($intlFormat); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 420 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 421 |  |  |         return $hasExplicitIntlFormatDefined; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 422 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 423 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 424 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 425 |  |  |      * @internal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 426 |  |  |      * @param PhoneMetadata $metadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 427 |  |  |      * @param \DOMElement $element | 
            
                                                                                                            
                            
            
                                    
            
            
                | 428 |  |  |      * @param bool $isShortNumberMetadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 429 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 430 |  |  |     public static function setRelevantDescPatterns(PhoneMetadata $metadata, \DOMElement $element, $isShortNumberMetadata) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 431 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 432 |  |  |         $generalDesc = self::processPhoneNumberDescElement(null, $element, self::GENERAL_DESC); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 433 |  |  |         $metadata->setGeneralDesc($generalDesc); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 434 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 435 |  |  |         $metadataId = $metadata->getId(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 436 |  |  |         // Calculate the possible lengths for the general description. This will be based on the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 437 |  |  |         // possible lengths of the child elements. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 438 |  |  |         self::setPossibleLengthsGeneralDesc($generalDesc, $metadataId, $element, $isShortNumberMetadata); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 439 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 440 |  |  |         if (!$isShortNumberMetadata) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 441 |  |  |             // Set fields used by regular length phone numbers. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 442 |  |  |             $metadata->setFixedLine(self::processPhoneNumberDescElement($generalDesc, $element, self::FIXED_LINE)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 443 |  |  |             $metadata->setMobile(self::processPhoneNumberDescElement($generalDesc, $element, self::MOBILE)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 444 |  |  |             $metadata->setSharedCost(self::processPhoneNumberDescElement($generalDesc, $element, self::SHARED_COST)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 445 |  |  |             $metadata->setVoip(self::processPhoneNumberDescElement($generalDesc, $element, self::VOIP)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 446 |  |  |             $metadata->setPersonalNumber(self::processPhoneNumberDescElement($generalDesc, $element, self::PERSONAL_NUMBER)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 447 |  |  |             $metadata->setPager(self::processPhoneNumberDescElement($generalDesc, $element, self::PAGER)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 448 |  |  |             $metadata->setUan(self::processPhoneNumberDescElement($generalDesc, $element, self::UAN)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 449 |  |  |             $metadata->setVoicemail(self::processPhoneNumberDescElement($generalDesc, $element, self::VOICEMAIL)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 450 |  |  |             $metadata->setNoInternationalDialling(self::processPhoneNumberDescElement($generalDesc, $element, self::NO_INTERNATIONAL_DIALLING)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 451 |  |  |             $metadata->setSameMobileAndFixedLinePattern($metadata->getMobile()->getNationalNumberPattern() === $metadata->getFixedLine()->getNationalNumberPattern()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 452 |  |  |             $metadata->setTollFree(self::processPhoneNumberDescElement($generalDesc, $element, self::TOLL_FREE)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 453 |  |  |             $metadata->setPremiumRate(self::processPhoneNumberDescElement($generalDesc, $element, self::PREMIUM_RATE)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 454 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 455 |  |  |             // Set fields used by short numbers. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 456 |  |  |             $metadata->setStandardRate(self::processPhoneNumberDescElement($generalDesc, $element, self::STANDARD_RATE)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 457 |  |  |             $metadata->setShortCode(self::processPhoneNumberDescElement($generalDesc, $element, self::SHORT_CODE)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 458 |  |  |             $metadata->setCarrierSpecific(self::processPhoneNumberDescElement($generalDesc, $element, self::CARRIER_SPECIFIC)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 459 |  |  |             $metadata->setEmergency(self::processPhoneNumberDescElement($generalDesc, $element, self::EMERGENCY)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 460 |  |  |             $metadata->setTollFree(self::processPhoneNumberDescElement($generalDesc, $element, self::TOLL_FREE)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 461 |  |  |             $metadata->setPremiumRate(self::processPhoneNumberDescElement($generalDesc, $element, self::PREMIUM_RATE)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 462 |  |  |             $metadata->setSmsServices(self::processPhoneNumberDescElement($generalDesc, $element, self::SMS_SERVICES)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 463 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 464 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 465 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 466 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 467 |  |  |      * Parses a possible length string into a set of the integers that are covered. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 468 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 469 |  |  |      * @param string $possibleLengthString a string specifying the possible lengths of phone numbers. Follows | 
            
                                                                                                            
                            
            
                                    
            
            
                | 470 |  |  |      * this syntax: ranges or elements are separated by commas, and ranges are specified in | 
            
                                                                                                            
                            
            
                                    
            
            
                | 471 |  |  |      * [min-max] notation, inclusive. For example, [3-5],7,9,[11-14] should be parsed to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 472 |  |  |      * 3,4,5,7,9,11,12,13,14 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 473 |  |  |      * @return array | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 474 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 475 |  |  |     private static function parsePossibleLengthStringToSet($possibleLengthString) | 
            
                                                                        
                            
            
                                    
            
            
                | 476 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 477 |  |  |         if (\strlen($possibleLengthString) === 0) { | 
            
                                                                        
                            
            
                                    
            
            
                | 478 |  |  |             throw new \RuntimeException('Empty possibleLength string found.'); | 
            
                                                                        
                            
            
                                    
            
            
                | 479 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 480 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 481 |  |  |         $lengths = \explode(',', $possibleLengthString); | 
            
                                                                        
                            
            
                                    
            
            
                | 482 |  |  |         $lengthSet = array(); | 
            
                                                                        
                            
            
                                    
            
            
                | 483 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 484 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 485 |  |  |         $lengthLength = \count($lengths); | 
            
                                                                        
                            
            
                                    
            
            
                | 486 |  |  |         for ($i = 0; $i < $lengthLength; $i++) { | 
            
                                                                        
                            
            
                                    
            
            
                | 487 |  |  |             $lengthSubstring = $lengths[$i]; | 
            
                                                                        
                            
            
                                    
            
            
                | 488 |  |  |             if (\strlen($lengthSubstring) === 0) { | 
            
                                                                        
                            
            
                                    
            
            
                | 489 |  |  |                 throw new \RuntimeException('Leading, trailing or adjacent commas in possible ' | 
            
                                                                        
                            
            
                                    
            
            
                | 490 |  |  |                     . "length string {$possibleLengthString}, these should only separate numbers or ranges."); | 
            
                                                                        
                            
            
                                    
            
            
                | 491 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 492 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 493 |  |  |             if (\substr($lengthSubstring, 0, 1) === '[') { | 
            
                                                                        
                            
            
                                    
            
            
                | 494 |  |  |                 if (\substr($lengthSubstring, -1) !== ']') { | 
            
                                                                        
                            
            
                                    
            
            
                | 495 |  |  |                     throw new \RuntimeException("Missing end of range character in possible length string {$possibleLengthString}."); | 
            
                                                                        
                            
            
                                    
            
            
                | 496 |  |  |                 } | 
            
                                                                        
                            
            
                                    
            
            
                | 497 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 498 |  |  |                 // Strip the leading and trailing [], and split on the -. | 
            
                                                                        
                            
            
                                    
            
            
                | 499 |  |  |                 $minMax = \explode('-', \substr($lengthSubstring, 1, -1)); | 
            
                                                                        
                            
            
                                    
            
            
                | 500 |  |  |                 if (\count($minMax) !== 2) { | 
            
                                                                        
                            
            
                                    
            
            
                | 501 |  |  |                     throw new \RuntimeException("Ranges must have exactly one - character: missing for {$possibleLengthString}."); | 
            
                                                                        
                            
            
                                    
            
            
                | 502 |  |  |                 } | 
            
                                                                        
                            
            
                                    
            
            
                | 503 |  |  |                 $min = (int)$minMax[0]; | 
            
                                                                        
                            
            
                                    
            
            
                | 504 |  |  |                 $max = (int)$minMax[1]; | 
            
                                                                        
                            
            
                                    
            
            
                | 505 |  |  |                 // We don't even accept [6-7] since we prefer the shorter 6,7 variant; for a range to be in | 
            
                                                                        
                            
            
                                    
            
            
                | 506 |  |  |                 // use the hyphen needs to replace at least one digit. | 
            
                                                                        
                            
            
                                    
            
            
                | 507 |  |  |                 if ($max - $min < 2) { | 
            
                                                                        
                            
            
                                    
            
            
                | 508 |  |  |                     throw new \RuntimeException("The first number in a range should be two or more digits lower than the second. Culprit possibleLength string: {$possibleLengthString}."); | 
            
                                                                        
                            
            
                                    
            
            
                | 509 |  |  |                 } | 
            
                                                                        
                            
            
                                    
            
            
                | 510 |  |  |                 for ($j = $min; $j <= $max; $j++) { | 
            
                                                                        
                            
            
                                    
            
            
                | 511 |  |  |                     if (\in_array($j, $lengthSet)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 512 |  |  |                         throw new \RuntimeException("Duplicate length element found ({$j}) in possibleLength string {$possibleLengthString}."); | 
            
                                                                        
                            
            
                                    
            
            
                | 513 |  |  |                     } | 
            
                                                                        
                            
            
                                    
            
            
                | 514 |  |  |                     $lengthSet[] = $j; | 
            
                                                                        
                            
            
                                    
            
            
                | 515 |  |  |                 } | 
            
                                                                        
                            
            
                                    
            
            
                | 516 |  |  |             } else { | 
            
                                                                        
                            
            
                                    
            
            
                | 517 |  |  |                 $length = $lengthSubstring; | 
            
                                                                        
                            
            
                                    
            
            
                | 518 |  |  |                 if (\in_array($length, $lengthSet)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 519 |  |  |                     throw new \RuntimeException("Duplicate length element found ({$length}) in possibleLength string {$possibleLengthString}."); | 
            
                                                                        
                            
            
                                    
            
            
                | 520 |  |  |                 } | 
            
                                                                        
                            
            
                                    
            
            
                | 521 |  |  |                 if (!\is_numeric($length)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 522 |  |  |                     throw new \RuntimeException("For input string \"{$length}\""); | 
            
                                                                        
                            
            
                                    
            
            
                | 523 |  |  |                 } | 
            
                                                                        
                            
            
                                    
            
            
                | 524 |  |  |                 $lengthSet[] = (int)$length; | 
            
                                                                        
                            
            
                                    
            
            
                | 525 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 526 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 527 |  |  |         return $lengthSet; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 528 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 529 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 530 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 531 |  |  |      * Reads the possible length present in the metadata and splits them into two sets: one for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 532 |  |  |      * full-length numbers, one for local numbers. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 533 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 534 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 535 |  |  |      * @param \DOMElement $data One or more phone number descriptions | 
            
                                                                                                            
                            
            
                                    
            
            
                | 536 |  |  |      * @param array $lengths An array in which to add possible lengths of full phone numbers | 
            
                                                                                                            
                            
            
                                    
            
            
                | 537 |  |  |      * @param array $localOnlyLengths An array in which to add possible lengths of phone numbers only diallable | 
            
                                                                                                            
                            
            
                                    
            
            
                | 538 |  |  |      *  locally (e.g. within a province) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 539 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 540 |  |  |     private static function populatePossibleLengthSets(\DOMElement $data, &$lengths, &$localOnlyLengths) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 541 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 542 |  |  |         $possibleLengths = $data->getElementsByTagName(self::POSSIBLE_LENGTHS); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 543 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 544 |  |  |         for ($i = 0; $i < $possibleLengths->length; $i++) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 545 |  |  |             /** @var \DOMElement $element */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 546 |  |  |             $element = $possibleLengths->item($i); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 547 |  |  |             $nationalLengths = $element->getAttribute(self::NATIONAL); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 548 |  |  |             // We don't add to the phone metadata yet, since we want to sort length elements found under | 
            
                                                                                                            
                            
            
                                    
            
            
                | 549 |  |  |             // different nodes first, make sure there are no duplicates between them and that the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 550 |  |  |             // localOnly lengths don't overlap with the others. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 551 |  |  |             $thisElementLengths = self::parsePossibleLengthStringToSet($nationalLengths); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 552 |  |  |             if ($element->hasAttribute(self::LOCAL_ONLY)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 553 |  |  |                 $localLengths = $element->getAttribute(self::LOCAL_ONLY); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 554 |  |  |                 $thisElementLocalOnlyLengths = self::parsePossibleLengthStringToSet($localLengths); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 555 |  |  |                 $intersection = \array_intersect($thisElementLengths, $thisElementLocalOnlyLengths); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 556 |  |  |                 if (\count($intersection) > 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 557 |  |  |                     throw new \RuntimeException('Possible length(s) found specified as a normal and local-only length: [' . \implode(',', $intersection) . '].'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 558 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 559 |  |  |                 // We check again when we set these lengths on the metadata itself in setPossibleLengths | 
            
                                                                                                            
                            
            
                                    
            
            
                | 560 |  |  |                 // that the elements in localOnly are not also in lengths. For e.g. the generalDesc, it | 
            
                                                                                                            
                            
            
                                    
            
            
                | 561 |  |  |                 // might have a local-only length for one type that is a normal length for another type. We | 
            
                                                                                                            
                            
            
                                    
            
            
                | 562 |  |  |                 // don't consider this an error, but we do want to remove the local-only lengths. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 563 |  |  |                 $localOnlyLengths = \array_merge($localOnlyLengths, $thisElementLocalOnlyLengths); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 564 |  |  |                 \sort($localOnlyLengths); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 565 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 566 |  |  |             // It is okay if at this time we have duplicates, because the same length might be possible | 
            
                                                                                                            
                            
            
                                    
            
            
                | 567 |  |  |             // for e.g. fixed-line and for mobile numbers, and this method operates potentially on | 
            
                                                                                                            
                            
            
                                    
            
            
                | 568 |  |  |             // multiple phoneNumberDesc XML elements. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 569 |  |  |             $lengths = \array_merge($lengths, $thisElementLengths); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 570 |  |  |             \sort($lengths); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 571 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 572 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 573 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 574 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 575 |  |  |      * Sets possible lengths in the general description, derived from certain child elements | 
            
                                                                                                            
                            
            
                                    
            
            
                | 576 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 577 |  |  |      * @internal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 578 |  |  |      * @param PhoneNumberDesc $generalDesc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 579 |  |  |      * @param string $metadataId | 
            
                                                                                                            
                            
            
                                    
            
            
                | 580 |  |  |      * @param \DOMElement $data | 
            
                                                                                                            
                            
            
                                    
            
            
                | 581 |  |  |      * @param bool $isShortNumberMetadata | 
            
                                                                                                            
                            
            
                                    
            
            
                | 582 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 583 |  |  |     public static function setPossibleLengthsGeneralDesc(PhoneNumberDesc $generalDesc, $metadataId, \DOMElement $data, $isShortNumberMetadata) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 584 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 585 |  |  |         $lengths = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 586 |  |  |         $localOnlyLengths = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 587 |  |  |         // The general description node should *always* be present if metadata for other types is | 
            
                                                                                                            
                            
            
                                    
            
            
                | 588 |  |  |         // present, aside from in some unit tests. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 589 |  |  |         // (However, for e.g. formatting metadata in PhoneNumberAlternateFormats, no PhoneNumberDesc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 590 |  |  |         // elements are present). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 591 |  |  |         $generalDescNodes = $data->getElementsByTagName(self::GENERAL_DESC); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 592 |  |  |         if ($generalDescNodes->length > 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 593 |  |  |             $generalDescNode = $generalDescNodes->item(0); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 594 |  |  |             self::populatePossibleLengthSets($generalDescNode, $lengths, $localOnlyLengths); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 595 |  |  |             if (\count($lengths) > 0 || \count($localOnlyLengths) > 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 596 |  |  |                 // We shouldn't have anything specified at the "general desc" level: we are going to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 597 |  |  |                 // calculate this ourselves from child elements. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 598 |  |  |                 throw new \RuntimeException("Found possible lengths specified at general desc: this should be derived from child elements. Affected country: {$metadataId}"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 599 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 600 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 601 |  |  |         if (!$isShortNumberMetadata) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 602 |  |  |             // Make a copy here since we want to remove some nodes, but we don't want to do that on our | 
            
                                                                                                            
                            
            
                                    
            
            
                | 603 |  |  |             // actual data. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 604 |  |  |             /** @var \DOMElement $allDescData */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 605 |  |  |             $allDescData = $data->cloneNode(true); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 606 |  |  |             foreach (self::$phoneNumberDescsWithoutMatchingTypes as $tag) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 607 |  |  |                 $nodesToRemove = $allDescData->getElementsByTagName($tag); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 608 |  |  |                 if ($nodesToRemove->length > 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 609 |  |  |                     // We check when we process phone number descriptions that there are only one of each | 
            
                                                                                                            
                            
            
                                    
            
            
                | 610 |  |  |                     // type, so this is safe to do. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 611 |  |  |                     $allDescData->removeChild($nodesToRemove->item(0)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 612 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 613 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 614 |  |  |             self::populatePossibleLengthSets($allDescData, $lengths, $localOnlyLengths); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 615 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 616 |  |  |             // For short number metadata, we want to copy the lengths from the "short code" section only. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 617 |  |  |             // This is because it's the more detailed validation pattern, it's not a sub-type of short | 
            
                                                                                                            
                            
            
                                    
            
            
                | 618 |  |  |             // codes. The other lengths will be checked later to see that they are a sub-set of these | 
            
                                                                                                            
                            
            
                                    
            
            
                | 619 |  |  |             // possible lengths. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 620 |  |  |             $shortCodeDescList = $data->getElementsByTagName(self::SHORT_CODE); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 621 |  |  |             if (\count($shortCodeDescList) > 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 622 |  |  |                 $shortCodeDesc = $shortCodeDescList->item(0); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 623 |  |  |                 self::populatePossibleLengthSets($shortCodeDesc, $lengths, $localOnlyLengths); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 624 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 625 |  |  |             if (\count($localOnlyLengths) > 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 626 |  |  |                 throw new \RuntimeException('Found local-only lengths in short-number metadata'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 627 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 628 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 629 |  |  |         self::setPossibleLengths($lengths, $localOnlyLengths, null, $generalDesc); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 630 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 631 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 632 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 633 |  |  |      * Sets the possible length fields in the metadata from the sets of data passed in. Checks that | 
            
                                                                                                            
                            
            
                                    
            
            
                | 634 |  |  |      * the length is covered by the "parent" phone number description element if one is present, and | 
            
                                                                                                            
                            
            
                                    
            
            
                | 635 |  |  |      * if the lengths are exactly the same as this, they are not filled in for efficiency reasons. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 636 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 637 |  |  |      * @param array $lengths | 
            
                                                                                                            
                            
            
                                    
            
            
                | 638 |  |  |      * @param array $localOnlyLengths | 
            
                                                                                                            
                            
            
                                    
            
            
                | 639 |  |  |      * @param PhoneNumberDesc $parentDesc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 640 |  |  |      * @param PhoneNumberDesc $desc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 641 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 642 |  |  |     private static function setPossibleLengths($lengths, $localOnlyLengths, PhoneNumberDesc $parentDesc = null, PhoneNumberDesc $desc) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 643 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 644 |  |  |         // We clear these fields since the metadata tends to inherit from the parent element for other | 
            
                                                                                                            
                            
            
                                    
            
            
                | 645 |  |  |         // fields (via a mergeFrom). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 646 |  |  |         $desc->clearPossibleLength(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 647 |  |  |         $desc->clearPossibleLengthLocalOnly(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 648 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 649 |  |  |         // Only add the lengths to this sub-type if they aren't exactly the same as the possible | 
            
                                                                                                            
                            
            
                                    
            
            
                | 650 |  |  |         // lengths in the general desc (for metadata size reasons). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 651 |  |  |         if ($parentDesc === null || !self::arePossibleLengthsEqual($lengths, $parentDesc)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 652 |  |  |             foreach ($lengths as $length) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 653 |  |  |                 if ($parentDesc === null || \in_array($length, $parentDesc->getPossibleLength())) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 654 |  |  |                     $desc->addPossibleLength($length); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 655 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 656 |  |  |                     // We shouldn't have possible lengths defined in a child element that are not covered by | 
            
                                                                                                            
                            
            
                                    
            
            
                | 657 |  |  |                     // the general description. We check this here even though the general description is | 
            
                                                                                                            
                            
            
                                    
            
            
                | 658 |  |  |                     // derived from child elements because it is only derived from a subset, and we need to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 659 |  |  |                     // ensure *all* child elements have a valid possible length. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 660 |  |  |                     throw new \RuntimeException("Out-of-range possible length found ({$length}), parent lengths " . \implode(',', $parentDesc->getPossibleLength())); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 661 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 662 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 663 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 664 |  |  |         // We check that the local-only length isn't also a normal possible length (only relevant for | 
            
                                                                                                            
                            
            
                                    
            
            
                | 665 |  |  |         // the general-desc, since within elements such as fixed-line we would throw an exception if we | 
            
                                                                                                            
                            
            
                                    
            
            
                | 666 |  |  |         // saw this) before adding it to the collection of possible local-only lengths. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 667 |  |  |         foreach ($localOnlyLengths as $length) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 668 |  |  |             if (!\in_array($length, $lengths)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 669 |  |  |                 // We check it is covered by either of the possible length sets of the parent | 
            
                                                                                                            
                            
            
                                    
            
            
                | 670 |  |  |                 // PhoneNumberDesc, because for example 7 might be a valid localOnly length for mobile, but | 
            
                                                                                                            
                            
            
                                    
            
            
                | 671 |  |  |                 // a valid national length for fixedLine, so the generalDesc would have the 7 removed from | 
            
                                                                                                            
                            
            
                                    
            
            
                | 672 |  |  |                 // localOnly. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 673 |  |  |                 if ($parentDesc === null | 
            
                                                                                                            
                            
            
                                    
            
            
                | 674 |  |  |                     || \in_array($length, $parentDesc->getPossibleLength()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 675 |  |  |                     || \in_array($length, $parentDesc->getPossibleLengthLocalOnly()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 676 |  |  |                 ) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 677 |  |  |                     $desc->addPossibleLengthLocalOnly($length); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 678 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 679 |  |  |                     throw new \RuntimeException("Out-of-range local-only possible length found ({$length}), parent length {$parentDesc->getPossibleLengthLocalOnly()}"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 680 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 681 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 682 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 683 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 684 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 685 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 686 |  |  |      * Processes a phone number description element from the XML file and returns it as a | 
            
                                                                                                            
                            
            
                                    
            
            
                | 687 |  |  |      * PhoneNumberDesc. If the description element is a fixed line or mobile number, the parent | 
            
                                                                                                            
                            
            
                                    
            
            
                | 688 |  |  |      * description will be used to fill in the whole element if necessary, or any components that are | 
            
                                                                                                            
                            
            
                                    
            
            
                | 689 |  |  |      * missing. For all other types, the parent description will only be used to fill in missing | 
            
                                                                                                            
                            
            
                                    
            
            
                | 690 |  |  |      * components if the type has a partial definition. For example, if no "tollFree" element exists, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 691 |  |  |      * we assume there are no toll free numbers for that locale, and return a phone number description | 
            
                                                                                                            
                            
            
                                    
            
            
                | 692 |  |  |      * with no national number data and [-1] for this possible lengths. Note that the parent | 
            
                                                                                                            
                            
            
                                    
            
            
                | 693 |  |  |      * description must therefore already be processed before this method is called on any child | 
            
                                                                                                            
                            
            
                                    
            
            
                | 694 |  |  |      * elements. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 695 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 696 |  |  |      * @internal | 
            
                                                                                                            
                            
            
                                    
            
            
                | 697 |  |  |      * @param PhoneNumberDesc $parentDesc a generic phone number description that will be used to fill in missing | 
            
                                                                                                            
                            
            
                                    
            
            
                | 698 |  |  |      *     parts of the description, or null if this is the root node. This must be processed before | 
            
                                                                                                            
                            
            
                                    
            
            
                | 699 |  |  |      *     this is run on any child elements. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 700 |  |  |      * @param \DOMElement $countryElement XML element representing all the country information | 
            
                                                                                                            
                            
            
                                    
            
            
                | 701 |  |  |      * @param string $numberType name of the number type, corresponding to the appropriate tag in the XML | 
            
                                                                                                            
                            
            
                                    
            
            
                | 702 |  |  |      * file with information about that type | 
            
                                                                                                            
                            
            
                                    
            
            
                | 703 |  |  |      * @return PhoneNumberDesc complete description of that phone number type | 
            
                                                                                                            
                            
            
                                    
            
            
                | 704 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 705 |  |  |     public static function processPhoneNumberDescElement( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 706 |  |  |         PhoneNumberDesc $parentDesc = null, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 707 |  |  |         \DOMElement $countryElement, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 708 |  |  |         $numberType | 
            
                                                                                                            
                            
            
                                    
            
            
                | 709 |  |  |     ) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 710 |  |  |         $phoneNumberDescList = $countryElement->getElementsByTagName($numberType); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 711 |  |  |         $numberDesc = new PhoneNumberDesc(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 712 |  |  |         if ($phoneNumberDescList->length == 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 713 |  |  |             // -1 will never match a possible phone number length, so is safe to use to ensure this never | 
            
                                                                                                            
                            
            
                                    
            
            
                | 714 |  |  |             // matches. We don't leave it empty, since for compression reasons, we use the empty list to | 
            
                                                                                                            
                            
            
                                    
            
            
                | 715 |  |  |             // mean that the generalDesc possible lengths apply. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 716 |  |  |             $numberDesc->setPossibleLength(array(-1)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 717 |  |  |             return $numberDesc; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 718 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 719 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 720 |  |  |         if ($parentDesc != null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 721 |  |  |             if ($parentDesc->getNationalNumberPattern() !== '') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 722 |  |  |                 $numberDesc->setNationalNumberPattern($parentDesc->getNationalNumberPattern()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 723 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 724 |  |  |             if ($parentDesc->getExampleNumber() !== '') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 725 |  |  |                 $numberDesc->setExampleNumber($parentDesc->getExampleNumber()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 726 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 727 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 728 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 729 |  |  |         if ($phoneNumberDescList->length > 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 730 |  |  |             if ($phoneNumberDescList->length > 1) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 731 |  |  |                 throw new \RuntimeException("Multiple elements with type {$numberType} found."); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 732 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 733 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 734 |  |  |             /** @var \DOMElement $element */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 735 |  |  |             $element = $phoneNumberDescList->item(0); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 736 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 737 |  |  |             if ($parentDesc != null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 738 |  |  |                 // New way of handling possible number lengths. We don't do this for the general | 
            
                                                                                                            
                            
            
                                    
            
            
                | 739 |  |  |                 // description, since these tags won't be present; instead we will calculate its values | 
            
                                                                                                            
                            
            
                                    
            
            
                | 740 |  |  |                 // based on the values for all the other number type descriptions (see | 
            
                                                                                                            
                            
            
                                    
            
            
                | 741 |  |  |                 // setPossibleLengthsGeneralDesc). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 742 |  |  |                 $lengths = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 743 |  |  |                 $localOnlyLengths = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 744 |  |  |                 self::populatePossibleLengthSets($element, $lengths, $localOnlyLengths); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 745 |  |  |                 self::setPossibleLengths($lengths, $localOnlyLengths, $parentDesc, $numberDesc); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 746 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 747 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 748 |  |  |             $validPattern = $element->getElementsByTagName(self::NATIONAL_NUMBER_PATTERN); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 749 |  |  |             if ($validPattern->length > 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 750 |  |  |                 $numberDesc->setNationalNumberPattern(self::validateRE($validPattern->item(0)->firstChild->nodeValue, true)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 751 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 752 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 753 |  |  |             $exampleNumber = $element->getElementsByTagName(self::EXAMPLE_NUMBER); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 754 |  |  |             if ($exampleNumber->length > 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 755 |  |  |                 $numberDesc->setExampleNumber($exampleNumber->item(0)->firstChild->nodeValue); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 756 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 757 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 758 |  |  |         return $numberDesc; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 759 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 760 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 761 |  |  |     private static function arePossibleLengthsEqual($possibleLengths, PhoneNumberDesc $desc) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 762 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 763 |  |  |         $descPossibleLength = $desc->getPossibleLength(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 764 |  |  |         if (\count($possibleLengths) != \count($descPossibleLength)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 765 |  |  |             return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 766 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 767 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 768 |  |  |         // Note that both should be sorted already, and we know they are the same length. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 769 |  |  |         $i = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 770 |  |  |         foreach ($possibleLengths as $length) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 771 |  |  |             if ($length != $descPossibleLength[$i]) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 772 |  |  |                 return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 773 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 774 |  |  |             $i++; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 775 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 776 |  |  |         return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 777 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 778 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 779 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 780 |  |  |      * @param PhoneMetadata[] $metadataCollection | 
            
                                                                                                            
                            
            
                                    
            
            
                | 781 |  |  |      * @return array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 782 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 783 |  |  |     public static function buildCountryCodeToRegionCodeMap($metadataCollection) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 784 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 785 |  |  |         $countryCodeToRegionCodeMap = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 786 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 787 |  |  |         foreach ($metadataCollection as $metadata) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 788 |  |  |             $regionCode = $metadata->getId(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 789 |  |  |             $countryCode = $metadata->getCountryCode(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 790 |  |  |             if (\array_key_exists($countryCode, $countryCodeToRegionCodeMap)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 791 |  |  |                 if ($metadata->getMainCountryForCode()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 792 |  |  |                     \array_unshift($countryCodeToRegionCodeMap[$countryCode], $regionCode); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 793 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 794 |  |  |                     $countryCodeToRegionCodeMap[$countryCode][] = $regionCode; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 795 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 796 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 797 |  |  |                 // For most countries, there will be only one region code for the country calling code. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 798 |  |  |                 $listWithRegionCode = array(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 799 |  |  |                 if ($regionCode != '') { // For alternate formats, there are no region codes at all. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 800 |  |  |                     $listWithRegionCode[] = $regionCode; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 801 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 802 |  |  |                 $countryCodeToRegionCodeMap[$countryCode] = $listWithRegionCode; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 803 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 804 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 805 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 806 |  |  |         return $countryCodeToRegionCodeMap; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 807 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 808 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 809 |  |  |  |