Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/harbormaster/controller/HarbormasterStepEditController.php
12256 views
1
<?php
2
3
final class HarbormasterStepEditController
4
extends HarbormasterPlanController {
5
6
public function handleRequest(AphrontRequest $request) {
7
$viewer = $this->getViewer();
8
$id = $request->getURIData('id');
9
10
if ($id) {
11
$step = id(new HarbormasterBuildStepQuery())
12
->setViewer($viewer)
13
->withIDs(array($id))
14
->requireCapabilities(
15
array(
16
PhabricatorPolicyCapability::CAN_VIEW,
17
PhabricatorPolicyCapability::CAN_EDIT,
18
))
19
->executeOne();
20
if (!$step) {
21
return new Aphront404Response();
22
}
23
$plan = $step->getBuildPlan();
24
25
$is_new = false;
26
} else {
27
$plan_id = $request->getURIData('plan');
28
$class = $request->getURIData('class');
29
30
$plan = id(new HarbormasterBuildPlanQuery())
31
->setViewer($viewer)
32
->withIDs(array($plan_id))
33
->requireCapabilities(
34
array(
35
PhabricatorPolicyCapability::CAN_VIEW,
36
PhabricatorPolicyCapability::CAN_EDIT,
37
))
38
->executeOne();
39
if (!$plan) {
40
return new Aphront404Response();
41
}
42
43
$impl = HarbormasterBuildStepImplementation::getImplementation($class);
44
if (!$impl) {
45
return new Aphront404Response();
46
}
47
48
if ($impl->shouldRequireAutotargeting()) {
49
// No manual creation of autotarget steps.
50
return new Aphront404Response();
51
}
52
53
$step = HarbormasterBuildStep::initializeNewStep($viewer)
54
->setBuildPlanPHID($plan->getPHID())
55
->setClassName($class);
56
57
$is_new = true;
58
}
59
60
$plan_uri = $this->getApplicationURI('plan/'.$plan->getID().'/');
61
62
if ($is_new) {
63
$cancel_uri = $plan_uri;
64
} else {
65
$cancel_uri = $this->getApplicationURI('step/view/'.$step->getID().'/');
66
}
67
68
$implementation = $step->getStepImplementation();
69
70
$field_list = PhabricatorCustomField::getObjectFields(
71
$step,
72
PhabricatorCustomField::ROLE_EDIT);
73
$field_list
74
->setViewer($viewer)
75
->readFieldsFromStorage($step);
76
77
$e_name = true;
78
$v_name = $step->getName();
79
$e_description = null;
80
$v_description = $step->getDescription();
81
$e_depends_on = null;
82
$v_depends_on = $step->getDetail('dependsOn', array());
83
84
$errors = array();
85
$validation_exception = null;
86
if ($request->isFormPost()) {
87
$e_name = null;
88
$v_name = $request->getStr('name');
89
$v_description = $request->getStr('description');
90
$v_depends_on = $request->getArr('dependsOn');
91
92
$xactions = $field_list->buildFieldTransactionsFromRequest(
93
new HarbormasterBuildStepTransaction(),
94
$request);
95
96
$editor = id(new HarbormasterBuildStepEditor())
97
->setActor($viewer)
98
->setContinueOnNoEffect(true)
99
->setContentSourceFromRequest($request);
100
101
$name_xaction = id(new HarbormasterBuildStepTransaction())
102
->setTransactionType(HarbormasterBuildStepTransaction::TYPE_NAME)
103
->setNewValue($v_name);
104
array_unshift($xactions, $name_xaction);
105
106
$depends_on_xaction = id(new HarbormasterBuildStepTransaction())
107
->setTransactionType(
108
HarbormasterBuildStepTransaction::TYPE_DEPENDS_ON)
109
->setNewValue($v_depends_on);
110
array_unshift($xactions, $depends_on_xaction);
111
112
$description_xaction = id(new HarbormasterBuildStepTransaction())
113
->setTransactionType(
114
HarbormasterBuildStepTransaction::TYPE_DESCRIPTION)
115
->setNewValue($v_description);
116
array_unshift($xactions, $description_xaction);
117
118
if ($is_new) {
119
// When creating a new step, make sure we have a create transaction
120
// so we'll apply the transactions even if the step has no
121
// configurable options.
122
$create_xaction = id(new HarbormasterBuildStepTransaction())
123
->setTransactionType(HarbormasterBuildStepTransaction::TYPE_CREATE);
124
array_unshift($xactions, $create_xaction);
125
}
126
127
try {
128
$editor->applyTransactions($step, $xactions);
129
130
$step_uri = $this->getApplicationURI('step/view/'.$step->getID().'/');
131
132
return id(new AphrontRedirectResponse())->setURI($step_uri);
133
} catch (PhabricatorApplicationTransactionValidationException $ex) {
134
$validation_exception = $ex;
135
}
136
}
137
138
$form = id(new AphrontFormView())
139
->setUser($viewer);
140
141
$instructions = $implementation->getEditInstructions();
142
if (strlen($instructions)) {
143
$form->appendRemarkupInstructions($instructions);
144
}
145
146
$form->appendChild(
147
id(new AphrontFormTextControl())
148
->setName('name')
149
->setLabel(pht('Name'))
150
->setError($e_name)
151
->setValue($v_name));
152
153
$form->appendChild(id(new AphrontFormDividerControl()));
154
155
$field_list->appendFieldsToForm($form);
156
157
$form->appendChild(id(new AphrontFormDividerControl()));
158
159
$form
160
->appendControl(
161
id(new AphrontFormTokenizerControl())
162
->setDatasource(id(new HarbormasterBuildDependencyDatasource())
163
->setParameters(array(
164
'planPHID' => $plan->getPHID(),
165
'stepPHID' => $is_new ? null : $step->getPHID(),
166
)))
167
->setName('dependsOn')
168
->setLabel(pht('Depends On'))
169
->setError($e_depends_on)
170
->setValue($v_depends_on));
171
172
$form
173
->appendChild(
174
id(new PhabricatorRemarkupControl())
175
->setUser($viewer)
176
->setName('description')
177
->setLabel(pht('Description'))
178
->setError($e_description)
179
->setValue($v_description));
180
181
$crumbs = $this->buildApplicationCrumbs();
182
$id = $plan->getID();
183
$crumbs->addTextCrumb(pht('Plan %d', $id), $plan_uri);
184
185
if ($is_new) {
186
$submit = pht('Create Build Step');
187
$header = id(new PHUIHeaderView())
188
->setHeader(pht('New Step: %s', $implementation->getName()))
189
->setHeaderIcon('fa-plus-square');
190
$crumbs->addTextCrumb(pht('Add Step'));
191
} else {
192
$submit = pht('Save Build Step');
193
$header = id(new PHUIHeaderView())
194
->setHeader(pht('Edit Step: %s', $implementation->getName()))
195
->setHeaderIcon('fa-pencil');
196
$crumbs->addTextCrumb(pht('Step %d', $step->getID()), $cancel_uri);
197
$crumbs->addTextCrumb(pht('Edit Step'));
198
}
199
$crumbs->setBorder(true);
200
201
$form->appendChild(
202
id(new AphrontFormSubmitControl())
203
->setValue($submit)
204
->addCancelButton($cancel_uri));
205
206
$box = id(new PHUIObjectBoxView())
207
->setHeaderText(pht('Step'))
208
->setValidationException($validation_exception)
209
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
210
->setForm($form);
211
212
$variables = $this->renderBuildVariablesTable();
213
214
if ($is_new) {
215
$xaction_view = null;
216
$timeline = null;
217
} else {
218
$timeline = $this->buildTransactionTimeline(
219
$step,
220
new HarbormasterBuildStepTransactionQuery());
221
$timeline->setShouldTerminate(true);
222
}
223
224
$view = id(new PHUITwoColumnView())
225
->setHeader($header)
226
->setFooter(array(
227
$box,
228
$variables,
229
$timeline,
230
));
231
232
return $this->newPage()
233
->setTitle($implementation->getName())
234
->setCrumbs($crumbs)
235
->appendChild($view);
236
237
}
238
239
private function renderBuildVariablesTable() {
240
$viewer = $this->getRequest()->getUser();
241
242
$variables = HarbormasterBuild::getAvailableBuildVariables();
243
ksort($variables);
244
245
$rows = array();
246
$rows[] = pht(
247
'The following variables can be used in most fields. '.
248
'To reference a variable, use `%s` in a field.',
249
'${name}');
250
$rows[] = sprintf(
251
'| %s | %s |',
252
pht('Variable'),
253
pht('Description'));
254
$rows[] = '|---|---|';
255
foreach ($variables as $name => $description) {
256
$rows[] = '| `'.$name.'` | '.$description.' |';
257
}
258
$rows = implode("\n", $rows);
259
260
$form = id(new AphrontFormView())
261
->setUser($viewer)
262
->appendRemarkupInstructions($rows);
263
264
return id(new PHUIObjectBoxView())
265
->setHeaderText(pht('Build Variables'))
266
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
267
->appendChild($form);
268
}
269
270
}
271
272