1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-18 21:02:41 +01:00

Make owners typeahead mostly reasonable

Summary: Ref T8320. Fixes T8427. This is still a little funky because Owners has weird name rules, but should fix the bugs (unselectable packages) in T8427.

Test Plan: Browsed Owners typaheads, used various search functions.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T8320, T8427

Differential Revision: https://secure.phabricator.com/D13349
This commit is contained in:
epriestley 2015-06-18 17:16:37 -07:00
parent b12f13efd8
commit 1851ca2d71
3 changed files with 110 additions and 92 deletions

View file

@ -7,6 +7,7 @@ final class PhabricatorOwnersPackageQuery
private $phids; private $phids;
private $ownerPHIDs; private $ownerPHIDs;
private $repositoryPHIDs; private $repositoryPHIDs;
private $namePrefix;
/** /**
* Owners are direct owners, and members of owning projects. * Owners are direct owners, and members of owning projects.
@ -31,62 +32,59 @@ final class PhabricatorOwnersPackageQuery
return $this; return $this;
} }
protected function loadPage() { public function withNamePrefix($prefix) {
$table = new PhabricatorOwnersPackage(); $this->namePrefix = $prefix;
$conn_r = $table->establishConnection('r'); return $this;
$data = queryfx_all(
$conn_r,
'SELECT p.* FROM %T p %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
} }
protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { public function newResultObject() {
$joins = array(); return new PhabricatorOwnersPackage();
}
protected function loadPage() {
return $this->loadStandardPage(new PhabricatorOwnersPackage());
}
protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {
$joins = parent::buildJoinClauseParts($conn);
if ($this->ownerPHIDs !== null) { if ($this->ownerPHIDs !== null) {
$joins[] = qsprintf( $joins[] = qsprintf(
$conn_r, $conn,
'JOIN %T o ON o.packageID = p.id', 'JOIN %T o ON o.packageID = p.id',
id(new PhabricatorOwnersOwner())->getTableName()); id(new PhabricatorOwnersOwner())->getTableName());
} }
if ($this->repositoryPHIDs !== null) { if ($this->repositoryPHIDs !== null) {
$joins[] = qsprintf( $joins[] = qsprintf(
$conn_r, $conn,
'JOIN %T rpath ON rpath.packageID = p.id', 'JOIN %T rpath ON rpath.packageID = p.id',
id(new PhabricatorOwnersPath())->getTableName()); id(new PhabricatorOwnersPath())->getTableName());
} }
return implode(' ', $joins); return $joins;
} }
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = array(); $where = parent::buildWhereClauseParts($conn);
if ($this->phids !== null) { if ($this->phids !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn,
'p.phid IN (%Ls)', 'p.phid IN (%Ls)',
$this->phids); $this->phids);
} }
if ($this->ids !== null) { if ($this->ids !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn,
'p.id IN (%Ld)', 'p.id IN (%Ld)',
$this->ids); $this->ids);
} }
if ($this->repositoryPHIDs !== null) { if ($this->repositoryPHIDs !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn,
'rpath.repositoryPHID IN (%Ls)', 'rpath.repositoryPHID IN (%Ls)',
$this->repositoryPHIDs); $this->repositoryPHIDs);
} }
@ -94,26 +92,79 @@ final class PhabricatorOwnersPackageQuery
if ($this->ownerPHIDs !== null) { if ($this->ownerPHIDs !== null) {
$base_phids = $this->ownerPHIDs; $base_phids = $this->ownerPHIDs;
$query = new PhabricatorProjectQuery(); $projects = id(new PhabricatorProjectQuery())
$query->setViewer($this->getViewer()); ->setViewer($this->getViewer())
$query->withMemberPHIDs($base_phids); ->withMemberPHIDs($base_phids)
$projects = $query->execute(); ->execute();
$project_phids = mpull($projects, 'getPHID'); $project_phids = mpull($projects, 'getPHID');
$all_phids = array_merge($base_phids, $project_phids); $all_phids = array_merge($base_phids, $project_phids);
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn,
'o.userPHID IN (%Ls)', 'o.userPHID IN (%Ls)',
$all_phids); $all_phids);
} }
$where[] = $this->buildPagingClause($conn_r); if (strlen($this->namePrefix)) {
return $this->formatWhereClause($where); // NOTE: This is a hacky mess, but this column is currently case
// sensitive and unique.
$where[] = qsprintf(
$conn,
'LOWER(p.name) LIKE %>',
phutil_utf8_strtolower($this->namePrefix));
}
return $where;
}
protected function shouldGroupQueryResultRows() {
if ($this->repositoryPHIDs) {
return true;
}
if ($this->ownerPHIDs) {
return true;
}
return parent::shouldGroupQueryResultRows();
}
public function getBuiltinOrders() {
return array(
'name' => array(
'vector' => array('name'),
'name' => pht('Name'),
),
) + parent::getBuiltinOrders();
}
public function getOrderableColumns() {
return parent::getOrderableColumns() + array(
'name' => array(
'table' => $this->getPrimaryTableAlias(),
'column' => 'name',
'type' => 'string',
'unique' => true,
'reverse' => true,
),
);
}
protected function getPagingValueMap($cursor, array $keys) {
$package = $this->loadCursorObject($cursor);
return array(
'id' => $package->getID(),
'name' => $package->getName(),
);
} }
public function getQueryApplicationClass() { public function getQueryApplicationClass() {
return 'PhabricatorOwnersApplication'; return 'PhabricatorOwnersApplication';
} }
protected function getPrimaryTableAlias() {
return 'p';
}
} }

View file

@ -11,68 +11,39 @@ final class PhabricatorOwnersPackageSearchEngine
return 'PhabricatorOwnersApplication'; return 'PhabricatorOwnersApplication';
} }
public function buildSavedQueryFromRequest(AphrontRequest $request) { public function newQuery() {
$saved = new PhabricatorSavedQuery(); return new PhabricatorOwnersPackageQuery();
$saved->setParameter(
'ownerPHIDs',
$this->readUsersFromRequest(
$request,
'owners',
array(
PhabricatorProjectProjectPHIDType::TYPECONST,
)));
$saved->setParameter(
'repositoryPHIDs',
$this->readPHIDsFromRequest(
$request,
'repositories',
array(
PhabricatorRepositoryRepositoryPHIDType::TYPECONST,
)));
return $saved;
} }
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { protected function buildCustomSearchFields() {
$query = id(new PhabricatorOwnersPackageQuery()); return array(
id(new PhabricatorSearchDatasourceField())
->setLabel(pht('Owners'))
->setKey('ownerPHIDs')
->setAliases(array('owner', 'owners'))
->setDatasource(new PhabricatorProjectOrUserDatasource()),
id(new PhabricatorSearchDatasourceField())
->setLabel(pht('Repositories'))
->setKey('repositoryPHIDs')
->setAliases(array('repository', 'repositories'))
->setDatasource(new DiffusionRepositoryDatasource()),
);
}
$owner_phids = $saved->getParameter('ownerPHIDs', array()); protected function buildQueryFromParameters(array $map) {
if ($owner_phids) { $query = $this->newQuery();
$query->withOwnerPHIDs($owner_phids);
if ($map['ownerPHIDs']) {
$query->withOwnerPHIDs($map['ownerPHIDs']);
} }
$repository_phids = $saved->getParameter('repositoryPHIDs', array()); if ($map['repositoryPHIDs']) {
if ($repository_phids) { $query->withRepositoryPHIDs($map['repositoryPHIDs']);
$query->withRepositoryPHIDs($repository_phids);
} }
return $query; return $query;
} }
public function buildSearchForm(
AphrontFormView $form,
PhabricatorSavedQuery $saved) {
$owner_phids = $saved->getParameter('ownerPHIDs', array());
$repository_phids = $saved->getParameter('repositoryPHIDs', array());
$form
->appendControl(
id(new AphrontFormTokenizerControl())
->setDatasource(new PhabricatorProjectOrUserDatasource())
->setName('owners')
->setLabel(pht('Owners'))
->setValue($owner_phids))
->appendControl(
id(new AphrontFormTokenizerControl())
->setDatasource(new DiffusionRepositoryDatasource())
->setName('repositories')
->setLabel(pht('Repositories'))
->setValue($repository_phids));
}
protected function getURI($path) { protected function getURI($path) {
return '/owners/'.$path; return '/owners/'.$path;
} }

View file

@ -3,11 +3,6 @@
final class PhabricatorOwnersPackageDatasource final class PhabricatorOwnersPackageDatasource
extends PhabricatorTypeaheadDatasource { extends PhabricatorTypeaheadDatasource {
public function isBrowsable() {
// TODO: Make this browsable.
return false;
}
public function getBrowseTitle() { public function getBrowseTitle() {
return pht('Browse Packages'); return pht('Browse Packages');
} }
@ -26,10 +21,11 @@ final class PhabricatorOwnersPackageDatasource
$results = array(); $results = array();
$packages = id(new PhabricatorOwnersPackageQuery()) $query = id(new PhabricatorOwnersPackageQuery())
->setViewer($viewer) ->withNamePrefix($raw_query)
->execute(); ->setOrder('name');
$packages = $this->executeQuery($query);
foreach ($packages as $package) { foreach ($packages as $package) {
$results[] = id(new PhabricatorTypeaheadResult()) $results[] = id(new PhabricatorTypeaheadResult())
->setName($package->getName()) ->setName($package->getName())
@ -37,7 +33,7 @@ final class PhabricatorOwnersPackageDatasource
->setPHID($package->getPHID()); ->setPHID($package->getPHID());
} }
return $results; return $this->filterResultsAgainstTokens($results);
} }
} }