$localizedLanguages) { $collator = collator_create($locale); uasort($localizedLanguages, function ($a, $b) use ($collator) { return collator_compare($collator, $a, $b); }); file_put_json(__DIR__ . '/language/' . $locale . '.json', $localizedLanguages); } $availableLocales = array_keys($languages); sort($availableLocales); // Available locales are stored in PHP, then manually // transferred to LanguageRepository. $data = " $languageName) { // Skip all languages that aren't an available locale at the same time. // This reduces the language list from about 515 to about 185 languages. if (!in_array($languageCode, $locales) && !in_array($languageCode, $explicitlyAllowed)) { continue; } if (in_array($languageCode, $explicitlyIgnored)) { continue; } // This language name is untranslated, use to the english version. if ($languageCode == str_replace('_', '-', $languageName)) { $languageName = $languages['en'][$languageCode]; // Maintain a count of untranslated languages per locale. $untranslatedCounts += [$locale => 0]; $untranslatedCounts[$locale]++; } $languages[$locale][$languageCode] = $languageName; } // CLDR v34 has an uneven language list due to missing translations. if ($locale != 'en') { $missingLanguages = array_diff_key($languages['en'], $languages[$locale]); foreach ($missingLanguages as $languageCode => $languageName) { $languages[$locale][$languageCode] = $languages['en'][$languageCode]; } } } // Ignore locales that are more than 80% untranslated. foreach ($untranslatedCounts as $locale => $count) { $totalCount = count($languages[$locale]); $untranslatedPercentage = $count * (100 / $totalCount); if ($untranslatedPercentage >= 80) { unset($languages[$locale]); } } return $languages; } /** * Filters out duplicate localizations (same as their parent locale). * * For example, "fr-FR" will be removed if "fr" has the same data. */ function filter_duplicate_localizations(array $localizations) { $duplicates = []; foreach ($localizations as $locale => $localizedLanguages) { if ($parentLocale = \CommerceGuys\Intl\Locale::getParent($locale)) { $parentLanguages = isset($localizations[$parentLocale]) ? $localizations[$parentLocale] : []; $diff = array_udiff($localizedLanguages, $parentLanguages, function ($first, $second) { return ($first === $second) ? 0 : 1; }); if (empty($diff)) { // The duplicates are not removed right away because they might // still be needed for other duplicate checks (for example, // when there are locales like bs-Latn-BA, bs-Latn, bs). $duplicates[] = $locale; } } } foreach ($duplicates as $locale) { unset($localizations[$locale]); } return $localizations; } /** * Creates a list of available locales. */ function discover_locales() { global $localeDirectory; // Locales listed without a "-" match all variants. // Locales listed with a "-" match only those exact ones. $ignoredLocales = [ // Interlingua is a made up language. 'ia', // Valencian differs from its parent only by a single character (è/é). 'ca-ES-VALENCIA', // Special "grouping" locales. 'root', 'en-US-POSIX', ]; // Gather available locales. $locales = []; if ($handle = opendir($localeDirectory)) { while (false !== ($entry = readdir($handle))) { if (substr($entry, 0, 1) != '.') { $entryParts = explode('-', $entry); if (!in_array($entry, $ignoredLocales) && !in_array($entryParts[0], $ignoredLocales)) { $locales[] = $entry; } } } closedir($handle); } return $locales; }