Skip to content

Commit 09deecd

Browse files
committed
[Intl] Add support for ISO-3166-1 numeric codes
1 parent 0bc39e8 commit 09deecd

File tree

5 files changed

+1024
-0
lines changed

5 files changed

+1024
-0
lines changed

src/Symfony/Component/Intl/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
6.4
5+
---
6+
7+
* Add support for ISO-3166-1 numeric codes with `Countries::getNumericCode()`, `Countries::getNumericCodes()`,
8+
`Countries::numericCodeExists()` and `Countries::getAlpha2FromNumeric()`
9+
410
5.3
511
---
612

src/Symfony/Component/Intl/Countries.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ public static function getAlpha3Codes(): array
5252
return self::readEntry(['Alpha2ToAlpha3'], 'meta');
5353
}
5454

55+
/**
56+
* Returns all available numeric country codes (3 digits).
57+
*
58+
* Countries are returned as ISO 3166 numeric three-digit country codes.
59+
*
60+
* This list only contains "officially assigned ISO 3166-1 numeric" country codes.
61+
*
62+
* @return string[]
63+
*/
64+
public static function getNumericCodes(): array
65+
{
66+
return self::readEntry(['Alpha2ToNumeric'], 'meta');
67+
}
68+
5569
public static function getAlpha3Code(string $alpha2Code): string
5670
{
5771
return self::readEntry(['Alpha2ToAlpha3', $alpha2Code], 'meta');
@@ -62,6 +76,16 @@ public static function getAlpha2Code(string $alpha3Code): string
6276
return self::readEntry(['Alpha3ToAlpha2', $alpha3Code], 'meta');
6377
}
6478

79+
public static function getNumericCode(string $alpha2Code): string
80+
{
81+
return self::readEntry(['Alpha2ToNumeric', $alpha2Code], 'meta');
82+
}
83+
84+
public static function getAlpha2FromNumeric(string $numericCode): string
85+
{
86+
return self::readEntry(['NumericToAlpha2', $numericCode], 'meta');
87+
}
88+
6589
public static function exists(string $alpha2Code): bool
6690
{
6791
try {
@@ -84,6 +108,17 @@ public static function alpha3CodeExists(string $alpha3Code): bool
84108
}
85109
}
86110

111+
public static function numericCodeExists(string $numericCode): bool
112+
{
113+
try {
114+
self::getAlpha2FromNumeric($numericCode);
115+
116+
return true;
117+
} catch (MissingResourceException $e) {
118+
return false;
119+
}
120+
}
121+
87122
/**
88123
* Gets the country name from its alpha2 code.
89124
*

src/Symfony/Component/Intl/Data/Generator/RegionDataGenerator.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,33 @@ class RegionDataGenerator extends AbstractDataGenerator
6161
'ZZ' => true, // Unknown Region
6262
];
6363

64+
// @see https://en.wikipedia.org/wiki/ISO_3166-1_numeric#Withdrawn_codes
65+
private const WITHDRAWN_CODES = [
66+
128, // Canton and Enderbury Islands
67+
200, // Czechoslovakia
68+
216, // Dronning Maud Land
69+
230, // Ethiopia
70+
249, // France, Metropolitan
71+
278, // German Democratic Republic
72+
280, // Germany, Federal Republic of
73+
396, // Johnston Island
74+
488, // Midway Islands
75+
530, // Netherlands Antilles
76+
532, // Netherlands Antilles
77+
536, // Neutral Zone
78+
582, // Pacific Islands (Trust Territory)
79+
590, // Panama
80+
658, // Saint Kitts-Nevis-Anguilla
81+
720, // Yemen, Democratic
82+
736, // Sudan
83+
810, // USSR
84+
849, // United States Miscellaneous Pacific Islands
85+
872, // Wake Island
86+
886, // Yemen Arab Republic
87+
890, // Yugoslavia, Socialist Federal Republic of
88+
891, // Serbia and Montenegro
89+
];
90+
6491
/**
6592
* Collects all available language codes.
6693
*
@@ -151,10 +178,16 @@ protected function generateDataForMeta(BundleEntryReaderInterface $reader, strin
151178
$alpha3ToAlpha2 = array_flip($alpha2ToAlpha3);
152179
asort($alpha3ToAlpha2);
153180

181+
$alpha2ToNumeric = $this->generateAlpha2ToNumericMapping($metadataBundle);
182+
$numericToAlpha2 = array_flip($alpha2ToNumeric);
183+
asort($numericToAlpha2);
184+
154185
return [
155186
'Regions' => $this->regionCodes,
156187
'Alpha2ToAlpha3' => $alpha2ToAlpha3,
157188
'Alpha3ToAlpha2' => $alpha3ToAlpha2,
189+
'Alpha2ToNumeric' => $alpha2ToNumeric,
190+
'NumericToAlpha2' => $numericToAlpha2,
158191
];
159192
}
160193

@@ -177,10 +210,13 @@ protected function generateRegionNames(ArrayAccessibleResourceBundle $localeBund
177210
private function generateAlpha2ToAlpha3Mapping(array $countries, ArrayAccessibleResourceBundle $metadataBundle): array
178211
{
179212
$aliases = iterator_to_array($metadataBundle['alias']['territory']);
213+
180214
$alpha2ToAlpha3 = [];
181215

182216
foreach ($aliases as $alias => $data) {
217+
183218
$country = $data['replacement'];
219+
184220
if (2 === \strlen($country) && 3 === \strlen($alias) && 'overlong' === $data['reason']) {
185221
if (isset(self::PREFERRED_ALPHA2_TO_ALPHA3_MAPPING[$country])) {
186222
// Validate to prevent typos
@@ -208,4 +244,32 @@ private function generateAlpha2ToAlpha3Mapping(array $countries, ArrayAccessible
208244

209245
return $alpha2ToAlpha3;
210246
}
247+
248+
private function generateAlpha2ToNumericMapping(ArrayAccessibleResourceBundle $metadataBundle): array
249+
{
250+
$aliases = iterator_to_array($metadataBundle['alias']['territory']);
251+
252+
$alpha2ToNumeric = [];
253+
254+
foreach ($aliases as $alias => $data) {
255+
256+
if (!is_numeric($alias)) {
257+
continue;
258+
}
259+
260+
if (in_array($alias, self::WITHDRAWN_CODES)) {
261+
continue;
262+
}
263+
264+
if ('deprecated' === $data['reason']) {
265+
continue;
266+
}
267+
268+
$alpha2ToNumeric[$data['replacement']] = (string) $alias;
269+
}
270+
271+
ksort($alpha2ToNumeric);
272+
273+
return $alpha2ToNumeric;
274+
}
211275
}

0 commit comments

Comments
 (0)