Skip to content

Commit 2b9d4f7

Browse files
aviveyavivey
authored andcommitted
Remarkup rule for rendering PHIDs as handles
Summary: adds the `{{PHID....}}` rule. Should mostly be useful in UI code that refers to Objects. It doesn't add any mention links/transactions. Test Plan: Comment with this, see email (plain + html) and comment box. Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D15488
1 parent 8f94aa8 commit 2b9d4f7

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed

src/__phutil_library_map__.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2454,6 +2454,7 @@
24542454
'PhabricatorHandlePool' => 'applications/phid/handle/pool/PhabricatorHandlePool.php',
24552455
'PhabricatorHandlePoolTestCase' => 'applications/phid/handle/pool/__tests__/PhabricatorHandlePoolTestCase.php',
24562456
'PhabricatorHandleQuery' => 'applications/phid/query/PhabricatorHandleQuery.php',
2457+
'PhabricatorHandleRemarkupRule' => 'applications/phid/remarkup/PhabricatorHandleRemarkupRule.php',
24572458
'PhabricatorHandlesEditField' => 'applications/transactions/editfield/PhabricatorHandlesEditField.php',
24582459
'PhabricatorHarbormasterApplication' => 'applications/harbormaster/application/PhabricatorHarbormasterApplication.php',
24592460
'PhabricatorHarbormasterConfigOptions' => 'applications/harbormaster/config/PhabricatorHarbormasterConfigOptions.php',
@@ -6897,6 +6898,7 @@
68976898
'PhabricatorHandlePool' => 'Phobject',
68986899
'PhabricatorHandlePoolTestCase' => 'PhabricatorTestCase',
68996900
'PhabricatorHandleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
6901+
'PhabricatorHandleRemarkupRule' => 'PhutilRemarkupRule',
69006902
'PhabricatorHandlesEditField' => 'PhabricatorPHIDListEditField',
69016903
'PhabricatorHarbormasterApplication' => 'PhabricatorApplication',
69026904
'PhabricatorHarbormasterConfigOptions' => 'PhabricatorApplicationConfigOptions',
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?php
2+
3+
final class PhabricatorHandleRemarkupRule extends PhutilRemarkupRule {
4+
5+
const KEY_RULE_HANDLE = 'rule.handle';
6+
const KEY_RULE_HANDLE_ORIGINAL = 'rule.handle.original';
7+
8+
public function apply($text) {
9+
return preg_replace_callback(
10+
'/{(PHID-[a-zA-Z0-9-]*)}/',
11+
array($this, 'markupHandle'),
12+
$text);
13+
}
14+
15+
public function markupHandle(array $matches) {
16+
$engine = $this->getEngine();
17+
$viewer = $engine->getConfig('viewer');
18+
19+
if (!$this->isFlatText($matches[0])) {
20+
return $matches[0];
21+
}
22+
23+
$phid_type = phid_get_type($matches[1]);
24+
if ($phid_type == PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN) {
25+
return $matches[0];
26+
}
27+
28+
$token = $engine->storeText($matches[0]);
29+
if ($engine->isTextMode()) {
30+
return $token;
31+
}
32+
33+
$original_key = self::KEY_RULE_HANDLE_ORIGINAL;
34+
$original = $engine->getTextMetadata($original_key, array());
35+
$original[$token] = $matches[0];
36+
$engine->setTextMetadata($original_key, $original);
37+
38+
$metadata_key = self::KEY_RULE_HANDLE;
39+
$metadata = $engine->getTextMetadata($metadata_key, array());
40+
$phid = $matches[1];
41+
if (empty($metadata[$phid])) {
42+
$metadata[$phid] = array();
43+
}
44+
$metadata[$phid][] = $token;
45+
$engine->setTextMetadata($metadata_key, $metadata);
46+
47+
return $token;
48+
}
49+
50+
public function didMarkupText() {
51+
$engine = $this->getEngine();
52+
53+
$metadata_key = self::KEY_RULE_HANDLE;
54+
55+
$metadata = $engine->getTextMetadata($metadata_key, array());
56+
if (empty($metadata)) {
57+
// No mentions, or we already processed them.
58+
return;
59+
}
60+
61+
$original_key = self::KEY_RULE_HANDLE_ORIGINAL;
62+
$original = $engine->getTextMetadata($original_key, array());
63+
64+
$phids = array_keys($metadata);
65+
66+
$handles = id(new PhabricatorHandleQuery())
67+
->setViewer($this->getEngine()->getConfig('viewer'))
68+
->withPHIDs($phids)
69+
->execute();
70+
71+
foreach ($metadata as $phid => $tokens) {
72+
$handle = idx($handles, $phid);
73+
74+
if ($handle->isComplete()) {
75+
if ($engine->isHTMLMailMode()) {
76+
$href = $handle->getURI();
77+
$href = PhabricatorEnv::getProductionURI($href);
78+
79+
$link = phutil_tag(
80+
'a',
81+
array(
82+
'href' => $href,
83+
'style' => '
84+
border-color: #f1f7ff;
85+
color: #19558d;
86+
background-color: #f1f7ff;
87+
border: 1px solid transparent;
88+
border-radius: 3px;
89+
font-weight: bold;
90+
padding: 0 4px;',
91+
),
92+
$handle->getLinkName());
93+
} else {
94+
$link = $handle->renderTag();
95+
$link->setPHID($phid);
96+
}
97+
foreach ($tokens as $token) {
98+
$engine->overwriteStoredText($token, $link);
99+
}
100+
} else {
101+
foreach ($tokens as $token) {
102+
$engine->overwriteStoredText($token, idx($original, $token));
103+
}
104+
}
105+
}
106+
107+
$engine->setTextMetadata($metadata_key, array());
108+
}
109+
}

src/infrastructure/markup/PhabricatorMarkupEngine.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,7 @@ public static function newMarkupEngine(array $options) {
494494

495495
$rules[] = new PhabricatorIconRemarkupRule();
496496
$rules[] = new PhabricatorEmojiRemarkupRule();
497+
$rules[] = new PhabricatorHandleRemarkupRule();
497498

498499
$applications = PhabricatorApplication::getAllInstalledApplications();
499500
foreach ($applications as $application) {

0 commit comments

Comments
 (0)