diff --git a/src/applications/differential/controller/DifferentialRevisionViewController.php b/src/applications/differential/controller/DifferentialRevisionViewController.php --- a/src/applications/differential/controller/DifferentialRevisionViewController.php +++ b/src/applications/differential/controller/DifferentialRevisionViewController.php @@ -40,6 +40,85 @@ return $this; } + + private function getCompleteHandles(PhabricatorHandleList $handles) { + $phids = array(); + + foreach ($handles as $phid => $handle) { + if (!$handle->isComplete()) { + continue; + } + $phids[] = $phid; + } + + return $handles->newSublist($phids); + } + + private function newMentionsTab( + DifferentialRevision $revision) { + + $phid = $revision->getPHID(); + + $edge_types = array( + PhabricatorObjectMentionedByObjectEdgeType::EDGECONST, + PhabricatorObjectMentionsObjectEdgeType::EDGECONST, + ); + + $edge_query = id(new PhabricatorEdgeQuery()) + ->withSourcePHIDs(array($phid)) + ->withEdgeTypes($edge_types); + + $edge_query->execute(); + + $in_type = PhabricatorObjectMentionedByObjectEdgeType::EDGECONST; + $out_type = PhabricatorObjectMentionsObjectEdgeType::EDGECONST; + + $in_phids = $edge_query->getDestinationPHIDs(array(), array($in_type)); + $out_phids = $edge_query->getDestinationPHIDs(array(), array($out_type)); + + // Filter out any mentioned users from the list. These are not generally + // very interesting to show in a relationship summary since they usually + // end up as subscribers anyway. + + $user_type = PhabricatorPeopleUserPHIDType::TYPECONST; + foreach ($out_phids as $key => $out_phid) { + if (phid_get_type($out_phid) == $user_type) { + unset($out_phids[$key]); + } + } + + if (!$in_phids && !$out_phids) { + return null; + } + + $viewer = $this->getViewer(); + $in_handles = $viewer->loadHandles($in_phids); + $out_handles = $viewer->loadHandles($out_phids); + + $in_handles = $this->getCompleteHandles($in_handles); + $out_handles = $this->getCompleteHandles($out_handles); + + if (!count($in_handles) && !count($out_handles)) { + return null; + } + + $view = new PHUIPropertyListView(); + + if (count($in_handles)) { + $view->addProperty(pht('Mentioned In'), $in_handles->renderList()); + } + + if (count($out_handles)) { + $view->addProperty(pht('Mentioned Here'), $out_handles->renderList()); + } + + return id(new PHUITabView()) + ->setName(pht('Mentions')) + ->setKey('mentions') + ->appendChild($view); + } + + public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); $this->revisionID = $request->getURIData('id'); @@ -488,6 +567,8 @@ ->setKey('history') ->appendChild($history)); + $tab_group->addTab($this->newMentionsTab($revision)); + $filetree = id(new DifferentialFileTreeEngine()) ->setViewer($viewer); $filetree_collapsed = !$filetree->getIsVisible();