diff --git a/src/applications/diffusion/controller/DiffusionExternalController.php b/src/applications/diffusion/controller/DiffusionExternalController.php index 8ae8dcdba1..ea1bc24ae2 100644 --- a/src/applications/diffusion/controller/DiffusionExternalController.php +++ b/src/applications/diffusion/controller/DiffusionExternalController.php @@ -1,148 +1,151 @@ getRequest(); $uri = $request->getStr('uri'); $id = $request->getStr('id'); $repositories = id(new PhabricatorRepository())->loadAll(); if ($uri) { $uri_path = id(new PhutilURI($uri))->getPath(); $matches = array(); // Try to figure out which tracked repository this external lives in by // comparing repository metadata. We look for an exact match, but accept // a partial match. foreach ($repositories as $key => $repository) { $remote_uri = new PhutilURI($repository->getRemoteURI()); if ($remote_uri->getPath() == $uri_path) { $matches[$key] = 1; } if ($repository->getPublicRemoteURI() == $uri) { $matches[$key] = 2; } if ($repository->getRemoteURI() == $uri) { $matches[$key] = 3; } } arsort($matches); $best_match = head_key($matches); if ($best_match) { $repository = $repositories[$best_match]; $redirect = DiffusionRequest::generateDiffusionURI( array( 'action' => 'browse', 'callsign' => $repository->getCallsign(), + 'branch' => $repository->getDefaultBranch(), 'commit' => $id, )); return id(new AphrontRedirectResponse())->setURI($redirect); } } // TODO: This is a rare query but does a table scan, add a key? $commits = id(new PhabricatorRepositoryCommit())->loadAllWhere( 'commitIdentifier = %s', $id); if (empty($commits)) { $desc = null; if ($uri) { $desc = phutil_escape_html($uri).', at '; } $desc .= phutil_escape_html($id); $content = id(new AphrontErrorView()) ->setTitle('Unknown External') ->setSeverity(AphrontErrorView::SEVERITY_WARNING) ->appendChild( "

This external ({$desc}) does not appear in any tracked ". "repository. It may exist in an untracked repository that ". "Diffusion does not know about.

"); } else if (count($commits) == 1) { $commit = head($commits); + $repo = $repositories[$commit->getRepositoryID()]; $redirect = DiffusionRequest::generateDiffusionURI( array( 'action' => 'browse', - 'callsign' => $repositories[$commit->getRepositoryID()] - ->getCallsign(), + 'callsign' => $repo->getCallsign(), + 'branch' => $repo->getDefaultBranch(), 'commit' => $commit->getCommitIdentifier(), )); return id(new AphrontRedirectResponse())->setURI($redirect); } else { $rows = array(); foreach ($commits as $commit) { $repo = $repositories[$commit->getRepositoryID()]; $href = DiffusionRequest::generateDiffusionURI( array( 'action' => 'browse', 'callsign' => $repo->getCallsign(), + 'branch' => $repo->getDefaultBranch(), 'commit' => $commit->getCommitIdentifier(), )); $rows[] = array( phutil_render_tag( 'a', array( 'href' => $href, ), phutil_escape_html( 'r'.$repo->getCallsign().$commit->getCommitIdentifier())), phutil_escape_html($commit->loadCommitData()->getSummary()), ); } $table = new AphrontTableView($rows); $table->setHeaders( array( 'Commit', 'Description', )); $table->setColumnClasses( array( 'pri', 'wide', )); $content = new AphrontPanelView(); $content->setHeader('Multiple Matching Commits'); $content->setCaption( 'This external reference matches multiple known commits.'); $content->appendChild($table); } return $this->buildStandardPageResponse( $content, array( 'title' => 'Unresolvable External', )); } } diff --git a/src/applications/owners/controller/PhabricatorOwnersDetailController.php b/src/applications/owners/controller/PhabricatorOwnersDetailController.php index e0992e99ad..59b541dd50 100644 --- a/src/applications/owners/controller/PhabricatorOwnersDetailController.php +++ b/src/applications/owners/controller/PhabricatorOwnersDetailController.php @@ -1,247 +1,248 @@ id = $data['id']; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $package = id(new PhabricatorOwnersPackage())->load($this->id); if (!$package) { return new Aphront404Response(); } $this->package = $package; $paths = $package->loadPaths(); $owners = $package->loadOwners(); $repository_phids = array(); foreach ($paths as $path) { $repository_phids[$path->getRepositoryPHID()] = true; } if ($repository_phids) { $repositories = id(new PhabricatorRepository())->loadAllWhere( 'phid in (%Ls)', array_keys($repository_phids)); $repositories = mpull($repositories, null, 'getPHID'); } else { $repositories = array(); } $phids = array(); foreach ($owners as $owner) { $phids[$owner->getUserPHID()] = true; } $phids = array_keys($phids); $handles = $this->loadViewerHandles($phids); $rows = array(); $rows[] = array( 'Name', phutil_escape_html($package->getName())); $rows[] = array( 'Description', phutil_escape_html($package->getDescription())); $primary_owner = null; $primary_phid = $package->getPrimaryOwnerPHID(); if ($primary_phid && isset($handles[$primary_phid])) { $primary_owner = ''.$handles[$primary_phid]->renderLink().''; } $rows[] = array( 'Primary Owner', $primary_owner, ); $owner_links = array(); foreach ($owners as $owner) { $owner_links[] = $handles[$owner->getUserPHID()]->renderLink(); } $owner_links = implode('
', $owner_links); $rows[] = array( 'Owners', $owner_links); $rows[] = array( 'Auditing', $package->getAuditingEnabled() ? 'Enabled' : 'Disabled', ); $path_links = array(); foreach ($paths as $path) { $repo = $repositories[$path->getRepositoryPHID()]; $href = DiffusionRequest::generateDiffusionURI( array( 'callsign' => $repo->getCallsign(), - 'path' => $path->getPath(), - 'action' => 'browse' + 'branch' => $repo->getDefaultBranch(), + 'path' => $path->getPath(), + 'action' => 'browse' )); $repo_name = ''.phutil_escape_html($repo->getName()). ''; $path_link = phutil_render_tag( 'a', array( 'href' => (string) $href, ), phutil_escape_html($path->getPath())); $path_links[] = $repo_name.' '.$path_link; } $path_links = implode('
', $path_links); $rows[] = array( 'Paths', $path_links); $table = new AphrontTableView($rows); $table->setColumnClasses( array( 'header', 'wide', )); $panel = new AphrontPanelView(); $panel->setHeader( 'Package Details for "'.phutil_escape_html($package->getName()).'"'); $panel->addButton( javelin_render_tag( 'a', array( 'href' => '/owners/delete/'.$package->getID().'/', 'class' => 'button grey', 'sigil' => 'workflow', ), 'Delete Package')); $panel->addButton( phutil_render_tag( 'a', array( 'href' => '/owners/edit/'.$package->getID().'/', 'class' => 'button', ), 'Edit Package')); $panel->appendChild($table); $key = 'package/'.$package->getID(); $this->setSideNavFilter($key); $commit_views = array(); $commit_uri = id(new PhutilURI('/audit/view/packagecommits/')) ->setQueryParams( array( 'phid' => $package->getPHID(), )); $attention_query = id(new PhabricatorAuditCommitQuery()) ->withPackagePHIDs(array($package->getPHID())) ->withStatus(PhabricatorAuditCommitQuery::STATUS_OPEN) ->needCommitData(true) ->setLimit(10); $attention_commits = $attention_query->execute(); if ($attention_commits) { $view = new PhabricatorAuditCommitListView(); $view->setUser($user); $view->setCommits($attention_commits); $commit_views[] = array( 'view' => $view, 'header' => 'Commits in this Package that Need Attention', 'button' => phutil_render_tag( 'a', array( 'href' => $commit_uri->alter('status', 'open'), 'class' => 'button grey', ), 'View All Problem Commits'), ); } $all_query = id(new PhabricatorAuditCommitQuery()) ->withPackagePHIDs(array($package->getPHID())) ->needCommitData(true) ->setLimit(100); $all_commits = $all_query->execute(); $view = new PhabricatorAuditCommitListView(); $view->setUser($user); $view->setCommits($all_commits); $view->setNoDataString('No commits in this package.'); $commit_views[] = array( 'view' => $view, 'header' => 'Recent Commits in Package', 'button' => phutil_render_tag( 'a', array( 'href' => $commit_uri, 'class' => 'button grey', ), 'View All Package Commits'), ); $phids = array(); foreach ($commit_views as $commit_view) { $phids[] = $commit_view['view']->getRequiredHandlePHIDs(); } $phids = array_mergev($phids); $handles = $this->loadViewerHandles($phids); $commit_panels = array(); foreach ($commit_views as $commit_view) { $commit_panel = new AphrontPanelView(); $commit_panel->setHeader(phutil_escape_html($commit_view['header'])); if (isset($commit_view['button'])) { $commit_panel->addButton($commit_view['button']); } $commit_view['view']->setHandles($handles); $commit_panel->appendChild($commit_view['view']); $commit_panels[] = $commit_panel; } return $this->buildStandardPageResponse( array( $panel, $commit_panels, ), array( 'title' => "Package '".$package->getName()."'", )); } protected function getExtraPackageViews() { $package = $this->package; return array( array('name' => 'Details', 'key' => 'package/'.$package->getID(), )); } } diff --git a/src/applications/owners/controller/PhabricatorOwnersListController.php b/src/applications/owners/controller/PhabricatorOwnersListController.php index 6ac24112c6..1a501bcff2 100644 --- a/src/applications/owners/controller/PhabricatorOwnersListController.php +++ b/src/applications/owners/controller/PhabricatorOwnersListController.php @@ -1,339 +1,340 @@ view = idx($data, 'view', 'owned'); $this->setSideNavFilter('view/'.$this->view); } public function processRequest() { $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 PhabricatorRepository()) ->loadOneWhere('callsign = %s', $request->getStr('repository')) ->getPHID(); } switch ($this->view) { case 'search': $packages = array(); $conn_r = $package->establishConnection('r'); $where = array('1 = 1'); $join = array(); 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 %~ OR %s LIKE CONCAT(path.path, %s)', $request->getStr('path'), $request->getStr('path'), '%'); } } 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', $package->getTableName(), implode(' ', $join), '('.implode(') AND (', $where).')'); $packages = $package->loadAllFromArray($data); $header = 'Search Results'; $nodata = '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 = 'Owned Packages'; $nodata = 'No owned packages'; break; case 'all': $packages = $package->loadAll(); $header = 'All Packages'; $nodata = 'There are no defined packages.'; break; } $content = $this->renderPackageTable( $packages, $header, $nodata); $filter = new AphrontListFilterView(); $filter->addButton( phutil_render_tag( 'a', array( 'href' => '/owners/new/', 'class' => 'green button', ), 'Create New Package')); $owners_search_value = array(); if ($request->getArr('owner')) { $phids = $request->getArr('owner'); $phid = reset($phids); $handles = $this->loadViewerHandles(array($phid)); $owners_search_value = array( $phid => $handles[$phid]->getFullName(), ); } $callsigns = array('' => '(Any Repository)'); $repositories = id(new PhabricatorRepository()) ->loadAllWhere('1 = 1 ORDER BY callsign'); 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('Name') ->setValue($request->getStr('name'))) ->appendChild( id(new AphrontFormTokenizerControl()) ->setDatasource('/typeahead/common/usersorprojects/') ->setLimit(1) ->setName('owner') ->setLabel('Owner') ->setValue($owners_search_value)) ->appendChild( id(new AphrontFormSelectControl()) ->setName('repository') ->setLabel('Repository') ->setOptions($callsigns) ->setValue($request->getStr('repository'))) ->appendChild( id(new AphrontFormTextControl()) ->setName('path') ->setLabel('Path') ->setValue($request->getStr('path'))) ->appendChild( id(new AphrontFormSubmitControl()) ->setValue('Search for Packages')); $filter->appendChild($form); return $this->buildStandardPageResponse( array( $filter, $content, ), array( 'title' => 'Package Index', )); } private function renderPackageTable(array $packages, $header, $nodata) { assert_instances_of($packages, 'PhabricatorOwnersPackage'); if ($packages) { $package_ids = mpull($packages, 'getID'); $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 PhabricatorRepository())->loadAllWhere( 'phid in (%Ls)', array_keys($repository_phids)); } 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(); foreach ($packages as $package) { $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] = ''.$pkg_owners[$key].''; } } $pkg_owners = implode('
', $pkg_owners); $pkg_paths = idx($paths, $package->getID(), array()); foreach ($pkg_paths as $key => $path) { $repo = $repositories[$path->getRepositoryPHID()]; if ($repo) { $href = DiffusionRequest::generateDiffusionURI( array( 'callsign' => $repo->getCallsign(), + 'branch' => $repo->getDefaultBranch(), 'path' => $path->getPath(), 'action' => 'browse', )); $pkg_paths[$key] = ''.phutil_escape_html($repo->getName()).' '. phutil_render_tag( 'a', array( 'href' => (string) $href, ), phutil_escape_html($path->getPath())); } else { $pkg_paths[$key] = phutil_escape_html($path->getPath()); } } $pkg_paths = implode('
', $pkg_paths); $rows[] = array( phutil_render_tag( 'a', array( 'href' => '/owners/package/'.$package->getID().'/', ), phutil_escape_html($package->getName())), $pkg_owners, $pkg_paths, phutil_render_tag( 'a', array( 'href' => '/audit/view/packagecommits/?phid='.$package->getPHID(), ), phutil_escape_html('Related Commits')) ); } $table = new AphrontTableView($rows); $table->setHeaders( array( 'Name', 'Owners', 'Paths', 'Related Commits', )); $table->setColumnClasses( array( 'pri', '', 'wide wrap', 'narrow', )); $panel = new AphrontPanelView(); $panel->setHeader($header); $panel->appendChild($table); return $panel; } protected function getExtraPackageViews() { switch ($this->view) { case 'search': $extra = array(array('name' => 'Search Results', 'key' => 'view/search')); break; default: $extra = array(); break; } return $extra; } }