@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add Badges to UserCache

Summary: Ref T12270. Builds out a BadgeCache for PhabricatorUser, primarily for Timeline, potentially feed? This should still work if we later let people pick which two, just switch query in BadgeCache.

Test Plan: Give out badges, test timeline for displaying badges from handles and without queries. Revoke a badge, see cache change.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T12270

Differential Revision: https://secure.phabricator.com/D17503

+141 -37
+2
src/__phutil_library_map__.php
··· 4067 4067 'PhabricatorUnknownContentSource' => 'infrastructure/contentsource/PhabricatorUnknownContentSource.php', 4068 4068 'PhabricatorUnsubscribedFromObjectEdgeType' => 'applications/transactions/edges/PhabricatorUnsubscribedFromObjectEdgeType.php', 4069 4069 'PhabricatorUser' => 'applications/people/storage/PhabricatorUser.php', 4070 + 'PhabricatorUserBadgesCacheType' => 'applications/people/cache/PhabricatorUserBadgesCacheType.php', 4070 4071 'PhabricatorUserBlurbField' => 'applications/people/customfield/PhabricatorUserBlurbField.php', 4071 4072 'PhabricatorUserCache' => 'applications/people/storage/PhabricatorUserCache.php', 4072 4073 'PhabricatorUserCacheType' => 'applications/people/cache/PhabricatorUserCacheType.php', ··· 9415 9416 'PhabricatorFulltextInterface', 9416 9417 'PhabricatorConduitResultInterface', 9417 9418 ), 9419 + 'PhabricatorUserBadgesCacheType' => 'PhabricatorUserCacheType', 9418 9420 'PhabricatorUserBlurbField' => 'PhabricatorUserCustomField', 9419 9421 'PhabricatorUserCache' => 'PhabricatorUserDAO', 9420 9422 'PhabricatorUserCacheType' => 'Phobject',
+41
src/applications/badges/editor/PhabricatorBadgesEditor.php
··· 118 118 return pht('[Badge]'); 119 119 } 120 120 121 + protected function applyFinalEffects( 122 + PhabricatorLiskDAO $object, 123 + array $xactions) { 124 + 125 + $badge_phid = $object->getPHID(); 126 + $user_phids = array(); 127 + $clear_everything = false; 128 + 129 + foreach ($xactions as $xaction) { 130 + switch ($xaction->getTransactionType()) { 131 + case PhabricatorBadgesBadgeAwardTransaction::TRANSACTIONTYPE: 132 + case PhabricatorBadgesBadgeRevokeTransaction::TRANSACTIONTYPE: 133 + foreach ($xaction->getNewValue() as $user_phid) { 134 + $user_phids[] = $user_phid; 135 + } 136 + break; 137 + default: 138 + $clear_everything = true; 139 + break; 140 + } 141 + } 142 + 143 + if ($clear_everything) { 144 + $awards = id(new PhabricatorBadgesAwardQuery()) 145 + ->setViewer($this->getActor()) 146 + ->withBadgePHIDs(array($badge_phid)) 147 + ->execute(); 148 + foreach ($awards as $award) { 149 + $user_phids[] = $award->getRecipientPHID(); 150 + } 151 + } 152 + 153 + if ($user_phids) { 154 + PhabricatorUserCache::clearCaches( 155 + PhabricatorUserBadgesCacheType::KEY_BADGES, 156 + $user_phids); 157 + } 158 + 159 + return $xactions; 160 + } 161 + 121 162 }
+61
src/applications/people/cache/PhabricatorUserBadgesCacheType.php
··· 1 + <?php 2 + 3 + final class PhabricatorUserBadgesCacheType 4 + extends PhabricatorUserCacheType { 5 + 6 + const CACHETYPE = 'badges.award'; 7 + 8 + const KEY_BADGES = 'user.badge.award.v1'; 9 + 10 + const BADGE_COUNT = 2; 11 + 12 + public function getAutoloadKeys() { 13 + return array( 14 + self::KEY_BADGES, 15 + ); 16 + } 17 + 18 + public function canManageKey($key) { 19 + return ($key === self::KEY_BADGES); 20 + } 21 + 22 + public function getValueFromStorage($value) { 23 + return phutil_json_decode($value); 24 + } 25 + 26 + public function newValueForUsers($key, array $users) { 27 + if (!$users) { 28 + return array(); 29 + } 30 + 31 + $user_phids = mpull($users, 'getPHID'); 32 + 33 + $results = array(); 34 + foreach ($user_phids as $user_phid) { 35 + $awards = id(new PhabricatorBadgesAwardQuery()) 36 + ->setViewer($this->getViewer()) 37 + ->withRecipientPHIDs(array($user_phid)) 38 + ->withBadgeStatuses(array(PhabricatorBadgesBadge::STATUS_ACTIVE)) 39 + ->setLimit(self::BADGE_COUNT) 40 + ->execute(); 41 + 42 + $award_data = array(); 43 + if ($awards) { 44 + foreach ($awards as $award) { 45 + $badge = $award->getBadge(); 46 + $award_data[] = array( 47 + 'icon' => $badge->getIcon(), 48 + 'name' => $badge->getName(), 49 + 'quality' => $badge->getQuality(), 50 + 'id' => $badge->getID(), 51 + ); 52 + } 53 + } 54 + $results[$user_phid] = phutil_json_encode($award_data); 55 + 56 + } 57 + 58 + return $results; 59 + } 60 + 61 + }
+13
src/applications/people/query/PhabricatorPeopleQuery.php
··· 24 24 private $needProfile; 25 25 private $needProfileImage; 26 26 private $needAvailability; 27 + private $needBadgeAwards; 27 28 private $cacheKeys = array(); 28 29 29 30 public function withIDs(array $ids) { ··· 135 136 136 137 public function needUserSettings($need) { 137 138 $cache_key = PhabricatorUserPreferencesCacheType::KEY_PREFERENCES; 139 + 140 + if ($need) { 141 + $this->cacheKeys[$cache_key] = true; 142 + } else { 143 + unset($this->cacheKeys[$cache_key]); 144 + } 145 + 146 + return $this; 147 + } 148 + 149 + public function needBadgeAwards($need) { 150 + $cache_key = PhabricatorUserBadgesCacheType::KEY_BADGES; 138 151 139 152 if ($need) { 140 153 $this->cacheKeys[$cache_key] = true;
+5
src/applications/people/storage/PhabricatorUser.php
··· 848 848 return $this->requireCacheData($message_key); 849 849 } 850 850 851 + public function getRecentBadgeAwards() { 852 + $badges_key = PhabricatorUserBadgesCacheType::KEY_BADGES; 853 + return $this->requireCacheData($badges_key); 854 + } 855 + 851 856 public function getFullName() { 852 857 if (strlen($this->getRealName())) { 853 858 return $this->getUsername().' ('.$this->getRealName().')';
+6 -13
src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php
··· 525 525 return null; 526 526 } 527 527 528 - $awards = id(new PhabricatorBadgesAwardQuery()) 529 - ->setViewer($this->getUser()) 530 - ->withRecipientPHIDs(array($user->getPHID())) 531 - ->withBadgeStatuses(array(PhabricatorBadgesBadge::STATUS_ACTIVE)) 532 - ->setLimit(2) 533 - ->execute(); 534 - 535 - $badges = mpull($awards, 'getBadge'); 536 - 528 + // Pull Badges from UserCache 529 + $badges = $user->getRecentBadgeAwards(); 537 530 $badge_view = null; 538 531 if ($badges) { 539 532 $badge_list = array(); 540 533 foreach ($badges as $badge) { 541 534 $badge_view = id(new PHUIBadgeMiniView()) 542 - ->setIcon($badge->getIcon()) 543 - ->setQuality($badge->getQuality()) 544 - ->setHeader($badge->getName()) 535 + ->setIcon($badge['icon']) 536 + ->setQuality($badge['quality']) 537 + ->setHeader($badge['name']) 545 538 ->setTipDirection('E') 546 - ->setHref('/badges/view/'.$badge->getID()); 539 + ->setHref('/badges/view/'.$badge['id'].'/'); 547 540 548 541 $badge_list[] = $badge_view; 549 542 }
+13 -24
src/view/phui/PHUITimelineView.php
··· 243 243 return; 244 244 } 245 245 246 - 247 - $awards = id(new PhabricatorBadgesAwardQuery()) 248 - ->setViewer($this->getViewer()) 249 - ->withRecipientPHIDs($user_phids) 250 - ->withBadgeStatuses(array(PhabricatorBadgesBadge::STATUS_ACTIVE)) 246 + $users = id(new PhabricatorPeopleQuery()) 247 + ->setViewer($viewer) 248 + ->withPHIDs($user_phids) 249 + ->needBadgeAwards(true) 251 250 ->execute(); 252 - 253 - $awards = mgroup($awards, 'getRecipientPHID'); 251 + $users = mpull($users, null, 'getPHID'); 254 252 255 253 foreach ($events as $event) { 256 - 257 - $author_awards = idx($awards, $event->getAuthorPHID(), array()); 258 - 259 - $badges = array(); 260 - foreach ($author_awards as $award) { 261 - $badge = $award->getBadge(); 262 - $badges[$award->getBadgePHID()] = $badge; 254 + $user_phid = $event->getAuthorPHID(); 255 + if (!array_key_exists($user_phid, $users)) { 256 + continue; 263 257 } 264 - 265 - // TODO: Pick the "best" badges in some smart way. For now, just pick 266 - // the first two. 267 - $badges = array_slice($badges, 0, 2); 268 - 258 + $badges = $users[$user_phid]->getRecentBadgeAwards(); 269 259 foreach ($badges as $badge) { 270 260 $badge_view = id(new PHUIBadgeMiniView()) 271 - ->setIcon($badge->getIcon()) 272 - ->setQuality($badge->getQuality()) 273 - ->setHeader($badge->getName()) 261 + ->setIcon($badge['icon']) 262 + ->setQuality($badge['quality']) 263 + ->setHeader($badge['name']) 274 264 ->setTipDirection('E') 275 - ->setHref('/badges/view/'.$badge->getID()); 276 - 265 + ->setHref('/badges/view/'.$badge['id'].'/'); 277 266 $event->addBadge($badge_view); 278 267 } 279 268 }