Page MenuHomePhabricator

D13142.id31774.diff
No OneTemporary

D13142.id31774.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
@@ -1976,6 +1976,8 @@
'PhabricatorListFilterUIExample' => 'applications/uiexample/examples/PhabricatorListFilterUIExample.php',
'PhabricatorLocalDiskFileStorageEngine' => 'applications/files/engine/PhabricatorLocalDiskFileStorageEngine.php',
'PhabricatorLocalTimeTestCase' => 'view/__tests__/PhabricatorLocalTimeTestCase.php',
+ 'PhabricatorLocaleScopeGuard' => 'infrastructure/internationalization/scope/PhabricatorLocaleScopeGuard.php',
+ 'PhabricatorLocaleScopeGuardTestCase' => 'infrastructure/internationalization/scope/__tests__/PhabricatorLocaleScopeGuardTestCase.php',
'PhabricatorLogTriggerAction' => 'infrastructure/daemon/workers/action/PhabricatorLogTriggerAction.php',
'PhabricatorLogoutController' => 'applications/auth/controller/PhabricatorLogoutController.php',
'PhabricatorLunarPhasePolicyRule' => 'applications/policy/rule/PhabricatorLunarPhasePolicyRule.php',
@@ -5389,6 +5391,8 @@
'PhabricatorListFilterUIExample' => 'PhabricatorUIExample',
'PhabricatorLocalDiskFileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorLocalTimeTestCase' => 'PhabricatorTestCase',
+ 'PhabricatorLocaleScopeGuard' => 'Phobject',
+ 'PhabricatorLocaleScopeGuardTestCase' => 'PhabricatorTestCase',
'PhabricatorLogTriggerAction' => 'PhabricatorTriggerAction',
'PhabricatorLogoutController' => 'PhabricatorAuthController',
'PhabricatorLunarPhasePolicyRule' => 'PhabricatorPolicyRule',
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
@@ -114,10 +114,7 @@
$request->setUser($user);
}
- $locale_code = $user->getTranslation();
- if ($locale_code) {
- PhabricatorEnv::setLocaleCode($locale_code);
- }
+ PhabricatorEnv::setLocaleCode($user->getTranslation());
$preferences = $user->loadPreferences();
if (PhabricatorEnv::getEnvConfig('darkconsole.enabled')) {
diff --git a/src/applications/repository/worker/PhabricatorRepositoryPushMailWorker.php b/src/applications/repository/worker/PhabricatorRepositoryPushMailWorker.php
--- a/src/applications/repository/worker/PhabricatorRepositoryPushMailWorker.php
+++ b/src/applications/repository/worker/PhabricatorRepositoryPushMailWorker.php
@@ -42,7 +42,8 @@
$task_data = $this->getTaskData();
$viewer = $target->getViewer();
- // TODO: Swap locale to viewer locale.
+
+ $locale = PhabricatorEnv::beginScopedLocale($viewer->getTranslation());
$logs = $event->getLogs();
diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
--- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
+++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
@@ -2139,8 +2139,10 @@
$mailed = array();
foreach ($targets as $target) {
$original_actor = $this->getActor();
- $this->setActor($target->getViewer());
- // TODO: Swap locale to viewer locale.
+
+ $viewer = $target->getViewer();
+ $this->setActor($viewer);
+ $locale = PhabricatorEnv::beginScopedLocale($viewer->getTranslation());
$caught = null;
try {
@@ -2153,6 +2155,8 @@
}
$this->setActor($original_actor);
+ unset($locale);
+
if ($caught) {
throw $ex;
}
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
@@ -129,7 +129,19 @@
self::setLocaleCode('en_US');
}
+ public static function beginScopedLocale($locale_code) {
+ return new PhabricatorLocaleScopeGuard($locale_code);
+ }
+
+ public static function getLocaleCode() {
+ return self::$localeCode;
+ }
+
public static function setLocaleCode($locale_code) {
+ if (!$locale_code) {
+ return;
+ }
+
if ($locale_code == self::$localeCode) {
return;
}
diff --git a/src/infrastructure/internationalization/scope/PhabricatorLocaleScopeGuard.php b/src/infrastructure/internationalization/scope/PhabricatorLocaleScopeGuard.php
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/internationalization/scope/PhabricatorLocaleScopeGuard.php
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * Change the effective locale for the lifetime of this guard.
+ *
+ * Use @{method:PhabricatorEnv::beginScopedLocale} to acquire a guard.
+ * Guards are released when they exit scope.
+ */
+final class PhabricatorLocaleScopeGuard
+ extends Phobject {
+
+ private static $stack = array();
+ private $key;
+ private $destroyed;
+
+ public function __construct($code) {
+ // If this is the first time we're building a guard, push the default
+ // locale onto the bottom of the stack. We'll never remove it.
+ if (empty(self::$stack)) {
+ self::$stack[] = PhabricatorEnv::getLocaleCode();
+ }
+
+ // If there's no locale, use the server default locale.
+ if (!$code) {
+ $code = self::$stack[0];
+ }
+
+ // Push this new locale onto the stack and set it as the active locale.
+ // We keep track of which key this guard owns, in case guards are destroyed
+ // out-of-order.
+ self::$stack[] = $code;
+ $this->key = last_key(self::$stack);
+
+ PhabricatorEnv::setLocaleCode($code);
+ }
+
+ public function __destruct() {
+ if ($this->destroyed) {
+ return;
+ }
+ $this->destroyed = true;
+
+ // Remove this locale from the stack and set the new active locale. Usually,
+ // we're the last item on the stack, so this shortens the stack by one item
+ // and sets the locale underneath. However, it's possible that guards are
+ // being destroyed out of order, so we might just be removing an item
+ // somewhere in the middle of the stack. In this case, we won't actually
+ // change the locale, just set it to its current value again.
+
+ unset(self::$stack[$this->key]);
+ PhabricatorEnv::setLocaleCode(end(self::$stack));
+ }
+
+}
diff --git a/src/infrastructure/internationalization/scope/__tests__/PhabricatorLocaleScopeGuardTestCase.php b/src/infrastructure/internationalization/scope/__tests__/PhabricatorLocaleScopeGuardTestCase.php
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/internationalization/scope/__tests__/PhabricatorLocaleScopeGuardTestCase.php
@@ -0,0 +1,38 @@
+<?php
+
+final class PhabricatorLocaleScopeGuardTestCase
+ extends PhabricatorTestCase {
+
+ public function testLocaleScopeGuard() {
+ $original = PhabricatorEnv::getLocaleCode();
+
+ // Set a guard; it should change the locale, then revert it when destroyed.
+ $guard = PhabricatorEnv::beginScopedLocale('en_GB');
+ $this->assertEqual('en_GB', PhabricatorEnv::getLocaleCode());
+ unset($guard);
+ $this->assertEqual($original, PhabricatorEnv::getLocaleCode());
+
+ // Nest guards, then destroy them out of order.
+ $guard1 = PhabricatorEnv::beginScopedLocale('en_GB');
+ $this->assertEqual('en_GB', PhabricatorEnv::getLocaleCode());
+ $guard2 = PhabricatorEnv::beginScopedLocale('en_A*');
+ $this->assertEqual('en_A*', PhabricatorEnv::getLocaleCode());
+ unset($guard1);
+ $this->assertEqual('en_A*', PhabricatorEnv::getLocaleCode());
+ unset($guard2);
+ $this->assertEqual($original, PhabricatorEnv::getLocaleCode());
+
+ // If you push `null`, that should mean "the default locale", not
+ // "the current locale".
+ $guard3 = PhabricatorEnv::beginScopedLocale('en_GB');
+ $this->assertEqual('en_GB', PhabricatorEnv::getLocaleCode());
+ $guard4 = PhabricatorEnv::beginScopedLocale(null);
+ $this->assertEqual($original, PhabricatorEnv::getLocaleCode());
+ unset($guard4);
+ $this->assertEqual('en_GB', PhabricatorEnv::getLocaleCode());
+ unset($guard3);
+ $this->assertEqual($original, PhabricatorEnv::getLocaleCode());
+
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Sun, Oct 20, 2:12 PM (4 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6716008
Default Alt Text
D13142.id31774.diff (8 KB)

Event Timeline