@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator

Allow user override translation and implement PhutilPerson

Test Plan:
Altered database.
Wrote a custom translation and selected it in preferences.
Verified that the text is custom translated.
Set language back to default.

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T1139

Differential Revision: https://secure.phabricator.com/D2757

vrana 48ebcf06 ec819c06

+63 -6
+2
resources/sql/patches/usertranslation.sql
··· 1 + ALTER TABLE `{$NAMESPACE}_user`.`user` 2 + ADD `translation` varchar(64) COLLATE utf8_bin AFTER `sex`;
+5 -1
src/__phutil_library_map__.php
··· 1908 1908 'PhabricatorUIPagerExample' => 'PhabricatorUIExample', 1909 1909 'PhabricatorUITooltipExample' => 'PhabricatorUIExample', 1910 1910 'PhabricatorUnitsTestCase' => 'PhabricatorTestCase', 1911 - 'PhabricatorUser' => 'PhabricatorUserDAO', 1911 + 'PhabricatorUser' => 1912 + array( 1913 + 0 => 'PhabricatorUserDAO', 1914 + 1 => 'PhutilPerson', 1915 + ), 1912 1916 'PhabricatorUserAccountSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 1913 1917 'PhabricatorUserConduitSettingsPanelController' => 'PhabricatorUserSettingsPanelController', 1914 1918 'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
+11
src/applications/base/controller/PhabricatorController.php
··· 60 60 } 61 61 } 62 62 63 + $translation = $user->getTranslation(); 64 + if ($translation && 65 + $translation != PhabricatorEnv::getEnvConfig('translation.provider') && 66 + class_exists($translation) && 67 + is_subclass_of($translation, 'PhabricatorTranslation')) { 68 + $translation = newv($translation, array()); 69 + PhutilTranslator::getInstance() 70 + ->setLanguage($translation->getLanguage()) 71 + ->addTranslations($translation->getTranslations()); 72 + } 73 + 63 74 $request->setUser($user); 64 75 65 76 if ($user->getIsDisabled() && $this->shouldRequireEnabledUser()) {
+30 -4
src/applications/people/controller/settings/panels/PhabricatorUserProfileSettingsPanelController.php
··· 41 41 $profile->setBlurb($request->getStr('blurb')); 42 42 43 43 $sex = $request->getStr('sex'); 44 - if (in_array($sex, array('m', 'f'))) { 44 + $sexes = array(PhutilPerson::SEX_MALE, PhutilPerson::SEX_FEMALE); 45 + if (in_array($sex, $sexes)) { 45 46 $user->setSex($sex); 46 47 } else { 47 48 $user->setSex(null); 48 49 } 50 + 51 + // Checked in runtime. 52 + $user->setTranslation($request->getStr('translation')); 49 53 50 54 if (!empty($_FILES['image'])) { 51 55 $err = idx($_FILES['image'], 'error'); ··· 111 115 $profile_uri = PhabricatorEnv::getURI('/p/'.$user->getUsername().'/'); 112 116 113 117 $sexes = array( 114 - '' => 'Unknown', 115 - 'm' => 'Male', 116 - 'f' => 'Female', 118 + PhutilPerson::SEX_UNKNOWN => 'Unknown', 119 + PhutilPerson::SEX_MALE => 'Male', 120 + PhutilPerson::SEX_FEMALE => 'Female', 117 121 ); 118 122 123 + $translations = array(); 124 + $symbols = id(new PhutilSymbolLoader()) 125 + ->setType('class') 126 + ->setAncestorClass('PhabricatorTranslation') 127 + ->setConcreteOnly(true) 128 + ->selectAndLoadSymbols(); 129 + foreach ($symbols as $symbol) { 130 + $class = $symbol['name']; 131 + $translations[$class] = newv($class, array())->getName(); 132 + } 133 + asort($translations); 134 + $default = PhabricatorEnv::newObjectFromConfig('translation.provider'); 135 + $translations = array( 136 + '' => 'Sever Default ('.$default->getName().')', 137 + ) + $translations; 138 + 119 139 $form = new AphrontFormView(); 120 140 $form 121 141 ->setUser($request->getUser()) ··· 133 153 ->setLabel('Sex') 134 154 ->setName('sex') 135 155 ->setValue($user->getSex())) 156 + ->appendChild( 157 + id(new AphrontFormSelectControl()) 158 + ->setOptions($translations) 159 + ->setLabel('Translation') 160 + ->setName('translation') 161 + ->setValue($user->getTranslation())) 136 162 ->appendChild( 137 163 id(new AphrontFormMarkupControl()) 138 164 ->setLabel('Profile URI')
+11 -1
src/applications/people/storage/PhabricatorUser.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 - final class PhabricatorUser extends PhabricatorUserDAO { 19 + final class PhabricatorUser extends PhabricatorUserDAO implements PhutilPerson { 20 20 21 21 const SESSION_TABLE = 'phabricator_session'; 22 22 const NAMETOKEN_TABLE = 'user_nametoken'; ··· 25 25 protected $userName; 26 26 protected $realName; 27 27 protected $sex; 28 + protected $translation; 28 29 protected $passwordSalt; 29 30 protected $passwordHash; 30 31 protected $profileImagePHID; ··· 88 89 $this->setPasswordHash($hash); 89 90 } 90 91 return $this; 92 + } 93 + 94 + // To satisfy PhutilPerson. 95 + public function getSex() { 96 + return $this->sex; 91 97 } 92 98 93 99 public function isLoggedIn() { ··· 622 628 623 629 public function getFullName() { 624 630 return $this->getUsername().' ('.$this->getRealName().')'; 631 + } 632 + 633 + public function __toString() { 634 + return $this->getUsername(); 625 635 } 626 636 627 637 public static function loadOneWithEmailAddress($address) {
+4
src/infrastructure/setup/sql/PhabricatorBuiltinPatchList.php
··· 891 891 'type' => 'sql', 892 892 'name' => $this->getPatchPath('threadtopic.sql'), 893 893 ), 894 + 'usertranslation.sql' => array( 895 + 'type' => 'sql', 896 + 'name' => $this->getPatchPath('usertranslation.sql'), 897 + ), 894 898 ); 895 899 } 896 900