'Iceland', 'dial' => '354', 'mask' => '### ####', 'trunk' => '' ]; * $countries['de']['mask'] = '#### #######'; * unset( $countries['ru'] ); * * return $countries; * } ); */ class Countries { /** * Countries, built once * * @var array|null */ private static $all = null; /** * Every country by its ISO code, sorted by name * * @return array [ code => [ 'name', 'dial', 'mask', 'trunk' ] ] */ public static function all() { if ( null !== self::$all ) { return self::$all; } $countries = [ 'ar' => [ __( 'Argentina', 'remaily' ), '54', '## ####-####' ], 'am' => [ __( 'Armenia', 'remaily' ), '374', '## ######' ], 'au' => [ __( 'Australia', 'remaily' ), '61', '# #### ####' ], 'at' => [ __( 'Austria', 'remaily' ), '43', '### #######' ], 'az' => [ __( 'Azerbaijan', 'remaily' ), '994', '## ### ## ##' ], 'bd' => [ __( 'Bangladesh', 'remaily' ), '880', '####-######' ], 'by' => [ __( 'Belarus', 'remaily' ), '375', '## ###-##-##', '80' ], 'be' => [ __( 'Belgium', 'remaily' ), '32', '### ## ## ##' ], 'br' => [ __( 'Brazil', 'remaily' ), '55', '(##) #####-####' ], 'bg' => [ __( 'Bulgaria', 'remaily' ), '359', '## ### ####' ], 'ca' => [ __( 'Canada', 'remaily' ), '1', '(###) ###-####', '1' ], 'cl' => [ __( 'Chile', 'remaily' ), '56', '# #### ####' ], 'cn' => [ __( 'China', 'remaily' ), '86', '### #### ####' ], 'co' => [ __( 'Colombia', 'remaily' ), '57', '### ### ####' ], 'hr' => [ __( 'Croatia', 'remaily' ), '385', '## ### ####' ], 'cy' => [ __( 'Cyprus', 'remaily' ), '357', '## ######', '' ], 'cz' => [ __( 'Czechia', 'remaily' ), '420', '### ### ###', '' ], 'dk' => [ __( 'Denmark', 'remaily' ), '45', '## ## ## ##', '' ], 'eg' => [ __( 'Egypt', 'remaily' ), '20', '### ### ####' ], 'ee' => [ __( 'Estonia', 'remaily' ), '372', '#### ####', '' ], 'fi' => [ __( 'Finland', 'remaily' ), '358', '## ### ####' ], 'fr' => [ __( 'France', 'remaily' ), '33', '# ## ## ## ##' ], 'ge' => [ __( 'Georgia', 'remaily' ), '995', '### ## ## ##' ], 'de' => [ __( 'Germany', 'remaily' ), '49', '### ########' ], 'gr' => [ __( 'Greece', 'remaily' ), '30', '### ### ####', '' ], 'hk' => [ __( 'Hong Kong', 'remaily' ), '852', '#### ####', '' ], 'hu' => [ __( 'Hungary', 'remaily' ), '36', '## ### ####', '06' ], 'in' => [ __( 'India', 'remaily' ), '91', '##### #####' ], 'id' => [ __( 'Indonesia', 'remaily' ), '62', '###-####-####' ], 'ie' => [ __( 'Ireland', 'remaily' ), '353', '## ### ####' ], 'il' => [ __( 'Israel', 'remaily' ), '972', '##-###-####' ], 'it' => [ __( 'Italy', 'remaily' ), '39', '### ### ####', '' ], 'jp' => [ __( 'Japan', 'remaily' ), '81', '##-####-####' ], 'kz' => [ __( 'Kazakhstan', 'remaily' ), '7', '(###) ###-##-##', '8' ], 'ke' => [ __( 'Kenya', 'remaily' ), '254', '### ######' ], 'lv' => [ __( 'Latvia', 'remaily' ), '371', '## ### ###', '' ], 'lt' => [ __( 'Lithuania', 'remaily' ), '370', '### #####' ], 'my' => [ __( 'Malaysia', 'remaily' ), '60', '##-### ####' ], 'mx' => [ __( 'Mexico', 'remaily' ), '52', '## #### ####' ], 'md' => [ __( 'Moldova', 'remaily' ), '373', '### ## ###' ], 'ma' => [ __( 'Morocco', 'remaily' ), '212', '###-######' ], 'nl' => [ __( 'Netherlands', 'remaily' ), '31', '# ########' ], 'nz' => [ __( 'New Zealand', 'remaily' ), '64', '## ### ####' ], 'ng' => [ __( 'Nigeria', 'remaily' ), '234', '### ### ####' ], 'no' => [ __( 'Norway', 'remaily' ), '47', '### ## ###', '' ], 'pk' => [ __( 'Pakistan', 'remaily' ), '92', '### #######' ], 'pe' => [ __( 'Peru', 'remaily' ), '51', '### ### ###' ], 'ph' => [ __( 'Philippines', 'remaily' ), '63', '### ### ####' ], 'pl' => [ __( 'Poland', 'remaily' ), '48', '### ### ###', '' ], 'pt' => [ __( 'Portugal', 'remaily' ), '351', '### ### ###', '' ], 'ro' => [ __( 'Romania', 'remaily' ), '40', '### ### ###' ], 'ru' => [ __( 'Russia', 'remaily' ), '7', '(###) ###-##-##', '8' ], 'sa' => [ __( 'Saudi Arabia', 'remaily' ), '966', '## ### ####' ], 'rs' => [ __( 'Serbia', 'remaily' ), '381', '## ### ####' ], 'sg' => [ __( 'Singapore', 'remaily' ), '65', '#### ####', '' ], 'sk' => [ __( 'Slovakia', 'remaily' ), '421', '### ### ###' ], 'si' => [ __( 'Slovenia', 'remaily' ), '386', '## ### ###' ], 'za' => [ __( 'South Africa', 'remaily' ), '27', '## ### ####' ], 'kr' => [ __( 'South Korea', 'remaily' ), '82', '##-####-####' ], 'es' => [ __( 'Spain', 'remaily' ), '34', '### ## ## ##', '' ], 'se' => [ __( 'Sweden', 'remaily' ), '46', '##-### ## ##' ], 'ch' => [ __( 'Switzerland', 'remaily' ), '41', '## ### ## ##' ], 'tw' => [ __( 'Taiwan', 'remaily' ), '886', '### ### ###' ], 'th' => [ __( 'Thailand', 'remaily' ), '66', '## ### ####' ], 'tr' => [ __( 'Turkey', 'remaily' ), '90', '(###) ### ## ##' ], 'ua' => [ __( 'Ukraine', 'remaily' ), '380', '## ### ## ##' ], 'ae' => [ __( 'United Arab Emirates', 'remaily' ), '971', '## ### ####' ], 'gb' => [ __( 'United Kingdom', 'remaily' ), '44', '#### ######' ], 'us' => [ __( 'United States', 'remaily' ), '1', '(###) ###-####', '1' ], 'uz' => [ __( 'Uzbekistan', 'remaily' ), '998', '## ### ## ##', '' ], 'vn' => [ __( 'Vietnam', 'remaily' ), '84', '## ### ## ##' ], ]; $all = []; foreach ( $countries as $code => $country ) { $all[ $code ] = [ 'name' => $country[0], 'dial' => $country[1], 'mask' => $country[2], 'trunk' => $country[3] ?? '0' ]; } /** * The countries of the Country field and the Tel field's masks * * @param array $countries [ code => [ 'name', 'dial', 'mask', 'trunk' ] ] */ $all = (array) apply_filters( 'remaily_countries', $all ); foreach ( $all as $code => $country ) { if ( !is_array( $country ) || empty( $country['name'] ) || !preg_match( '/^[a-z]{2}$/', (string) $code ) ) { unset( $all[ $code ] ); continue; } $all[ $code ] = [ 'name' => (string) $country['name'], 'dial' => preg_replace( '/\D/', '', (string) ( $country['dial'] ?? '' ) ), 'mask' => (string) ( $country['mask'] ?? '' ), 'trunk' => preg_replace( '/\D/', '', (string) ( $country['trunk'] ?? '0' ) ), ]; } uasort( $all, static fn( $a, $b ) => strcasecmp( remove_accents( $a['name'] ), remove_accents( $b['name'] ) ) ); return self::$all = $all; } /** * The codes a field offers: those of its list ("us, ca gb", in that order; '' for every country) without the * ones it leaves out * * @param string $include Codes to offer * @param string $exclude Codes to leave out * * @return string[] */ public static function codes( $include, $exclude = '' ) { $codes = self::clean( $include ) ? explode( ', ', self::clean( $include ) ) : array_keys( self::all() ); return array_values( array_diff( $codes, explode( ', ', self::clean( $exclude ) ) ) ); } /** * A list of codes as saved: the known ones, lower case, once each, "us, ca, gb" * * @param string $list Codes * * @return string */ public static function clean( $list ) { $codes = preg_split( '/[\s,;]+/', strtolower( (string) $list ), -1, PREG_SPLIT_NO_EMPTY ); return implode( ', ', array_intersect( array_unique( $codes ), array_keys( self::all() ) ) ); } /** * A country's flag: the two regional-indicator letters most systems draw as one (Windows shows the letters) * * @param string $code ISO code * * @return string UTF-8 */ public static function flag( $code ) { return html_entity_decode( implode( '', array_map( static fn( $char ) => '&#' . ( 127397 + ord( $char ) ) . ';', str_split( strtoupper( $code ) ) ) ), ENT_QUOTES, 'UTF-8' ); } /** * A control with the picked country's flag and a caret inside it, at the start, and the country's name after them * when given (tel.js keeps them in step with the list) * * @param string $control Control's HTML * @param string $code Country picked ('' for none) * @param bool $flags The flag; false: the country's letters (US) * @param string $class Wrapper's own class * @param string|null $name The name shown after the caret: the Country field's (its list's own text is hidden) * * @return string */ public static function flagged( $control, $code, $flags, $class, $name = null ) { $mark = '' === $code ? '' : ( $flags ? self::flag( $code ) : strtoupper( $code ) ); return sprintf( '%5$s', esc_attr( $class ), $flags ? '' : ' data-letters', esc_html( $mark ), null === $name ? '' : '' . esc_html( $name ) . '', $control ); } }