mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-19 05:12:41 +01:00
Use ApplicationSearch in Owners
Summary: Ref T8320. Modernize search and major interfaces. This slightly regresses some list view and search features; I'll probably restore some later (once the Query has proper `needX(...)` methods) and drop the rest. Test Plan: Browsed, edited, deleted, and created packages. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T8320 Differential Revision: https://secure.phabricator.com/D13024
This commit is contained in:
parent
e9f4a84a89
commit
6d5d34e6a8
9 changed files with 247 additions and 455 deletions
|
@ -2178,6 +2178,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorOwnersPackagePHIDType' => 'applications/owners/phid/PhabricatorOwnersPackagePHIDType.php',
|
'PhabricatorOwnersPackagePHIDType' => 'applications/owners/phid/PhabricatorOwnersPackagePHIDType.php',
|
||||||
'PhabricatorOwnersPackagePathValidator' => 'applications/repository/worker/commitchangeparser/PhabricatorOwnersPackagePathValidator.php',
|
'PhabricatorOwnersPackagePathValidator' => 'applications/repository/worker/commitchangeparser/PhabricatorOwnersPackagePathValidator.php',
|
||||||
'PhabricatorOwnersPackageQuery' => 'applications/owners/query/PhabricatorOwnersPackageQuery.php',
|
'PhabricatorOwnersPackageQuery' => 'applications/owners/query/PhabricatorOwnersPackageQuery.php',
|
||||||
|
'PhabricatorOwnersPackageSearchEngine' => 'applications/owners/query/PhabricatorOwnersPackageSearchEngine.php',
|
||||||
'PhabricatorOwnersPackageTestCase' => 'applications/owners/storage/__tests__/PhabricatorOwnersPackageTestCase.php',
|
'PhabricatorOwnersPackageTestCase' => 'applications/owners/storage/__tests__/PhabricatorOwnersPackageTestCase.php',
|
||||||
'PhabricatorOwnersPath' => 'applications/owners/storage/PhabricatorOwnersPath.php',
|
'PhabricatorOwnersPath' => 'applications/owners/storage/PhabricatorOwnersPath.php',
|
||||||
'PhabricatorPHDConfigOptions' => 'applications/config/option/PhabricatorPHDConfigOptions.php',
|
'PhabricatorPHDConfigOptions' => 'applications/config/option/PhabricatorPHDConfigOptions.php',
|
||||||
|
@ -5584,6 +5585,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorOwnersPackageEditor' => 'PhabricatorEditor',
|
'PhabricatorOwnersPackageEditor' => 'PhabricatorEditor',
|
||||||
'PhabricatorOwnersPackagePHIDType' => 'PhabricatorPHIDType',
|
'PhabricatorOwnersPackagePHIDType' => 'PhabricatorPHIDType',
|
||||||
'PhabricatorOwnersPackageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorOwnersPackageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorOwnersPackageSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||||
'PhabricatorOwnersPackageTestCase' => 'PhabricatorTestCase',
|
'PhabricatorOwnersPackageTestCase' => 'PhabricatorTestCase',
|
||||||
'PhabricatorOwnersPath' => 'PhabricatorOwnersDAO',
|
'PhabricatorOwnersPath' => 'PhabricatorOwnersDAO',
|
||||||
'PhabricatorPHDConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorPHDConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
|
|
|
@ -42,8 +42,7 @@ final class PhabricatorOwnersApplication extends PhabricatorApplication {
|
||||||
public function getRoutes() {
|
public function getRoutes() {
|
||||||
return array(
|
return array(
|
||||||
'/owners/' => array(
|
'/owners/' => array(
|
||||||
'' => 'PhabricatorOwnersListController',
|
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorOwnersListController',
|
||||||
'view/(?P<view>[^/]+)/' => 'PhabricatorOwnersListController',
|
|
||||||
'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorOwnersEditController',
|
'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorOwnersEditController',
|
||||||
'new/' => 'PhabricatorOwnersEditController',
|
'new/' => 'PhabricatorOwnersEditController',
|
||||||
'package/(?P<id>[1-9]\d*)/' => 'PhabricatorOwnersDetailController',
|
'package/(?P<id>[1-9]\d*)/' => 'PhabricatorOwnersDetailController',
|
||||||
|
|
|
@ -1,70 +1,3 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
abstract class PhabricatorOwnersController extends PhabricatorController {
|
abstract class PhabricatorOwnersController extends PhabricatorController {}
|
||||||
|
|
||||||
private $filter;
|
|
||||||
|
|
||||||
private function getSideNavFilter() {
|
|
||||||
return $this->filter;
|
|
||||||
}
|
|
||||||
protected function setSideNavFilter($filter) {
|
|
||||||
$this->filter = $filter;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function buildSideNavView() {
|
|
||||||
$nav = new AphrontSideNavFilterView();
|
|
||||||
$base_uri = new PhutilURI('/owners/');
|
|
||||||
$nav->setBaseURI($base_uri);
|
|
||||||
|
|
||||||
$nav->addLabel(pht('Packages'));
|
|
||||||
$this->getExtraPackageViews($nav);
|
|
||||||
$nav->addFilter('view/owned', pht('Owned'));
|
|
||||||
$nav->addFilter('view/projects', pht('Projects'));
|
|
||||||
$nav->addFilter('view/all', pht('All'));
|
|
||||||
|
|
||||||
$nav->selectFilter($this->getSideNavFilter(), 'view/owned');
|
|
||||||
|
|
||||||
$filter = $nav->getSelectedFilter();
|
|
||||||
switch ($filter) {
|
|
||||||
case 'view/owned':
|
|
||||||
$title = pht('Owned Packages');
|
|
||||||
break;
|
|
||||||
case 'view/all':
|
|
||||||
$title = pht('All Packages');
|
|
||||||
break;
|
|
||||||
case 'view/projects':
|
|
||||||
$title = pht('Projects');
|
|
||||||
break;
|
|
||||||
case 'new':
|
|
||||||
$title = pht('New Package');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$title = pht('Package');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $nav;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function buildApplicationCrumbs() {
|
|
||||||
$crumbs = parent::buildApplicationCrumbs();
|
|
||||||
|
|
||||||
$crumbs->addAction(
|
|
||||||
id(new PHUIListItemView())
|
|
||||||
->setName(pht('Create Package'))
|
|
||||||
->setHref('/owners/new/')
|
|
||||||
->setIcon('fa-plus-square'));
|
|
||||||
|
|
||||||
return $crumbs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function buildApplicationMenu() {
|
|
||||||
return $this->buildSideNavView()->getMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getExtraPackageViews(AphrontSideNavFilterView $view) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,22 +3,20 @@
|
||||||
final class PhabricatorOwnersDetailController
|
final class PhabricatorOwnersDetailController
|
||||||
extends PhabricatorOwnersController {
|
extends PhabricatorOwnersController {
|
||||||
|
|
||||||
private $id;
|
public function shouldAllowPublic() {
|
||||||
private $package;
|
return true;
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
|
||||||
$this->id = $data['id'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function processRequest() {
|
public function handleRequest(AphrontRequest $request) {
|
||||||
$request = $this->getRequest();
|
$viewer = $this->getViewer();
|
||||||
$user = $request->getUser();
|
|
||||||
|
|
||||||
$package = id(new PhabricatorOwnersPackage())->load($this->id);
|
$package = id(new PhabricatorOwnersPackageQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIDs(array($request->getURIData('id')))
|
||||||
|
->executeOne();
|
||||||
if (!$package) {
|
if (!$package) {
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
$this->package = $package;
|
|
||||||
|
|
||||||
$paths = $package->loadPaths();
|
$paths = $package->loadPaths();
|
||||||
$owners = $package->loadOwners();
|
$owners = $package->loadOwners();
|
||||||
|
@ -30,7 +28,7 @@ final class PhabricatorOwnersDetailController
|
||||||
|
|
||||||
if ($repository_phids) {
|
if ($repository_phids) {
|
||||||
$repositories = id(new PhabricatorRepositoryQuery())
|
$repositories = id(new PhabricatorRepositoryQuery())
|
||||||
->setViewer($user)
|
->setViewer($viewer)
|
||||||
->withPHIDs(array_keys($repository_phids))
|
->withPHIDs(array_keys($repository_phids))
|
||||||
->execute();
|
->execute();
|
||||||
$repositories = mpull($repositories, null, 'getPHID');
|
$repositories = mpull($repositories, null, 'getPHID');
|
||||||
|
@ -131,9 +129,6 @@ final class PhabricatorOwnersDetailController
|
||||||
$panel->setHeader($header);
|
$panel->setHeader($header);
|
||||||
$panel->appendChild($table);
|
$panel->appendChild($table);
|
||||||
|
|
||||||
$key = 'package/'.$package->getID();
|
|
||||||
$this->setSideNavFilter($key);
|
|
||||||
|
|
||||||
$commit_views = array();
|
$commit_views = array();
|
||||||
|
|
||||||
$commit_uri = id(new PhutilURI('/audit/'))
|
$commit_uri = id(new PhutilURI('/audit/'))
|
||||||
|
@ -151,7 +146,7 @@ final class PhabricatorOwnersDetailController
|
||||||
->execute();
|
->execute();
|
||||||
if ($attention_commits) {
|
if ($attention_commits) {
|
||||||
$view = id(new PhabricatorAuditListView())
|
$view = id(new PhabricatorAuditListView())
|
||||||
->setUser($user)
|
->setUser($viewer)
|
||||||
->setCommits($attention_commits);
|
->setCommits($attention_commits);
|
||||||
|
|
||||||
$commit_views[] = array(
|
$commit_views[] = array(
|
||||||
|
@ -172,7 +167,7 @@ final class PhabricatorOwnersDetailController
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
$view = id(new PhabricatorAuditListView())
|
$view = id(new PhabricatorAuditListView())
|
||||||
->setUser($user)
|
->setUser($viewer)
|
||||||
->setCommits($all_commits)
|
->setCommits($all_commits)
|
||||||
->setNoDataString(pht('No commits in this package.'));
|
->setNoDataString(pht('No commits in this package.'));
|
||||||
|
|
||||||
|
@ -210,21 +205,15 @@ final class PhabricatorOwnersDetailController
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
$crumbs->addTextCrumb($package->getName());
|
$crumbs->addTextCrumb($package->getName());
|
||||||
|
|
||||||
$nav = $this->buildSideNavView();
|
|
||||||
$nav->appendChild($crumbs);
|
|
||||||
$nav->appendChild($panel);
|
|
||||||
$nav->appendChild($commit_panels);
|
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
return $this->buildApplicationPage(
|
||||||
$nav,
|
array(
|
||||||
|
$crumbs,
|
||||||
|
$panel,
|
||||||
|
$commit_panels,
|
||||||
|
),
|
||||||
array(
|
array(
|
||||||
'title' => pht('Package %s', $package->getName()),
|
'title' => pht('Package %s', $package->getName()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getExtraPackageViews(AphrontSideNavFilterView $view) {
|
|
||||||
$package = $this->package;
|
|
||||||
$view->addFilter('package/'.$package->getID(), pht('Details'));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,24 +3,27 @@
|
||||||
final class PhabricatorOwnersEditController
|
final class PhabricatorOwnersEditController
|
||||||
extends PhabricatorOwnersController {
|
extends PhabricatorOwnersController {
|
||||||
|
|
||||||
private $id;
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
$viewer = $request->getUser();
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
$id = $request->getURIData('id');
|
||||||
$this->id = idx($data, 'id');
|
if ($id) {
|
||||||
}
|
$package = id(new PhabricatorOwnersPackageQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
public function processRequest() {
|
->withIDs(array($id))
|
||||||
$request = $this->getRequest();
|
->requireCapabilities(
|
||||||
$user = $request->getUser();
|
array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
if ($this->id) {
|
// TODO: Support this capability.
|
||||||
$package = id(new PhabricatorOwnersPackage())->load($this->id);
|
// PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
))
|
||||||
|
->executeOne();
|
||||||
if (!$package) {
|
if (!$package) {
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$package = new PhabricatorOwnersPackage();
|
$package = new PhabricatorOwnersPackage();
|
||||||
$package->setPrimaryOwnerPHID($user->getPHID());
|
$package->setPrimaryOwnerPHID($viewer->getPHID());
|
||||||
}
|
}
|
||||||
|
|
||||||
$e_name = true;
|
$e_name = true;
|
||||||
|
@ -89,7 +92,7 @@ final class PhabricatorOwnersEditController
|
||||||
$package->attachOldPrimaryOwnerPHID($old_primary);
|
$package->attachOldPrimaryOwnerPHID($old_primary);
|
||||||
try {
|
try {
|
||||||
id(new PhabricatorOwnersPackageEditor())
|
id(new PhabricatorOwnersPackageEditor())
|
||||||
->setActor($user)
|
->setActor($viewer)
|
||||||
->setPackage($package)
|
->setPackage($package)
|
||||||
->save();
|
->save();
|
||||||
return id(new AphrontRedirectResponse())
|
return id(new AphrontRedirectResponse())
|
||||||
|
@ -123,15 +126,12 @@ final class PhabricatorOwnersEditController
|
||||||
|
|
||||||
if ($package->getID()) {
|
if ($package->getID()) {
|
||||||
$title = pht('Edit Package');
|
$title = pht('Edit Package');
|
||||||
$side_nav_filter = 'edit/'.$this->id;
|
|
||||||
} else {
|
} else {
|
||||||
$title = pht('New Package');
|
$title = pht('New Package');
|
||||||
$side_nav_filter = 'new';
|
|
||||||
}
|
}
|
||||||
$this->setSideNavFilter($side_nav_filter);
|
|
||||||
|
|
||||||
$repos = id(new PhabricatorRepositoryQuery())
|
$repos = id(new PhabricatorRepositoryQuery())
|
||||||
->setViewer($user)
|
->setViewer($viewer)
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
$default_paths = array();
|
$default_paths = array();
|
||||||
|
@ -171,7 +171,7 @@ final class PhabricatorOwnersEditController
|
||||||
: '/owners/';
|
: '/owners/';
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
$form = id(new AphrontFormView())
|
||||||
->setUser($user)
|
->setUser($viewer)
|
||||||
->appendChild(
|
->appendChild(
|
||||||
id(new AphrontFormTextControl())
|
id(new AphrontFormTextControl())
|
||||||
->setLabel(pht('Name'))
|
->setLabel(pht('Name'))
|
||||||
|
@ -256,24 +256,14 @@ final class PhabricatorOwnersEditController
|
||||||
$crumbs->addTextCrumb(pht('New Package'));
|
$crumbs->addTextCrumb(pht('New Package'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$nav = $this->buildSideNavView();
|
|
||||||
$nav->appendChild($crumbs);
|
|
||||||
$nav->appendChild($form_box);
|
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
return $this->buildApplicationPage(
|
||||||
array(
|
array(
|
||||||
$nav,
|
$crumbs,
|
||||||
|
$form_box,
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getExtraPackageViews(AphrontSideNavFilterView $view) {
|
|
||||||
if ($this->id) {
|
|
||||||
$view->addFilter('edit/'.$this->id, pht('Edit'));
|
|
||||||
} else {
|
|
||||||
$view->addFilter('new', pht('New'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,341 +3,52 @@
|
||||||
final class PhabricatorOwnersListController
|
final class PhabricatorOwnersListController
|
||||||
extends PhabricatorOwnersController {
|
extends PhabricatorOwnersController {
|
||||||
|
|
||||||
protected $view;
|
public function shouldAllowPublic() {
|
||||||
|
return true;
|
||||||
public function willProcessRequest(array $data) {
|
|
||||||
$this->view = idx($data, 'view', 'owned');
|
|
||||||
$this->setSideNavFilter('view/'.$this->view);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function processRequest() {
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
$controller = id(new PhabricatorApplicationSearchController())
|
||||||
|
->setQueryKey($request->getURIData('queryKey'))
|
||||||
|
->setSearchEngine(new PhabricatorOwnersPackageSearchEngine())
|
||||||
|
->setNavigation($this->buildSideNavView());
|
||||||
|
|
||||||
$request = $this->getRequest();
|
return $this->delegateToController($controller);
|
||||||
$user = $request->getUser();
|
|
||||||
|
|
||||||
$package = new PhabricatorOwnersPackage();
|
|
||||||
$owner = new PhabricatorOwnersOwner();
|
|
||||||
$path = new PhabricatorOwnersPath();
|
|
||||||
|
|
||||||
$repository_phid = '';
|
|
||||||
if ($request->getStr('repository') != '') {
|
|
||||||
$repository_phid = id(new PhabricatorRepositoryQuery())
|
|
||||||
->setViewer($user)
|
|
||||||
->withCallsigns(array($request->getStr('repository')))
|
|
||||||
->executeOne()
|
|
||||||
->getPHID();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($this->view) {
|
|
||||||
case 'search':
|
|
||||||
$packages = array();
|
|
||||||
|
|
||||||
$conn_r = $package->establishConnection('r');
|
|
||||||
|
|
||||||
$where = array('1 = 1');
|
|
||||||
$join = array();
|
|
||||||
$having = '';
|
|
||||||
|
|
||||||
if ($request->getStr('name')) {
|
|
||||||
$where[] = qsprintf(
|
|
||||||
$conn_r,
|
|
||||||
'p.name LIKE %~',
|
|
||||||
$request->getStr('name'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($repository_phid || $request->getStr('path')) {
|
|
||||||
|
|
||||||
$join[] = qsprintf(
|
|
||||||
$conn_r,
|
|
||||||
'JOIN %T path ON path.packageID = p.id',
|
|
||||||
$path->getTableName());
|
|
||||||
|
|
||||||
if ($repository_phid) {
|
|
||||||
$where[] = qsprintf(
|
|
||||||
$conn_r,
|
|
||||||
'path.repositoryPHID = %s',
|
|
||||||
$repository_phid);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->getStr('path')) {
|
|
||||||
$where[] = qsprintf(
|
|
||||||
$conn_r,
|
|
||||||
'(path.path LIKE %~ AND NOT path.excluded) OR
|
|
||||||
%s LIKE CONCAT(REPLACE(path.path, %s, %s), %s)',
|
|
||||||
$request->getStr('path'),
|
|
||||||
$request->getStr('path'),
|
|
||||||
'_',
|
|
||||||
'\_',
|
|
||||||
'%');
|
|
||||||
$having = 'HAVING MAX(path.excluded) = 0';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->getArr('owner')) {
|
|
||||||
$join[] = qsprintf(
|
|
||||||
$conn_r,
|
|
||||||
'JOIN %T o ON o.packageID = p.id',
|
|
||||||
$owner->getTableName());
|
|
||||||
$where[] = qsprintf(
|
|
||||||
$conn_r,
|
|
||||||
'o.userPHID IN (%Ls)',
|
|
||||||
$request->getArr('owner'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = queryfx_all(
|
|
||||||
$conn_r,
|
|
||||||
'SELECT p.* FROM %T p %Q WHERE %Q GROUP BY p.id %Q',
|
|
||||||
$package->getTableName(),
|
|
||||||
implode(' ', $join),
|
|
||||||
'('.implode(') AND (', $where).')',
|
|
||||||
$having);
|
|
||||||
$packages = $package->loadAllFromArray($data);
|
|
||||||
|
|
||||||
$header = pht('Search Results');
|
|
||||||
$nodata = pht('No packages match your query.');
|
|
||||||
break;
|
|
||||||
case 'owned':
|
|
||||||
$data = queryfx_all(
|
|
||||||
$package->establishConnection('r'),
|
|
||||||
'SELECT p.* FROM %T p JOIN %T o ON p.id = o.packageID
|
|
||||||
WHERE o.userPHID = %s GROUP BY p.id',
|
|
||||||
$package->getTableName(),
|
|
||||||
$owner->getTableName(),
|
|
||||||
$user->getPHID());
|
|
||||||
$packages = $package->loadAllFromArray($data);
|
|
||||||
|
|
||||||
$header = pht('Owned Packages');
|
|
||||||
$nodata = pht('No owned packages');
|
|
||||||
break;
|
|
||||||
case 'projects':
|
|
||||||
$projects = id(new PhabricatorProjectQuery())
|
|
||||||
->setViewer($user)
|
|
||||||
->withMemberPHIDs(array($user->getPHID()))
|
|
||||||
->withStatus(PhabricatorProjectQuery::STATUS_ANY)
|
|
||||||
->execute();
|
|
||||||
$owner_phids = mpull($projects, 'getPHID');
|
|
||||||
if ($owner_phids) {
|
|
||||||
$data = queryfx_all(
|
|
||||||
$package->establishConnection('r'),
|
|
||||||
'SELECT p.* FROM %T p JOIN %T o ON p.id = o.packageID
|
|
||||||
WHERE o.userPHID IN (%Ls) GROUP BY p.id',
|
|
||||||
$package->getTableName(),
|
|
||||||
$owner->getTableName(),
|
|
||||||
$owner_phids);
|
|
||||||
} else {
|
|
||||||
$data = array();
|
|
||||||
}
|
|
||||||
$packages = $package->loadAllFromArray($data);
|
|
||||||
|
|
||||||
$header = pht('Project Packages');
|
|
||||||
$nodata = pht('No owned packages');
|
|
||||||
break;
|
|
||||||
case 'all':
|
|
||||||
$packages = $package->loadAll();
|
|
||||||
|
|
||||||
$header = pht('All Packages');
|
|
||||||
$nodata = pht('There are no defined packages.');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$content = $this->renderPackageTable(
|
|
||||||
$packages,
|
|
||||||
$header,
|
|
||||||
$nodata);
|
|
||||||
|
|
||||||
$filter = new AphrontListFilterView();
|
|
||||||
|
|
||||||
$owner_phids = $request->getArr('owner');
|
|
||||||
|
|
||||||
$callsigns = array('' => pht('(Any Repository)'));
|
|
||||||
$repositories = id(new PhabricatorRepositoryQuery())
|
|
||||||
->setViewer($user)
|
|
||||||
->setOrder('callsign')
|
|
||||||
->execute();
|
|
||||||
foreach ($repositories as $repository) {
|
|
||||||
$callsigns[$repository->getCallsign()] =
|
|
||||||
$repository->getCallsign().': '.$repository->getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
|
||||||
->setUser($user)
|
|
||||||
->setAction('/owners/view/search/')
|
|
||||||
->setMethod('GET')
|
|
||||||
->appendChild(
|
|
||||||
id(new AphrontFormTextControl())
|
|
||||||
->setName('name')
|
|
||||||
->setLabel(pht('Name'))
|
|
||||||
->setValue($request->getStr('name')))
|
|
||||||
->appendControl(
|
|
||||||
id(new AphrontFormTokenizerControl())
|
|
||||||
->setDatasource(new PhabricatorProjectOrUserDatasource())
|
|
||||||
->setLimit(1)
|
|
||||||
->setName('owner')
|
|
||||||
->setLabel(pht('Owner'))
|
|
||||||
->setValue($owner_phids))
|
|
||||||
->appendChild(
|
|
||||||
id(new AphrontFormSelectControl())
|
|
||||||
->setName('repository')
|
|
||||||
->setLabel(pht('Repository'))
|
|
||||||
->setOptions($callsigns)
|
|
||||||
->setValue($request->getStr('repository')))
|
|
||||||
->appendChild(
|
|
||||||
id(new AphrontFormTextControl())
|
|
||||||
->setName('path')
|
|
||||||
->setLabel(pht('Path'))
|
|
||||||
->setValue($request->getStr('path')))
|
|
||||||
->appendChild(
|
|
||||||
id(new AphrontFormSubmitControl())
|
|
||||||
->setValue(pht('Search for Packages')));
|
|
||||||
|
|
||||||
$filter->appendChild($form);
|
|
||||||
$title = pht('Package Index');
|
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
|
||||||
$crumbs->addTextCrumb($header);
|
|
||||||
$crumbs->setBorder(true);
|
|
||||||
|
|
||||||
$nav = $this->buildSideNavView();
|
|
||||||
$nav->appendChild($crumbs);
|
|
||||||
$nav->appendChild($filter);
|
|
||||||
$nav->appendChild($content);
|
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
|
||||||
$nav,
|
|
||||||
array(
|
|
||||||
'title' => pht('Package Index'),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function renderPackageTable(array $packages, $header, $nodata) {
|
public function buildSideNavView($for_app = false) {
|
||||||
assert_instances_of($packages, 'PhabricatorOwnersPackage');
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
if ($packages) {
|
$nav = new AphrontSideNavFilterView();
|
||||||
$package_ids = mpull($packages, 'getID');
|
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||||
|
|
||||||
$owners = id(new PhabricatorOwnersOwner())->loadAllWhere(
|
if ($for_app) {
|
||||||
'packageID IN (%Ld)',
|
$nav->addFilter('new/', pht('Create Package'));
|
||||||
$package_ids);
|
|
||||||
|
|
||||||
$paths = id(new PhabricatorOwnersPath())->loadAllWhere(
|
|
||||||
'packageID in (%Ld)',
|
|
||||||
$package_ids);
|
|
||||||
|
|
||||||
$phids = array();
|
|
||||||
foreach ($owners as $owner) {
|
|
||||||
$phids[$owner->getUserPHID()] = true;
|
|
||||||
}
|
|
||||||
$phids = array_keys($phids);
|
|
||||||
$handles = $this->loadViewerHandles($phids);
|
|
||||||
|
|
||||||
$repository_phids = array();
|
|
||||||
foreach ($paths as $path) {
|
|
||||||
$repository_phids[$path->getRepositoryPHID()] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($repository_phids) {
|
|
||||||
$repositories = id(new PhabricatorRepositoryQuery())
|
|
||||||
->setViewer($this->getRequest()->getUser())
|
|
||||||
->withPHIDs(array_keys($repository_phids))
|
|
||||||
->execute();
|
|
||||||
} else {
|
|
||||||
$repositories = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
$repositories = mpull($repositories, null, 'getPHID');
|
|
||||||
$owners = mgroup($owners, 'getPackageID');
|
|
||||||
$paths = mgroup($paths, 'getPackageID');
|
|
||||||
} else {
|
|
||||||
$handles = array();
|
|
||||||
$repositories = array();
|
|
||||||
$owners = array();
|
|
||||||
$paths = array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$rows = array();
|
id(new PhabricatorOwnersPackageSearchEngine())
|
||||||
foreach ($packages as $package) {
|
->setViewer($viewer)
|
||||||
|
->addNavigationItems($nav->getMenu());
|
||||||
|
|
||||||
$pkg_owners = idx($owners, $package->getID(), array());
|
$nav->selectFilter(null);
|
||||||
foreach ($pkg_owners as $key => $owner) {
|
|
||||||
$pkg_owners[$key] = $handles[$owner->getUserPHID()]->renderLink();
|
|
||||||
if ($owner->getUserPHID() == $package->getPrimaryOwnerPHID()) {
|
|
||||||
$pkg_owners[$key] = phutil_tag('strong', array(), $pkg_owners[$key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$pkg_owners = phutil_implode_html(phutil_tag('br'), $pkg_owners);
|
|
||||||
|
|
||||||
$pkg_paths = idx($paths, $package->getID(), array());
|
return $nav;
|
||||||
foreach ($pkg_paths as $key => $path) {
|
|
||||||
$repo = idx($repositories, $path->getRepositoryPHID());
|
|
||||||
if ($repo) {
|
|
||||||
$href = DiffusionRequest::generateDiffusionURI(
|
|
||||||
array(
|
|
||||||
'callsign' => $repo->getCallsign(),
|
|
||||||
'branch' => $repo->getDefaultBranch(),
|
|
||||||
'path' => $path->getPath(),
|
|
||||||
'action' => 'browse',
|
|
||||||
));
|
|
||||||
$pkg_paths[$key] = hsprintf(
|
|
||||||
'%s %s%s',
|
|
||||||
($path->getExcluded() ? "\xE2\x80\x93" : '+'),
|
|
||||||
phutil_tag('strong', array(), $repo->getName()),
|
|
||||||
phutil_tag(
|
|
||||||
'a',
|
|
||||||
array(
|
|
||||||
'href' => (string)$href,
|
|
||||||
),
|
|
||||||
$path->getPath()));
|
|
||||||
} else {
|
|
||||||
$pkg_paths[$key] = $path->getPath();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$pkg_paths = phutil_implode_html(phutil_tag('br'), $pkg_paths);
|
|
||||||
|
|
||||||
$rows[] = array(
|
|
||||||
phutil_tag(
|
|
||||||
'a',
|
|
||||||
array(
|
|
||||||
'href' => '/owners/package/'.$package->getID().'/',
|
|
||||||
),
|
|
||||||
$package->getName()),
|
|
||||||
$pkg_owners,
|
|
||||||
$pkg_paths,
|
|
||||||
phutil_tag(
|
|
||||||
'a',
|
|
||||||
array(
|
|
||||||
'href' => '/audit/?auditorPHIDs='.$package->getPHID(),
|
|
||||||
),
|
|
||||||
pht('Related Commits')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$table = new AphrontTableView($rows);
|
|
||||||
$table->setHeaders(
|
|
||||||
array(
|
|
||||||
pht('Name'),
|
|
||||||
pht('Owners'),
|
|
||||||
pht('Paths'),
|
|
||||||
pht('Related Commits'),
|
|
||||||
));
|
|
||||||
$table->setColumnClasses(
|
|
||||||
array(
|
|
||||||
'pri',
|
|
||||||
'',
|
|
||||||
'wide wrap',
|
|
||||||
'narrow',
|
|
||||||
));
|
|
||||||
|
|
||||||
$panel = new PHUIObjectBoxView();
|
|
||||||
$panel->setHeaderText($header);
|
|
||||||
$panel->appendChild($table);
|
|
||||||
|
|
||||||
return $panel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getExtraPackageViews(AphrontSideNavFilterView $view) {
|
public function buildApplicationMenu() {
|
||||||
if ($this->view == 'search') {
|
return $this->buildSideNavView(true)->getMenu();
|
||||||
$view->addFilter('view/search', pht('Search Results'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function buildApplicationCrumbs() {
|
||||||
|
$crumbs = parent::buildApplicationCrumbs();
|
||||||
|
|
||||||
|
$crumbs->addAction(
|
||||||
|
id(new PHUIListItemView())
|
||||||
|
->setName(pht('Create Package'))
|
||||||
|
->setHref($this->getApplicationURI('new/'))
|
||||||
|
->setIcon('fa-plus-square'));
|
||||||
|
|
||||||
|
return $crumbs;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
final class PhabricatorOwnersPackageQuery
|
final class PhabricatorOwnersPackageQuery
|
||||||
extends PhabricatorCursorPagedPolicyAwareQuery {
|
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
|
|
||||||
|
private $ids;
|
||||||
private $phids;
|
private $phids;
|
||||||
private $ownerPHIDs;
|
private $ownerPHIDs;
|
||||||
|
private $repositoryPHIDs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Owners are direct owners, and members of owning projects.
|
* Owners are direct owners, and members of owning projects.
|
||||||
|
@ -19,6 +21,16 @@ final class PhabricatorOwnersPackageQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withIDs(array $ids) {
|
||||||
|
$this->ids = $ids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withRepositoryPHIDs(array $phids) {
|
||||||
|
$this->repositoryPHIDs = $phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
protected function loadPage() {
|
protected function loadPage() {
|
||||||
$table = new PhabricatorOwnersPackage();
|
$table = new PhabricatorOwnersPackage();
|
||||||
$conn_r = $table->establishConnection('r');
|
$conn_r = $table->establishConnection('r');
|
||||||
|
@ -38,27 +50,48 @@ final class PhabricatorOwnersPackageQuery
|
||||||
protected function buildJoinClause(AphrontDatabaseConnection $conn_r) {
|
protected function buildJoinClause(AphrontDatabaseConnection $conn_r) {
|
||||||
$joins = array();
|
$joins = array();
|
||||||
|
|
||||||
if ($this->ownerPHIDs) {
|
if ($this->ownerPHIDs !== null) {
|
||||||
$joins[] = qsprintf(
|
$joins[] = qsprintf(
|
||||||
$conn_r,
|
$conn_r,
|
||||||
'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) {
|
||||||
|
$joins[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'JOIN %T rpath ON rpath.packageID = p.id',
|
||||||
|
id(new PhabricatorOwnersPath())->getTableName());
|
||||||
|
}
|
||||||
|
|
||||||
return implode(' ', $joins);
|
return implode(' ', $joins);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
||||||
$where = array();
|
$where = array();
|
||||||
|
|
||||||
if ($this->phids) {
|
if ($this->phids !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn_r,
|
||||||
'p.phid IN (%Ls)',
|
'p.phid IN (%Ls)',
|
||||||
$this->phids);
|
$this->phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->ownerPHIDs) {
|
if ($this->ids !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'p.id IN (%Ld)',
|
||||||
|
$this->ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->repositoryPHIDs !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'rpath.repositoryPHID IN (%Ls)',
|
||||||
|
$this->repositoryPHIDs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->ownerPHIDs !== null) {
|
||||||
$base_phids = $this->ownerPHIDs;
|
$base_phids = $this->ownerPHIDs;
|
||||||
|
|
||||||
$query = new PhabricatorProjectQuery();
|
$query = new PhabricatorProjectQuery();
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorOwnersPackageSearchEngine
|
||||||
|
extends PhabricatorApplicationSearchEngine {
|
||||||
|
|
||||||
|
public function getResultTypeDescription() {
|
||||||
|
return pht('Owners Packages');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationClassName() {
|
||||||
|
return 'PhabricatorOwnersApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
||||||
|
$saved = new PhabricatorSavedQuery();
|
||||||
|
|
||||||
|
$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) {
|
||||||
|
$query = id(new PhabricatorOwnersPackageQuery());
|
||||||
|
|
||||||
|
$owner_phids = $saved->getParameter('ownerPHIDs', array());
|
||||||
|
if ($owner_phids) {
|
||||||
|
$query->withOwnerPHIDs($owner_phids);
|
||||||
|
}
|
||||||
|
|
||||||
|
$repository_phids = $saved->getParameter('repositoryPHIDs', array());
|
||||||
|
if ($repository_phids) {
|
||||||
|
$query->withRepositoryPHIDs($repository_phids);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
return '/owners/'.$path;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getBuiltinQueryNames() {
|
||||||
|
$names = array();
|
||||||
|
|
||||||
|
if ($this->requireViewer()->isLoggedIn()) {
|
||||||
|
$names['owned'] = pht('Owned');
|
||||||
|
}
|
||||||
|
|
||||||
|
$names += array(
|
||||||
|
'all' => pht('All Packages'),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildSavedQueryFromBuiltin($query_key) {
|
||||||
|
$query = $this->newSavedQuery();
|
||||||
|
$query->setQueryKey($query_key);
|
||||||
|
|
||||||
|
switch ($query_key) {
|
||||||
|
case 'all':
|
||||||
|
return $query;
|
||||||
|
case 'owned':
|
||||||
|
return $query->setParameter(
|
||||||
|
'ownerPHIDs',
|
||||||
|
array($this->requireViewer()->getPHID()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderResultList(
|
||||||
|
array $packages,
|
||||||
|
PhabricatorSavedQuery $query,
|
||||||
|
array $handles) {
|
||||||
|
assert_instances_of($packages, 'PhabricatorOwnersPackage');
|
||||||
|
|
||||||
|
$viewer = $this->requireViewer();
|
||||||
|
|
||||||
|
$list = id(new PHUIObjectItemListView())
|
||||||
|
->setUser($viewer);
|
||||||
|
foreach ($packages as $package) {
|
||||||
|
$id = $package->getID();
|
||||||
|
|
||||||
|
$item = id(new PHUIObjectItemView())
|
||||||
|
->setObject($package)
|
||||||
|
->setObjectName(pht('Package %d', $id))
|
||||||
|
->setHeader($package->getName())
|
||||||
|
->setHref('/owners/package/'.$id.'/');
|
||||||
|
|
||||||
|
$list->addItem($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ final class PhabricatorOwnersPackage extends PhabricatorOwnersDAO
|
||||||
return array(
|
return array(
|
||||||
// This information is better available from the history table.
|
// This information is better available from the history table.
|
||||||
self::CONFIG_TIMESTAMPS => false,
|
self::CONFIG_TIMESTAMPS => false,
|
||||||
self::CONFIG_AUX_PHID => true,
|
self::CONFIG_AUX_PHID => true,
|
||||||
self::CONFIG_COLUMN_SCHEMA => array(
|
self::CONFIG_COLUMN_SCHEMA => array(
|
||||||
'name' => 'text128',
|
'name' => 'text128',
|
||||||
'originalName' => 'text255',
|
'originalName' => 'text255',
|
||||||
|
@ -60,7 +60,8 @@ final class PhabricatorOwnersPackage extends PhabricatorOwnersDAO
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generatePHID() {
|
public function generatePHID() {
|
||||||
return PhabricatorPHID::generateNewPHID('OPKG');
|
return PhabricatorPHID::generateNewPHID(
|
||||||
|
PhabricatorOwnersPackagePHIDType::TYPECONST);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attachUnsavedOwners(array $owners) {
|
public function attachUnsavedOwners(array $owners) {
|
||||||
|
|
Loading…
Reference in a new issue