Page MenuHomePhabricator

D11747.diff
No OneTemporary

D11747.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1245,7 +1245,6 @@
'PhabricatorActionView' => 'view/layout/PhabricatorActionView.php',
'PhabricatorActivitySettingsPanel' => 'applications/settings/panel/PhabricatorActivitySettingsPanel.php',
'PhabricatorAdministratorsPolicyRule' => 'applications/policy/rule/PhabricatorAdministratorsPolicyRule.php',
- 'PhabricatorAllCapsTranslation' => 'infrastructure/internationalization/translation/PhabricatorAllCapsTranslation.php',
'PhabricatorAlmanacApplication' => 'applications/almanac/application/PhabricatorAlmanacApplication.php',
'PhabricatorAmazonAuthProvider' => 'applications/auth/provider/PhabricatorAmazonAuthProvider.php',
'PhabricatorAnchorView' => 'view/layout/PhabricatorAnchorView.php',
@@ -1414,7 +1413,6 @@
'PhabricatorAutoEventListener' => 'infrastructure/events/PhabricatorAutoEventListener.php',
'PhabricatorBarePageUIExample' => 'applications/uiexample/examples/PhabricatorBarePageUIExample.php',
'PhabricatorBarePageView' => 'view/page/PhabricatorBarePageView.php',
- 'PhabricatorBaseEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php',
'PhabricatorBaseProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorBaseProtocolAdapter.php',
'PhabricatorBaseURISetupCheck' => 'applications/config/check/PhabricatorBaseURISetupCheck.php',
'PhabricatorBcryptPasswordHasher' => 'infrastructure/util/password/PhabricatorBcryptPasswordHasher.php',
@@ -1435,6 +1433,7 @@
'PhabricatorBotTarget' => 'infrastructure/daemon/bot/target/PhabricatorBotTarget.php',
'PhabricatorBotUser' => 'infrastructure/daemon/bot/target/PhabricatorBotUser.php',
'PhabricatorBotWhatsNewHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotWhatsNewHandler.php',
+ 'PhabricatorBritishEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorBritishEnglishTranslation.php',
'PhabricatorBuiltinPatchList' => 'infrastructure/storage/patch/PhabricatorBuiltinPatchList.php',
'PhabricatorBusyUIExample' => 'applications/uiexample/examples/PhabricatorBusyUIExample.php',
'PhabricatorCacheDAO' => 'applications/cache/storage/PhabricatorCacheDAO.php',
@@ -1717,7 +1716,6 @@
'PhabricatorEmbedFileRemarkupRule' => 'applications/files/markup/PhabricatorEmbedFileRemarkupRule.php',
'PhabricatorEmojiRemarkupRule' => 'applications/macro/markup/PhabricatorEmojiRemarkupRule.php',
'PhabricatorEmptyQueryException' => 'infrastructure/query/PhabricatorEmptyQueryException.php',
- 'PhabricatorEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorEnglishTranslation.php',
'PhabricatorEnv' => 'infrastructure/env/PhabricatorEnv.php',
'PhabricatorEnvTestCase' => 'infrastructure/env/__tests__/PhabricatorEnvTestCase.php',
'PhabricatorEvent' => 'infrastructure/events/PhabricatorEvent.php',
@@ -2563,7 +2561,6 @@
'PhabricatorTransactions' => 'applications/transactions/constants/PhabricatorTransactions.php',
'PhabricatorTransactionsApplication' => 'applications/transactions/application/PhabricatorTransactionsApplication.php',
'PhabricatorTransformedFile' => 'applications/files/storage/PhabricatorTransformedFile.php',
- 'PhabricatorTranslation' => 'infrastructure/internationalization/translation/PhabricatorTranslation.php',
'PhabricatorTranslationsConfigOptions' => 'applications/config/option/PhabricatorTranslationsConfigOptions.php',
'PhabricatorTriggerAction' => 'infrastructure/daemon/workers/action/PhabricatorTriggerAction.php',
'PhabricatorTriggerClock' => 'infrastructure/daemon/workers/clock/PhabricatorTriggerClock.php',
@@ -2587,6 +2584,7 @@
'PhabricatorUIExample' => 'applications/uiexample/examples/PhabricatorUIExample.php',
'PhabricatorUIExampleRenderController' => 'applications/uiexample/controller/PhabricatorUIExampleRenderController.php',
'PhabricatorUIExamplesApplication' => 'applications/uiexample/application/PhabricatorUIExamplesApplication.php',
+ 'PhabricatorUSEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php',
'PhabricatorUnitsTestCase' => 'view/__tests__/PhabricatorUnitsTestCase.php',
'PhabricatorUnsubscribedFromObjectEdgeType' => 'applications/transactions/edges/PhabricatorUnsubscribedFromObjectEdgeType.php',
'PhabricatorUser' => 'applications/people/storage/PhabricatorUser.php',
@@ -2618,6 +2616,7 @@
'PhabricatorUserTransaction' => 'applications/people/storage/PhabricatorUserTransaction.php',
'PhabricatorUsersPolicyRule' => 'applications/policy/rule/PhabricatorUsersPolicyRule.php',
'PhabricatorVCSResponse' => 'applications/repository/response/PhabricatorVCSResponse.php',
+ 'PhabricatorVeryWowEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorVeryWowEnglishTranslation.php',
'PhabricatorWatcherHasObjectEdgeType' => 'applications/transactions/edges/PhabricatorWatcherHasObjectEdgeType.php',
'PhabricatorWordPressAuthProvider' => 'applications/auth/provider/PhabricatorWordPressAuthProvider.php',
'PhabricatorWorker' => 'infrastructure/daemon/workers/PhabricatorWorker.php',
@@ -4472,7 +4471,6 @@
'PhabricatorActionView' => 'AphrontView',
'PhabricatorActivitySettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorAdministratorsPolicyRule' => 'PhabricatorPolicyRule',
- 'PhabricatorAllCapsTranslation' => 'PhabricatorTranslation',
'PhabricatorAlmanacApplication' => 'PhabricatorApplication',
'PhabricatorAmazonAuthProvider' => 'PhabricatorOAuth2AuthProvider',
'PhabricatorAnchorView' => 'AphrontView',
@@ -4658,7 +4656,6 @@
'PhabricatorAutoEventListener' => 'PhabricatorEventListener',
'PhabricatorBarePageUIExample' => 'PhabricatorUIExample',
'PhabricatorBarePageView' => 'AphrontPageView',
- 'PhabricatorBaseEnglishTranslation' => 'PhabricatorTranslation',
'PhabricatorBaseURISetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorBcryptPasswordHasher' => 'PhabricatorPasswordHasher',
'PhabricatorBinariesSetupCheck' => 'PhabricatorSetupCheck',
@@ -4675,6 +4672,7 @@
'PhabricatorBotSymbolHandler' => 'PhabricatorBotHandler',
'PhabricatorBotUser' => 'PhabricatorBotTarget',
'PhabricatorBotWhatsNewHandler' => 'PhabricatorBotHandler',
+ 'PhabricatorBritishEnglishTranslation' => 'PhutilTranslation',
'PhabricatorBuiltinPatchList' => 'PhabricatorSQLPatchList',
'PhabricatorBusyUIExample' => 'PhabricatorUIExample',
'PhabricatorCacheDAO' => 'PhabricatorLiskDAO',
@@ -4986,7 +4984,6 @@
'PhabricatorEmbedFileRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'PhabricatorEmojiRemarkupRule' => 'PhutilRemarkupRule',
'PhabricatorEmptyQueryException' => 'Exception',
- 'PhabricatorEnglishTranslation' => 'PhabricatorBaseEnglishTranslation',
'PhabricatorEnvTestCase' => 'PhabricatorTestCase',
'PhabricatorEvent' => 'PhutilEvent',
'PhabricatorEventListener' => 'PhutilEventListener',
@@ -5910,6 +5907,7 @@
'PhabricatorUIConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorUIExampleRenderController' => 'PhabricatorController',
'PhabricatorUIExamplesApplication' => 'PhabricatorApplication',
+ 'PhabricatorUSEnglishTranslation' => 'PhutilTranslation',
'PhabricatorUnitsTestCase' => 'PhabricatorTestCase',
'PhabricatorUnsubscribedFromObjectEdgeType' => 'PhabricatorEdgeType',
'PhabricatorUser' => array(
@@ -5954,6 +5952,7 @@
'PhabricatorUserTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorUsersPolicyRule' => 'PhabricatorPolicyRule',
'PhabricatorVCSResponse' => 'AphrontResponse',
+ 'PhabricatorVeryWowEnglishTranslation' => 'PhutilTranslation',
'PhabricatorWatcherHasObjectEdgeType' => 'PhabricatorEdgeType',
'PhabricatorWordPressAuthProvider' => 'PhabricatorOAuth2AuthProvider',
'PhabricatorWorkerActiveTask' => 'PhabricatorWorkerTask',
diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php
--- a/src/applications/base/controller/PhabricatorController.php
+++ b/src/applications/base/controller/PhabricatorController.php
@@ -96,13 +96,9 @@
$request->setUser($user);
}
- $translation = $user->getTranslation();
- if ($translation &&
- $translation != PhabricatorEnv::getEnvConfig('translation.provider')) {
- $translation = newv($translation, array());
- PhutilTranslator::getInstance()
- ->setLanguage($translation->getLanguage())
- ->addTranslations($translation->getCleanTranslations());
+ $locale_code = $user->getTranslation();
+ if ($locale_code) {
+ PhabricatorEnv::setLocaleCode($locale_code);
}
$preferences = $user->loadPreferences();
diff --git a/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php b/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php
--- a/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php
+++ b/src/applications/config/check/PhabricatorExtraConfigSetupCheck.php
@@ -203,6 +203,9 @@
'the server as the user you want it to run under.'),
'notification.debug' => pht(
'Notifications no longer have a dedicated debugging mode.'),
+ 'translation.provider' => pht(
+ 'The translation implementation has changed and providers are no '.
+ 'longer used or supported.'),
);
return $ancient_config;
diff --git a/src/applications/config/option/PhabricatorTranslationsConfigOptions.php b/src/applications/config/option/PhabricatorTranslationsConfigOptions.php
--- a/src/applications/config/option/PhabricatorTranslationsConfigOptions.php
+++ b/src/applications/config/option/PhabricatorTranslationsConfigOptions.php
@@ -21,19 +21,6 @@
public function getOptions() {
return array(
- $this->newOption(
- 'translation.provider',
- 'class',
- 'PhabricatorEnglishTranslation')
- ->setBaseClass('PhabricatorTranslation')
- ->setSummary(pht('Translation class that should be used for strings.'))
- ->setDescription(
- pht(
- 'This allows customizing texts used in Phabricator. The class '.
- 'must extend PhabricatorTranslation.'))
- ->addExample('PhabricatorEnglishTranslation', pht('Valid Setting')),
- // TODO: This should be dict<string,string> I think, but that doesn't
- // exist yet.
$this->newOption('translation.override', 'wild', array())
->setSummary(pht('Override translations.'))
->setDescription(
diff --git a/src/applications/people/storage/PhabricatorUser.php b/src/applications/people/storage/PhabricatorUser.php
--- a/src/applications/people/storage/PhabricatorUser.php
+++ b/src/applications/people/storage/PhabricatorUser.php
@@ -190,19 +190,6 @@
return '@'.$this->getUsername();
}
- public function getTranslation() {
- try {
- if ($this->translation &&
- class_exists($this->translation) &&
- is_subclass_of($this->translation, 'PhabricatorTranslation')) {
- return $this->translation;
- }
- } catch (PhutilMissingSymbolException $ex) {
- return null;
- }
- return null;
- }
-
public function isLoggedIn() {
return !($this->getPHID() === null);
}
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
@@ -64,20 +64,28 @@
PhutilPerson::SEX_FEMALE => $label_her,
);
+ $locales = PhutilLocale::loadAllLocales();
+ $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
+ $is_dev = PhabricatorEnv::getEnvConfig('phabricator.developer-mode');
+
$translations = array();
- $symbols = id(new PhutilSymbolLoader())
- ->setType('class')
- ->setAncestorClass('PhabricatorTranslation')
- ->setConcreteOnly(true)
- ->selectAndLoadSymbols();
- foreach ($symbols as $symbol) {
- $class = $symbol['name'];
- $translations[$class] = newv($class, array())->getName();
+ 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);
- $default = PhabricatorEnv::newObjectFromConfig('translation.provider');
+ // TODO: Implement "locale.default" and use it here.
+ $default = 'en_US';
$translations = array(
- '' => pht('Server Default (%s)', $default->getName()),
+ '' => pht('Server Default: %s', $locales[$default]->getLocaleName()),
) + $translations;
$form = new AphrontFormView();
diff --git a/src/docs/contributor/internationalization.diviner b/src/docs/contributor/internationalization.diviner
--- a/src/docs/contributor/internationalization.diviner
+++ b/src/docs/contributor/internationalization.diviner
@@ -1,33 +1,33 @@
@title Internationalization
@group developer
-What is required from developers to get Phabricator translatable.
+Describes Phabricator translation and localization.
-= API =
+Overview
+========
-Translator API is provided by libphutil. It gives us
-@{class@libphutil:PhutilTranslator} class and global @{function@libphutil:pht}
-function built on top of it.
+Phabricator partially supports internationalization, but many of the tools
+are missing or in a prototype state.
-Developers are supposed to call @{function@libphutil:pht} on all strings that
-require translation.
+This document very briefly summarizes some of what exists today.
-Phabricator provides translations for this translator through
-@{class:PhabricatorTranslation} class.
+Writing Translatable Code
+========
-= Adding a New Translation =
+Strings are marked for translation with @{function@libphutil:pht}.
-Adding a translation which uses the same language rules as some already existing
-translation is relatively simple: Just extend @{class:PhabricatorTranslation}
-and you will be able to specify this class in the global configuration
-'translation.provider' and users will be able to select it in their preferences.
+Adding a New Locale
+=========
-= Adding a New Language =
+To add a new locale, subclass @{class:PhutilLocale}.
-Adding a language involves all steps as adding a translation plus specifying the
-language rules in @{method@libphutil:PhutilTranslator::chooseVariant}.
+Translating Strings
+========
-= Singular and Plural =
+To translate strings, subclass @{class:PhutilTranslation}.
+
+Singular and Plural
+========
Different languages have various rules for using singular and plural. All you
need to do is to call @{function@libphutil:pht} with a text that is suitable for
@@ -46,7 +46,8 @@
The ugly identifier passed to @{function@libphutil:pht} will remain in the text
only if the translation doesn't exist.
-= Male and Female =
+Male and Female
+========
Different languages use different words for talking about males, females and
unknown genders. Callsites have to call @{function@libphutil:pht} passing
diff --git a/src/infrastructure/env/PhabricatorEnv.php b/src/infrastructure/env/PhabricatorEnv.php
--- a/src/infrastructure/env/PhabricatorEnv.php
+++ b/src/infrastructure/env/PhabricatorEnv.php
@@ -55,6 +55,7 @@
private static $overrideSource;
private static $requestBaseURI;
private static $cache;
+ private static $localeCode;
/**
* @phutil-external-symbol class PhabricatorStartup
@@ -123,10 +124,34 @@
PhabricatorEventEngine::initialize();
- $translation = PhabricatorEnv::newObjectFromConfig('translation.provider');
- PhutilTranslator::getInstance()
- ->setLanguage($translation->getLanguage())
- ->addTranslations($translation->getCleanTranslations());
+ // TODO: Add a "locale.default" config option once we have some reasonable
+ // defaults which aren't silly nonsense.
+ self::setLocaleCode('en_US');
+ }
+
+ public static function setLocaleCode($locale_code) {
+ if ($locale_code == self::$localeCode) {
+ return;
+ }
+
+ try {
+ $locale = PhutilLocale::loadLocale($locale_code);
+ $translations = PhutilTranslation::getTranslationMapForLocale(
+ $locale_code);
+
+ $override = PhabricatorEnv::getEnvConfig('translation.override');
+ if (!is_array($override)) {
+ $override = array();
+ }
+
+ PhutilTranslator::getInstance()
+ ->setLocale($locale)
+ ->setTranslations($override + $translations);
+
+ self::$localeCode = $locale_code;
+ } catch (Exception $ex) {
+ // Just ignore this; the user likely has an out-of-date locale code.
+ }
}
private static function buildConfigurationSourceStack() {
diff --git a/src/infrastructure/internationalization/translation/PhabricatorAllCapsTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorAllCapsTranslation.php
deleted file mode 100644
--- a/src/infrastructure/internationalization/translation/PhabricatorAllCapsTranslation.php
+++ /dev/null
@@ -1,18 +0,0 @@
-<?php
-
-final class PhabricatorAllCapsTranslation
- extends PhabricatorTranslation {
-
- final public function getLanguage() {
- return 'en-ac';
- }
-
- public function getName() {
- return 'All Caps';
- }
-
- public function getTranslations() {
- return array();
- }
-
-}
diff --git a/src/infrastructure/internationalization/translation/PhabricatorBritishEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorBritishEnglishTranslation.php
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/internationalization/translation/PhabricatorBritishEnglishTranslation.php
@@ -0,0 +1,31 @@
+<?php
+
+final class PhabricatorBritishEnglishTranslation
+ extends PhutilTranslation {
+
+ public function getLocaleCode() {
+ return 'en_GB';
+ }
+
+ protected function getTranslations() {
+ return array(
+ '%s set this project\'s color to %s.' =>
+ '%s set this project\'s colour to %s.',
+ 'Basic Colors' =>
+ 'Basic Colours',
+ 'Choose Icon and Color...' =>
+ 'Choose Icon and Colour...',
+ 'Choose Background Color' =>
+ 'Choose Background Colour',
+ 'Color' => 'Colour',
+ 'Colors' => 'Colours',
+ 'Colors and Transforms' => 'Colours and Transforms',
+ 'Configure the Phabricator UI, including colors.' =>
+ 'Configure the Phabricator UI, including colours.',
+ 'Flag Color' => 'Flag Colour',
+ 'Sets the color of the main header.' =>
+ 'Sets the colour of the main header.',
+ );
+ }
+
+}
diff --git a/src/infrastructure/internationalization/translation/PhabricatorEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorEnglishTranslation.php
deleted file mode 100644
--- a/src/infrastructure/internationalization/translation/PhabricatorEnglishTranslation.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-final class PhabricatorEnglishTranslation
- extends PhabricatorBaseEnglishTranslation {
-
- public function getName() {
- return 'English';
- }
-
- public function getTranslations() {
- return
- PhabricatorEnv::getEnvConfig('translation.override') +
- parent::getTranslations();
- }
-
-}
diff --git a/src/infrastructure/internationalization/translation/PhabricatorTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorTranslation.php
deleted file mode 100644
--- a/src/infrastructure/internationalization/translation/PhabricatorTranslation.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-abstract class PhabricatorTranslation {
-
- abstract public function getLanguage();
- abstract public function getName();
- abstract public function getTranslations();
-
-
- /**
- * Return the cleaned translation array.
- *
- * @return dict<string, wild> Translation map with empty translations removed.
- */
- public function getCleanTranslations() {
- return $this->clean($this->getTranslations());
- }
-
-
- /**
- * Removes NULL-valued translation keys from the translation map, to prevent
- * echoing out empty strings.
- *
- * @param dict<string, wild> Translation map, with empty translations.
- * @return dict<string, wild> Map with empty translations removed.
- */
- protected function clean(array $translation_array) {
- foreach ($translation_array as $key => $translation_string) {
- if ($translation_string === null) {
- unset($translation_array[$key]);
- }
- }
-
- return $translation_array;
- }
-
-}
diff --git a/src/infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
rename from src/infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php
rename to src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
--- a/src/infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php
+++ b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
@@ -1,13 +1,13 @@
<?php
-abstract class PhabricatorBaseEnglishTranslation
- extends PhabricatorTranslation {
+final class PhabricatorUSEnglishTranslation
+ extends PhutilTranslation {
- final public function getLanguage() {
- return 'en';
+ public function getLocaleCode() {
+ return 'en_US';
}
- public function getTranslations() {
+ protected function getTranslations() {
return array(
'No daemon(s) with id(s) "%s" exist!' => array(
'No daemon with id %s exists!',
diff --git a/src/infrastructure/internationalization/translation/PhabricatorVeryWowEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorVeryWowEnglishTranslation.php
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/internationalization/translation/PhabricatorVeryWowEnglishTranslation.php
@@ -0,0 +1,22 @@
+<?php
+
+final class PhabricatorVeryWowEnglishTranslation
+ extends PhutilTranslation {
+
+ public function getLocaleCode() {
+ return 'en_W*';
+ }
+
+ protected function getTranslations() {
+ return array(
+ 'Search' => 'Search! Wow!',
+ 'Review Code' => 'Wow! Code Review! Wow!',
+ 'Tasks and Bugs' => 'Much Bug! Very Bad!',
+ 'Cancel' => 'Nope!',
+ 'Advanced Search' => 'Much Search!',
+ 'No search results.' => 'No results! Wow!',
+ 'Send Message' => 'Bark! Bark Bark!',
+ );
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Thu, Nov 21, 1:34 PM (21 h, 55 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6716835
Default Alt Text
D11747.diff (22 KB)

Event Timeline