Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/owners/controller/PhabricatorOwnersDetailController.php
13450 views
1
<?php
2
3
final class PhabricatorOwnersDetailController
4
extends PhabricatorOwnersController {
5
6
public function shouldAllowPublic() {
7
return true;
8
}
9
10
public function handleRequest(AphrontRequest $request) {
11
$viewer = $this->getViewer();
12
13
$package = id(new PhabricatorOwnersPackageQuery())
14
->setViewer($viewer)
15
->withIDs(array($request->getURIData('id')))
16
->needPaths(true)
17
->executeOne();
18
if (!$package) {
19
return new Aphront404Response();
20
}
21
22
$paths = $package->getPaths();
23
24
$repository_phids = array();
25
foreach ($paths as $path) {
26
$repository_phids[$path->getRepositoryPHID()] = true;
27
}
28
29
if ($repository_phids) {
30
$repositories = id(new PhabricatorRepositoryQuery())
31
->setViewer($viewer)
32
->withPHIDs(array_keys($repository_phids))
33
->execute();
34
$repositories = mpull($repositories, null, 'getPHID');
35
} else {
36
$repositories = array();
37
}
38
39
$field_list = PhabricatorCustomField::getObjectFields(
40
$package,
41
PhabricatorCustomField::ROLE_VIEW);
42
$field_list
43
->setViewer($viewer)
44
->readFieldsFromStorage($package);
45
46
$curtain = $this->buildCurtain($package);
47
$details = $this->buildPackageDetailView($package, $field_list);
48
49
if ($package->isArchived()) {
50
$header_icon = 'fa-ban';
51
$header_name = pht('Archived');
52
$header_color = 'dark';
53
} else {
54
$header_icon = 'fa-check';
55
$header_name = pht('Active');
56
$header_color = 'bluegrey';
57
}
58
59
$header = id(new PHUIHeaderView())
60
->setUser($viewer)
61
->setHeader($package->getName())
62
->setStatus($header_icon, $header_color, $header_name)
63
->setPolicyObject($package)
64
->setHeaderIcon('fa-gift');
65
66
$commit_views = array();
67
68
$params = array(
69
'package' => $package->getPHID(),
70
);
71
72
$commit_uri = new PhutilURI('/diffusion/commit/', $params);
73
74
$status_concern = DiffusionCommitAuditStatus::CONCERN_RAISED;
75
76
$attention_commits = id(new DiffusionCommitQuery())
77
->setViewer($request->getUser())
78
->withPackagePHIDs(array($package->getPHID()))
79
->withStatuses(
80
array(
81
$status_concern,
82
))
83
->needCommitData(true)
84
->needAuditRequests(true)
85
->needIdentities(true)
86
->setLimit(10)
87
->execute();
88
$view = id(new DiffusionCommitGraphView())
89
->setViewer($viewer)
90
->setCommits($attention_commits)
91
->newObjectItemListView();
92
93
$view->setNoDataString(pht('This package has no open problem commits.'));
94
95
$commit_views[] = array(
96
'view' => $view,
97
'header' => pht('Needs Attention'),
98
'icon' => 'fa-warning',
99
'button' => id(new PHUIButtonView())
100
->setTag('a')
101
->setHref($commit_uri->alter('status', $status_concern))
102
->setIcon('fa-list-ul')
103
->setText(pht('View All')),
104
);
105
106
$all_commits = id(new DiffusionCommitQuery())
107
->setViewer($request->getUser())
108
->withPackagePHIDs(array($package->getPHID()))
109
->needCommitData(true)
110
->needAuditRequests(true)
111
->needIdentities(true)
112
->setLimit(25)
113
->execute();
114
115
$view = id(new DiffusionCommitGraphView())
116
->setViewer($viewer)
117
->setCommits($all_commits)
118
->newObjectItemListView();
119
120
$view->setNoDataString(pht('No commits in this package.'));
121
122
$commit_views[] = array(
123
'view' => $view,
124
'header' => pht('Recent Commits'),
125
'icon' => 'fa-code',
126
'button' => id(new PHUIButtonView())
127
->setTag('a')
128
->setHref($commit_uri)
129
->setIcon('fa-list-ul')
130
->setText(pht('View All')),
131
);
132
133
$commit_panels = array();
134
foreach ($commit_views as $commit_view) {
135
$commit_panel = id(new PHUIObjectBoxView())
136
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
137
$commit_header = id(new PHUIHeaderView())
138
->setHeader($commit_view['header'])
139
->setHeaderIcon($commit_view['icon']);
140
if (isset($commit_view['button'])) {
141
$commit_header->addActionLink($commit_view['button']);
142
}
143
$commit_panel->setHeader($commit_header);
144
$commit_panel->appendChild($commit_view['view']);
145
146
$commit_panels[] = $commit_panel;
147
}
148
149
$crumbs = $this->buildApplicationCrumbs();
150
$crumbs->addTextCrumb($package->getMonogram());
151
$crumbs->setBorder(true);
152
153
$rules_view = $this->newRulesView($package);
154
155
$timeline = $this->buildTransactionTimeline(
156
$package,
157
new PhabricatorOwnersPackageTransactionQuery());
158
$timeline->setShouldTerminate(true);
159
160
$view = id(new PHUITwoColumnView())
161
->setHeader($header)
162
->setCurtain($curtain)
163
->setMainColumn(array(
164
$this->renderPathsTable($paths, $repositories),
165
$rules_view,
166
$commit_panels,
167
$timeline,
168
))
169
->addPropertySection(pht('Details'), $details);
170
171
return $this->newPage()
172
->setTitle($package->getName())
173
->setCrumbs($crumbs)
174
->appendChild($view);
175
}
176
177
private function buildPackageDetailView(
178
PhabricatorOwnersPackage $package,
179
PhabricatorCustomFieldList $field_list) {
180
181
$viewer = $this->getViewer();
182
$view = id(new PHUIPropertyListView())
183
->setUser($viewer);
184
185
$owners = $package->getOwners();
186
if ($owners) {
187
$owner_list = $viewer->renderHandleList(mpull($owners, 'getUserPHID'));
188
} else {
189
$owner_list = phutil_tag('em', array(), pht('None'));
190
}
191
$view->addProperty(pht('Owners'), $owner_list);
192
193
194
$dominion = $package->getDominion();
195
$dominion_map = PhabricatorOwnersPackage::getDominionOptionsMap();
196
$spec = idx($dominion_map, $dominion, array());
197
$name = idx($spec, 'short', $dominion);
198
$view->addProperty(pht('Dominion'), $name);
199
200
$authority_mode = $package->getAuthorityMode();
201
$authority_map = PhabricatorOwnersPackage::getAuthorityOptionsMap();
202
$spec = idx($authority_map, $authority_mode, array());
203
$name = idx($spec, 'short', $authority_mode);
204
$view->addProperty(pht('Authority'), $name);
205
206
$auto = $package->getAutoReview();
207
$autoreview_map = PhabricatorOwnersPackage::getAutoreviewOptionsMap();
208
$spec = idx($autoreview_map, $auto, array());
209
$name = idx($spec, 'name', $auto);
210
$view->addProperty(pht('Auto Review'), $name);
211
212
$rule = $package->newAuditingRule();
213
$view->addProperty(pht('Auditing'), $rule->getDisplayName());
214
215
$ignored = $package->getIgnoredPathAttributes();
216
$ignored = array_keys($ignored);
217
if ($ignored) {
218
$ignored = implode(', ', $ignored);
219
} else {
220
$ignored = phutil_tag('em', array(), pht('None'));
221
}
222
223
$view->addProperty(pht('Ignored Attributes'), $ignored);
224
225
$description = $package->getDescription();
226
if (strlen($description)) {
227
$description = new PHUIRemarkupView($viewer, $description);
228
$view->addSectionHeader(pht('Description'));
229
$view->addTextContent($description);
230
}
231
232
$field_list->appendFieldsToPropertyList(
233
$package,
234
$viewer,
235
$view);
236
237
return $view;
238
}
239
240
private function buildCurtain(PhabricatorOwnersPackage $package) {
241
$viewer = $this->getViewer();
242
243
$can_edit = PhabricatorPolicyFilter::hasCapability(
244
$viewer,
245
$package,
246
PhabricatorPolicyCapability::CAN_EDIT);
247
248
$id = $package->getID();
249
$edit_uri = $this->getApplicationURI("/edit/{$id}/");
250
$paths_uri = $this->getApplicationURI("/paths/{$id}/");
251
252
$curtain = $this->newCurtainView($package);
253
254
$curtain->addAction(
255
id(new PhabricatorActionView())
256
->setName(pht('Edit Package'))
257
->setIcon('fa-pencil')
258
->setDisabled(!$can_edit)
259
->setWorkflow(!$can_edit)
260
->setHref($edit_uri));
261
262
if ($package->isArchived()) {
263
$curtain->addAction(
264
id(new PhabricatorActionView())
265
->setName(pht('Activate Package'))
266
->setIcon('fa-check')
267
->setDisabled(!$can_edit)
268
->setWorkflow($can_edit)
269
->setHref($this->getApplicationURI("/archive/{$id}/")));
270
} else {
271
$curtain->addAction(
272
id(new PhabricatorActionView())
273
->setName(pht('Archive Package'))
274
->setIcon('fa-ban')
275
->setDisabled(!$can_edit)
276
->setWorkflow($can_edit)
277
->setHref($this->getApplicationURI("/archive/{$id}/")));
278
}
279
280
$curtain->addAction(
281
id(new PhabricatorActionView())
282
->setName(pht('Edit Paths'))
283
->setIcon('fa-folder-open')
284
->setDisabled(!$can_edit)
285
->setWorkflow(!$can_edit)
286
->setHref($paths_uri));
287
288
return $curtain;
289
}
290
291
private function renderPathsTable(array $paths, array $repositories) {
292
$viewer = $this->getViewer();
293
294
$rows = array();
295
foreach ($paths as $path) {
296
$repo = idx($repositories, $path->getRepositoryPHID());
297
if (!$repo) {
298
continue;
299
}
300
$href = $repo->generateURI(
301
array(
302
'branch' => $repo->getDefaultBranch(),
303
'path' => $path->getPathDisplay(),
304
'action' => 'browse',
305
));
306
307
$path_link = phutil_tag(
308
'a',
309
array(
310
'href' => (string)$href,
311
),
312
$path->getPathDisplay());
313
314
$rows[] = array(
315
($path->getExcluded() ? '-' : '+'),
316
$repo->getName(),
317
$path_link,
318
);
319
}
320
321
$info = null;
322
if (!$paths) {
323
$info = id(new PHUIInfoView())
324
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
325
->setErrors(
326
array(
327
pht(
328
'This package does not contain any paths yet. Use '.
329
'"Edit Paths" to add some.'),
330
));
331
}
332
333
$table = id(new AphrontTableView($rows))
334
->setHeaders(
335
array(
336
null,
337
pht('Repository'),
338
pht('Path'),
339
))
340
->setColumnClasses(
341
array(
342
null,
343
null,
344
'wide',
345
));
346
347
if ($info) {
348
$table->setNotice($info);
349
}
350
351
$header = id(new PHUIHeaderView())
352
->setHeader(pht('Paths'))
353
->setHeaderIcon('fa-folder-open');
354
355
$box = id(new PHUIObjectBoxView())
356
->setHeader($header)
357
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
358
->setTable($table);
359
360
return $box;
361
}
362
363
private function newRulesView(PhabricatorOwnersPackage $package) {
364
$viewer = $this->getViewer();
365
366
$limit = 10;
367
$rules = id(new HeraldRuleQuery())
368
->setViewer($viewer)
369
->withDisabled(false)
370
->withAffectedObjectPHIDs(array($package->getPHID()))
371
->needValidateAuthors(true)
372
->setLimit($limit + 1)
373
->execute();
374
375
$more_results = (count($rules) > $limit);
376
$rules = array_slice($rules, 0, $limit);
377
378
$list = id(new HeraldRuleListView())
379
->setViewer($viewer)
380
->setRules($rules)
381
->newObjectList();
382
383
$list->setNoDataString(
384
pht(
385
'No active Herald rules add this package as an auditor, reviewer, '.
386
'or subscriber.'));
387
388
$more_href = new PhutilURI(
389
'/herald/',
390
array('affectedPHID' => $package->getPHID()));
391
392
if ($more_results) {
393
$list->newTailButton()
394
->setHref($more_href);
395
}
396
397
$more_link = id(new PHUIButtonView())
398
->setTag('a')
399
->setIcon('fa-list-ul')
400
->setText(pht('View All Rules'))
401
->setHref($more_href);
402
403
$header = id(new PHUIHeaderView())
404
->setHeader(pht('Affected By Herald Rules'))
405
->setHeaderIcon(id(new PhabricatorHeraldApplication())->getIcon())
406
->addActionLink($more_link);
407
408
return id(new PHUIObjectBoxView())
409
->setHeader($header)
410
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
411
->appendChild($list);
412
}
413
414
}
415
416