Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/differential/conduit/DifferentialGetCommitMessageConduitAPIMethod.php
12256 views
1
<?php
2
3
final class DifferentialGetCommitMessageConduitAPIMethod
4
extends DifferentialConduitAPIMethod {
5
6
public function getAPIMethodName() {
7
return 'differential.getcommitmessage';
8
}
9
10
public function getMethodDescription() {
11
return pht('Retrieve Differential commit messages or message templates.');
12
}
13
14
protected function defineParamTypes() {
15
$edit_types = array('edit', 'create');
16
17
return array(
18
'revision_id' => 'optional revision_id',
19
'fields' => 'optional dict<string, wild>',
20
'edit' => 'optional '.$this->formatStringConstants($edit_types),
21
);
22
}
23
24
protected function defineReturnType() {
25
return 'nonempty string';
26
}
27
28
protected function defineErrorTypes() {
29
return array(
30
'ERR_NOT_FOUND' => pht('Revision was not found.'),
31
);
32
}
33
34
protected function execute(ConduitAPIRequest $request) {
35
$id = $request->getValue('revision_id');
36
$viewer = $request->getUser();
37
38
if ($id) {
39
$revision = id(new DifferentialRevisionQuery())
40
->withIDs(array($id))
41
->setViewer($viewer)
42
->needReviewers(true)
43
->needActiveDiffs(true)
44
->executeOne();
45
if (!$revision) {
46
throw new ConduitException('ERR_NOT_FOUND');
47
}
48
} else {
49
$revision = DifferentialRevision::initializeNewRevision($viewer);
50
}
51
52
// There are three modes here: "edit", "create", and "read" (which has
53
// no value for the "edit" parameter).
54
55
// In edit or create mode, we hide read-only fields. In create mode, we
56
// show "Field:" templates for some fields even if they are empty.
57
$edit_mode = $request->getValue('edit');
58
59
$is_any_edit = $edit_mode !== null && (bool)strlen($edit_mode);
60
$is_create = ($edit_mode == 'create');
61
62
$field_list = DifferentialCommitMessageField::newEnabledFields($viewer);
63
64
$custom_storage = $this->loadCustomFieldStorage($viewer, $revision);
65
foreach ($field_list as $field) {
66
$field->setCustomFieldStorage($custom_storage);
67
}
68
69
// If we're editing the message, remove fields like "Conflicts" and
70
// "git-svn-id" which should not be presented to the user for editing.
71
if ($is_any_edit) {
72
foreach ($field_list as $field_key => $field) {
73
if (!$field->isFieldEditable()) {
74
unset($field_list[$field_key]);
75
}
76
}
77
}
78
79
$overrides = $request->getValue('fields', array());
80
81
$value_map = array();
82
foreach ($field_list as $field_key => $field) {
83
if (array_key_exists($field_key, $overrides)) {
84
$field_value = $overrides[$field_key];
85
} else {
86
$field_value = $field->readFieldValueFromObject($revision);
87
}
88
89
// We're calling this method on the value no matter where we got it
90
// from, so we hit the same validation logic for values which came over
91
// the wire and which we generated.
92
$field_value = $field->readFieldValueFromConduit($field_value);
93
94
$value_map[$field_key] = $field_value;
95
}
96
97
$key_title = DifferentialTitleCommitMessageField::FIELDKEY;
98
99
$commit_message = array();
100
foreach ($field_list as $field_key => $field) {
101
$label = $field->getFieldName();
102
$wire_value = $value_map[$field_key];
103
$value = $field->renderFieldValue($wire_value);
104
105
$is_template = ($is_create && $field->isTemplateField());
106
107
if (!is_string($value) && !is_null($value)) {
108
throw new Exception(
109
pht(
110
'Commit message field "%s" was expected to render a string or '.
111
'null value, but rendered a "%s" instead.',
112
$field->getFieldKey(),
113
gettype($value)));
114
}
115
116
$is_title = ($field_key == $key_title);
117
118
if ($value === null || !strlen($value)) {
119
if ($is_template) {
120
$commit_message[] = $label.': ';
121
}
122
} else {
123
if ($is_title) {
124
$commit_message[] = $value;
125
} else {
126
$value = str_replace(
127
array("\r\n", "\r"),
128
array("\n", "\n"),
129
$value);
130
if (strpos($value, "\n") !== false || substr($value, 0, 2) === ' ') {
131
$commit_message[] = "{$label}:\n{$value}";
132
} else {
133
$commit_message[] = "{$label}: {$value}";
134
}
135
}
136
}
137
}
138
139
return implode("\n\n", $commit_message);
140
}
141
142
private function loadCustomFieldStorage(
143
PhabricatorUser $viewer,
144
DifferentialRevision $revision) {
145
146
$custom_field_list = PhabricatorCustomField::getObjectFields(
147
$revision,
148
PhabricatorCustomField::ROLE_STORAGE);
149
150
$custom_field_list
151
->setViewer($viewer)
152
->readFieldsFromStorage($revision);
153
154
$custom_field_map = array();
155
foreach ($custom_field_list->getFields() as $custom_field) {
156
if (!$custom_field->shouldUseStorage()) {
157
continue;
158
}
159
$custom_field_key = $custom_field->getFieldKey();
160
$custom_field_value = $custom_field->getValueForStorage();
161
$custom_field_map[$custom_field_key] = $custom_field_value;
162
}
163
164
return $custom_field_map;
165
}
166
167
168
}
169
170