Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / owners / controller / PhabricatorOwnersDetailController.php
blob8512107e75d2d0f3757cfa2452dbb8297a3c013f
1 <?php
3 final class PhabricatorOwnersDetailController
4 extends PhabricatorOwnersController {
6 public function shouldAllowPublic() {
7 return true;
10 public function handleRequest(AphrontRequest $request) {
11 $viewer = $this->getViewer();
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();
22 $paths = $package->getPaths();
24 $repository_phids = array();
25 foreach ($paths as $path) {
26 $repository_phids[$path->getRepositoryPHID()] = true;
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();
39 $field_list = PhabricatorCustomField::getObjectFields(
40 $package,
41 PhabricatorCustomField::ROLE_VIEW);
42 $field_list
43 ->setViewer($viewer)
44 ->readFieldsFromStorage($package);
46 $curtain = $this->buildCurtain($package);
47 $details = $this->buildPackageDetailView($package, $field_list);
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';
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');
66 $commit_views = array();
68 $params = array(
69 'package' => $package->getPHID(),
72 $commit_uri = new PhutilURI('/diffusion/commit/', $params);
74 $status_concern = DiffusionCommitAuditStatus::CONCERN_RAISED;
76 $attention_commits = id(new DiffusionCommitQuery())
77 ->setViewer($request->getUser())
78 ->withPackagePHIDs(array($package->getPHID()))
79 ->withStatuses(
80 array(
81 $status_concern,
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();
93 $view->setNoDataString(pht('This package has no open problem commits.'));
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')),
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();
115 $view = id(new DiffusionCommitGraphView())
116 ->setViewer($viewer)
117 ->setCommits($all_commits)
118 ->newObjectItemListView();
120 $view->setNoDataString(pht('No commits in this package.'));
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')),
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']);
143 $commit_panel->setHeader($commit_header);
144 $commit_panel->appendChild($commit_view['view']);
146 $commit_panels[] = $commit_panel;
149 $crumbs = $this->buildApplicationCrumbs();
150 $crumbs->addTextCrumb($package->getMonogram());
151 $crumbs->setBorder(true);
153 $rules_view = $this->newRulesView($package);
155 $timeline = $this->buildTransactionTimeline(
156 $package,
157 new PhabricatorOwnersPackageTransactionQuery());
158 $timeline->setShouldTerminate(true);
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,
169 ->addPropertySection(pht('Details'), $details);
171 return $this->newPage()
172 ->setTitle($package->getName())
173 ->setCrumbs($crumbs)
174 ->appendChild($view);
177 private function buildPackageDetailView(
178 PhabricatorOwnersPackage $package,
179 PhabricatorCustomFieldList $field_list) {
181 $viewer = $this->getViewer();
182 $view = id(new PHUIPropertyListView())
183 ->setUser($viewer);
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'));
191 $view->addProperty(pht('Owners'), $owner_list);
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);
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);
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);
212 $rule = $package->newAuditingRule();
213 $view->addProperty(pht('Auditing'), $rule->getDisplayName());
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'));
223 $view->addProperty(pht('Ignored Attributes'), $ignored);
225 $description = $package->getDescription();
226 if (strlen($description)) {
227 $description = new PHUIRemarkupView($viewer, $description);
228 $view->addSectionHeader(pht('Description'));
229 $view->addTextContent($description);
232 $field_list->appendFieldsToPropertyList(
233 $package,
234 $viewer,
235 $view);
237 return $view;
240 private function buildCurtain(PhabricatorOwnersPackage $package) {
241 $viewer = $this->getViewer();
243 $can_edit = PhabricatorPolicyFilter::hasCapability(
244 $viewer,
245 $package,
246 PhabricatorPolicyCapability::CAN_EDIT);
248 $id = $package->getID();
249 $edit_uri = $this->getApplicationURI("/edit/{$id}/");
250 $paths_uri = $this->getApplicationURI("/paths/{$id}/");
252 $curtain = $this->newCurtainView($package);
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));
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}/")));
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));
288 return $curtain;
291 private function renderPathsTable(array $paths, array $repositories) {
292 $viewer = $this->getViewer();
294 $rows = array();
295 foreach ($paths as $path) {
296 $repo = idx($repositories, $path->getRepositoryPHID());
297 if (!$repo) {
298 continue;
300 $href = $repo->generateURI(
301 array(
302 'branch' => $repo->getDefaultBranch(),
303 'path' => $path->getPathDisplay(),
304 'action' => 'browse',
307 $path_link = phutil_tag(
308 'a',
309 array(
310 'href' => (string)$href,
312 $path->getPathDisplay());
314 $rows[] = array(
315 ($path->getExcluded() ? '-' : '+'),
316 $repo->getName(),
317 $path_link,
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.'),
333 $table = id(new AphrontTableView($rows))
334 ->setHeaders(
335 array(
336 null,
337 pht('Repository'),
338 pht('Path'),
340 ->setColumnClasses(
341 array(
342 null,
343 null,
344 'wide',
347 if ($info) {
348 $table->setNotice($info);
351 $header = id(new PHUIHeaderView())
352 ->setHeader(pht('Paths'))
353 ->setHeaderIcon('fa-folder-open');
355 $box = id(new PHUIObjectBoxView())
356 ->setHeader($header)
357 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
358 ->setTable($table);
360 return $box;
363 private function newRulesView(PhabricatorOwnersPackage $package) {
364 $viewer = $this->getViewer();
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();
375 $more_results = (count($rules) > $limit);
376 $rules = array_slice($rules, 0, $limit);
378 $list = id(new HeraldRuleListView())
379 ->setViewer($viewer)
380 ->setRules($rules)
381 ->newObjectList();
383 $list->setNoDataString(
384 pht(
385 'No active Herald rules add this package as an auditor, reviewer, '.
386 'or subscriber.'));
388 $more_href = new PhutilURI(
389 '/herald/',
390 array('affectedPHID' => $package->getPHID()));
392 if ($more_results) {
393 $list->newTailButton()
394 ->setHref($more_href);
397 $more_link = id(new PHUIButtonView())
398 ->setTag('a')
399 ->setIcon('fa-list-ul')
400 ->setText(pht('View All Rules'))
401 ->setHref($more_href);
403 $header = id(new PHUIHeaderView())
404 ->setHeader(pht('Affected By Herald Rules'))
405 ->setHeaderIcon(id(new PhabricatorHeraldApplication())->getIcon())
406 ->addActionLink($more_link);
408 return id(new PHUIObjectBoxView())
409 ->setHeader($header)
410 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
411 ->appendChild($list);