Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2896088
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
19 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/applications/audit/controller/list/PhabricatorAuditListController.php b/src/applications/audit/controller/list/PhabricatorAuditListController.php
index 595145f671..cef50cf335 100644
--- a/src/applications/audit/controller/list/PhabricatorAuditListController.php
+++ b/src/applications/audit/controller/list/PhabricatorAuditListController.php
@@ -1,474 +1,474 @@
<?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('phid'));
+ $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('phid')
+ ->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') {
$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;
}
$audits = $query->execute();
$audits = $pager->sliceResults($audits);
$view = new PhabricatorAuditListView();
$view->setAudits($audits);
$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);
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') {
$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);
$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);
return $panel;
}
}
diff --git a/src/applications/audit/query/commit/PhabricatorAuditCommitQuery.php b/src/applications/audit/query/commit/PhabricatorAuditCommitQuery.php
index 36b68b62e5..3bdcea6937 100644
--- a/src/applications/audit/query/commit/PhabricatorAuditCommitQuery.php
+++ b/src/applications/audit/query/commit/PhabricatorAuditCommitQuery.php
@@ -1,179 +1,177 @@
<?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 $authorPHIDs;
private $packagePHIDs;
- private $packageConstraint;
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 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() {
- if ($this->packagePHIDs) {
-
- // TODO: This is an odd, awkward query plan because these rows aren't
- // on the same database as the commits. Once they're migrated we can
- // resolve this via JOIN.
-
- // TODO: Clean this up now that we've moved the table.
-
- $table = new PhabricatorRepositoryAuditRequest();
- $conn_r = $table->establishConnection('r');
- $phids = queryfx_all(
- $conn_r,
- 'SELECT DISTINCT commitPHID FROM %T WHERE auditorPHID IN (%Ls)
- ORDER BY id DESC %Q',
- $table->getTableName(),
- $this->packagePHIDs,
- $this->buildLimitClause($conn_r));
- $this->packageConstraint = ipull($phids, 'commitPHID');
- $this->limit = null;
- $this->offset = null;
- }
-
$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 * FROM %T %Q %Q %Q',
+ '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 epoch DESC';
+ 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->authorPHIDs) {
$where[] = qsprintf(
$conn_r,
- 'authorPHID IN (%Ls)',
+ 'c.authorPHID IN (%Ls)',
$this->authorPHIDs);
}
- if ($this->packageConstraint !== null) {
+ if ($this->packagePHIDs) {
$where[] = qsprintf(
$conn_r,
- 'phid IN (%Ls)',
- $this->packageConstraint);
+ 'req.auditorPHID in (%Ls)',
+ $this->packagePHIDs);
}
$status = $this->status;
switch ($status) {
case self::STATUS_OPEN:
$where[] = qsprintf(
$conn_r,
- 'auditStatus = %s',
+ '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 '';
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Jan 19 2025, 22:30 (6 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1129432
Default Alt Text
(19 KB)
Attached To
Mode
rP Phorge
Attached
Detach File
Event Timeline
Log In to Comment