diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -4067,6 +4067,7 @@ 'PhabricatorUnknownContentSource' => 'infrastructure/contentsource/PhabricatorUnknownContentSource.php', 'PhabricatorUnsubscribedFromObjectEdgeType' => 'applications/transactions/edges/PhabricatorUnsubscribedFromObjectEdgeType.php', 'PhabricatorUser' => 'applications/people/storage/PhabricatorUser.php', + 'PhabricatorUserBadgesCacheType' => 'applications/people/cache/PhabricatorUserBadgesCacheType.php', 'PhabricatorUserBlurbField' => 'applications/people/customfield/PhabricatorUserBlurbField.php', 'PhabricatorUserCache' => 'applications/people/storage/PhabricatorUserCache.php', 'PhabricatorUserCacheType' => 'applications/people/cache/PhabricatorUserCacheType.php', @@ -9415,6 +9416,7 @@ 'PhabricatorFulltextInterface', 'PhabricatorConduitResultInterface', ), + 'PhabricatorUserBadgesCacheType' => 'PhabricatorUserCacheType', 'PhabricatorUserBlurbField' => 'PhabricatorUserCustomField', 'PhabricatorUserCache' => 'PhabricatorUserDAO', 'PhabricatorUserCacheType' => 'Phobject', diff --git a/src/applications/badges/editor/PhabricatorBadgesEditor.php b/src/applications/badges/editor/PhabricatorBadgesEditor.php --- a/src/applications/badges/editor/PhabricatorBadgesEditor.php +++ b/src/applications/badges/editor/PhabricatorBadgesEditor.php @@ -118,4 +118,35 @@ return pht('[Badge]'); } + protected function applyFinalEffects( + PhabricatorLiskDAO $object, + array $xactions) { + + $badge_phid = $object->getPHID(); + + foreach ($xactions as $xaction) { + switch ($xaction->getTransactionType()) { + case PhabricatorBadgesBadgeAwardTransaction::TRANSACTIONTYPE: + case PhabricatorBadgesBadgeRevokeTransaction::TRANSACTIONTYPE: + $user_phids = $xaction->getNewValue(); + break; + default: + $user_phids = id(new PhabricatorBadgesAwardQuery()) + ->setViewer($this->getActor()) + ->withBadgePHIDs(array($badge_phid)) + ->execute(); + $user_phids = mpull($user_phids, 'getRecipientPHID'); + break; + } + } + + foreach ($user_phids as $user_phid) { + PhabricatorUserCache::clearCache( + PhabricatorUserBadgesCacheType::KEY_BADGES, + $user_phid); + } + + return $xactions; + } + } diff --git a/src/applications/people/cache/PhabricatorUserBadgesCacheType.php b/src/applications/people/cache/PhabricatorUserBadgesCacheType.php new file mode 100644 --- /dev/null +++ b/src/applications/people/cache/PhabricatorUserBadgesCacheType.php @@ -0,0 +1,61 @@ +setViewer($this->getViewer()) + ->withRecipientPHIDs(array($user_phid)) + ->withBadgeStatuses(array(PhabricatorBadgesBadge::STATUS_ACTIVE)) + ->setLimit(self::BADGE_COUNT) + ->execute(); + + $award_data = array(); + if ($awards) { + foreach ($awards as $award) { + $badge = $award->getBadge(); + $award_data[] = array( + 'icon' => $badge->getIcon(), + 'name' => $badge->getName(), + 'quality' => $badge->getQuality(), + 'id' => $badge->getID(), + ); + } + } + $results[$user_phid] = phutil_json_encode($award_data); + + } + + return $results; + } + +} diff --git a/src/applications/people/query/PhabricatorPeopleQuery.php b/src/applications/people/query/PhabricatorPeopleQuery.php --- a/src/applications/people/query/PhabricatorPeopleQuery.php +++ b/src/applications/people/query/PhabricatorPeopleQuery.php @@ -24,6 +24,7 @@ private $needProfile; private $needProfileImage; private $needAvailability; + private $needBadgeAwards; private $cacheKeys = array(); public function withIDs(array $ids) { @@ -145,6 +146,18 @@ return $this; } + public function needBadgeAwards($need) { + $cache_key = PhabricatorUserBadgesCacheType::KEY_BADGES; + + if ($need) { + $this->cacheKeys[$cache_key] = true; + } else { + unset($this->cacheKeys[$cache_key]); + } + + return $this; + } + public function newResultObject() { return new PhabricatorUser(); } diff --git a/src/applications/people/storage/PhabricatorUser.php b/src/applications/people/storage/PhabricatorUser.php --- a/src/applications/people/storage/PhabricatorUser.php +++ b/src/applications/people/storage/PhabricatorUser.php @@ -848,6 +848,11 @@ return $this->requireCacheData($message_key); } + public function getRecentBadgeAwards() { + $badges_key = PhabricatorUserBadgesCacheType::KEY_BADGES; + return $this->requireCacheData($badges_key); + } + public function getFullName() { if (strlen($this->getRealName())) { return $this->getUsername().' ('.$this->getRealName().')'; diff --git a/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php b/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php --- a/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php +++ b/src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php @@ -525,25 +525,18 @@ return null; } - $awards = id(new PhabricatorBadgesAwardQuery()) - ->setViewer($this->getUser()) - ->withRecipientPHIDs(array($user->getPHID())) - ->withBadgeStatuses(array(PhabricatorBadgesBadge::STATUS_ACTIVE)) - ->setLimit(2) - ->execute(); - - $badges = mpull($awards, 'getBadge'); - + // Pull Badges from UserCache + $badges = $user->getRecentBadgeAwards(); $badge_view = null; if ($badges) { $badge_list = array(); foreach ($badges as $badge) { $badge_view = id(new PHUIBadgeMiniView()) - ->setIcon($badge->getIcon()) - ->setQuality($badge->getQuality()) - ->setHeader($badge->getName()) + ->setIcon($badge['icon']) + ->setQuality($badge['quality']) + ->setHeader($badge['name']) ->setTipDirection('E') - ->setHref('/badges/view/'.$badge->getID()); + ->setHref('/badges/view/'.$badge['id'].'/'); $badge_list[] = $badge_view; } 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 @@ -243,37 +243,23 @@ return; } - - $awards = id(new PhabricatorBadgesAwardQuery()) - ->setViewer($this->getViewer()) - ->withRecipientPHIDs($user_phids) - ->withBadgeStatuses(array(PhabricatorBadgesBadge::STATUS_ACTIVE)) + $users = id(new PhabricatorPeopleQuery()) + ->setViewer($viewer) + ->withPHIDs($user_phids) + ->needBadgeAwards(true) ->execute(); - - $awards = mgroup($awards, 'getRecipientPHID'); + $users = mpull($users, null, 'getPHID'); foreach ($events as $event) { - - $author_awards = idx($awards, $event->getAuthorPHID(), array()); - - $badges = array(); - foreach ($author_awards as $award) { - $badge = $award->getBadge(); - $badges[$award->getBadgePHID()] = $badge; - } - - // TODO: Pick the "best" badges in some smart way. For now, just pick - // the first two. - $badges = array_slice($badges, 0, 2); - + $user_phid = $event->getAuthorPHID(); + $badges = $users[$user_phid]->getRecentBadgeAwards(); foreach ($badges as $badge) { $badge_view = id(new PHUIBadgeMiniView()) - ->setIcon($badge->getIcon()) - ->setQuality($badge->getQuality()) - ->setHeader($badge->getName()) + ->setIcon($badge['icon']) + ->setQuality($badge['quality']) + ->setHeader($badge['name']) ->setTipDirection('E') - ->setHref('/badges/view/'.$badge->getID()); - + ->setHref('/badges/view/'.$badge['id'].'/'); $event->addBadge($badge_view); } }