diff --git a/src/applications/transactions/view/PhabricatorApplicationTransactionView.php b/src/applications/transactions/view/PhabricatorApplicationTransactionView.php --- a/src/applications/transactions/view/PhabricatorApplicationTransactionView.php +++ b/src/applications/transactions/view/PhabricatorApplicationTransactionView.php @@ -211,17 +211,21 @@ throw new PhutilInvalidStateException('setObjectPHID'); } - $view = new PHUITimelineView(); - $view->setShouldTerminate($this->shouldTerminate); - $view->setQuoteTargetID($this->getQuoteTargetID()); - $view->setQuoteRef($this->getQuoteRef()); + $view = id(new PHUITimelineView()) + ->setUser($this->getUser()) + ->setShouldTerminate($this->shouldTerminate) + ->setQuoteTargetID($this->getQuoteTargetID()) + ->setQuoteRef($this->getQuoteRef()); + $events = $this->buildEvents($with_hiding); foreach ($events as $event) { $view->addEvent($event); } + if ($this->getPager()) { $view->setPager($this->getPager()); } + if ($this->getRenderData()) { $view->setRenderData($this->getRenderData()); } @@ -394,6 +398,7 @@ $event = id(new PHUITimelineEventView()) ->setUser($viewer) + ->setAuthorPHID($xaction->getAuthorPHID()) ->setTransactionPHID($xaction->getPHID()) ->setUserHandle($xaction->getHandle($xaction->getAuthorPHID())) ->setIcon($xaction->getIcon()) diff --git a/src/view/phui/PHUIBadgeMiniView.php b/src/view/phui/PHUIBadgeMiniView.php --- a/src/view/phui/PHUIBadgeMiniView.php +++ b/src/view/phui/PHUIBadgeMiniView.php @@ -46,20 +46,18 @@ } return array( - 'class' => implode(' ', $classes), - 'sigil' => 'has-tooltip', - 'href' => $this->href, - 'meta' => array( - 'tip' => $this->header, - ), - ); + 'class' => implode(' ', $classes), + 'sigil' => 'has-tooltip', + 'href' => $this->href, + 'meta' => array( + 'tip' => $this->header, + ), + ); } protected function getTagContent() { - return id(new PHUIIconView()) ->setIconFont($this->icon); - } } diff --git a/src/view/phui/PHUITimelineEventView.php b/src/view/phui/PHUITimelineEventView.php --- a/src/view/phui/PHUITimelineEventView.php +++ b/src/view/phui/PHUITimelineEventView.php @@ -26,8 +26,18 @@ private $quoteRef; private $reallyMajorEvent; private $hideCommentOptions = false; + private $authorPHID; private $badges = array(); + public function setAuthorPHID($author_phid) { + $this->authorPHID = $author_phid; + return $this; + } + + public function getAuthorPHID() { + return $this->authorPHID; + } + public function setQuoteRef($quote_ref) { $this->quoteRef = $quote_ref; return $this; diff --git a/src/view/phui/PHUITimelineView.php b/src/view/phui/PHUITimelineView.php --- a/src/view/phui/PHUITimelineView.php +++ b/src/view/phui/PHUITimelineView.php @@ -145,6 +145,7 @@ } if ($show) { + $this->prepareBadgeData($show); $events[] = phutil_implode_html($spacer, $show); } @@ -183,4 +184,82 @@ ''); } + private function prepareBadgeData(array $events) { + assert_instances_of($events, 'PHUITimelineEventView'); + + $viewer = $this->getUser(); + $can_use_badges = PhabricatorApplication::isClassInstalledForViewer( + 'PhabricatorBadgesApplication', + $viewer); + if (!$can_use_badges) { + return; + } + + $user_phid_type = PhabricatorPeopleUserPHIDType::TYPECONST; + $badge_edge_type = PhabricatorRecipientHasBadgeEdgeType::EDGECONST; + + $user_phids = array(); + foreach ($events as $key => $event) { + if (!$event->hasChildren()) { + // This is a minor event, so we don't have space to show badges. + unset($events[$key]); + continue; + } + + $author_phid = $event->getAuthorPHID(); + if (!$author_phid) { + unset($events[$key]); + continue; + } + + if (phid_get_type($author_phid) != $user_phid_type) { + // This is likely an application actor, like "Herald" or "Harbormaster". + // They can't have badges. + unset($events[$key]); + continue; + } + + $user_phids[$author_phid] = $author_phid; + } + + if (!$user_phids) { + return; + } + + $edges = id(new PhabricatorEdgeQuery()) + ->withSourcePHIDs($user_phids) + ->withEdgeTypes(array($badge_edge_type)); + $edges->execute(); + + $badge_phids = $edges->getDestinationPHIDs(); + if (!$badge_phids) { + return; + } + + $all_badges = id(new PhabricatorBadgesQuery()) + ->setViewer($viewer) + ->withPHIDs($badge_phids) + ->execute(); + $all_badges = mpull($all_badges, null, 'getPHID'); + + foreach ($events as $event) { + $author_phid = $event->getAuthorPHID(); + $event_phids = $edges->getDestinationPHIDs(array($author_phid)); + $badges = array_select_keys($all_badges, $event_phids); + + // TODO: Pick the "best" badges in some smart way. For now, just pick + // the first two. + $badges = array_slice($badges, 0, 2); + foreach ($badges as $badge) { + $badge_view = id(new PHUIBadgeMiniView()) + ->setIcon($badge->getIcon()) + ->setQuality($badge->getQuality()) + ->setHeader($badge->getName()) + ->setHref('/badges/view/'.$badge->getID()); + + $event->addBadge($badge_view); + } + } + } + }