diff --git a/src/applications/diffusion/controller/DiffusionLintController.php b/src/applications/diffusion/controller/DiffusionLintController.php index 876947ffa1..585bc7b27a 100644 --- a/src/applications/diffusion/controller/DiffusionLintController.php +++ b/src/applications/diffusion/controller/DiffusionLintController.php @@ -1,157 +1,228 @@ getRequest(); + $user = $this->getRequest()->getUser(); $drequest = $this->diffusionRequest; - if ($this->getRequest()->getStr('lint') !== null) { - $controller = new DiffusionLintDetailsController($this->getRequest()); + if ($request->getStr('lint') !== null) { + $controller = new DiffusionLintDetailsController($request); $controller->setDiffusionRequest($drequest); return $this->delegateToController($controller); } - $codes = $this->loadLintCodes(); - $codes = array_reverse(isort($codes, 'n')); - + $owners = array(); if (!$drequest) { + if (!$request->getArr('owner')) { + $owners[$user->getPHID()] = $user->getFullName(); + } else { + $phids = $request->getArr('owner'); + $phid = reset($phids); + $handles = $this->loadViewerHandles(array($phid)); + $owners[$phid] = $handles[$phid]->getFullName(); + } + } + + $codes = $this->loadLintCodes(array_keys($owners)); + + if ($codes && !$drequest) { $branches = id(new PhabricatorRepositoryBranch())->loadAllWhere( 'id IN (%Ld)', array_unique(ipull($codes, 'branchID'))); $repositories = id(new PhabricatorRepository())->loadAllWhere( 'id IN (%Ld)', array_unique(mpull($branches, 'getRepositoryID'))); $drequests = array(); foreach ($branches as $id => $branch) { $drequests[$id] = DiffusionRequest::newFromDictionary(array( 'repository' => $repositories[$branch->getRepositoryID()], 'branch' => $branch->getName(), )); } } $rows = array(); foreach ($codes as $code) { if (!$this->diffusionRequest) { $drequest = $drequests[$code['branchID']]; } $rows[] = array( hsprintf( '%s', $drequest->generateURI(array( 'action' => 'lint', 'lint' => $code['code'], )), $code['n']), hsprintf( '%s', $drequest->generateURI(array( 'action' => 'browse', 'lint' => $code['code'], )), $code['files']), hsprintf( '%s', $drequest->generateURI(array('action' => 'lint')), $drequest->getCallsign()), phutil_escape_html(ArcanistLintSeverity::getStringForSeverity( $code['maxSeverity'])), phutil_escape_html($code['code']), phutil_escape_html($code['maxName']), phutil_escape_html($code['maxDescription']), ); } $table = id(new AphrontTableView($rows)) ->setHeaders(array( 'Problems', 'Files', 'Repository', 'Severity', 'Code', 'Name', 'Example', )) ->setColumnVisibility(array(true, true, !$this->diffusionRequest)) ->setColumnClasses(array('n', 'n', '', '', 'pri', '', '')); $content = array(); $content[] = $this->buildCrumbs( array( 'branch' => true, 'path' => true, 'view' => 'lint', )); + $link = null; if ($this->diffusionRequest) { $link = hsprintf( '%s', $drequest->generateURI(array( 'action' => 'lint', 'lint' => '', )), pht('Switch to List View')); + + } else { + $form = id(new AphrontFormView()) + ->setUser($user) + ->setMethod('GET') + ->appendChild( + id(new AphrontFormTokenizerControl()) + ->setDatasource('/typeahead/common/users/') + ->setLimit(1) + ->setName('owner') + ->setLabel('Owner') + ->setValue($owners)) + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue('Filter')); + $content[] = id(new AphrontListFilterView())->appendChild($form); } $content[] = id(new AphrontPanelView()) ->setHeader(pht('%d Lint Message(s)', array_sum(ipull($codes, 'n')))) ->setCaption($link) ->appendChild($table); $title = array('Lint'); if ($this->diffusionRequest) { $title[] = $drequest->getCallsign(); $content = $this->buildSideNav('lint', false)->appendChild($content); } return $this->buildStandardPageResponse( $content, array('title' => $title)); } - private function loadLintCodes() { + private function loadLintCodes(array $owner_phids) { $drequest = $this->diffusionRequest; $conn = id(new PhabricatorRepository())->establishConnection('r'); $where = array('1 = 1'); if ($drequest) { $branch = $drequest->loadBranch(); if (!$branch) { return array(); } $where[] = qsprintf($conn, 'branchID = %d', $branch->getID()); if ($drequest->getPath() != '') { $is_dir = (substr($drequest->getPath(), -1) == '/'); $where[] = qsprintf( $conn, 'path '.($is_dir ? 'LIKE %>' : '= %s'), '/'.$drequest->getPath()); } } + if ($owner_phids) { + $packages = id(new PhabricatorOwnersOwner()) + ->loadAllWhere('userPHID IN (%Ls)', $owner_phids); + if (!$packages) { + return array(); + } + + $paths = id(new PhabricatorOwnersPath()) + ->loadAllWhere('packageID IN (%Ld)', array_keys($packages)); + if (!$paths) { + return array(); + } + + $repositories = id(new PhabricatorRepository())->loadAllWhere( + 'phid IN (%Ls)', + array_unique(mpull($paths, 'getRepositoryPHID'))); + $repositories = mpull($repositories, 'getID', 'getPHID'); + + $branches = id(new PhabricatorRepositoryBranch())->loadAllWhere( + 'repositoryID IN (%Ld)', + $repositories); + $branches = mgroup($branches, 'getRepositoryID'); + + $or = array(); + foreach ($paths as $path) { + $branch = idx($branches, $repositories[$path->getRepositoryPHID()]); + if ($branch) { + $or[] = qsprintf( + $conn, + '(branchID IN (%Ld) AND path LIKE %>)', + array_keys($branch), + $path->getPath()); + } + } + if (!$or) { + return array(); + } + $where[] = '('.implode(' OR ', $or).')'; + } + return queryfx_all( $conn, 'SELECT branchID, code, MAX(severity) AS maxSeverity, MAX(name) AS maxName, MAX(description) AS maxDescription, COUNT(DISTINCT path) AS files, COUNT(*) AS n FROM %T WHERE %Q - GROUP BY branchID, code', + GROUP BY branchID, code + ORDER BY n DESC', PhabricatorRepository::TABLE_LINTMESSAGE, implode(' AND ', $where)); } } diff --git a/src/applications/people/controller/PhabricatorPeopleProfileController.php b/src/applications/people/controller/PhabricatorPeopleProfileController.php index a51e71abf5..838d511200 100644 --- a/src/applications/people/controller/PhabricatorPeopleProfileController.php +++ b/src/applications/people/controller/PhabricatorPeopleProfileController.php @@ -1,221 +1,226 @@ username = idx($data, 'username'); $this->page = idx($data, 'page'); } public function getProfileUser() { return $this->profileUser; } public function processRequest() { $viewer = $this->getRequest()->getUser(); $user = id(new PhabricatorUser())->loadOneWhere( 'userName = %s', $this->username); if (!$user) { return new Aphront404Response(); } $this->profileUser = $user; require_celerity_resource('phabricator-profile-css'); $profile = id(new PhabricatorUserProfile())->loadOneWhere( 'userPHID = %s', $user->getPHID()); if (!$profile) { $profile = new PhabricatorUserProfile(); } $username = phutil_escape_uri($user->getUserName()); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI('/p/'.$username.'/')); $nav->addFilter('feed', 'Feed'); $nav->addFilter('about', 'About'); $nav->addSpacer(); $nav->addLabel('Activity'); $external_arrow = "\xE2\x86\x97"; $nav->addFilter( null, "Revisions {$external_arrow}", '/differential/filter/revisions/'.$username.'/'); $nav->addFilter( null, "Tasks {$external_arrow}", '/maniphest/view/action/?users='.$user->getPHID()); $nav->addFilter( null, "Commits {$external_arrow}", '/audit/view/author/'.$username.'/'); + $nav->addFilter( + null, + "Lint Messages {$external_arrow}", + '/diffusion/lint/?owner[0]='.$user->getPHID()); + $oauths = id(new PhabricatorUserOAuthInfo())->loadAllWhere( 'userID = %d', $user->getID()); $oauths = mpull($oauths, null, 'getOAuthProvider'); $providers = PhabricatorOAuthProvider::getAllProviders(); $added_spacer = false; foreach ($providers as $provider) { if (!$provider->isProviderEnabled()) { continue; } $provider_key = $provider->getProviderKey(); if (!isset($oauths[$provider_key])) { continue; } $name = $provider->getProviderName().' Profile'; $href = $oauths[$provider_key]->getAccountURI(); if ($href) { if (!$added_spacer) { $nav->addSpacer(); $nav->addLabel('Linked Accounts'); $added_spacer = true; } $nav->addFilter(null, $name.' '.$external_arrow, $href); } } $this->page = $nav->selectFilter($this->page, 'feed'); switch ($this->page) { case 'feed': $content = $this->renderUserFeed($user); break; case 'about': $content = $this->renderBasicInformation($user, $profile); break; default: throw new Exception("Unknown page '{$this->page}'!"); } $picture = $user->loadProfileImageURI(); $header = new PhabricatorProfileHeaderView(); $header ->setProfilePicture($picture) ->setName($user->getUserName().' ('.$user->getRealName().')') ->setDescription($profile->getTitle()); if ($user->getIsDisabled()) { $header->setStatus('Disabled'); } else { $statuses = id(new PhabricatorUserStatus())->loadCurrentStatuses( array($user->getPHID())); if ($statuses) { $header->setStatus(reset($statuses)->getTerseSummary($viewer)); } } $header->appendChild($nav); $nav->appendChild( '
'.$content.'
'); if ($user->getPHID() == $viewer->getPHID()) { $nav->addSpacer(); $nav->addFilter(null, 'Edit Profile...', '/settings/panel/profile/'); } if ($viewer->getIsAdmin()) { $nav->addSpacer(); $nav->addFilter( null, 'Administrate User...', '/people/edit/'.$user->getID().'/'); } return $this->buildApplicationPage( $header, array( 'title' => $user->getUsername(), )); } private function renderBasicInformation($user, $profile) { $blurb = nonempty( $profile->getBlurb(), '//Nothing is known about this rare specimen.//'); $engine = PhabricatorMarkupEngine::newProfileMarkupEngine(); $blurb = $engine->markupText($blurb); $viewer = $this->getRequest()->getUser(); $content = '

Basic Information

PHID '.phutil_escape_html($user->getPHID()).'
User Since '.phabricator_datetime($user->getDateCreated(), $viewer). '
'; $content .= '

Flavor Text

Blurb '.$blurb.'
'; return $content; } private function renderUserFeed(PhabricatorUser $user) { $viewer = $this->getRequest()->getUser(); $query = new PhabricatorFeedQuery(); $query->setFilterPHIDs( array( $user->getPHID(), )); $query->setLimit(100); $query->setViewer($viewer); $stories = $query->execute(); $builder = new PhabricatorFeedBuilder($stories); $builder->setUser($viewer); $view = $builder->buildView(); return '

Activity Feed

'.$view->render().'
'; } }