Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/macro/markup/PhabricatorImageMacroRemarkupRule.php
12241 views
1
<?php
2
3
final class PhabricatorImageMacroRemarkupRule extends PhutilRemarkupRule {
4
5
private $macros;
6
7
const KEY_RULE_MACRO = 'rule.macro';
8
9
public function apply($text) {
10
return preg_replace_callback(
11
'@^\s*([a-zA-Z0-9:_\x7f-\xff-]+)$@m',
12
array($this, 'markupImageMacro'),
13
$text);
14
}
15
16
public function markupImageMacro(array $matches) {
17
if ($this->macros === null) {
18
$this->macros = array();
19
20
$viewer = $this->getEngine()->getConfig('viewer');
21
$rows = id(new PhabricatorMacroQuery())
22
->setViewer($viewer)
23
->withStatus(PhabricatorMacroQuery::STATUS_ACTIVE)
24
->execute();
25
26
$this->macros = mpull($rows, 'getPHID', 'getName');
27
}
28
29
$name = (string)$matches[1];
30
if (empty($this->macros[$name])) {
31
return $matches[1];
32
}
33
34
$engine = $this->getEngine();
35
36
37
$metadata_key = self::KEY_RULE_MACRO;
38
$metadata = $engine->getTextMetadata($metadata_key, array());
39
40
$token = $engine->storeText('<macro>');
41
$metadata[] = array(
42
'token' => $token,
43
'phid' => $this->macros[$name],
44
'original' => $name,
45
);
46
47
$engine->setTextMetadata($metadata_key, $metadata);
48
49
return $token;
50
}
51
52
public function didMarkupText() {
53
$engine = $this->getEngine();
54
$metadata_key = self::KEY_RULE_MACRO;
55
$metadata = $engine->getTextMetadata($metadata_key, array());
56
57
if (!$metadata) {
58
return;
59
}
60
61
$phids = ipull($metadata, 'phid');
62
$viewer = $this->getEngine()->getConfig('viewer');
63
64
// Load all the macros.
65
$macros = id(new PhabricatorMacroQuery())
66
->setViewer($viewer)
67
->withStatus(PhabricatorMacroQuery::STATUS_ACTIVE)
68
->withPHIDs($phids)
69
->execute();
70
$macros = mpull($macros, null, 'getPHID');
71
72
// Load all the images and audio.
73
$file_phids = array_merge(
74
array_values(mpull($macros, 'getFilePHID')),
75
array_values(mpull($macros, 'getAudioPHID')));
76
77
$file_phids = array_filter($file_phids);
78
79
$files = array();
80
if ($file_phids) {
81
$files = id(new PhabricatorFileQuery())
82
->setViewer($viewer)
83
->withPHIDs($file_phids)
84
->execute();
85
$files = mpull($files, null, 'getPHID');
86
}
87
88
// Replace any macros that we couldn't load the macro or image for with
89
// the original text.
90
foreach ($metadata as $key => $spec) {
91
$macro = idx($macros, $spec['phid']);
92
if ($macro) {
93
$file = idx($files, $macro->getFilePHID());
94
if ($file) {
95
continue;
96
}
97
}
98
99
$engine->overwriteStoredText($spec['token'], $spec['original']);
100
unset($metadata[$key]);
101
}
102
103
foreach ($metadata as $spec) {
104
$macro = $macros[$spec['phid']];
105
$file = $files[$macro->getFilePHID()];
106
$src_uri = $file->getBestURI();
107
108
if ($this->getEngine()->isTextMode()) {
109
$result = $spec['original'].' <'.$src_uri.'>';
110
$engine->overwriteStoredText($spec['token'], $result);
111
continue;
112
} else if ($this->getEngine()->isHTMLMailMode()) {
113
$src_uri = PhabricatorEnv::getProductionURI($src_uri);
114
}
115
116
$id = null;
117
$audio = idx($files, $macro->getAudioPHID());
118
$should_play = ($audio && $macro->getAudioBehavior() !=
119
PhabricatorFileImageMacro::AUDIO_BEHAVIOR_NONE);
120
if ($should_play) {
121
$id = celerity_generate_unique_node_id();
122
123
$loop = null;
124
switch ($macro->getAudioBehavior()) {
125
case PhabricatorFileImageMacro::AUDIO_BEHAVIOR_LOOP:
126
$loop = true;
127
break;
128
}
129
130
Javelin::initBehavior(
131
'audio-source',
132
array(
133
'sourceID' => $id,
134
'audioURI' => $audio->getBestURI(),
135
'loop' => $loop,
136
));
137
}
138
139
$result = $this->newTag(
140
'img',
141
array(
142
'id' => $id,
143
'src' => $src_uri,
144
'alt' => $spec['original'],
145
'title' => $spec['original'],
146
'height' => $file->getImageHeight(),
147
'width' => $file->getImageWidth(),
148
'class' => 'phabricator-remarkup-macro',
149
));
150
151
$engine->overwriteStoredText($spec['token'], $result);
152
}
153
154
$engine->setTextMetadata($metadata_key, array());
155
}
156
157
}
158
159