1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-18 21:02: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:
epriestley 2015-05-27 10:29:01 -07:00
parent e9f4a84a89
commit 6d5d34e6a8
9 changed files with 247 additions and 455 deletions

View file

@ -2178,6 +2178,7 @@ phutil_register_library_map(array(
'PhabricatorOwnersPackagePHIDType' => 'applications/owners/phid/PhabricatorOwnersPackagePHIDType.php',
'PhabricatorOwnersPackagePathValidator' => 'applications/repository/worker/commitchangeparser/PhabricatorOwnersPackagePathValidator.php',
'PhabricatorOwnersPackageQuery' => 'applications/owners/query/PhabricatorOwnersPackageQuery.php',
'PhabricatorOwnersPackageSearchEngine' => 'applications/owners/query/PhabricatorOwnersPackageSearchEngine.php',
'PhabricatorOwnersPackageTestCase' => 'applications/owners/storage/__tests__/PhabricatorOwnersPackageTestCase.php',
'PhabricatorOwnersPath' => 'applications/owners/storage/PhabricatorOwnersPath.php',
'PhabricatorPHDConfigOptions' => 'applications/config/option/PhabricatorPHDConfigOptions.php',
@ -5584,6 +5585,7 @@ phutil_register_library_map(array(
'PhabricatorOwnersPackageEditor' => 'PhabricatorEditor',
'PhabricatorOwnersPackagePHIDType' => 'PhabricatorPHIDType',
'PhabricatorOwnersPackageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorOwnersPackageSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorOwnersPackageTestCase' => 'PhabricatorTestCase',
'PhabricatorOwnersPath' => 'PhabricatorOwnersDAO',
'PhabricatorPHDConfigOptions' => 'PhabricatorApplicationConfigOptions',

View file

@ -42,8 +42,7 @@ final class PhabricatorOwnersApplication extends PhabricatorApplication {
public function getRoutes() {
return array(
'/owners/' => array(
'' => 'PhabricatorOwnersListController',
'view/(?P<view>[^/]+)/' => 'PhabricatorOwnersListController',
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorOwnersListController',
'edit/(?P<id>[1-9]\d*)/' => 'PhabricatorOwnersEditController',
'new/' => 'PhabricatorOwnersEditController',
'package/(?P<id>[1-9]\d*)/' => 'PhabricatorOwnersDetailController',

View file

@ -1,70 +1,3 @@
<?php
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;
}
}
abstract class PhabricatorOwnersController extends PhabricatorController {}

View file

@ -3,22 +3,20 @@
final class PhabricatorOwnersDetailController
extends PhabricatorOwnersController {
private $id;
private $package;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
public function shouldAllowPublic() {
return true;
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$package = id(new PhabricatorOwnersPackage())->load($this->id);
$package = id(new PhabricatorOwnersPackageQuery())
->setViewer($viewer)
->withIDs(array($request->getURIData('id')))
->executeOne();
if (!$package) {
return new Aphront404Response();
}
$this->package = $package;
$paths = $package->loadPaths();
$owners = $package->loadOwners();
@ -30,7 +28,7 @@ final class PhabricatorOwnersDetailController
if ($repository_phids) {
$repositories = id(new PhabricatorRepositoryQuery())
->setViewer($user)
->setViewer($viewer)
->withPHIDs(array_keys($repository_phids))
->execute();
$repositories = mpull($repositories, null, 'getPHID');
@ -131,9 +129,6 @@ final class PhabricatorOwnersDetailController
$panel->setHeader($header);
$panel->appendChild($table);
$key = 'package/'.$package->getID();
$this->setSideNavFilter($key);
$commit_views = array();
$commit_uri = id(new PhutilURI('/audit/'))
@ -151,7 +146,7 @@ final class PhabricatorOwnersDetailController
->execute();
if ($attention_commits) {
$view = id(new PhabricatorAuditListView())
->setUser($user)
->setUser($viewer)
->setCommits($attention_commits);
$commit_views[] = array(
@ -172,7 +167,7 @@ final class PhabricatorOwnersDetailController
->execute();
$view = id(new PhabricatorAuditListView())
->setUser($user)
->setUser($viewer)
->setCommits($all_commits)
->setNoDataString(pht('No commits in this package.'));
@ -210,21 +205,15 @@ final class PhabricatorOwnersDetailController
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($package->getName());
$nav = $this->buildSideNavView();
$nav->appendChild($crumbs);
$nav->appendChild($panel);
$nav->appendChild($commit_panels);
return $this->buildApplicationPage(
$nav,
array(
$crumbs,
$panel,
$commit_panels,
),
array(
'title' => pht('Package %s', $package->getName()),
));
}
protected function getExtraPackageViews(AphrontSideNavFilterView $view) {
$package = $this->package;
$view->addFilter('package/'.$package->getID(), pht('Details'));
}
}

View file

@ -3,24 +3,27 @@
final class PhabricatorOwnersEditController
extends PhabricatorOwnersController {
private $id;
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getUser();
public function willProcessRequest(array $data) {
$this->id = idx($data, 'id');
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
if ($this->id) {
$package = id(new PhabricatorOwnersPackage())->load($this->id);
$id = $request->getURIData('id');
if ($id) {
$package = id(new PhabricatorOwnersPackageQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
// TODO: Support this capability.
// PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$package) {
return new Aphront404Response();
}
} else {
$package = new PhabricatorOwnersPackage();
$package->setPrimaryOwnerPHID($user->getPHID());
$package->setPrimaryOwnerPHID($viewer->getPHID());
}
$e_name = true;
@ -89,7 +92,7 @@ final class PhabricatorOwnersEditController
$package->attachOldPrimaryOwnerPHID($old_primary);
try {
id(new PhabricatorOwnersPackageEditor())
->setActor($user)
->setActor($viewer)
->setPackage($package)
->save();
return id(new AphrontRedirectResponse())
@ -123,15 +126,12 @@ final class PhabricatorOwnersEditController
if ($package->getID()) {
$title = pht('Edit Package');
$side_nav_filter = 'edit/'.$this->id;
} else {
$title = pht('New Package');
$side_nav_filter = 'new';
}
$this->setSideNavFilter($side_nav_filter);
$repos = id(new PhabricatorRepositoryQuery())
->setViewer($user)
->setViewer($viewer)
->execute();
$default_paths = array();
@ -171,7 +171,7 @@ final class PhabricatorOwnersEditController
: '/owners/';
$form = id(new AphrontFormView())
->setUser($user)
->setUser($viewer)
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Name'))
@ -256,24 +256,14 @@ final class PhabricatorOwnersEditController
$crumbs->addTextCrumb(pht('New Package'));
}
$nav = $this->buildSideNavView();
$nav->appendChild($crumbs);
$nav->appendChild($form_box);
return $this->buildApplicationPage(
array(
$nav,
$crumbs,
$form_box,
),
array(
'title' => $title,
));
}
protected function getExtraPackageViews(AphrontSideNavFilterView $view) {
if ($this->id) {
$view->addFilter('edit/'.$this->id, pht('Edit'));
} else {
$view->addFilter('new', pht('New'));
}
}
}

View file

@ -3,341 +3,52 @@
final class PhabricatorOwnersListController
extends PhabricatorOwnersController {
protected $view;
public function willProcessRequest(array $data) {
$this->view = idx($data, 'view', 'owned');
$this->setSideNavFilter('view/'.$this->view);
public function shouldAllowPublic() {
return true;
}
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();
$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'),
));
return $this->delegateToController($controller);
}
private function renderPackageTable(array $packages, $header, $nodata) {
assert_instances_of($packages, 'PhabricatorOwnersPackage');
public function buildSideNavView($for_app = false) {
$viewer = $this->getViewer();
if ($packages) {
$package_ids = mpull($packages, 'getID');
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
$owners = id(new PhabricatorOwnersOwner())->loadAllWhere(
'packageID IN (%Ld)',
$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();
if ($for_app) {
$nav->addFilter('new/', pht('Create Package'));
}
$rows = array();
foreach ($packages as $package) {
id(new PhabricatorOwnersPackageSearchEngine())
->setViewer($viewer)
->addNavigationItems($nav->getMenu());
$pkg_owners = idx($owners, $package->getID(), array());
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);
$nav->selectFilter(null);
$pkg_paths = idx($paths, $package->getID(), array());
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;
return $nav;
}
protected function getExtraPackageViews(AphrontSideNavFilterView $view) {
if ($this->view == 'search') {
$view->addFilter('view/search', pht('Search Results'));
}
public function buildApplicationMenu() {
return $this->buildSideNavView(true)->getMenu();
}
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;
}
}

View file

@ -3,8 +3,10 @@
final class PhabricatorOwnersPackageQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $ownerPHIDs;
private $repositoryPHIDs;
/**
* Owners are direct owners, and members of owning projects.
@ -19,6 +21,16 @@ final class PhabricatorOwnersPackageQuery
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() {
$table = new PhabricatorOwnersPackage();
$conn_r = $table->establishConnection('r');
@ -38,27 +50,48 @@ final class PhabricatorOwnersPackageQuery
protected function buildJoinClause(AphrontDatabaseConnection $conn_r) {
$joins = array();
if ($this->ownerPHIDs) {
if ($this->ownerPHIDs !== null) {
$joins[] = qsprintf(
$conn_r,
'JOIN %T o ON o.packageID = p.id',
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);
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
if ($this->phids) {
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
'p.phid IN (%Ls)',
$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;
$query = new PhabricatorProjectQuery();

View file

@ -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;
}
}

View file

@ -37,7 +37,7 @@ final class PhabricatorOwnersPackage extends PhabricatorOwnersDAO
return array(
// This information is better available from the history table.
self::CONFIG_TIMESTAMPS => false,
self::CONFIG_AUX_PHID => true,
self::CONFIG_AUX_PHID => true,
self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'text128',
'originalName' => 'text255',
@ -60,7 +60,8 @@ final class PhabricatorOwnersPackage extends PhabricatorOwnersDAO
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID('OPKG');
return PhabricatorPHID::generateNewPHID(
PhabricatorOwnersPackagePHIDType::TYPECONST);
}
public function attachUnsavedOwners(array $owners) {