Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/files/document/PhabricatorDocumentEngine.php
12241 views
1
<?php
2
3
abstract class PhabricatorDocumentEngine
4
extends Phobject {
5
6
private $viewer;
7
private $highlightedLines = array();
8
private $encodingConfiguration;
9
private $highlightingConfiguration;
10
private $blameConfiguration = true;
11
12
final public function setViewer(PhabricatorUser $viewer) {
13
$this->viewer = $viewer;
14
return $this;
15
}
16
17
final public function getViewer() {
18
return $this->viewer;
19
}
20
21
final public function setHighlightedLines(array $highlighted_lines) {
22
$this->highlightedLines = $highlighted_lines;
23
return $this;
24
}
25
26
final public function getHighlightedLines() {
27
return $this->highlightedLines;
28
}
29
30
final public function canRenderDocument(PhabricatorDocumentRef $ref) {
31
return $this->canRenderDocumentType($ref);
32
}
33
34
public function canDiffDocuments(
35
PhabricatorDocumentRef $uref = null,
36
PhabricatorDocumentRef $vref = null) {
37
return false;
38
}
39
40
public function newBlockDiffViews(
41
PhabricatorDocumentRef $uref,
42
PhabricatorDocumentEngineBlock $ublock,
43
PhabricatorDocumentRef $vref,
44
PhabricatorDocumentEngineBlock $vblock) {
45
46
$u_content = $this->newBlockContentView($uref, $ublock);
47
$v_content = $this->newBlockContentView($vref, $vblock);
48
49
return id(new PhabricatorDocumentEngineBlockDiff())
50
->setOldContent($u_content)
51
->addOldClass('old')
52
->addOldClass('old-full')
53
->setNewContent($v_content)
54
->addNewClass('new')
55
->addNewClass('new-full');
56
}
57
58
public function newBlockContentView(
59
PhabricatorDocumentRef $ref,
60
PhabricatorDocumentEngineBlock $block) {
61
return $block->getContent();
62
}
63
64
public function newEngineBlocks(
65
PhabricatorDocumentRef $uref,
66
PhabricatorDocumentRef $vref) {
67
throw new PhutilMethodNotImplementedException();
68
}
69
70
public function canConfigureEncoding(PhabricatorDocumentRef $ref) {
71
return false;
72
}
73
74
public function canConfigureHighlighting(PhabricatorDocumentRef $ref) {
75
return false;
76
}
77
78
public function canBlame(PhabricatorDocumentRef $ref) {
79
return false;
80
}
81
82
final public function setEncodingConfiguration($config) {
83
$this->encodingConfiguration = $config;
84
return $this;
85
}
86
87
final public function getEncodingConfiguration() {
88
return $this->encodingConfiguration;
89
}
90
91
final public function setHighlightingConfiguration($config) {
92
$this->highlightingConfiguration = $config;
93
return $this;
94
}
95
96
final public function getHighlightingConfiguration() {
97
return $this->highlightingConfiguration;
98
}
99
100
final public function setBlameConfiguration($blame_configuration) {
101
$this->blameConfiguration = $blame_configuration;
102
return $this;
103
}
104
105
final public function getBlameConfiguration() {
106
return $this->blameConfiguration;
107
}
108
109
final protected function getBlameEnabled() {
110
return $this->blameConfiguration;
111
}
112
113
public function shouldRenderAsync(PhabricatorDocumentRef $ref) {
114
return false;
115
}
116
117
abstract protected function canRenderDocumentType(
118
PhabricatorDocumentRef $ref);
119
120
final public function newDocument(PhabricatorDocumentRef $ref) {
121
$can_complete = $this->canRenderCompleteDocument($ref);
122
$can_partial = $this->canRenderPartialDocument($ref);
123
124
if (!$can_complete && !$can_partial) {
125
return $this->newMessage(
126
pht(
127
'This document is too large to be rendered inline. (The document '.
128
'is %s bytes, the limit for this engine is %s bytes.)',
129
new PhutilNumber($ref->getByteLength()),
130
new PhutilNumber($this->getByteLengthLimit())));
131
}
132
133
return $this->newDocumentContent($ref);
134
}
135
136
final public function newDocumentIcon(PhabricatorDocumentRef $ref) {
137
return id(new PHUIIconView())
138
->setIcon($this->getDocumentIconIcon($ref));
139
}
140
141
abstract protected function newDocumentContent(
142
PhabricatorDocumentRef $ref);
143
144
protected function getDocumentIconIcon(PhabricatorDocumentRef $ref) {
145
return 'fa-file-o';
146
}
147
148
protected function getDocumentRenderingText(PhabricatorDocumentRef $ref) {
149
return pht('Loading...');
150
}
151
152
final public function getDocumentEngineKey() {
153
return $this->getPhobjectClassConstant('ENGINEKEY');
154
}
155
156
final public static function getAllEngines() {
157
return id(new PhutilClassMapQuery())
158
->setAncestorClass(__CLASS__)
159
->setUniqueMethod('getDocumentEngineKey')
160
->execute();
161
}
162
163
final public function newSortVector(PhabricatorDocumentRef $ref) {
164
$content_score = $this->getContentScore($ref);
165
166
// Prefer engines which can render the entire file over engines which
167
// can only render a header, and engines which can render a header over
168
// engines which can't render anything.
169
if ($this->canRenderCompleteDocument($ref)) {
170
$limit_score = 0;
171
} else if ($this->canRenderPartialDocument($ref)) {
172
$limit_score = 1;
173
} else {
174
$limit_score = 2;
175
}
176
177
return id(new PhutilSortVector())
178
->addInt($limit_score)
179
->addInt(-$content_score);
180
}
181
182
protected function getContentScore(PhabricatorDocumentRef $ref) {
183
return 2000;
184
}
185
186
abstract public function getViewAsLabel(PhabricatorDocumentRef $ref);
187
188
public function getViewAsIconIcon(PhabricatorDocumentRef $ref) {
189
$can_complete = $this->canRenderCompleteDocument($ref);
190
$can_partial = $this->canRenderPartialDocument($ref);
191
192
if (!$can_complete && !$can_partial) {
193
return 'fa-times';
194
}
195
196
return $this->getDocumentIconIcon($ref);
197
}
198
199
public function getViewAsIconColor(PhabricatorDocumentRef $ref) {
200
$can_complete = $this->canRenderCompleteDocument($ref);
201
202
if (!$can_complete) {
203
return 'grey';
204
}
205
206
return null;
207
}
208
209
final public static function getEnginesForRef(
210
PhabricatorUser $viewer,
211
PhabricatorDocumentRef $ref) {
212
$engines = self::getAllEngines();
213
214
foreach ($engines as $key => $engine) {
215
$engine = id(clone $engine)
216
->setViewer($viewer);
217
218
if (!$engine->canRenderDocument($ref)) {
219
unset($engines[$key]);
220
continue;
221
}
222
223
$engines[$key] = $engine;
224
}
225
226
if (!$engines) {
227
throw new Exception(pht('No content engine can render this document.'));
228
}
229
230
$vectors = array();
231
foreach ($engines as $key => $usable_engine) {
232
$vectors[$key] = $usable_engine->newSortVector($ref);
233
}
234
$vectors = msortv($vectors, 'getSelf');
235
236
return array_select_keys($engines, array_keys($vectors));
237
}
238
239
protected function getByteLengthLimit() {
240
return (1024 * 1024 * 8);
241
}
242
243
protected function canRenderCompleteDocument(PhabricatorDocumentRef $ref) {
244
$limit = $this->getByteLengthLimit();
245
if ($limit) {
246
$length = $ref->getByteLength();
247
if ($length > $limit) {
248
return false;
249
}
250
}
251
252
return true;
253
}
254
255
protected function canRenderPartialDocument(PhabricatorDocumentRef $ref) {
256
return false;
257
}
258
259
protected function newMessage($message) {
260
return phutil_tag(
261
'div',
262
array(
263
'class' => 'document-engine-error',
264
),
265
$message);
266
}
267
268
final public function newLoadingContent(PhabricatorDocumentRef $ref) {
269
$spinner = id(new PHUIIconView())
270
->setIcon('fa-gear')
271
->addClass('ph-spin');
272
273
return phutil_tag(
274
'div',
275
array(
276
'class' => 'document-engine-loading',
277
),
278
array(
279
$spinner,
280
$this->getDocumentRenderingText($ref),
281
));
282
}
283
284
public function shouldSuggestEngine(PhabricatorDocumentRef $ref) {
285
return false;
286
}
287
288
}
289
290