Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/differential/editor/DifferentialRevisionEditEngine.php
12256 views
1
<?php
2
3
final class DifferentialRevisionEditEngine
4
extends PhabricatorEditEngine {
5
6
private $diff;
7
8
const ENGINECONST = 'differential.revision';
9
10
const ACTIONGROUP_REVIEW = 'review';
11
const ACTIONGROUP_REVISION = 'revision';
12
13
public function getEngineName() {
14
return pht('Revisions');
15
}
16
17
public function getSummaryHeader() {
18
return pht('Configure Revision Forms');
19
}
20
21
public function getSummaryText() {
22
return pht(
23
'Configure creation and editing revision forms in Differential.');
24
}
25
26
public function getEngineApplicationClass() {
27
return 'PhabricatorDifferentialApplication';
28
}
29
30
public function isEngineConfigurable() {
31
return false;
32
}
33
34
protected function newEditableObject() {
35
$viewer = $this->getViewer();
36
return DifferentialRevision::initializeNewRevision($viewer);
37
}
38
39
protected function newObjectQuery() {
40
return id(new DifferentialRevisionQuery())
41
->needActiveDiffs(true)
42
->needReviewers(true)
43
->needReviewerAuthority(true);
44
}
45
46
protected function getObjectCreateTitleText($object) {
47
return pht('Create New Revision');
48
}
49
50
protected function getObjectEditTitleText($object) {
51
$monogram = $object->getMonogram();
52
$title = $object->getTitle();
53
54
$diff = $this->getDiff();
55
if ($diff) {
56
return pht('Update Revision %s: %s', $monogram, $title);
57
} else {
58
return pht('Edit Revision %s: %s', $monogram, $title);
59
}
60
}
61
62
protected function getObjectEditShortText($object) {
63
return $object->getMonogram();
64
}
65
66
public function getCreateURI($form_key) {
67
return '/differential/diff/create/';
68
}
69
70
protected function getObjectCreateShortText() {
71
return pht('Create Revision');
72
}
73
74
protected function getObjectName() {
75
return pht('Revision');
76
}
77
78
protected function getCommentViewButtonText($object) {
79
if ($object->isDraft()) {
80
return pht('Submit Quietly');
81
}
82
83
return parent::getCommentViewButtonText($object);
84
}
85
86
protected function getObjectViewURI($object) {
87
return $object->getURI();
88
}
89
90
protected function getEditorURI() {
91
return $this->getApplication()->getApplicationURI('revision/edit/');
92
}
93
94
public function setDiff(DifferentialDiff $diff) {
95
$this->diff = $diff;
96
return $this;
97
}
98
99
public function getDiff() {
100
return $this->diff;
101
}
102
103
protected function newCommentActionGroups() {
104
return array(
105
id(new PhabricatorEditEngineCommentActionGroup())
106
->setKey(self::ACTIONGROUP_REVIEW)
107
->setLabel(pht('Review Actions')),
108
id(new PhabricatorEditEngineCommentActionGroup())
109
->setKey(self::ACTIONGROUP_REVISION)
110
->setLabel(pht('Revision Actions')),
111
);
112
}
113
114
protected function buildCustomEditFields($object) {
115
$viewer = $this->getViewer();
116
117
$plan_required = PhabricatorEnv::getEnvConfig(
118
'differential.require-test-plan-field');
119
$plan_enabled = $this->isCustomFieldEnabled(
120
$object,
121
'differential:test-plan');
122
123
$diff = $this->getDiff();
124
if ($diff) {
125
$diff_phid = $diff->getPHID();
126
} else {
127
$diff_phid = null;
128
}
129
130
$is_create = $this->getIsCreate();
131
$is_update = ($diff && !$is_create);
132
133
$fields = array();
134
135
$fields[] = id(new PhabricatorHandlesEditField())
136
->setKey(DifferentialRevisionUpdateTransaction::EDITKEY)
137
->setLabel(pht('Update Diff'))
138
->setDescription(pht('New diff to create or update the revision with.'))
139
->setConduitDescription(pht('Create or update a revision with a diff.'))
140
->setConduitTypeDescription(pht('PHID of the diff.'))
141
->setTransactionType(
142
DifferentialRevisionUpdateTransaction::TRANSACTIONTYPE)
143
->setHandleParameterType(new AphrontPHIDListHTTPParameterType())
144
->setSingleValue($diff_phid)
145
->setIsFormField((bool)$diff)
146
->setIsReorderable(false)
147
->setIsDefaultable(false)
148
->setIsInvisible(true)
149
->setIsLockable(false);
150
151
if ($is_update) {
152
$fields[] = id(new PhabricatorInstructionsEditField())
153
->setKey('update.help')
154
->setValue(pht('Describe the updates you have made to the diff.'));
155
$fields[] = id(new PhabricatorCommentEditField())
156
->setKey('update.comment')
157
->setLabel(pht('Comment'))
158
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
159
->setIsWebOnly(true)
160
->setDescription(pht('Comments providing context for the update.'));
161
$fields[] = id(new PhabricatorSubmitEditField())
162
->setKey('update.submit')
163
->setValue($this->getObjectEditButtonText($object));
164
$fields[] = id(new PhabricatorDividerEditField())
165
->setKey('update.note');
166
}
167
168
$fields[] = id(new PhabricatorTextEditField())
169
->setKey(DifferentialRevisionTitleTransaction::EDITKEY)
170
->setLabel(pht('Title'))
171
->setIsRequired(true)
172
->setTransactionType(
173
DifferentialRevisionTitleTransaction::TRANSACTIONTYPE)
174
->setDescription(pht('The title of the revision.'))
175
->setConduitDescription(pht('Retitle the revision.'))
176
->setConduitTypeDescription(pht('New revision title.'))
177
->setValue($object->getTitle());
178
179
$author_field = id(new PhabricatorDatasourceEditField())
180
->setKey(DifferentialRevisionAuthorTransaction::EDITKEY)
181
->setLabel(pht('Author'))
182
->setDatasource(new PhabricatorPeopleDatasource())
183
->setTransactionType(
184
DifferentialRevisionAuthorTransaction::TRANSACTIONTYPE)
185
->setDescription(pht('Foist this revision upon someone else.'))
186
->setConduitDescription(pht('Foist this revision upon another user.'))
187
->setConduitTypeDescription(pht('New author.'))
188
->setSingleValue($object->getAuthorPHID());
189
190
// Don't show the "Author" field when creating a revision using the web
191
// workflow, since it adds more noise than signal to this workflow.
192
if ($this->getIsCreate()) {
193
$author_field->setIsHidden(true);
194
}
195
196
// Only show the "Foist Upon" comment action to the current revision
197
// author. Other users can use "Edit Revision", it's just very unlikley
198
// that they're interested in this action.
199
if ($viewer->getPHID() === $object->getAuthorPHID()) {
200
$author_field->setCommentActionLabel(pht('Foist Upon'));
201
}
202
203
$fields[] = $author_field;
204
205
$fields[] = id(new PhabricatorRemarkupEditField())
206
->setKey(DifferentialRevisionSummaryTransaction::EDITKEY)
207
->setLabel(pht('Summary'))
208
->setTransactionType(
209
DifferentialRevisionSummaryTransaction::TRANSACTIONTYPE)
210
->setDescription(pht('The summary of the revision.'))
211
->setConduitDescription(pht('Change the revision summary.'))
212
->setConduitTypeDescription(pht('New revision summary.'))
213
->setValue($object->getSummary());
214
215
if ($plan_enabled) {
216
$fields[] = id(new PhabricatorRemarkupEditField())
217
->setKey(DifferentialRevisionTestPlanTransaction::EDITKEY)
218
->setLabel(pht('Test Plan'))
219
->setIsRequired($plan_required)
220
->setTransactionType(
221
DifferentialRevisionTestPlanTransaction::TRANSACTIONTYPE)
222
->setDescription(
223
pht('Actions performed to verify the behavior of the change.'))
224
->setConduitDescription(pht('Update the revision test plan.'))
225
->setConduitTypeDescription(pht('New test plan.'))
226
->setValue($object->getTestPlan());
227
}
228
229
$fields[] = id(new PhabricatorDatasourceEditField())
230
->setKey(DifferentialRevisionReviewersTransaction::EDITKEY)
231
->setLabel(pht('Reviewers'))
232
->setDatasource(new DifferentialReviewerDatasource())
233
->setUseEdgeTransactions(true)
234
->setTransactionType(
235
DifferentialRevisionReviewersTransaction::TRANSACTIONTYPE)
236
->setCommentActionLabel(pht('Change Reviewers'))
237
->setDescription(pht('Reviewers for this revision.'))
238
->setConduitDescription(pht('Change the reviewers for this revision.'))
239
->setConduitTypeDescription(pht('New reviewers.'))
240
->setValue($object->getReviewerPHIDsForEdit());
241
242
$fields[] = id(new PhabricatorDatasourceEditField())
243
->setKey('repositoryPHID')
244
->setLabel(pht('Repository'))
245
->setDatasource(new DiffusionRepositoryDatasource())
246
->setTransactionType(
247
DifferentialRevisionRepositoryTransaction::TRANSACTIONTYPE)
248
->setDescription(pht('The repository the revision belongs to.'))
249
->setConduitDescription(pht('Change the repository for this revision.'))
250
->setConduitTypeDescription(pht('New repository.'))
251
->setSingleValue($object->getRepositoryPHID());
252
253
// This is a little flimsy, but allows "Maniphest Tasks: ..." to continue
254
// working properly in commit messages until we fully sort out T5873.
255
$fields[] = id(new PhabricatorHandlesEditField())
256
->setKey('tasks')
257
->setUseEdgeTransactions(true)
258
->setIsFormField(false)
259
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
260
->setMetadataValue(
261
'edge:type',
262
DifferentialRevisionHasTaskEdgeType::EDGECONST)
263
->setDescription(pht('Tasks associated with this revision.'))
264
->setConduitDescription(pht('Change associated tasks.'))
265
->setConduitTypeDescription(pht('List of tasks.'))
266
->setValue(array());
267
268
$fields[] = id(new PhabricatorHandlesEditField())
269
->setKey('parents')
270
->setUseEdgeTransactions(true)
271
->setIsFormField(false)
272
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
273
->setMetadataValue(
274
'edge:type',
275
DifferentialRevisionDependsOnRevisionEdgeType::EDGECONST)
276
->setDescription(pht('Parent revisions of this revision.'))
277
->setConduitDescription(pht('Change associated parent revisions.'))
278
->setConduitTypeDescription(pht('List of revisions.'))
279
->setValue(array());
280
281
$fields[] = id(new PhabricatorHandlesEditField())
282
->setKey('children')
283
->setUseEdgeTransactions(true)
284
->setIsFormField(false)
285
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
286
->setMetadataValue(
287
'edge:type',
288
DifferentialRevisionDependedOnByRevisionEdgeType::EDGECONST)
289
->setDescription(pht('Child revisions of this revision.'))
290
->setConduitDescription(pht('Change associated child revisions.'))
291
->setConduitTypeDescription(pht('List of revisions.'))
292
->setValue(array());
293
294
$actions = DifferentialRevisionActionTransaction::loadAllActions();
295
$actions = msortv($actions, 'getRevisionActionOrderVector');
296
297
foreach ($actions as $key => $action) {
298
$fields[] = $action->newEditField($object, $viewer);
299
}
300
301
$fields[] = id(new PhabricatorBoolEditField())
302
->setKey('draft')
303
->setLabel(pht('Hold as Draft'))
304
->setIsFormField(false)
305
->setOptions(
306
pht('Autosubmit Once Builds Finish'),
307
pht('Hold as Draft'))
308
->setTransactionType(
309
DifferentialRevisionHoldDraftTransaction::TRANSACTIONTYPE)
310
->setDescription(pht('Hold revision as as draft.'))
311
->setConduitDescription(
312
pht(
313
'Change autosubmission from draft state after builds finish.'))
314
->setConduitTypeDescription(pht('New "Hold as Draft" setting.'))
315
->setValue($object->getHoldAsDraft());
316
317
return $fields;
318
}
319
320
private function isCustomFieldEnabled(DifferentialRevision $revision, $key) {
321
$field_list = PhabricatorCustomField::getObjectFields(
322
$revision,
323
PhabricatorCustomField::ROLE_VIEW);
324
325
$fields = $field_list->getFields();
326
return isset($fields[$key]);
327
}
328
329
protected function newAutomaticCommentTransactions($object) {
330
$viewer = $this->getViewer();
331
332
$editor = $object->getApplicationTransactionEditor()
333
->setActor($viewer);
334
335
$xactions = $editor->newAutomaticInlineTransactions(
336
$object,
337
DifferentialTransaction::TYPE_INLINE,
338
new DifferentialDiffInlineCommentQuery());
339
340
return $xactions;
341
}
342
343
protected function newCommentPreviewContent($object, array $xactions) {
344
$viewer = $this->getViewer();
345
$type_inline = DifferentialTransaction::TYPE_INLINE;
346
347
$inlines = array();
348
foreach ($xactions as $xaction) {
349
if ($xaction->getTransactionType() === $type_inline) {
350
$inlines[] = $xaction->getComment();
351
}
352
}
353
354
$content = array();
355
356
if ($inlines) {
357
// Reload inlines to get inline context.
358
$inlines = id(new DifferentialDiffInlineCommentQuery())
359
->setViewer($viewer)
360
->withIDs(mpull($inlines, 'getID'))
361
->needInlineContext(true)
362
->execute();
363
364
$inline_preview = id(new PHUIDiffInlineCommentPreviewListView())
365
->setViewer($viewer)
366
->setInlineComments($inlines);
367
368
$content[] = phutil_tag(
369
'div',
370
array(
371
'id' => 'inline-comment-preview',
372
),
373
$inline_preview);
374
}
375
376
return $content;
377
}
378
379
380
}
381
382