Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/differential/editor/DifferentialDiffEditor.php
12256 views
1
<?php
2
3
final class DifferentialDiffEditor
4
extends PhabricatorApplicationTransactionEditor {
5
6
private $diffDataDict;
7
private $lookupRepository = true;
8
9
public function setLookupRepository($bool) {
10
$this->lookupRepository = $bool;
11
return $this;
12
}
13
14
public function getEditorApplicationClass() {
15
return 'PhabricatorDifferentialApplication';
16
}
17
18
public function getEditorObjectsDescription() {
19
return pht('Differential Diffs');
20
}
21
22
public function getTransactionTypes() {
23
$types = parent::getTransactionTypes();
24
25
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
26
$types[] = DifferentialDiffTransaction::TYPE_DIFF_CREATE;
27
28
return $types;
29
}
30
31
protected function getCustomTransactionOldValue(
32
PhabricatorLiskDAO $object,
33
PhabricatorApplicationTransaction $xaction) {
34
35
switch ($xaction->getTransactionType()) {
36
case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
37
return null;
38
}
39
40
return parent::getCustomTransactionOldValue($object, $xaction);
41
}
42
43
protected function getCustomTransactionNewValue(
44
PhabricatorLiskDAO $object,
45
PhabricatorApplicationTransaction $xaction) {
46
47
switch ($xaction->getTransactionType()) {
48
case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
49
$this->diffDataDict = $xaction->getNewValue();
50
return true;
51
}
52
53
return parent::getCustomTransactionNewValue($object, $xaction);
54
}
55
56
protected function applyCustomInternalTransaction(
57
PhabricatorLiskDAO $object,
58
PhabricatorApplicationTransaction $xaction) {
59
60
switch ($xaction->getTransactionType()) {
61
case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
62
$dict = $this->diffDataDict;
63
$this->updateDiffFromDict($object, $dict);
64
return;
65
}
66
67
return parent::applyCustomInternalTransaction($object, $xaction);
68
}
69
70
protected function applyCustomExternalTransaction(
71
PhabricatorLiskDAO $object,
72
PhabricatorApplicationTransaction $xaction) {
73
74
switch ($xaction->getTransactionType()) {
75
case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
76
return;
77
}
78
79
return parent::applyCustomExternalTransaction($object, $xaction);
80
}
81
82
protected function applyFinalEffects(
83
PhabricatorLiskDAO $object,
84
array $xactions) {
85
86
// If we didn't get an explicit `repositoryPHID` (which means the client
87
// is old, or couldn't figure out which repository the working copy
88
// belongs to), apply heuristics to try to figure it out.
89
90
if ($this->lookupRepository && !$object->getRepositoryPHID()) {
91
$repository = id(new DifferentialRepositoryLookup())
92
->setDiff($object)
93
->setViewer($this->getActor())
94
->lookupRepository();
95
if ($repository) {
96
$object->setRepositoryPHID($repository->getPHID());
97
$object->setRepositoryUUID($repository->getUUID());
98
$object->save();
99
}
100
}
101
102
return $xactions;
103
}
104
105
/**
106
* We run Herald as part of transaction validation because Herald can
107
* block diff creation for Differential diffs. Its important to do this
108
* separately so no Herald logs are saved; these logs could expose
109
* information the Herald rules are intended to block.
110
*/
111
protected function validateTransaction(
112
PhabricatorLiskDAO $object,
113
$type,
114
array $xactions) {
115
116
$errors = parent::validateTransaction($object, $type, $xactions);
117
118
foreach ($xactions as $xaction) {
119
switch ($type) {
120
case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
121
$diff = clone $object;
122
$diff = $this->updateDiffFromDict($diff, $xaction->getNewValue());
123
124
$adapter = $this->buildHeraldAdapter($diff, $xactions);
125
$adapter->setContentSource($this->getContentSource());
126
$adapter->setIsNewObject($this->getIsNewObject());
127
128
$engine = new HeraldEngine();
129
130
$rules = $engine->loadRulesForAdapter($adapter);
131
$rules = mpull($rules, null, 'getID');
132
133
$effects = $engine->applyRules($rules, $adapter);
134
$action_block = DifferentialBlockHeraldAction::ACTIONCONST;
135
136
$blocking_effect = null;
137
foreach ($effects as $effect) {
138
if ($effect->getAction() == $action_block) {
139
$blocking_effect = $effect;
140
break;
141
}
142
}
143
144
if ($blocking_effect) {
145
$rule = $blocking_effect->getRule();
146
147
$message = $effect->getTarget();
148
if (!strlen($message)) {
149
$message = pht('(None.)');
150
}
151
152
$errors[] = new PhabricatorApplicationTransactionValidationError(
153
$type,
154
pht('Rejected by Herald'),
155
pht(
156
"Creation of this diff was rejected by Herald rule %s.\n".
157
" Rule: %s\n".
158
"Reason: %s",
159
$rule->getMonogram(),
160
$rule->getName(),
161
$message));
162
}
163
break;
164
}
165
}
166
167
return $errors;
168
}
169
170
171
protected function shouldPublishFeedStory(
172
PhabricatorLiskDAO $object,
173
array $xactions) {
174
return false;
175
}
176
177
protected function shouldSendMail(
178
PhabricatorLiskDAO $object,
179
array $xactions) {
180
return false;
181
}
182
183
protected function supportsSearch() {
184
return false;
185
}
186
187
/* -( Herald Integration )------------------------------------------------- */
188
189
/**
190
* See @{method:validateTransaction}. The only Herald action is to block
191
* the creation of Diffs. We thus have to be careful not to save any
192
* data and do this validation very early.
193
*/
194
protected function shouldApplyHeraldRules(
195
PhabricatorLiskDAO $object,
196
array $xactions) {
197
198
return false;
199
}
200
201
protected function buildHeraldAdapter(
202
PhabricatorLiskDAO $object,
203
array $xactions) {
204
205
$adapter = id(new HeraldDifferentialDiffAdapter())
206
->setDiff($object);
207
208
return $adapter;
209
}
210
211
private function updateDiffFromDict(DifferentialDiff $diff, $dict) {
212
$diff
213
->setSourcePath(idx($dict, 'sourcePath'))
214
->setSourceMachine(idx($dict, 'sourceMachine'))
215
->setBranch(idx($dict, 'branch'))
216
->setCreationMethod(idx($dict, 'creationMethod'))
217
->setAuthorPHID(idx($dict, 'authorPHID', $this->getActor()))
218
->setBookmark(idx($dict, 'bookmark'))
219
->setRepositoryPHID(idx($dict, 'repositoryPHID'))
220
->setRepositoryUUID(idx($dict, 'repositoryUUID'))
221
->setSourceControlSystem(idx($dict, 'sourceControlSystem'))
222
->setSourceControlPath(idx($dict, 'sourceControlPath'))
223
->setSourceControlBaseRevision(idx($dict, 'sourceControlBaseRevision'))
224
->setLintStatus(idx($dict, 'lintStatus'))
225
->setUnitStatus(idx($dict, 'unitStatus'));
226
227
return $diff;
228
}
229
}
230
231