Commit c90ae9dd authored by Oliver Bartsch's avatar Oliver Bartsch
Browse files

[!!!][TASK] Remove sys_language database table

The database table sys_language has become obsolete
with the introduction of site handling and site
languages.

Therefore, the sys_language database table and the
corresponding TCA is now removed. Fixtures and tests
are adjusted to no longer rely on this table.

Additionally, also a couple of code comments through
the Core are adjusted.

Executed commands:

   composer u typo3/cms-styleguide

Resolves: #96277
Related: #94165
Releases: main
Change-Id: I4ab0f3c7bb6de110cc1ce9826b2718f60d8a18a0
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/72534

Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Stefan Bürk's avatarStefan Bürk <stefan@buerk.tech>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: Stefan Bürk's avatarStefan Bürk <stefan@buerk.tech>
Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
parent e8b07362
......@@ -8144,12 +8144,12 @@
"source": {
"type": "git",
"url": "https://github.com/TYPO3/styleguide.git",
"reference": "d3b947caaf099f8bd7b6dce7c0fb75352bb7e6d9"
"reference": "e8ff67e717d0f28c7a9ba30083139a257cb04947"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/TYPO3/styleguide/zipball/d3b947caaf099f8bd7b6dce7c0fb75352bb7e6d9",
"reference": "d3b947caaf099f8bd7b6dce7c0fb75352bb7e6d9",
"url": "https://api.github.com/repos/TYPO3/styleguide/zipball/e8ff67e717d0f28c7a9ba30083139a257cb04947",
"reference": "e8ff67e717d0f28c7a9ba30083139a257cb04947",
"shasum": ""
},
"require-dev": {
......@@ -8209,7 +8209,7 @@
"issues": "https://github.com/TYPO3/styleguide/issues",
"source": "https://github.com/TYPO3/styleguide/tree/main"
},
"time": "2021-12-01T12:02:28+00:00"
"time": "2021-12-07T14:13:05+00:00"
},
{
"name": "typo3/testing-framework",
......
......@@ -2312,11 +2312,10 @@ class EditDocumentController
}
/**
* Returns languages available for record translations on given page.
* Returns languages available for record translations on given page.
*
* @param int $id Page id: If zero, the query will select all sys_language records from root level which are NOT
* hidden. If set to another value, the query will select all sys_language records that has a
* translation record on that page (and is not hidden, unless you are admin user)
* @param int $id Page id: If zero, all available system languages will be returned. If set to
* another value, only languages, a page translation exists for, will be returned.
* @param string $table For pages we want all languages, for other records the languages of the page translations
* @return array Array with languages (uid, title, ISOcode, flagIcon)
*/
......
......@@ -895,7 +895,7 @@ class PageLayoutController
******************************/
/**
* Returns the number of hidden elements (including those hidden by start/end times)
* on the current page (for the current sys_language)
* on the current page (for the current site language)
*
* @param array $languageColumns
* @return int
......
......@@ -611,7 +611,7 @@ class SiteConfigurationController
$newSysSiteData['errorHandling'] = $validChildren;
}
// Verify there is only one inline child per sys_language record configured.
// Verify there is at least one site_language element configured.
if (!isset($newSysSiteData['languages']) || !is_array($newSysSiteData['languages']) || count($newSysSiteData['languages']) < 1) {
throw new \RuntimeException(
'No default language definition found. The interface does not allow this. Aborting',
......
......@@ -31,7 +31,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
abstract class AbstractContentPagePositionMap
{
/**
* Can be set to the sys_language uid to select content elements for.
* Can be set to the language id to select content elements for.
*/
public int $cur_sys_language = 0;
......
......@@ -283,7 +283,7 @@ class BackendUtility
*
* @param string $table Table name present in $GLOBALS['TCA']
* @param int $uid The uid of the record
* @param int $language The uid of the language record in sys_language
* @param int $language The id of the site language
* @param string $andWhereClause Optional additional WHERE clause (default: '')
* @return mixed Multidimensional array with selected records, empty array if none exists and FALSE if table is not localizable
*/
......
......@@ -28,9 +28,6 @@ entitySettings:
columnNames: {title: 'header', type: 'CType'}
workspace:
tableName: 'sys_workspace'
language:
tableName: 'sys_language'
columnNames: {code: 'language_isocode'}
visitorGroup:
tableName: 'fe_groups'
visitor:
......@@ -47,10 +44,6 @@ entitySettings:
entities:
workspace:
- self: {id: 1, title: 'Workspace'}
language:
- self: {id: 1, title: 'French', code: 'fr'}
- self: {id: 2, title: 'Franco-Canadian', code: 'fr'}
- self: {id: 3, title: 'Spanish', code: 'es'}
beGroup:
- self: {id: 9, title: 'editors', db_mountpoints: '1000,2000,8110', tables_select: 'pages,tt_content', tables_modify: 'pages,tt_content', page_types_select: '1,4,7,254', groupMods: 'web_layout,web_list'}
page:
......
......@@ -48,7 +48,6 @@ class LocalizationControllerTest extends AbstractDataHandlerActionTestCase
parent::setUp();
$this->importDataSet(__DIR__ . '/Fixtures/pages.xml');
$this->importDataSet('PACKAGE:typo3/testing-framework/Resources/Core/Functional/Fixtures/sys_language.xml');
$this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-default-language.xml');
$this->setUpFrontendRootPage(1);
$this->setUpFrontendSite(1, $this->siteLanguageConfiguration);
......
......@@ -28,9 +28,6 @@ entitySettings:
columnNames: {title: 'header', type: 'CType'}
workspace:
tableName: 'sys_workspace'
language:
tableName: 'sys_language'
columnNames: {code: 'language_isocode'}
visitorGroup:
tableName: 'fe_groups'
visitor:
......@@ -45,10 +42,6 @@ entitySettings:
entities:
workspace:
- self: {id: 1, title: 'Workspace'}
language:
- self: {id: 1, title: 'French', code: 'fr'}
- self: {id: 2, title: 'Franco-Canadian', code: 'fr'}
- self: {id: 3, title: 'Spanish', code: 'es'}
page:
- self: {id: *idAcmeRootPage, title: 'ACME Inc', type: *pageShortcut, shortcut: 'first', root: true, slug: '/'}
children:
......
......@@ -29,9 +29,6 @@ entitySettings:
defaultValues: {colPos: 0}
workspace:
tableName: 'sys_workspace'
language:
tableName: 'sys_language'
columnNames: {code: 'language_isocode'}
visitorGroup:
tableName: 'fe_groups'
visitor:
......@@ -46,9 +43,6 @@ entitySettings:
entities:
workspace:
- self: {id: 1, title: 'Workspace'}
language:
- self: {id: 1, title: 'French', code: 'fr'}
- self: {id: 2, title: 'Franco-Canadian', code: 'fr'}
page:
- self: {id: *idAcmeRootPage, title: 'ACME Inc', type: *pageShortcut, shortcut: 'first', root: true}
children:
......
......@@ -679,7 +679,7 @@ class BackendUserAuthentication extends AbstractUserAuthentication
}
/**
* Checking if a language value (-1, 0 and >0 for sys_language records) is allowed to be edited by the user.
* Checking if a language value (-1, 0 and >0) is allowed to be edited by the user.
*
* @param int $langValue Language value to evaluate
* @return bool Returns TRUE if the language value is allowed, otherwise FALSE.
......
......@@ -3222,7 +3222,7 @@ class DataHandler implements LoggerAwareInterface
* @param bool $first Is a flag set, if the record copied is NOT a 'slave' to another record copied. That is, if this record was asked to be copied in the cmd-array
* @param array $overrideValues Associative array with field/value pairs to override directly. Notice; Fields must exist in the table record and NOT be among excluded fields!
* @param string $excludeFields Commalist of fields to exclude from the copy process (might get default values)
* @param int $language Language ID (from sys_language table)
* @param int $language Language ID
* @param bool $ignoreLocalization If TRUE, any localization routine is skipped
* @return int|null ID of new record, if any
* @internal should only be used from within DataHandler
......@@ -3702,7 +3702,7 @@ class DataHandler implements LoggerAwareInterface
* @param array $row Record array
* @param array $conf TCA field configuration
* @param int $realDestPid Real page id (pid) the record is copied to
* @param int $language Language ID (from sys_language table) used in the duplicated record
* @param int $language Language ID used in the duplicated record
* @param array $workspaceOptions Options to be forwarded if actions happen on a workspace currently
* @return array|string
* @internal
......@@ -4427,7 +4427,7 @@ class DataHandler implements LoggerAwareInterface
*
* @param string $table Table name
* @param int $uid Record uid (to be localized)
* @param int $language Language ID (from sys_language table)
* @param int $language Language ID
* @return int|bool The uid (int) of the new translated record or FALSE (bool) if something went wrong
* @internal should only be used from within DataHandler
*/
......
......@@ -390,7 +390,7 @@ class PageRepository implements LoggerAwareInterface
* Returns the relevant page overlay record fields
*
* @param mixed $pageInput If $pageInput is an integer, it's the pid of the pageOverlay record and thus the page overlay record is returned. If $pageInput is an array, it's a page-record and based on this page record the language record is found and OVERLAID before the page record is returned.
* @param int $languageUid Language UID if you want to set an alternative value to $this->sys_language_uid which is default. Should be >=0
* @param int $languageUid anguage UID if you want to set an alternative value to $this->sys_language_uid which is default. Should be >=0
* @throws \UnexpectedValueException
* @return array Page row which is overlaid with language_overlay record (or the overlay record alone)
*/
......@@ -525,7 +525,7 @@ class PageRepository implements LoggerAwareInterface
* But that's not how it's done right now.
*
* @param array $pageUids
* @param array $languageUids uid of sys_language, please note that the order is important here.
* @param array $languageUids uid of site language, please note that the order is important here.
* @return array
*/
protected function getPageOverlaysForLanguageUids(array $pageUids, array $languageUids): array
......@@ -594,7 +594,7 @@ class PageRepository implements LoggerAwareInterface
*
* @param string $table Table name
* @param array $row Record to overlay. Must contain uid, pid and $table]['ctrl']['languageField']
* @param int $sys_language_content Pointer to the sys_language uid for content on the site.
* @param int $sys_language_content Pointer to the site language id for content on the site.
* @param string $OLmode Overlay mode. If "hideNonTranslated" then records without translation will not be returned un-translated but unset (and return value is NULL)
* @throws \UnexpectedValueException
* @return mixed Returns the input record, possibly overlaid with a translation. But if $OLmode is "hideNonTranslated" then it will return NULL if no translation is found.
......
......@@ -43,7 +43,7 @@ class NullSite implements SiteInterface
/**
* Sets up a null site object
*
* @param array $languages (sys_language objects)
* @param array|null $languages site languages
* @param Uri|null $baseEntryPoint
*/
public function __construct(array $languages = null, Uri $baseEntryPoint = null)
......
......@@ -25,7 +25,7 @@ use Psr\Http\Message\UriInterface;
class SiteLanguage
{
/**
* The language mapped to the sys_language DB entry.
* The language id.
*
* @var int
*/
......
......@@ -204,7 +204,7 @@ class ExtensionManagementUtility
*/
public static function addTCAcolumns($table, $columnArray)
{
if (is_array($columnArray) && is_array($GLOBALS['TCA'][$table]) && is_array($GLOBALS['TCA'][$table]['columns'])) {
if (is_array($columnArray) && is_array($GLOBALS['TCA'][$table]['columns'] ?? false)) {
// Candidate for array_merge() if integer-keys will some day make trouble...
$GLOBALS['TCA'][$table]['columns'] = array_merge($GLOBALS['TCA'][$table]['columns'], $columnArray);
}
......
......@@ -1282,7 +1282,6 @@ return [
be_users.after = be_groups
sys_filemounts.after = be_users
sys_file_storage.after = sys_filemounts
sys_language.after = sys_file_storage
fe_users.after = fe_groups
fe_users.before = pages
sys_template.after = pages
......
<?php
return [
'ctrl' => [
'label' => 'title',
'tstamp' => 'tstamp',
'sortby' => 'sorting',
'default_sortby' => 'title',
'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_language',
'adminOnly' => true,
'groupName' => 'system',
'rootLevel' => 1,
'enablecolumns' => [
'disabled' => 'hidden',
],
'typeicon_column' => 'flag',
'typeicon_classes' => [
'default' => 'mimetypes-x-sys_language',
'mask' => 'flags-###TYPE###',
],
'versioningWS_alwaysAllowLiveEdit' => true,
],
'columns' => [
'title' => [
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
'config' => [
'type' => 'input',
'size' => 35,
'max' => 80,
'eval' => 'trim,required',
],
],
'hidden' => [
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.enabled',
'exclude' => true,
'config' => [
'type' => 'check',
'renderType' => 'checkboxToggle',
'default' => 0,
'items' => [
[
0 => '',
'invertStateDisplay' => true,
],
],
],
],
'language_isocode' => [
'exclude' => true,
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_language.language_isocode',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'maxitems' => 1,
'items' => [],
'itemsProcFunc' => \TYPO3\CMS\Core\Service\IsoCodeService::class . '->renderIsoCodeSelectDropdown',
],
],
'flag' => [
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_language.flag',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['', 0, ''],
['multiple', 'multiple', 'flags-multiple'],
['ad', 'ad', 'flags-ad'],
['ae', 'ae', 'flags-ae'],
['af', 'af', 'flags-af'],
['ag', 'ag', 'flags-ag'],
['ai', 'ai', 'flags-ai'],
['al', 'al', 'flags-al'],
['am', 'am', 'flags-am'],
['an', 'an', 'flags-an'],
['ao', 'ao', 'flags-ao'],
['aq', 'aq', 'flags-aq'],
['ar', 'ar', 'flags-ar'],
['as', 'as', 'flags-as'],
['at', 'at', 'flags-at'],
['au', 'au', 'flags-au'],
['aw', 'aw', 'flags-aw'],
['ax', 'ax', 'flags-ax'],
['az', 'az', 'flags-az'],
['ba', 'ba', 'flags-ba'],
['bb', 'bb', 'flags-bb'],
['bd', 'bd', 'flags-bd'],
['be', 'be', 'flags-be'],
['bf', 'bf', 'flags-bf'],
['bg', 'bg', 'flags-bg'],
['bh', 'bh', 'flags-bh'],
['bi', 'bi', 'flags-bi'],
['bj', 'bj', 'flags-bj'],
['bl', 'bl', 'flags-bl'],
['bm', 'bm', 'flags-bm'],
['bn', 'bn', 'flags-bn'],
['bo', 'bo', 'flags-bo'],
['bq', 'bq', 'flags-bq'],
['br', 'br', 'flags-br'],
['bs', 'bs', 'flags-bs'],
['bt', 'bt', 'flags-bt'],
['bv', 'bv', 'flags-bv'],
['bw', 'bw', 'flags-bw'],
['by', 'by', 'flags-by'],
['bz', 'bz', 'flags-bz'],
['ca', 'ca', 'flags-ca'],
['catalonia', 'catalonia', 'flags-catalonia'],
['cc', 'cc', 'flags-cc'],
['cd', 'cd', 'flags-cd'],
['cf', 'cf', 'flags-cf'],
['cg', 'cg', 'flags-cg'],
['ch', 'ch', 'flags-ch'],
['ci', 'ci', 'flags-ci'],
['ck', 'ck', 'flags-ck'],
['cl', 'cl', 'flags-cl'],
['cm', 'cm', 'flags-cm'],
['cn', 'cn', 'flags-cn'],
['co', 'co', 'flags-co'],
['cr', 'cr', 'flags-cr'],
['cs', 'cs', 'flags-cs'],
['cu', 'cu', 'flags-cu'],
['cv', 'cv', 'flags-cv'],
['cw', 'cw', 'flags-cw'],
['cx', 'cx', 'flags-cx'],
['cy', 'cy', 'flags-cy'],
['cz', 'cz', 'flags-cz'],
['de', 'de', 'flags-de'],
['dj', 'dj', 'flags-dj'],
['dk', 'dk', 'flags-dk'],
['dm', 'dm', 'flags-dm'],
['do', 'do', 'flags-do'],
['dz', 'dz', 'flags-dz'],
['ec', 'ec', 'flags-ec'],
['ee', 'ee', 'flags-ee'],
['eg', 'eg', 'flags-eg'],
['eh', 'eh', 'flags-eh'],
['en-us-gb', 'en-us-gb', 'flags-en-us-gb'],
['england', 'england', 'flags-gb-eng'],
['er', 'er', 'flags-er'],
['es', 'es', 'flags-es'],
['et', 'et', 'flags-et'],
['eu', 'eu', 'flags-eu'],
['fi', 'fi', 'flags-fi'],
['fj', 'fj', 'flags-fj'],
['fk', 'fk', 'flags-fk'],
['fm', 'fm', 'flags-fm'],
['fo', 'fo', 'flags-fo'],
['fr', 'fr', 'flags-fr'],
['ga', 'ga', 'flags-ga'],
['gb', 'gb', 'flags-gb'],
['gd', 'gd', 'flags-gd'],
['ge', 'ge', 'flags-ge'],
['gf', 'gf', 'flags-gf'],
['gg', 'gg', 'flags-gg'],
['gh', 'gh', 'flags-gh'],
['gi', 'gi', 'flags-gi'],
['gl', 'gl', 'flags-gl'],
['gm', 'gm', 'flags-gm'],
['gn', 'gn', 'flags-gn'],
['gp', 'gp', 'flags-gp'],
['gq', 'gq', 'flags-gq'],
['gr', 'gr', 'flags-gr'],
['gs', 'gs', 'flags-gs'],
['gt', 'gt', 'flags-gt'],
['gu', 'gu', 'flags-gu'],
['gw', 'gw', 'flags-gw'],
['gy', 'gy', 'flags-gy'],
['hk', 'hk', 'flags-hk'],
['hm', 'hm', 'flags-hm'],
['hn', 'hn', 'flags-hn'],
['hr', 'hr', 'flags-hr'],
['ht', 'ht', 'flags-ht'],
['hu', 'hu', 'flags-hu'],
['id', 'id', 'flags-id'],
['ie', 'ie', 'flags-ie'],
['il', 'il', 'flags-il'],
['im', 'im', 'flags-im'],
['in', 'in', 'flags-in'],
['io', 'io', 'flags-io'],
['iq', 'iq', 'flags-iq'],
['ir', 'ir', 'flags-ir'],
['is', 'is', 'flags-is'],
['it', 'it', 'flags-it'],
['jm', 'jm', 'flags-jm'],
['jo', 'jo', 'flags-jo'],
['jp', 'jp', 'flags-jp'],
['ke', 'ke', 'flags-ke'],
['kg', 'kg', 'flags-kg'],
['kh', 'kh', 'flags-kh'],
['ki', 'ki', 'flags-ki'],
['kl', 'kl', 'flags-kl'],
['km', 'km', 'flags-km'],
['kn', 'kn', 'flags-kn'],
['kp', 'kp', 'flags-kp'],
['kr', 'kr', 'flags-kr'],
['kw', 'kw', 'flags-kw'],
['ky', 'ky', 'flags-ky'],
['kz', 'kz', 'flags-kz'],
['la', 'la', 'flags-la'],
['lb', 'lb', 'flags-lb'],
['lc', 'lc', 'flags-lc'],
['li', 'li', 'flags-li'],
['lk', 'lk', 'flags-lk'],
['lr', 'lr', 'flags-lr'],
['ls', 'ls', 'flags-ls'],
['lt', 'lt', 'flags-lt'],
['lu', 'lu', 'flags-lu'],
['lv', 'lv', 'flags-lv'],
['ly', 'ly', 'flags-ly'],
['ma', 'ma', 'flags-ma'],
['mc', 'mc', 'flags-mc'],
['md', 'md', 'flags-md'],
['me', 'me', 'flags-me'],
['mf', 'mf', 'flags-mf'],
['mg', 'mg', 'flags-mg'],
['mh', 'mh', 'flags-mh'],
['mi', 'mi', 'flags-mi'],
['mk', 'mk', 'flags-mk'],
['ml', 'ml', 'flags-ml'],
['mm', 'mm', 'flags-mm'],
['mn', 'mn', 'flags-mn'],
['mo', 'mo', 'flags-mo'],
['mp', 'mp', 'flags-mp'],
['mq', 'mq', 'flags-mq'],
['mr', 'mr', 'flags-mr'],
['ms', 'ms', 'flags-ms'],
['mt', 'mt', 'flags-mt'],
['mu', 'mu', 'flags-mu'],
['mv', 'mv', 'flags-mv'],
['mw', 'mw', 'flags-mw'],
['mx', 'mx', 'flags-mx'],
['my', 'my', 'flags-my'],
['mz', 'mz', 'flags-mz'],
['na', 'na', 'flags-na'],
['nc', 'nc', 'flags-nc'],
['ne', 'ne', 'flags-ne'],
['nf', 'nf', 'flags-nf'],
['ng', 'ng', 'flags-ng'],
['ni', 'ni', 'flags-ni'],
['gb-nir', 'gb-nir', 'flags-gb-nir'],
['nl', 'nl', 'flags-nl'],
['no', 'no', 'flags-no'],
['np', 'np', 'flags-np'],
['nr', 'nr', 'flags-nr'],
['nu', 'nu', 'flags-nu'],
['nz', 'nz', 'flags-nz'],
['om', 'om', 'flags-om'],
['pa', 'pa', 'flags-pa'],
['pe', 'pe', 'flags-pe'],
['pf', 'pf', 'flags-pf'],
['pg', 'pg', 'flags-pg'],
['ph', 'ph', 'flags-ph'],
['pk', 'pk', 'flags-pk'],
['pl', 'pl', 'flags-pl'],
['pm', 'pm', 'flags-pm'],
['pn', 'pn', 'flags-pn'],
['pr', 'pr', 'flags-pr'],
['ps', 'ps', 'flags-ps'],
['pt', 'pt', 'flags-pt'],
['pw', 'pw', 'flags-pw'],
['py', 'py', 'flags-py'],
['qa', 'qa', 'flags-qa'],
['qc', 'qc', 'flags-qc'],
['re', 're', 'flags-re'],
['ro', 'ro', 'flags-ro'],
['rs', 'rs', 'flags-rs'],
['ru', 'ru', 'flags-ru'],
['rw', 'rw', 'flags-rw'],
['sa', 'sa', 'flags-sa'],
['sb', 'sb', 'flags-sb'],
['sc', 'sc', 'flags-sc'],
['gb-sct', 'gb-sct', 'flags-gb-sct'],
['sd', 'sd', 'flags-sd'],
['se', 'se', 'flags-se'],
['sg', 'sg', 'flags-sg'],
['sh', 'sh', 'flags-sh'],
['si', 'si', 'flags-si'],
['sj', 'sj', 'flags-sj'],
['sk', 'sk', 'flags-sk'],
['sl', 'sl', 'flags-sl'],
['sm', 'sm', 'flags-sm'],
['sn', 'sn', 'flags-sn'],
['so', 'so', 'flags-so'],
['sr', 'sr', 'flags-sr'],
['ss', 'ss', 'flags-ss'],
['st', 'st', 'flags-st'],
['sv', 'sv', 'flags-sv'],
['sx', 'sx', 'flags-sx'],
['sy', 'sy', 'flags-sy'],
['sz', 'sz', 'flags-sz'],
['tc', 'tc', 'flags-tc'],
['td', 'td', 'flags-td'],
['tf', 'tf', 'flags-tf'],
['tg', 'tg', 'flags-tg'],
['th', 'th', 'flags-th'],
['tj', 'tj', 'flags-tj'],
['tk', 'tk', 'flags-tk'],
['tl', 'tl', 'flags-tl'],
['tm', 'tm', 'flags-tm'],
['tn', 'tn', 'flags-tn'],
['to', 'to', 'flags-to'],
['tr', 'tr', 'flags-tr'],
['tt', 'tt', 'flags-tt'],
['tv', 'tv', 'flags-tv'],
['tw', 'tw', 'flags-tw'],
['tz', 'tz', 'flags-tz'],
['ua', 'ua', 'flags-ua'],
['ug', 'ug', 'flags-ug'],
['um', 'um', 'flags-um'],
['us', 'us', 'flags-us'],
['uy', 'uy', 'flags-uy'],
['uz', 'uz', 'flags-uz'],
['va', 'va', 'flags-va'],
['vc', 'vc', 'flags-vc'],
['ve', 've', 'flags-ve'],
['vg', 'vg', 'flags-vg'],
['vi', 'vi', 'flags-vi'],
['vn', 'vn', 'flags-vn'],
['vu', 'vu', 'flags-vu'],
['gb-wls', 'gb-wls', 'flags-gb-wls'],