@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

Write a very basic string extractor

Summary: Ref T1139. This has some issues and glitches, but is a reasonable initial attempt that gets some of the big pieces in. We have about 5,200 strings in Phabricator.

Test Plan: {F108261}

Reviewers: btrahan

Reviewed By: btrahan

CC: aran, chad

Maniphest Tasks: T1139

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

+136 -5
+1
bin/i18n
··· 1 + ../scripts/setup/manage_i18n.php
+21
scripts/setup/manage_i18n.php
··· 1 + #!/usr/bin/env php 2 + <?php 3 + 4 + $root = dirname(dirname(dirname(__FILE__))); 5 + require_once $root.'/scripts/__init_script__.php'; 6 + 7 + $args = new PhutilArgumentParser($argv); 8 + $args->setTagline('manage internationalization'); 9 + $args->setSynopsis(<<<EOSYNOPSIS 10 + **i18n** __command__ [__options__] 11 + Manage translations and internationalization. 12 + 13 + EOSYNOPSIS 14 + ); 15 + $args->parseStandardArguments(); 16 + 17 + $workflows = id(new PhutilSymbolLoader()) 18 + ->setAncestorClass('PhabricatorInternationalizationManagementWorkflow') 19 + ->loadObjects(); 20 + $workflows[] = new PhutilHelpArgumentWorkflow(); 21 + $args->parseWorkflows($workflows);
+8 -4
src/__phutil_library_map__.php
··· 1066 1066 'PhabricatorActionListExample' => 'applications/uiexample/examples/PhabricatorActionListExample.php', 1067 1067 'PhabricatorActionListView' => 'view/layout/PhabricatorActionListView.php', 1068 1068 'PhabricatorActionView' => 'view/layout/PhabricatorActionView.php', 1069 - 'PhabricatorAllCapsTranslation' => 'infrastructure/internationalization/PhabricatorAllCapsTranslation.php', 1069 + 'PhabricatorAllCapsTranslation' => 'infrastructure/internationalization/translation/PhabricatorAllCapsTranslation.php', 1070 1070 'PhabricatorAnchorView' => 'view/layout/PhabricatorAnchorView.php', 1071 1071 'PhabricatorAphrontBarExample' => 'applications/uiexample/examples/PhabricatorAphrontBarExample.php', 1072 1072 'PhabricatorAphrontViewTestCase' => 'view/__tests__/PhabricatorAphrontViewTestCase.php', ··· 1230 1230 'PhabricatorAuthenticationConfigOptions' => 'applications/config/option/PhabricatorAuthenticationConfigOptions.php', 1231 1231 'PhabricatorBarePageExample' => 'applications/uiexample/examples/PhabricatorBarePageExample.php', 1232 1232 'PhabricatorBarePageView' => 'view/page/PhabricatorBarePageView.php', 1233 - 'PhabricatorBaseEnglishTranslation' => 'infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php', 1233 + 'PhabricatorBaseEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php', 1234 1234 'PhabricatorBaseProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorBaseProtocolAdapter.php', 1235 1235 'PhabricatorBot' => 'infrastructure/daemon/bot/PhabricatorBot.php', 1236 1236 'PhabricatorBotBaseStreamingProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorBotBaseStreamingProtocolAdapter.php', ··· 1434 1434 'PhabricatorEmailTokenController' => 'applications/auth/controller/PhabricatorEmailTokenController.php', 1435 1435 'PhabricatorEmailVerificationController' => 'applications/auth/controller/PhabricatorEmailVerificationController.php', 1436 1436 'PhabricatorEmptyQueryException' => 'infrastructure/query/PhabricatorEmptyQueryException.php', 1437 - 'PhabricatorEnglishTranslation' => 'infrastructure/internationalization/PhabricatorEnglishTranslation.php', 1437 + 'PhabricatorEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorEnglishTranslation.php', 1438 1438 'PhabricatorEnv' => 'infrastructure/env/PhabricatorEnv.php', 1439 1439 'PhabricatorEnvTestCase' => 'infrastructure/env/__tests__/PhabricatorEnvTestCase.php', 1440 1440 'PhabricatorErrorExample' => 'applications/uiexample/examples/PhabricatorErrorExample.php', ··· 1573 1573 'PhabricatorInlineCommentInterface' => 'infrastructure/diff/interface/PhabricatorInlineCommentInterface.php', 1574 1574 'PhabricatorInlineCommentPreviewController' => 'infrastructure/diff/PhabricatorInlineCommentPreviewController.php', 1575 1575 'PhabricatorInlineSummaryView' => 'infrastructure/diff/view/PhabricatorInlineSummaryView.php', 1576 + 'PhabricatorInternationalizationManagementExtractWorkflow' => 'infrastructure/internationalization/management/PhabricatorInternationalizationManagementExtractWorkflow.php', 1577 + 'PhabricatorInternationalizationManagementWorkflow' => 'infrastructure/internationalization/management/PhabricatorInternationalizationManagementWorkflow.php', 1576 1578 'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/PhabricatorJavelinLinter.php', 1577 1579 'PhabricatorJumpNavHandler' => 'applications/search/engine/PhabricatorJumpNavHandler.php', 1578 1580 'PhabricatorKeyValueDatabaseCache' => 'applications/cache/PhabricatorKeyValueDatabaseCache.php', ··· 2098 2100 'PhabricatorTransactionView' => 'view/layout/PhabricatorTransactionView.php', 2099 2101 'PhabricatorTransactions' => 'applications/transactions/constants/PhabricatorTransactions.php', 2100 2102 'PhabricatorTransformedFile' => 'applications/files/storage/PhabricatorTransformedFile.php', 2101 - 'PhabricatorTranslation' => 'infrastructure/internationalization/PhabricatorTranslation.php', 2103 + 'PhabricatorTranslation' => 'infrastructure/internationalization/translation/PhabricatorTranslation.php', 2102 2104 'PhabricatorTranslationsConfigOptions' => 'applications/config/option/PhabricatorTranslationsConfigOptions.php', 2103 2105 'PhabricatorTrivialTestCase' => 'infrastructure/testing/__tests__/PhabricatorTrivialTestCase.php', 2104 2106 'PhabricatorTwoColumnExample' => 'applications/uiexample/examples/PhabricatorTwoColumnExample.php', ··· 4270 4272 'PhabricatorInlineCommentInterface' => 'PhabricatorMarkupInterface', 4271 4273 'PhabricatorInlineCommentPreviewController' => 'PhabricatorController', 4272 4274 'PhabricatorInlineSummaryView' => 'AphrontView', 4275 + 'PhabricatorInternationalizationManagementExtractWorkflow' => 'PhabricatorInternationalizationManagementWorkflow', 4276 + 'PhabricatorInternationalizationManagementWorkflow' => 'PhabricatorManagementWorkflow', 4273 4277 'PhabricatorJavelinLinter' => 'ArcanistLinter', 4274 4278 'PhabricatorKeyValueDatabaseCache' => 'PhutilKeyValueCache', 4275 4279 'PhabricatorLegalpadConfigOptions' => 'PhabricatorApplicationConfigOptions',
+1 -1
src/aphront/AphrontRequest.php
··· 357 357 'This Phabricator install is configured as "%s", but you are '. 358 358 'using the domain name "%s" to access a page which is trying to '. 359 359 'set a cookie. Acccess Phabricator on the configured primary '. 360 - 'domain or a configured alternate domain. Phabricator will not '. 360 + 'domain or a configured alternate domain. Phabricator will not '. 361 361 'set cookies on other domains for security reasons.', 362 362 $configured_as, 363 363 $accessed_as));
src/infrastructure/internationalization/PhabricatorAllCapsTranslation.php src/infrastructure/internationalization/translation/PhabricatorAllCapsTranslation.php
src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php src/infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php
src/infrastructure/internationalization/PhabricatorEnglishTranslation.php src/infrastructure/internationalization/translation/PhabricatorEnglishTranslation.php
src/infrastructure/internationalization/PhabricatorTranslation.php src/infrastructure/internationalization/translation/PhabricatorTranslation.php
+99
src/infrastructure/internationalization/management/PhabricatorInternationalizationManagementExtractWorkflow.php
··· 1 + <?php 2 + 3 + final class PhabricatorInternationalizationManagementExtractWorkflow 4 + extends PhabricatorInternationalizationManagementWorkflow { 5 + 6 + public function didConstruct() { 7 + $this 8 + ->setName('extract') 9 + ->setSynopsis(pht('Extract translatable strings.')) 10 + ->setArguments( 11 + array( 12 + array( 13 + 'name' => 'paths', 14 + 'wildcard' => true, 15 + ), 16 + )); 17 + } 18 + 19 + public function execute(PhutilArgumentParser $args) { 20 + $console = PhutilConsole::getConsole(); 21 + $paths = $args->getArg('paths'); 22 + 23 + $futures = array(); 24 + foreach ($paths as $path) { 25 + $root = Filesystem::resolvePath($path); 26 + $path_files = id(new FileFinder($root)) 27 + ->withType('f') 28 + ->withSuffix('php') 29 + ->find(); 30 + 31 + foreach ($path_files as $file) { 32 + $full_path = $root.DIRECTORY_SEPARATOR.$file; 33 + $data = Filesystem::readFile($full_path); 34 + $futures[$full_path] = xhpast_get_parser_future($data); 35 + } 36 + } 37 + 38 + $console->writeOut( 39 + "%s\n", 40 + pht('Found %s file(s)...', new PhutilNumber(count($futures)))); 41 + 42 + $results = array(); 43 + 44 + $bar = id(new PhutilConsoleProgressBar()) 45 + ->setTotal(count($futures)); 46 + foreach (Futures($futures)->limit(8) as $full_path => $future) { 47 + $bar->update(1); 48 + 49 + $tree = XHPASTTree::newFromDataAndResolvedExecFuture( 50 + Filesystem::readFile($full_path), 51 + $future->resolve()); 52 + 53 + $root = $tree->getRootNode(); 54 + $calls = $root->selectDescendantsOfType('n_FUNCTION_CALL'); 55 + foreach ($calls as $call) { 56 + $name = $call->getChildByIndex(0)->getConcreteString(); 57 + if ($name == 'pht') { 58 + $params = $call->getChildByIndex(1, 'n_CALL_PARAMETER_LIST'); 59 + $string_node = $params->getChildByIndex(0); 60 + $string_line = $string_node->getLineNumber(); 61 + try { 62 + $string_value = $string_node->evalStatic(); 63 + 64 + $results[$string_value][] = array( 65 + 'file' => Filesystem::readablePath($full_path), 66 + 'line' => $string_line, 67 + ); 68 + } catch (Exception $ex) { 69 + // TODO: Deal with this junks. 70 + } 71 + } 72 + } 73 + 74 + $tree->dispose(); 75 + } 76 + $bar->done(); 77 + 78 + ksort($results); 79 + 80 + $out = array(); 81 + $out[] = '<?php'; 82 + $out[] = '// @nolint'; 83 + $out[] = 'return array('; 84 + foreach ($results as $string => $locations) { 85 + foreach ($locations as $location) { 86 + $out[] = ' // '.$location['file'].':'.$location['line']; 87 + } 88 + $out[] = " '".addcslashes($string, "\0..\37\\'\177..\377")."' => null,"; 89 + $out[] = null; 90 + } 91 + $out[] = ');'; 92 + $out[] = null; 93 + 94 + echo implode("\n", $out); 95 + 96 + return 0; 97 + } 98 + 99 + }
+6
src/infrastructure/internationalization/management/PhabricatorInternationalizationManagementWorkflow.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorInternationalizationManagementWorkflow 4 + extends PhabricatorManagementWorkflow { 5 + 6 + }