From 342c011a6cff7bdbe1235fe71ffc8f0c7b06ed29 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 18 Mar 2020 21:02:23 +0900 Subject: [PATCH] Add functions for converting between country codes and calling codes --- common/framework/i18n.php | 105 ++++++++++++++++++++++++++++++ tests/unit/framework/i18nTest.php | 32 +++++++++ 2 files changed, 137 insertions(+) diff --git a/common/framework/i18n.php b/common/framework/i18n.php index fe3ee894b..283f68a67 100644 --- a/common/framework/i18n.php +++ b/common/framework/i18n.php @@ -18,6 +18,11 @@ class i18n const SORT_NAME_KOREAN = 7; const SORT_NAME_NATIVE = 8; + /** + * Local cache. + */ + protected static $_countries = array(); + /** * Get the list of all countries. * @@ -26,6 +31,11 @@ class i18n */ public static function listCountries($sort_by = self::SORT_NAME_ENGLISH) { + if (isset(self::$_countries[$sort_by])) + { + return self::$_countries[$sort_by]; + } + $countries = (include \RX_BASEDIR . 'common/defaults/countries.php'); $result = array(); @@ -73,6 +83,101 @@ class i18n break; } + self::$_countries[$sort_by] = $result; return $result; } + + /** + * Get the calling code from a country code (either ISO-3166-1 alpha2 or alpha3). + * + * This function returns null if a matching country is not found. + * + * @param $code Country code + * @return string|null + */ + public static function getCallingCodeByCountryCode($code) + { + $countries = self::listCountries(); + if (strlen($code) === 3) + { + return (isset($countries[$code]) && $countries[$code]->calling_code) ? $countries[$code]->calling_code : null; + } + else + { + foreach ($countries as $country) + { + if ($country->iso_3166_1_alpha2 === $code) + { + return $country->calling_code; + } + } + } + + return null; + } + + /** + * Get the country code (either ISO-3166-1 alpha2 or alpha3) from a calling code. + * + * This function may return the wrong country if two or more countries share a calling code. + * This function returns null if a matching country is not found. + * + * @param $code Calling code + * @return string|null + */ + public static function getCountryCodeByCallingCode($code, $type = 3) + { + $countries = self::listCountries(); + $code = preg_replace('/[^0-9]/', '', $code); + foreach ($countries as $country) + { + if (preg_replace('/[^0-9]/', '', $country->calling_code) === $code) + { + return $type == 3 ? $country->iso_3166_1_alpha3 : $country->iso_3166_1_alpha2; + } + } + + return null; + } + /** + * Format a phone number with country code. + * + * @param string $phone_number + * @param string $phone_country + * @param bool $pretty (optional) + * @return string + */ + public static function formatPhoneNumber($phone_number, $phone_country, $pretty = true) + { + if (!is_numeric($phone_country)) + { + $phone_country = self::getCallingCodeByCountryCode($phone_country); + } + + if ($pretty) + { + if ($phone_country == 82) + { + $pretty_phone_number = Korea::formatPhoneNumber($phone_number); + } + elseif ($phone_country == 1) + { + $digits = preg_replace('/[^0-9]/', '', $phone_number); + $pretty_phone_number = substr($digits, 0, 3) . '-' . substr($digits, 3, 3) . '-' . substr($digits, 6); + } + else + { + $pretty_phone_number = preg_replace('/[^0-9-]/', '', $phone_number); + } + return sprintf('(+%s) %s', $phone_country, $pretty_phone_number); + } + else + { + if (!in_array(strval($phone_country), array('39', '378', '379'))) + { + $phone_number = preg_replace('/^0/', '', $phone_number); + } + return sprintf('+%s', preg_replace('/[^0-9]/', '', $phone_country . $phone_number)); + } + } } diff --git a/tests/unit/framework/i18nTest.php b/tests/unit/framework/i18nTest.php index 481ab9cf6..726895f19 100644 --- a/tests/unit/framework/i18nTest.php +++ b/tests/unit/framework/i18nTest.php @@ -38,4 +38,36 @@ class i18nTest extends \Codeception\TestCase\Test $this->assertEquals('United States of America', $sort_native['USA']->name_english); $this->assertEquals('nz', $sort_native['NZL']->cctld); } + + public function testGetCallingCodeByCountryCode() + { + $this->assertEquals('82', Rhymix\Framework\i18n::getCallingCodeByCountryCode('KOR')); + $this->assertEquals('82', Rhymix\Framework\i18n::getCallingCodeByCountryCode('KR')); + $this->assertEquals('1', Rhymix\Framework\i18n::getCallingCodeByCountryCode('USA')); + $this->assertEquals('1', Rhymix\Framework\i18n::getCallingCodeByCountryCode('US')); + $this->assertEquals('47', Rhymix\Framework\i18n::getCallingCodeByCountryCode('NOR')); + $this->assertEquals('1-242', Rhymix\Framework\i18n::getCallingCodeByCountryCode('BHS')); + $this->assertEquals('44-1624', Rhymix\Framework\i18n::getCallingCodeByCountryCode('IMN')); + $this->assertNull(Rhymix\Framework\i18n::getCallingCodeByCountryCode('XXX')); + } + + public function testGetCountryCodeByCallingCode() + { + $this->assertEquals('KOR', Rhymix\Framework\i18n::getCountryCodeByCallingCode('82')); + $this->assertEquals('KR', Rhymix\Framework\i18n::getCountryCodeByCallingCode('82', 2)); + $this->assertEquals('ASM', Rhymix\Framework\i18n::getCountryCodeByCallingCode('1-684')); + $this->assertEquals('AS', Rhymix\Framework\i18n::getCountryCodeByCallingCode('1684', 2)); + } + + public function testFormatPhoneNumber() + { + $this->assertEquals('(+82) 010-2345-6789', Rhymix\Framework\i18n::formatPhoneNumber('01023456789', '82')); + $this->assertEquals('(+82) 010-2345-6789', Rhymix\Framework\i18n::formatPhoneNumber('010.2345.6789', 'KOR')); + $this->assertEquals('(+1) 473-555-1212', Rhymix\Framework\i18n::formatPhoneNumber('4735551212', '1')); + $this->assertEquals('(+44) 1420-123456', Rhymix\Framework\i18n::formatPhoneNumber('1420-123 456', 'GB')); + $this->assertEquals('(+44-1481) 01234567', Rhymix\Framework\i18n::formatPhoneNumber('01234567', 'GGY')); + $this->assertEquals('+821023456789', Rhymix\Framework\i18n::formatPhoneNumber('01023456789', '82', false)); + $this->assertEquals('+14735551212', Rhymix\Framework\i18n::formatPhoneNumber('4735551212', '1', false)); + $this->assertEquals('+390669800000', Rhymix\Framework\i18n::formatPhoneNumber('06698-00000', '39', false)); + } }