Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/differential/conduit/DifferentialConduitAPIMethod.php
12256 views
1
<?php
2
3
abstract class DifferentialConduitAPIMethod extends ConduitAPIMethod {
4
5
final public function getApplication() {
6
return PhabricatorApplication::getByClass(
7
'PhabricatorDifferentialApplication');
8
}
9
10
protected function buildDiffInfoDictionary(DifferentialDiff $diff) {
11
$uri = '/differential/diff/'.$diff->getID().'/';
12
$uri = PhabricatorEnv::getProductionURI($uri);
13
14
return array(
15
'id' => $diff->getID(),
16
'phid' => $diff->getPHID(),
17
'uri' => $uri,
18
);
19
}
20
21
protected function buildInlineInfoDictionary(
22
DifferentialInlineComment $inline,
23
DifferentialChangeset $changeset = null) {
24
25
$file_path = null;
26
$diff_id = null;
27
if ($changeset) {
28
$file_path = $inline->getIsNewFile()
29
? $changeset->getFilename()
30
: $changeset->getOldFile();
31
32
$diff_id = $changeset->getDiffID();
33
}
34
35
return array(
36
'id' => $inline->getID(),
37
'authorPHID' => $inline->getAuthorPHID(),
38
'filePath' => $file_path,
39
'isNewFile' => $inline->getIsNewFile(),
40
'lineNumber' => $inline->getLineNumber(),
41
'lineLength' => $inline->getLineLength(),
42
'diffID' => $diff_id,
43
'content' => $inline->getContent(),
44
);
45
}
46
47
protected function applyFieldEdit(
48
ConduitAPIRequest $request,
49
DifferentialRevision $revision,
50
DifferentialDiff $diff,
51
array $fields,
52
$message) {
53
54
$viewer = $request->getUser();
55
56
// We're going to build the body of a "differential.revision.edit" API
57
// request, then just call that code directly.
58
59
$xactions = array();
60
$xactions[] = array(
61
'type' => DifferentialRevisionUpdateTransaction::EDITKEY,
62
'value' => $diff->getPHID(),
63
);
64
65
$field_map = DifferentialCommitMessageField::newEnabledFields($viewer);
66
$values = $request->getValue('fields', array());
67
foreach ($values as $key => $value) {
68
$field = idx($field_map, $key);
69
if (!$field) {
70
// NOTE: We're just ignoring fields we don't know about. This isn't
71
// ideal, but the way the workflow currently works involves us getting
72
// several read-only fields, like the revision ID field, which we should
73
// just skip.
74
continue;
75
}
76
77
// The transaction itself will be validated so this is somewhat
78
// redundant, but this validator will sometimes give us a better error
79
// message or a better reaction to a bad value type.
80
$value = $field->readFieldValueFromConduit($value);
81
82
foreach ($field->getFieldTransactions($value) as $xaction) {
83
$xactions[] = $xaction;
84
}
85
}
86
87
$message = $request->getValue('message');
88
if (strlen($message)) {
89
// This is a little awkward, and should move elsewhere or be removed. It
90
// largely exists for legacy reasons. See some discussion in T7899.
91
$first_line = head(phutil_split_lines($message, false));
92
93
$first_line = id(new PhutilUTF8StringTruncator())
94
->setMaximumBytes(250)
95
->setMaximumGlyphs(80)
96
->truncateString($first_line);
97
98
$diff->setDescription($first_line);
99
$diff->save();
100
101
$xactions[] = array(
102
'type' => PhabricatorCommentEditEngineExtension::EDITKEY,
103
'value' => $message,
104
);
105
}
106
107
$method = 'differential.revision.edit';
108
$params = array(
109
'transactions' => $xactions,
110
);
111
112
if ($revision->getID()) {
113
$params['objectIdentifier'] = $revision->getID();
114
}
115
116
return id(new ConduitCall($method, $params, $strict = true))
117
->setUser($viewer)
118
->execute();
119
}
120
121
protected function loadCustomFieldsForRevisions(
122
PhabricatorUser $viewer,
123
array $revisions) {
124
assert_instances_of($revisions, 'DifferentialRevision');
125
126
if (!$revisions) {
127
return array();
128
}
129
130
$field_lists = array();
131
foreach ($revisions as $revision) {
132
$revision_phid = $revision->getPHID();
133
134
$field_list = PhabricatorCustomField::getObjectFields(
135
$revision,
136
PhabricatorCustomField::ROLE_CONDUIT);
137
138
$field_list
139
->setViewer($viewer)
140
->readFieldsFromObject($revision);
141
142
$field_lists[$revision_phid] = $field_list;
143
}
144
145
$all_fields = array();
146
foreach ($field_lists as $field_list) {
147
foreach ($field_list->getFields() as $field) {
148
$all_fields[] = $field;
149
}
150
}
151
152
id(new PhabricatorCustomFieldStorageQuery())
153
->addFields($all_fields)
154
->execute();
155
156
$results = array();
157
foreach ($field_lists as $revision_phid => $field_list) {
158
$results[$revision_phid] = array();
159
foreach ($field_list->getFields() as $field) {
160
$field_key = $field->getFieldKeyForConduit();
161
$value = $field->getConduitDictionaryValue();
162
$results[$revision_phid][$field_key] = $value;
163
}
164
}
165
166
// For compatibility, fill in these "custom fields" by querying for them
167
// efficiently. See T11404 for discussion.
168
169
$legacy_edge_map = array(
170
'phabricator:projects' =>
171
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
172
'phabricator:depends-on' =>
173
DifferentialRevisionDependsOnRevisionEdgeType::EDGECONST,
174
);
175
176
$query = id(new PhabricatorEdgeQuery())
177
->withSourcePHIDs(array_keys($results))
178
->withEdgeTypes($legacy_edge_map);
179
180
$query->execute();
181
182
foreach ($results as $revision_phid => $dict) {
183
foreach ($legacy_edge_map as $edge_key => $edge_type) {
184
$phid_list = $query->getDestinationPHIDs(
185
array($revision_phid),
186
array($edge_type));
187
188
$results[$revision_phid][$edge_key] = $phid_list;
189
}
190
}
191
192
return $results;
193
}
194
195
}
196
197