@@ -56,11 +56,14 @@ class RegionDataGenerator extends AbstractDataGenerator
56
56
'QO ' => true , // Outlying Oceania
57
57
'XA ' => true , // Pseudo-Accents
58
58
'XB ' => true , // Pseudo-Bidi
59
- 'XK ' => true , // Kosovo
60
59
// Misc
61
60
'ZZ ' => true , // Unknown Region
62
61
];
63
62
63
+ private const USER_ASSIGNED = [
64
+ 'XK ' => true , // Kosovo
65
+ ];
66
+
64
67
// @see https://en.wikipedia.org/wiki/ISO_3166-1_numeric#Withdrawn_codes
65
68
private const WITHDRAWN_CODES = [
66
69
128 , // Canton and Enderbury Islands
@@ -97,7 +100,7 @@ class RegionDataGenerator extends AbstractDataGenerator
97
100
98
101
public static function isValidCountryCode (int |string |null $ region ): bool
99
102
{
100
- if (isset (self ::DENYLIST [$ region ])) {
103
+ if (isset (self ::DENYLIST [$ region ]) || isset ( self :: USER_ASSIGNED [ $ region ]) ) {
101
104
return false ;
102
105
}
103
106
@@ -109,6 +112,11 @@ public static function isValidCountryCode(int|string|null $region): bool
109
112
return true ;
110
113
}
111
114
115
+ public static function isUserAssignedCountryCode (int |string |null $ region ): bool
116
+ {
117
+ return isset (self ::USER_ASSIGNED [$ region ]);
118
+ }
119
+
112
120
protected function scanLocales (LocaleScanner $ scanner , string $ sourceDir ): array
113
121
{
114
122
return $ scanner ->scanLocales ($ sourceDir .'/region ' );
@@ -131,9 +139,7 @@ protected function generateDataForLocale(BundleEntryReaderInterface $reader, str
131
139
132
140
// isset() on \ResourceBundle returns true even if the value is null
133
141
if (isset ($ localeBundle ['Countries ' ]) && null !== $ localeBundle ['Countries ' ]) {
134
- $ data = [
135
- 'Names ' => $ this ->generateRegionNames ($ localeBundle ),
136
- ];
142
+ $ data = $ this ->generateRegionNames ($ localeBundle );
137
143
138
144
$ this ->regionCodes = array_merge ($ this ->regionCodes , array_keys ($ data ['Names ' ]));
139
145
@@ -153,23 +159,39 @@ protected function generateDataForMeta(BundleEntryReaderInterface $reader, strin
153
159
$ metadataBundle = $ reader ->read ($ tempDir , 'metadata ' );
154
160
155
161
$ this ->regionCodes = array_unique ($ this ->regionCodes );
156
-
157
162
sort ($ this ->regionCodes );
158
163
159
164
$ alpha2ToAlpha3 = $ this ->generateAlpha2ToAlpha3Mapping (array_flip ($ this ->regionCodes ), $ metadataBundle );
165
+ $ userAssignedAlpha2ToAlpha3 = $ this ->generateAlpha2ToAlpha3Mapping (self ::USER_ASSIGNED , $ metadataBundle );
166
+
160
167
$ alpha3ToAlpha2 = array_flip ($ alpha2ToAlpha3 );
161
168
asort ($ alpha3ToAlpha2 );
169
+ $ userAssignedAlpha3toAlpha2 = array_flip ($ userAssignedAlpha2ToAlpha3 );
170
+ asort ($ userAssignedAlpha3toAlpha2 );
162
171
163
172
$ alpha2ToNumeric = $ this ->generateAlpha2ToNumericMapping (array_flip ($ this ->regionCodes ), $ metadataBundle );
173
+ $ userAssignedAlpha2ToNumeric = $ this ->generateAlpha2ToNumericMapping (self ::USER_ASSIGNED , $ metadataBundle );
174
+
164
175
$ numericToAlpha2 = [];
165
176
foreach ($ alpha2ToNumeric as $ alpha2 => $ numeric ) {
166
177
// Add underscore prefix to force keys with leading zeros to remain as string keys.
167
178
$ numericToAlpha2 ['_ ' .$ numeric ] = $ alpha2 ;
168
179
}
180
+ $ userAssignedNumericToAlpha2 = [];
181
+ foreach ($ userAssignedAlpha2ToNumeric as $ alpha2 => $ numeric ) {
182
+ // Add underscore prefix to force keys with leading zeros to remain as string keys.
183
+ $ userAssignedNumericToAlpha2 ['_ ' .$ numeric ] = $ alpha2 ;
184
+ }
169
185
170
186
asort ($ numericToAlpha2 );
187
+ asort ($ userAssignedNumericToAlpha2 );
171
188
172
189
return [
190
+ 'UserAssignedRegions ' => array_keys (self ::USER_ASSIGNED ),
191
+ 'UserAssignedAlpha2ToAlpha3 ' => $ userAssignedAlpha2ToAlpha3 ,
192
+ 'UserAssignedAlpha3ToAlpha2 ' => $ userAssignedAlpha3toAlpha2 ,
193
+ 'UserAssignedAlpha2ToNumeric ' => $ userAssignedAlpha2ToNumeric ,
194
+ 'UserAssignedNumericToAlpha2 ' => $ userAssignedNumericToAlpha2 ,
173
195
'Regions ' => $ this ->regionCodes ,
174
196
'Alpha2ToAlpha3 ' => $ alpha2ToAlpha3 ,
175
197
'Alpha3ToAlpha2 ' => $ alpha3ToAlpha2 ,
@@ -181,14 +203,19 @@ protected function generateDataForMeta(BundleEntryReaderInterface $reader, strin
181
203
protected function generateRegionNames (ArrayAccessibleResourceBundle $ localeBundle ): array
182
204
{
183
205
$ unfilteredRegionNames = iterator_to_array ($ localeBundle ['Countries ' ]);
184
- $ regionNames = [];
206
+ $ regionNames = [' UserAssignedNames ' => [], ' Names ' => [] ];
185
207
186
208
foreach ($ unfilteredRegionNames as $ region => $ regionName ) {
187
- if (!self ::isValidCountryCode ($ region )) {
209
+ if (!self ::isValidCountryCode ($ region ) && ! self :: isUserAssignedCountryCode ( $ region ) ) {
188
210
continue ;
189
211
}
190
212
191
- $ regionNames [$ region ] = $ regionName ;
213
+ if (self ::isUserAssignedCountryCode ($ region )) {
214
+ $ regionNames ['UserAssignedNames ' ][$ region ] = $ regionName ;
215
+ continue ;
216
+ }
217
+
218
+ $ regionNames ['Names ' ][$ region ] = $ regionName ;
192
219
}
193
220
194
221
return $ regionNames ;
@@ -204,7 +231,9 @@ private function generateAlpha2ToAlpha3Mapping(array $countries, ArrayAccessible
204
231
$ country = $ data ['replacement ' ];
205
232
206
233
if (2 === \strlen ($ country ) && 3 === \strlen ($ alias ) && 'overlong ' === $ data ['reason ' ]) {
207
- if (isset (self ::PREFERRED_ALPHA2_TO_ALPHA3_MAPPING [$ country ])) {
234
+ if (isset ($ countries [$ country ]) && self ::isUserAssignedCountryCode ($ country )) {
235
+ $ alpha2ToAlpha3 [$ country ] = $ alias ;
236
+ } elseif (isset ($ countries [$ country ]) && !self ::isUserAssignedCountryCode ($ country ) && isset (self ::PREFERRED_ALPHA2_TO_ALPHA3_MAPPING [$ country ])) {
208
237
// Validate to prevent typos
209
238
if (!isset ($ aliases [self ::PREFERRED_ALPHA2_TO_ALPHA3_MAPPING [$ country ]])) {
210
239
throw new RuntimeException ('The statically set three-letter mapping ' .self ::PREFERRED_ALPHA2_TO_ALPHA3_MAPPING [$ country ].' for the country code ' .$ country .' seems to be invalid. Typo? ' );
0 commit comments