diff --git a/src/applications/settings/panel/PhabricatorAccountSettingsPanel.php b/src/applications/settings/panel/PhabricatorAccountSettingsPanel.php --- a/src/applications/settings/panel/PhabricatorAccountSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorAccountSettingsPanel.php @@ -53,29 +53,7 @@ PhutilPerson::SEX_FEMALE => $label_her, ); - $locales = PhutilLocale::loadAllLocales(); - $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); - $is_dev = PhabricatorEnv::getEnvConfig('phabricator.developer-mode'); - - $translations = array(); - foreach ($locales as $locale) { - if ($is_serious && $locale->isSillyLocale()) { - // Omit silly locales on serious business installs. - continue; - } - if (!$is_dev && $locale->isTestLocale()) { - // Omit test locales on installs which aren't in development mode. - continue; - } - $translations[$locale->getLocaleCode()] = $locale->getLocaleName(); - } - - asort($translations); - // TODO: Implement "locale.default" and use it here. - $default = 'en_US'; - $translations = array( - '' => pht('Server Default: %s', $locales[$default]->getLocaleName()), - ) + $translations; + $translations = $this->getTranslationOptions(); $form = new AphrontFormView(); $form @@ -107,4 +85,81 @@ $form_box, ); } + + private function getTranslationOptions() { + $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); + $locales = PhutilLocale::loadAllLocales(); + + $group_labels = array( + 'normal' => pht('Translations'), + 'limited' => pht('Limited Translations'), + 'silly' => pht('Silly Translations'), + 'test' => pht('Developer/Test Translations'), + ); + + $groups = array_fill_keys(array_keys($group_labels), array()); + + $translations = array(); + foreach ($locales as $locale) { + $code = $locale->getLocaleCode(); + $name = $locale->getLocaleName(); + + if ($locale->isSillyLocale()) { + if ($is_serious) { + // Omit silly locales on serious business installs. + continue; + } + $groups['silly'][$code] = $name; + continue; + } + + if ($locale->isTestLocale()) { + $groups['test'][$code] = $name; + continue; + } + + $strings = PhutilTranslation::getTranslationMapForLocale($code); + $size = count($strings); + + // If a translation is English, assume it can fall back to the default + // strings and don't caveat its completeness. + $is_english = (substr($code, 0, 3) == 'en_'); + + // Arbitrarily pick some number of available strings to promote a + // translation out of the "limited" group. The major goal is just to + // keep locales with very few strings out of the main group, so users + // aren't surprised if a locale has no upstream translations available. + if ($size > 512 || $is_english) { + $type = 'normal'; + } else { + $type = 'limited'; + } + + $groups[$type][$code] = $name; + } + + // TODO: Select a default properly. + $default = 'en_US'; + + $results = array(); + foreach ($groups as $key => $group) { + $label = $group_labels[$key]; + if (!$group) { + continue; + } + + asort($group); + + if ($key == 'normal') { + $group = array( + '' => pht('Server Default: %s', $locales[$default]->getLocaleName()), + ) + $group; + } + + $results[$label] = $group; + } + + return $results; + } + }