@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

Implement "@{config:...}" as a real Remarkup rule

Summary:
See <https://discourse.phabricator-community.org/t/firehose-webhook-not-working-with-self-hosted-requestbin-instance/2240/>. I want to make it easier to link to configuration from system text.

We currently use this weird hack with `{{...}}` that only works within Config itself. Instead, use `@{config:...}`, which is already used by Diviner for `@{class:...}`, etc., so it shouldn't conflict with anything.

Test Plan: Viewed config options, clicked links to other config options.

Reviewers: amckinley

Reviewed By: amckinley

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

+56 -9
+2
src/__phutil_library_map__.php
··· 2672 2672 'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php', 2673 2673 'PhabricatorConfigPurgeCacheController' => 'applications/config/controller/PhabricatorConfigPurgeCacheController.php', 2674 2674 'PhabricatorConfigRegexOptionType' => 'applications/config/custom/PhabricatorConfigRegexOptionType.php', 2675 + 'PhabricatorConfigRemarkupRule' => 'infrastructure/markup/rule/PhabricatorConfigRemarkupRule.php', 2675 2676 'PhabricatorConfigRequestExceptionHandlerModule' => 'applications/config/module/PhabricatorConfigRequestExceptionHandlerModule.php', 2676 2677 'PhabricatorConfigResponse' => 'applications/config/response/PhabricatorConfigResponse.php', 2677 2678 'PhabricatorConfigSchemaQuery' => 'applications/config/schema/PhabricatorConfigSchemaQuery.php', ··· 8409 8410 'PhabricatorConfigProxySource' => 'PhabricatorConfigSource', 8410 8411 'PhabricatorConfigPurgeCacheController' => 'PhabricatorConfigController', 8411 8412 'PhabricatorConfigRegexOptionType' => 'PhabricatorConfigJSONOptionType', 8413 + 'PhabricatorConfigRemarkupRule' => 'PhutilRemarkupRule', 8412 8414 'PhabricatorConfigRequestExceptionHandlerModule' => 'PhabricatorConfigModule', 8413 8415 'PhabricatorConfigResponse' => 'AphrontStandaloneHTMLResponse', 8414 8416 'PhabricatorConfigSchemaQuery' => 'Phobject',
+3 -3
src/applications/config/option/PhabricatorAuthenticationConfigOptions.php
··· 33 33 pht( 34 34 'If true, email addresses must be verified (by clicking a link '. 35 35 'in an email) before a user can login. By default, verification '. 36 - 'is optional unless {{auth.email-domains}} is nonempty.')), 36 + 'is optional unless @{config:auth.email-domains} is nonempty.')), 37 37 $this->newOption('auth.require-approval', 'bool', true) 38 38 ->setBoolOptions( 39 39 array( ··· 55 55 "registration, you can disable the queue to reduce administrative ". 56 56 "overhead.\n\n". 57 57 "NOTE: Before you disable the queue, make sure ". 58 - "{{auth.email-domains}} is configured correctly ". 58 + "@{config:auth.email-domains} is configured correctly ". 59 59 "for your install!")), 60 60 $this->newOption('auth.email-domains', 'list<string>', array()) 61 61 ->setSummary(pht('Only allow registration from particular domains.')) ··· 66 66 "here.\n\nUsers will only be allowed to register using email ". 67 67 "addresses at one of the domains, and will only be able to add ". 68 68 "new email addresses for these domains. If you configure this, ". 69 - "it implies {{auth.require-email-verification}}.\n\n". 69 + "it implies @{config:auth.require-email-verification}.\n\n". 70 70 "You should omit the `@` from domains. Note that the domain must ". 71 71 "match exactly. If you allow `yourcompany.com`, that permits ". 72 72 "`joe@yourcompany.com` but rejects `joe@mail.yourcompany.com`."))
-6
src/applications/config/option/PhabricatorConfigOption.php
··· 209 209 return null; 210 210 } 211 211 212 - // TODO: Some day, we should probably implement this as a real rule. 213 - $description = preg_replace( 214 - '/{{([^}]+)}}/', 215 - '[[/config/edit/\\1/ | \\1]]', 216 - $description); 217 - 218 212 return new PHUIRemarkupView($viewer, $description); 219 213 } 220 214
+1
src/infrastructure/markup/PhabricatorMarkupEngine.php
··· 510 510 $rules[] = new PhutilRemarkupDocumentLinkRule(); 511 511 $rules[] = new PhabricatorNavigationRemarkupRule(); 512 512 $rules[] = new PhabricatorKeyboardRemarkupRule(); 513 + $rules[] = new PhabricatorConfigRemarkupRule(); 513 514 514 515 if ($options['youtube']) { 515 516 $rules[] = new PhabricatorYoutubeRemarkupRule();
+50
src/infrastructure/markup/rule/PhabricatorConfigRemarkupRule.php
··· 1 + <?php 2 + 3 + final class PhabricatorConfigRemarkupRule 4 + extends PhutilRemarkupRule { 5 + 6 + public function apply($text) { 7 + return preg_replace_callback( 8 + '(@{config:([^}]+)})', 9 + array($this, 'markupConfig'), 10 + $text); 11 + } 12 + 13 + public function getPriority() { 14 + // We're reusing the Diviner atom syntax, so make sure we evaluate before 15 + // the Diviner rule evaluates. 16 + return id(new DivinerSymbolRemarkupRule())->getPriority() - 1; 17 + } 18 + 19 + public function markupConfig(array $matches) { 20 + if (!$this->isFlatText($matches[0])) { 21 + return $matches[0]; 22 + } 23 + 24 + $config_key = $matches[1]; 25 + 26 + try { 27 + $option = PhabricatorEnv::getEnvConfig($config_key); 28 + } catch (Exception $ex) { 29 + return $matches[0]; 30 + } 31 + 32 + $is_text = $this->getEngine()->isTextMode(); 33 + $is_html_mail = $this->getEngine()->isHTMLMailMode(); 34 + 35 + if ($is_text || $is_html_mail) { 36 + return pht('"%s"', $config_key); 37 + } 38 + 39 + $link = phutil_tag( 40 + 'a', 41 + array( 42 + 'href' => urisprintf('/config/edit/%s/', $config_key), 43 + 'target' => '_blank', 44 + ), 45 + $config_key); 46 + 47 + return $this->getEngine()->storeText($link); 48 + } 49 + 50 + }