Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/audit/controller/list/PhabricatorAuditListController.php b/src/applications/audit/controller/list/PhabricatorAuditListController.php
index cef50cf335..fa75d73c0d 100644
--- a/src/applications/audit/controller/list/PhabricatorAuditListController.php
+++ b/src/applications/audit/controller/list/PhabricatorAuditListController.php
@@ -1,474 +1,494 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorAuditListController extends PhabricatorAuditController {
private $filter;
private $name;
private $filterStatus;
public function willProcessRequest(array $data) {
$this->filter = idx($data, 'filter');
$this->name = idx($data, 'name');
}
public function processRequest() {
$request = $this->getRequest();
$nav = $this->buildNavAndSelectFilter();
if ($request->isFormPost()) {
// If the list filter is POST'ed, redirect to GET so the page can be
// bookmarked.
$uri = $request->getRequestURI();
$phid = head($request->getArr('set_phid'));
$user = id(new PhabricatorUser())->loadOneWhere(
'phid = %s',
$phid);
$uri = $request->getRequestURI();
if ($user) {
$username = phutil_escape_uri($user->getUsername());
$uri = '/audit/view/'.$this->filter.'/'.$username.'/';
} else if ($phid) {
$uri = $request->getRequestURI();
$uri = $uri->alter('phid', $phid);
}
return id(new AphrontRedirectResponse())->setURI($uri);
}
$this->filterStatus = $request->getStr('status', 'all');
$handle = $this->loadHandle();
$nav->appendChild($this->buildListFilters($handle));
$title = null;
$message = null;
if (!$handle) {
switch ($this->filter) {
case 'project':
$title = 'Choose A Project';
$message = 'Choose a project to view audits for.';
break;
case 'package':
case 'packagecommits':
$title = 'Choose a Package';
$message = 'Choose a package to view audits for.';
break;
}
}
if (!$message) {
$nav->appendChild($this->buildViews($handle));
} else {
$panel = id(new AphrontErrorView())
->setSeverity(AphrontErrorView::SEVERITY_NODATA)
->setTitle($title)
->appendChild($message);
$nav->appendChild($panel);
}
return $this->buildStandardPageResponse(
$nav,
array(
'title' => 'Audits',
));
}
private function buildNavAndSelectFilter() {
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI('/audit/view/'));
$nav->addLabel('Active');
$nav->addFilter('active', 'Need Attention');
$nav->addLabel('Audits');
$nav->addFilter('audits', 'All');
$nav->addFilter('user', 'By User');
$nav->addFilter('project', 'By Project');
$nav->addFilter('package', 'By Package');
$nav->addLabel('Commits');
$nav->addFilter('commits', 'All');
$nav->addFilter('author', 'By Author');
$nav->addFilter('packagecommits', 'By Package');
$this->filter = $nav->selectFilter($this->filter, 'active');
return $nav;
}
private function buildListFilters(PhabricatorObjectHandle $handle = null) {
$request = $this->getRequest();
$user = $request->getUser();
$form = new AphrontFormView();
$form->setUser($user);
$show_status = false;
$show_user = false;
$show_project = false;
$show_package = false;
switch ($this->filter) {
case 'audits':
case 'commits':
$show_status = true;
break;
case 'active':
$show_user = true;
break;
case 'author':
case 'user':
$show_user = true;
$show_status = true;
break;
case 'project':
$show_project = true;
$show_status = true;
break;
case 'package':
case 'packagecommits':
$show_package = true;
$show_status = true;
break;
}
if ($show_user || $show_project || $show_package) {
if ($show_user) {
$uri = '/typeahead/common/users/';
$label = 'User';
} else if ($show_project) {
$uri = '/typeahead/common/projects/';
$label = 'Project';
} else if ($show_package) {
$uri = '/typeahead/common/packages/';
$label = 'Package';
}
$tok_value = null;
if ($handle) {
$tok_value = array(
$handle->getPHID() => $handle->getFullName(),
);
}
$form->appendChild(
id(new AphrontFormTokenizerControl())
->setName('set_phid')
->setLabel($label)
->setLimit(1)
->setDatasource($uri)
->setValue($tok_value));
}
if ($show_status) {
$form->appendChild(
id(new AphrontFormToggleButtonsControl())
->setName('status')
->setLabel('Status')
->setBaseURI($request->getRequestURI(), 'status')
->setValue($this->filterStatus)
->setButtons(
array(
'all' => 'All',
'open' => 'Open',
)));
}
$form->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Filter Audits'));
$view = new AphrontListFilterView();
$view->appendChild($form);
return $view;
}
private function loadHandle() {
$request = $this->getRequest();
$default = null;
switch ($this->filter) {
case 'user':
case 'active':
case 'author':
$default = $request->getUser()->getPHID();
if ($this->name) {
$user = id(new PhabricatorUser())->loadOneWhere(
'username = %s',
$this->name);
if ($user) {
$default = $user->getPHID();
}
}
break;
}
$phid = $request->getStr('phid', $default);
if (!$phid) {
return null;
}
$phids = array($phid);
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$handle = $handles[$phid];
$this->validateHandle($handle);
return $handle;
}
private function validateHandle(PhabricatorObjectHandle $handle) {
switch ($this->filter) {
case 'active':
case 'user':
case 'author':
if ($handle->getType() !== PhabricatorPHIDConstants::PHID_TYPE_USER) {
throw new Exception("PHID must be a user PHID!");
}
break;
case 'package':
case 'packagecommits':
if ($handle->getType() !== PhabricatorPHIDConstants::PHID_TYPE_OPKG) {
throw new Exception("PHID must be a package PHID!");
}
break;
case 'project':
if ($handle->getType() !== PhabricatorPHIDConstants::PHID_TYPE_PROJ) {
throw new Exception("PHID must be a project PHID!");
}
break;
case 'audits':
case 'commits':
break;
default:
throw new Exception("Unknown filter '{$this->filter}'!");
}
}
private function buildViews(PhabricatorObjectHandle $handle = null) {
$views = array();
switch ($this->filter) {
case 'active':
$views[] = $this->buildAuditView($handle);
$views[] = $this->buildCommitView($handle);
break;
case 'audits':
case 'user':
case 'package':
case 'project':
$views[] = $this->buildAuditView($handle);
break;
case 'commits':
case 'packagecommits':
case 'author':
$views[] = $this->buildCommitView($handle);
break;
}
return $views;
}
private function buildAuditView(PhabricatorObjectHandle $handle = null) {
$request = $this->getRequest();
- $pager = new AphrontPagerView();
- $pager->setURI($request->getRequestURI(), 'offset');
-
$query = new PhabricatorAuditQuery();
- if ($this->filter != 'active') {
+ $use_pager = ($this->filter != 'active');
+
+ if ($use_pager) {
+ $pager = new AphrontPagerView();
+ $pager->setURI($request->getRequestURI(), 'offset');
+ $pager->setOffset($request->getInt('offset'));
+
$query->setOffset($pager->getOffset());
$query->setLimit($pager->getPageSize() + 1);
}
$phids = null;
switch ($this->filter) {
case 'user':
case 'active':
$obj = id(new PhabricatorUser())->loadOneWhere(
'phid = %s',
$handle->getPHID());
if (!$obj) {
throw new Exception("Invalid user!");
}
$phids = PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($obj);
break;
case 'project':
case 'package':
$phids = array($handle->getPHID());
break;
case 'audits';
break;
default:
throw new Exception("Unknown filter!");
}
if ($phids) {
$query->withAuditorPHIDs($phids);
}
switch ($this->filter) {
case 'audits':
case 'user':
case 'project':
case 'package':
switch ($this->filterStatus) {
case 'open':
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
break;
}
break;
case 'active':
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
break;
}
if ($handle) {
$handle_name = phutil_escape_html($handle->getName());
} else {
$handle_name = null;
}
switch ($this->filter) {
case 'active':
$header = 'Required Audits';
$nodata = 'No commits require your audit.';
break;
case 'user':
$header = "Audits for {$handle_name}";
$nodata = "No matching audits by {$handle_name}.";
break;
case 'audits':
$header = "Audits";
$nodata = "No matching audits.";
break;
case 'project':
$header = "Audits in Project '{$handle_name}'";
$nodata = "No matching audits in project '{$handle_name}'.";
break;
case 'package':
$header = "Audits for Package '{$handle_name}'";
$nodata = "No matching audits in package '{$handle_name}'.";
break;
}
+ $query->needCommitData(true);
+
$audits = $query->execute();
- $audits = $pager->sliceResults($audits);
+ if ($use_pager) {
+ $audits = $pager->sliceResults($audits);
+ }
$view = new PhabricatorAuditListView();
$view->setAudits($audits);
+ $view->setCommits($query->getCommits());
$view->setNoDataString($nodata);
$phids = $view->getRequiredHandlePHIDs();
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$view->setHandles($handles);
$panel = new AphrontPanelView();
$panel->setHeader($header);
$panel->appendChild($view);
- $panel->appendChild($pager);
+
+ if ($use_pager) {
+ $panel->appendChild($pager);
+ }
return $panel;
}
private function buildCommitView(PhabricatorObjectHandle $handle = null) {
$request = $this->getRequest();
- $pager = new AphrontPagerView();
- $pager->setURI($request->getRequestURI(), 'offset');
-
$query = new PhabricatorAuditCommitQuery();
$query->needCommitData(true);
- if ($this->filter != 'active') {
+ $use_pager = ($this->filter != 'active');
+
+ if ($use_pager) {
+ $pager = new AphrontPagerView();
+ $pager->setURI($request->getRequestURI(), 'offset');
+ $pager->setOffset($request->getInt('offset'));
+
$query->setOffset($pager->getOffset());
$query->setLimit($pager->getPageSize() + 1);
}
switch ($this->filter) {
case 'active':
case 'author':
$query->withAuthorPHIDs(array($handle->getPHID()));
break;
case 'packagecommits':
$query->withPackagePHIDs(array($handle->getPHID()));
break;
}
switch ($this->filter) {
case 'active':
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
break;
case 'author':
case 'packagecommits':
switch ($this->filterStatus) {
case 'open':
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
break;
}
break;
}
if ($handle) {
$handle_name = phutil_escape_html($handle->getName());
} else {
$handle_name = null;
}
switch ($this->filter) {
case 'active':
$header = 'Problem Commits';
$nodata = 'None of your commits have open concerns.';
break;
case 'author':
$header = "Commits by {$handle_name}";
$nodata = "No matching commits by {$handle_name}.";
break;
case 'commits':
$header = "Commits";
$nodata = "No matching commits.";
break;
case 'packagecommits':
$header = "Commits in Package '{$handle_name}'";
$nodata = "No matching commits in package '{$handle_name}'.";
break;
}
$commits = $query->execute();
- $commits = $pager->sliceResults($commits);
+
+ if ($use_pager) {
+ $commits = $pager->sliceResults($commits);
+ }
$view = new PhabricatorAuditCommitListView();
$view->setUser($request->getUser());
$view->setCommits($commits);
$view->setNoDataString($nodata);
$phids = $view->getRequiredHandlePHIDs();
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$view->setHandles($handles);
$panel = new AphrontPanelView();
$panel->setHeader($header);
$panel->appendChild($view);
- $panel->appendChild($pager);
+
+ if ($use_pager) {
+ $panel->appendChild($pager);
+ }
return $panel;
}
}
diff --git a/src/applications/audit/query/audit/PhabricatorAuditQuery.php b/src/applications/audit/query/audit/PhabricatorAuditQuery.php
index 7987d9926d..3c912441cf 100644
--- a/src/applications/audit/query/audit/PhabricatorAuditQuery.php
+++ b/src/applications/audit/query/audit/PhabricatorAuditQuery.php
@@ -1,131 +1,175 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorAuditQuery {
private $offset;
private $limit;
private $auditorPHIDs;
private $commitPHIDs;
+ private $needCommits;
+ private $needCommitData;
+
private $status = 'status-any';
const STATUS_ANY = 'status-any';
const STATUS_OPEN = 'status-open';
+ private $commits;
+
public function withCommitPHIDs(array $commit_phids) {
$this->commitPHIDs = $commit_phids;
return $this;
}
public function withAuditorPHIDs(array $auditor_phids) {
$this->auditorPHIDs = $auditor_phids;
return $this;
}
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function setOffset($offset) {
$this->offset = $offset;
return $this;
}
public function setLimit($limit) {
$this->limit = $limit;
return $this;
}
+ public function needCommits($need) {
+ $this->needCommits = $need;
+ return $this;
+ }
+
+ public function needCommitData($need) {
+ $this->needCommitData = $need;
+ return $this;
+ }
+
public function execute() {
$table = new PhabricatorRepositoryAuditRequest();
$conn_r = $table->establishConnection('r');
$where = $this->buildWhereClause($conn_r);
+ $order = $this->buildOrderClause($conn_r);
$limit = $this->buildLimitClause($conn_r);
$data = queryfx_all(
$conn_r,
- 'SELECT * FROM %T %Q %Q',
+ 'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$where,
+ $order,
$limit);
$audits = $table->loadAllFromArray($data);
+
+ if ($this->needCommits || $this->needCommitData) {
+ $phids = mpull($audits, 'getCommitPHID', 'getCommitPHID');
+ if ($phids) {
+ $cquery = new PhabricatorAuditCommitQuery();
+ $cquery->needCommitData($this->needCommitData);
+ $cquery->withCommitPHIDs(array_keys($phids));
+ $commits = $cquery->execute();
+ } else {
+ $commits = array();
+ }
+ $this->commits = $commits;
+ }
+
return $audits;
+ }
+ public function getCommits() {
+ if ($this->commits === null) {
+ throw new Exception(
+ "Call needCommits() or needCommitData() and then execute() the query ".
+ "before calling getCommits()!");
+ }
+
+ return $this->commits;
}
private function buildWhereClause($conn_r) {
$where = array();
if ($this->commitPHIDs) {
$where[] = qsprintf(
$conn_r,
'commitPHID IN (%Ls)',
$this->commitPHIDs);
}
if ($this->auditorPHIDs) {
$where[] = qsprintf(
$conn_r,
'auditorPHID IN (%Ls)',
$this->auditorPHIDs);
}
$status = $this->status;
switch ($status) {
case self::STATUS_OPEN:
$where[] = qsprintf(
$conn_r,
'auditStatus in (%Ls)',
array(
PhabricatorAuditStatusConstants::AUDIT_REQUIRED,
PhabricatorAuditStatusConstants::CONCERNED,
PhabricatorAuditStatusConstants::AUDIT_REQUESTED,
));
break;
case self::STATUS_ANY:
break;
default:
throw new Exception("Unknown status '{$status}'!");
}
if ($where) {
$where = 'WHERE ('.implode(') AND (', $where).')';
} else {
$where = '';
}
return $where;
}
private function buildLimitClause($conn_r) {
if ($this->limit && $this->offset) {
return qsprintf($conn_r, 'LIMIT %d, %d', $this->offset, $this->limit);
} else if ($this->limit) {
return qsprintf($conn_r, 'LIMIT %d', $this->limit);
} else if ($this->offset) {
return qsprintf($conn_r, 'LIMIT %d, %d', $this->offset, PHP_INT_MAX);
} else {
return '';
}
}
+ private function buildOrderClause($conn_r) {
+ return 'ORDER BY id DESC';
+ }
+
}
diff --git a/src/applications/audit/query/audit/__init__.php b/src/applications/audit/query/audit/__init__.php
index c5988d711d..332df08a56 100644
--- a/src/applications/audit/query/audit/__init__.php
+++ b/src/applications/audit/query/audit/__init__.php
@@ -1,15 +1,18 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/audit/constants/status');
+phutil_require_module('phabricator', 'applications/audit/query/commit');
phutil_require_module('phabricator', 'applications/repository/storage/auditrequest');
phutil_require_module('phabricator', 'storage/qsprintf');
phutil_require_module('phabricator', 'storage/queryfx');
+phutil_require_module('phutil', 'utils');
+
phutil_require_source('PhabricatorAuditQuery.php');
diff --git a/src/applications/audit/query/commit/PhabricatorAuditCommitQuery.php b/src/applications/audit/query/commit/PhabricatorAuditCommitQuery.php
index 3bdcea6937..35fce40425 100644
--- a/src/applications/audit/query/commit/PhabricatorAuditCommitQuery.php
+++ b/src/applications/audit/query/commit/PhabricatorAuditCommitQuery.php
@@ -1,177 +1,190 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorAuditCommitQuery {
private $offset;
private $limit;
+ private $commitPHIDs;
private $authorPHIDs;
private $packagePHIDs;
private $needCommitData;
private $status = 'status-any';
const STATUS_ANY = 'status-any';
const STATUS_OPEN = 'status-open';
public function withAuthorPHIDs(array $author_phids) {
$this->authorPHIDs = $author_phids;
return $this;
}
public function withPackagePHIDs(array $phids) {
$this->packagePHIDs = $phids;
return $this;
}
+ public function withCommitPHIDs(array $phids) {
+ $this->commitPHIDs = $phids;
+ return $this;
+ }
+
public function withStatus($status) {
$this->status = $status;
return $this;
}
public function needCommitData($need) {
$this->needCommitData = $need;
return $this;
}
public function setOffset($offset) {
$this->offset = $offset;
return $this;
}
public function setLimit($limit) {
$this->limit = $limit;
return $this;
}
public function execute() {
$table = new PhabricatorRepositoryCommit();
$conn_r = $table->establishConnection('r');
$join = $this->buildJoinClause($conn_r);
$where = $this->buildWhereClause($conn_r);
$order = $this->buildOrderClause($conn_r);
$limit = $this->buildLimitClause($conn_r);
$data = queryfx_all(
$conn_r,
'SELECT c.* FROM %T c %Q %Q %Q %Q',
$table->getTableName(),
$join,
$where,
$order,
$limit);
$commits = $table->loadAllFromArray($data);
if ($this->needCommitData && $commits) {
$data = id(new PhabricatorRepositoryCommitData())->loadAllWhere(
'commitID in (%Ld)',
mpull($commits, 'getID'));
$data = mpull($data, null, 'getCommitID');
foreach ($commits as $commit) {
if (idx($data, $commit->getID())) {
$commit->attachCommitData($data[$commit->getID()]);
} else {
$commit->attachCommitData(new PhabricatorRepositoryCommitData());
}
}
}
return $commits;
}
private function buildOrderClause($conn_r) {
return 'ORDER BY c.epoch DESC';
}
private function buildJoinClause($conn_r) {
$join = array();
if ($this->packagePHIDs) {
$join[] = qsprintf(
$conn_r,
'JOIN %T req ON c.phid = req.commitPHID',
id(new PhabricatorRepositoryAuditRequest())->getTableName());
}
if ($join) {
$join = implode(' ', $join);
} else {
$join = '';
}
return $join;
}
private function buildWhereClause($conn_r) {
$where = array();
+ if ($this->commitPHIDs) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'c.phid IN (%Ls)',
+ $this->commitPHIDs);
+ }
+
if ($this->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
'c.authorPHID IN (%Ls)',
$this->authorPHIDs);
}
if ($this->packagePHIDs) {
$where[] = qsprintf(
$conn_r,
'req.auditorPHID in (%Ls)',
$this->packagePHIDs);
}
$status = $this->status;
switch ($status) {
case self::STATUS_OPEN:
$where[] = qsprintf(
$conn_r,
'c.auditStatus = %s',
PhabricatorAuditCommitStatusConstants::CONCERN_RAISED);
break;
case self::STATUS_ANY:
break;
default:
throw new Exception("Unknown status '{$status}'!");
}
if ($where) {
$where = 'WHERE ('.implode(') AND (', $where).')';
} else {
$where = '';
}
return $where;
}
private function buildLimitClause($conn_r) {
if ($this->limit && $this->offset) {
return qsprintf($conn_r, 'LIMIT %d, %d', $this->offset, $this->limit);
} else if ($this->limit) {
return qsprintf($conn_r, 'LIMIT %d', $this->limit);
} else if ($this->offset) {
return qsprintf($conn_r, 'LIMIT %d, %d', $this->offset, PHP_INT_MAX);
} else {
return '';
}
}
}
diff --git a/src/applications/audit/view/list/PhabricatorAuditListView.php b/src/applications/audit/view/list/PhabricatorAuditListView.php
index 7c77718c0d..75bb642316 100644
--- a/src/applications/audit/view/list/PhabricatorAuditListView.php
+++ b/src/applications/audit/view/list/PhabricatorAuditListView.php
@@ -1,132 +1,164 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorAuditListView extends AphrontView {
private $audits;
private $handles;
private $authorityPHIDs = array();
private $noDataString;
+ private $commits;
public function setAudits(array $audits) {
$this->audits = $audits;
return $this;
}
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function setAuthorityPHIDs(array $phids) {
$this->authorityPHIDs = $phids;
return $this;
}
public function setNoDataString($no_data_string) {
$this->noDataString = $no_data_string;
return $this;
}
public function getNoDataString() {
return $this->noDataString;
}
+ public function setCommits(array $commits) {
+ $this->commits = mpull($commits, null, 'getPHID');
+ return $this;
+ }
+
public function getRequiredHandlePHIDs() {
$phids = array();
foreach ($this->audits as $audit) {
$phids[$audit->getCommitPHID()] = true;
$phids[$audit->getAuditorPHID()] = true;
}
return array_keys($phids);
}
private function getHandle($phid) {
$handle = idx($this->handles, $phid);
if (!$handle) {
throw new Exception("No handle for '{$phid}'!");
}
return $handle;
}
+ private function getCommitDescription($phid) {
+ if ($this->commits === null) {
+ return null;
+ }
+
+ $commit = idx($this->commits, $phid);
+ if (!$commit) {
+ return null;
+ }
+
+ return $commit->getCommitData()->getSummary();
+ }
+
public function render() {
$authority = array_fill_keys($this->authorityPHIDs, true);
$rowc = array();
$last = null;
$rows = array();
foreach ($this->audits as $audit) {
$commit_phid = $audit->getCommitPHID();
if ($last == $commit_phid) {
$commit_name = null;
+ $commit_desc = null;
} else {
$commit_name = $this->getHandle($commit_phid)->renderLink();
+ $commit_desc = $this->getCommitDescription($commit_phid);
$last = $commit_phid;
}
$reasons = $audit->getAuditReasons();
foreach ($reasons as $key => $reason) {
$reasons[$key] = phutil_escape_html($reason);
}
$reasons = implode('<br />', $reasons);
$status_code = $audit->getAuditStatus();
$status = PhabricatorAuditStatusConstants::getStatusName($status_code);
$auditor_handle = $this->getHandle($audit->getAuditorPHID());
$rows[] = array(
$commit_name,
+ phutil_escape_html($commit_desc),
$auditor_handle->renderLink(),
phutil_escape_html($status),
$reasons,
);
if (empty($authority[$audit->getAuditorPHID()])) {
$rowc[] = null;
} else {
$rowc[] = 'highlighted';
}
}
$table = new AphrontTableView($rows);
$table->setHeaders(
array(
'Commit',
+ 'Description',
'Auditor',
'Status',
'Details',
));
$table->setColumnClasses(
array(
'pri',
+ (($this->commits === null) ? '' : 'wide'),
'',
'',
- 'wide',
+ (($this->commits === null) ? 'wide' : ''),
));
$table->setRowClasses($rowc);
+ $table->setColumnVisibility(
+ array(
+ true,
+ ($this->commits !== null),
+ true,
+ true,
+ true,
+ ));
if ($this->noDataString) {
$table->setNoDataString($this->noDataString);
}
return $table->render();
}
}
diff --git a/src/applications/directory/controller/main/PhabricatorDirectoryMainController.php b/src/applications/directory/controller/main/PhabricatorDirectoryMainController.php
index f4fed2b268..0fff29b9e6 100644
--- a/src/applications/directory/controller/main/PhabricatorDirectoryMainController.php
+++ b/src/applications/directory/controller/main/PhabricatorDirectoryMainController.php
@@ -1,656 +1,659 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class PhabricatorDirectoryMainController
extends PhabricatorDirectoryController {
private $filter;
private $subfilter;
public function willProcessRequest(array $data) {
$this->filter = idx($data, 'filter');
$this->subfilter = idx($data, 'subfilter');
}
public function shouldRequireAdmin() {
// These controllers are admin-only by default, but this one is public,
// so allow non-admin users to view it.
return false;
}
public function processRequest() {
$user = $this->getRequest()->getUser();
$nav = $this->buildNav();
$this->filter = $nav->selectFilter($this->filter, 'home');
switch ($this->filter) {
case 'jump':
break;
case 'home':
case 'feed':
$project_query = new PhabricatorProjectQuery();
$project_query->setMembers(array($user->getPHID()));
$projects = $project_query->execute();
break;
default:
throw new Exception("Unknown filter '{$this->filter}'!");
}
switch ($this->filter) {
case 'feed':
return $this->buildFeedResponse($nav, $projects);
case 'jump':
return $this->buildJumpResponse($nav);
default:
return $this->buildMainResponse($nav, $projects);
}
}
private function buildMainResponse($nav, $projects) {
if (PhabricatorEnv::getEnvConfig('maniphest.enabled')) {
$unbreak_panel = $this->buildUnbreakNowPanel();
$triage_panel = $this->buildNeedsTriagePanel($projects);
$tasks_panel = $this->buildTasksPanel();
} else {
$unbreak_panel = null;
$triage_panel = null;
$tasks_panel = null;
}
$jump_panel = $this->buildJumpPanel();
$revision_panel = $this->buildRevisionPanel();
$app_panel = $this->buildAppPanel();
$audit_panel = $this->buildAuditPanel();
$commit_panel = $this->buildCommitPanel();
$content = array(
$app_panel,
$jump_panel,
$unbreak_panel,
$triage_panel,
$revision_panel,
$tasks_panel,
$audit_panel,
$commit_panel,
);
$nav->appendChild($content);
return $this->buildStandardPageResponse(
$nav,
array(
'title' => 'Phabricator',
));
}
private function buildJumpResponse($nav) {
$request = $this->getRequest();
if ($request->isFormPost()) {
$jump = $request->getStr('jump');
$response = PhabricatorJumpNavHandler::jumpPostResponse($jump);
if ($response) {
return $response;
} else {
$query = new PhabricatorSearchQuery();
$query->setQuery($jump);
$query->save();
return id(new AphrontRedirectResponse())
->setURI('/search/'.$query->getQueryKey().'/');
}
}
$nav->appendChild($this->buildJumpPanel());
return $this->buildStandardPageResponse(
$nav,
array(
'title' => 'Jump Nav',
));
}
private function buildFeedResponse($nav, $projects) {
$subnav = new AphrontSideNavFilterView();
$subnav->setBaseURI(new PhutilURI('/feed/'));
$subnav->addFilter('all', 'All Activity', '/feed/');
$subnav->addFilter('projects', 'My Projects');
$filter = $subnav->selectFilter($this->subfilter, 'all');
switch ($filter) {
case 'all':
$phids = array();
break;
case 'projects':
$phids = mpull($projects, 'getPHID');
break;
}
$view = $this->buildFeedView($phids);
$subnav->appendChild($view);
$nav->appendChild($subnav);
return $this->buildStandardPageResponse(
$nav,
array(
'title' => 'Feed',
));
}
private function buildUnbreakNowPanel() {
$user = $this->getRequest()->getUser();
$user_phid = $user->getPHID();
$task_query = new ManiphestTaskQuery();
$task_query->withStatus(ManiphestTaskQuery::STATUS_OPEN);
$task_query->withPriority(ManiphestTaskPriority::PRIORITY_UNBREAK_NOW);
$task_query->setLimit(10);
$tasks = $task_query->execute();
if (!$tasks) {
return $this->renderMiniPanel(
'No "Unbreak Now!" Tasks',
'Nothing appears to be critically broken right now.');
}
$panel = new AphrontPanelView();
$panel->setHeader('Unbreak Now!');
$panel->setCaption('Open tasks with "Unbreak Now!" priority.');
$panel->addButton(
phutil_render_tag(
'a',
array(
'href' => '/maniphest/view/all/',
'class' => 'grey button',
),
"View All Unbreak Now \xC2\xBB"));
$panel->appendChild($this->buildTaskListView($tasks));
return $panel;
}
private function buildNeedsTriagePanel(array $projects) {
$user = $this->getRequest()->getUser();
$user_phid = $user->getPHID();
if ($projects) {
$task_query = new ManiphestTaskQuery();
$task_query->withStatus(ManiphestTaskQuery::STATUS_OPEN);
$task_query->withPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
$task_query->withProjects(mpull($projects, 'getPHID'));
$task_query->withAnyProject(true);
$task_query->setLimit(10);
$tasks = $task_query->execute();
} else {
$tasks = array();
}
if (!$tasks) {
return $this->renderMiniPanel(
'No "Needs Triage" Tasks',
'No tasks in <a href="/project/">projects you are a member of</a> '.
'need triage.</p>');
}
$panel = new AphrontPanelView();
$panel->setHeader('Needs Triage');
$panel->setCaption(
'Open tasks with "Needs Triage" priority in '.
'<a href="/project/">projects you are a member of</a>.');
$panel->addButton(
phutil_render_tag(
'a',
array(
// TODO: This should filter to just your projects' need-triage
// tasks?
'href' => '/maniphest/view/alltriage/',
'class' => 'grey button',
),
"View All Triage \xC2\xBB"));
$panel->appendChild($this->buildTaskListView($tasks));
return $panel;
}
private function buildRevisionPanel() {
$user = $this->getRequest()->getUser();
$user_phid = $user->getPHID();
$revision_query = new DifferentialRevisionQuery();
$revision_query->withStatus(DifferentialRevisionQuery::STATUS_OPEN);
$revision_query->withResponsibleUsers(array($user_phid));
$revision_query->needRelationships(true);
// NOTE: We need to unlimit this query to hit the responsible user
// fast-path.
$revision_query->setLimit(null);
$revisions = $revision_query->execute();
list($active, $waiting) = DifferentialRevisionQuery::splitResponsible(
$revisions,
$user_phid);
if (!$active) {
return $this->renderMiniPanel(
'No Waiting Revisions',
'No revisions are waiting on you.');
}
$panel = new AphrontPanelView();
$panel->setHeader('Revisions Waiting on You');
$panel->setCaption('Revisions waiting for you for review or commit.');
$panel->addButton(
phutil_render_tag(
'a',
array(
'href' => '/differential/',
'class' => 'button grey',
),
"View Active Revisions \xC2\xBB"));
$fields =
$revision_view = id(new DifferentialRevisionListView())
->setRevisions($active)
->setFields(DifferentialRevisionListView::getDefaultFields())
->setUser($user);
$phids = array_merge(
array($user_phid),
$revision_view->getRequiredHandlePHIDs());
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$revision_view->setHandles($handles);
$panel->appendChild($revision_view);
return $panel;
}
private function buildTasksPanel() {
$user = $this->getRequest()->getUser();
$user_phid = $user->getPHID();
$task_query = new ManiphestTaskQuery();
$task_query->withStatus(ManiphestTaskQuery::STATUS_OPEN);
$task_query->setGroupBy(ManiphestTaskQuery::GROUP_PRIORITY);
$task_query->withOwners(array($user_phid));
$task_query->setLimit(10);
$tasks = $task_query->execute();
if (!$tasks) {
return $this->renderMiniPanel(
'No Assigned Tasks',
'You have no assigned tasks.');
}
$panel = new AphrontPanelView();
$panel->setHeader('Assigned Tasks');
$panel->setCaption('Tasks assigned to you.');
$panel->addButton(
phutil_render_tag(
'a',
array(
'href' => '/maniphest/',
'class' => 'button grey',
),
"View Active Tasks \xC2\xBB"));
$panel->appendChild($this->buildTaskListView($tasks));
return $panel;
}
private function buildTaskListView(array $tasks) {
$user = $this->getRequest()->getUser();
$phids = array_filter(mpull($tasks, 'getOwnerPHID'));
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$view = new ManiphestTaskListView();
$view->setTasks($tasks);
$view->setUser($user);
$view->setHandles($handles);
return $view;
}
private function buildFeedView(array $phids) {
$request = $this->getRequest();
$user = $request->getUser();
$user_phid = $user->getPHID();
$feed_query = new PhabricatorFeedQuery();
if ($phids) {
$feed_query->setFilterPHIDs($phids);
}
// TODO: All this limit stuff should probably be consolidated into the
// feed query?
$old_link = null;
$new_link = null;
$feed_query->setAfter($request->getStr('after'));
$feed_query->setBefore($request->getStr('before'));
$limit = 500;
// Grab one more story than we intend to display so we can figure out
// if we need to render an "Older Posts" link or not (with reasonable
// accuracy, at least).
$feed_query->setLimit($limit + 1);
$feed = $feed_query->execute();
$extra_row = (count($feed) == $limit + 1);
$have_new = ($request->getStr('before')) ||
($request->getStr('after') && $extra_row);
$have_old = ($request->getStr('after')) ||
($request->getStr('before') && $extra_row) ||
(!$request->getStr('before') &&
!$request->getStr('after') &&
$extra_row);
$feed = array_slice($feed, 0, $limit, $preserve_keys = true);
if ($have_old) {
$old_link = phutil_render_tag(
'a',
array(
'href' => '?before='.end($feed)->getChronologicalKey(),
'class' => 'phabricator-feed-older-link',
),
"Older Stories \xC2\xBB");
}
if ($have_new) {
$new_link = phutil_render_tag(
'a',
array(
'href' => '?after='.reset($feed)->getChronologicalKey(),
'class' => 'phabricator-feed-newer-link',
),
"\xC2\xAB Newer Stories");
}
$builder = new PhabricatorFeedBuilder($feed);
$builder->setUser($user);
$feed_view = $builder->buildView();
return
'<div style="padding: 1em 3em;">'.
'<div style="margin: 0 1em;">'.
'<h1 style="font-size: 18px; '.
'border-bottom: 1px solid #aaaaaa; '.
'padding: 0;">Feed</h1>'.
'</div>'.
$feed_view->render().
'<div class="phabricator-feed-frame">'.
$new_link.
$old_link.
'</div>'.
'</div>';
}
private function buildJumpPanel() {
$request = $this->getRequest();
$user = $request->getUser();
$uniq_id = celerity_generate_unique_node_id();
Javelin::initBehavior(
'phabricator-autofocus',
array(
'id' => $uniq_id,
));
require_celerity_resource('phabricator-jump-nav');
$doc_href = PhabricatorEnv::getDocLink('article/Jump_Nav_User_Guide.html');
$doc_link = phutil_render_tag(
'a',
array(
'href' => $doc_href,
),
'Jump Nav User Guide');
$jump_input = phutil_render_tag(
'input',
array(
'type' => 'text',
'class' => 'phabricator-jump-nav',
'name' => 'jump',
'id' => $uniq_id,
));
$jump_caption = phutil_render_tag(
'p',
array(
'class' => 'phabricator-jump-nav-caption',
),
'Enter the name of an object like <tt>D123</tt> to quickly jump to '.
'it. See '.$doc_link.' or type <tt>help</tt>.');
$panel = new AphrontPanelView();
$panel->addClass('aphront-unpadded-panel-view');
$panel->appendChild(
phabricator_render_form(
$user,
array(
'action' => '/jump/',
'method' => 'POST',
'class' => 'phabricator-jump-nav-form',
),
$jump_input.
$jump_caption));
return $panel;
}
private function buildAppPanel() {
require_celerity_resource('phabricator-app-buttons-css');
$nav_buttons = array();
$nav_buttons[] = array(
'Differential',
'/differential/',
'differential');
if (PhabricatorEnv::getEnvConfig('maniphest.enabled')) {
$nav_buttons[] = array(
'Maniphest',
'/maniphest/',
'maniphest');
$nav_buttons[] = array(
'Create Task',
'/maniphest/task/create/',
'create-task');
}
$nav_buttons[] = array(
'Upload File',
'/file/',
'upload-file');
$nav_buttons[] = array(
'Create Paste',
'/paste/',
'create-paste');
if (PhabricatorEnv::getEnvConfig('phriction.enabled')) {
$nav_buttons[] = array(
'Browse Wiki',
'/w/',
'phriction');
}
$nav_buttons[] = array(
'Browse Code',
'/diffusion/',
'diffusion');
$nav_buttons[] = array(
'Audit Code',
'/audit/',
'audit');
$view = new AphrontNullView();
$view->appendChild('<div class="phabricator-app-buttons">');
foreach ($nav_buttons as $info) {
list($name, $uri, $icon) = $info;
$button = phutil_render_tag(
'a',
array(
'href' => $uri,
'class' => 'app-button icon-'.$icon,
),
phutil_render_tag(
'div',
array(
'class' => 'app-icon icon-'.$icon,
),
''));
$caption = phutil_render_tag(
'a',
array(
'href' => $uri,
'class' => 'phabricator-button-caption',
),
phutil_escape_html($name));
$view->appendChild(
'<div class="phabricator-app-button">'.
$button.
$caption.
'</div>');
}
$view->appendChild('<div style="clear: both;"></div></div>');
return $view;
}
private function renderMiniPanel($title, $body) {
$panel = new AphrontMiniPanelView();
$panel->appendChild(
phutil_render_tag(
'p',
array(
),
'<strong>'.$title.':</strong> '.$body));
return $panel;
}
public function buildAuditPanel() {
$request = $this->getRequest();
$user = $request->getUser();
$phids = PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($user);
$query = new PhabricatorAuditQuery();
$query->withAuditorPHIDs($phids);
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
+ $query->needCommitData(true);
$query->setLimit(10);
$audits = $query->execute();
+ $commits = $query->getCommits();
if (!$audits) {
return $this->renderMinipanel(
'No Audits',
'No commits are waiting for you to audit them.');
}
$view = new PhabricatorAuditListView();
$view->setAudits($audits);
+ $view->setCommits($commits);
$phids = $view->getRequiredHandlePHIDs();
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$view->setHandles($handles);
$panel = new AphrontPanelView();
$panel->setHeader('Audits');
$panel->setCaption('Commits awaiting your audit.');
$panel->appendChild($view);
$panel->addButton(
phutil_render_tag(
'a',
array(
'href' => '/audit/',
'class' => 'button grey',
),
"View Active Audits \xC2\xBB"));
return $panel;
}
public function buildCommitPanel() {
$request = $this->getRequest();
$user = $request->getUser();
$phids = array($user->getPHID());
$query = new PhabricatorAuditCommitQuery();
$query->withAuthorPHIDs($phids);
$query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
$query->needCommitData(true);
$query->setLimit(10);
$commits = $query->execute();
if (!$commits) {
return $this->renderMinipanel(
'No Problem Commits',
'No one has raised concerns with your commits.');
}
$view = new PhabricatorAuditCommitListView();
$view->setCommits($commits);
$view->setUser($user);
$phids = $view->getRequiredHandlePHIDs();
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$view->setHandles($handles);
$panel = new AphrontPanelView();
$panel->setHeader('Problem Commits');
$panel->setCaption('Commits which auditors have raised concerns about.');
$panel->appendChild($view);
$panel->addButton(
phutil_render_tag(
'a',
array(
'href' => '/audit/',
'class' => 'button grey',
),
"View Problem Commits \xC2\xBB"));
return $panel;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jul 1, 5:59 PM (21 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
164505
Default Alt Text
(47 KB)

Event Timeline