1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 08:42:41 +01:00

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
This commit is contained in:
Chad Little 2017-03-17 10:32:07 -07:00
parent 65de9e9f5e
commit aef2a39a81
7 changed files with 141 additions and 37 deletions

View file

@ -4067,6 +4067,7 @@ phutil_register_library_map(array(
'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 @@ phutil_register_library_map(array(
'PhabricatorFulltextInterface',
'PhabricatorConduitResultInterface',
),
'PhabricatorUserBadgesCacheType' => 'PhabricatorUserCacheType',
'PhabricatorUserBlurbField' => 'PhabricatorUserCustomField',
'PhabricatorUserCache' => 'PhabricatorUserDAO',
'PhabricatorUserCacheType' => 'Phobject',

View file

@ -118,4 +118,45 @@ final class PhabricatorBadgesEditor
return pht('[Badge]');
}
protected function applyFinalEffects(
PhabricatorLiskDAO $object,
array $xactions) {
$badge_phid = $object->getPHID();
$user_phids = array();
$clear_everything = false;
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorBadgesBadgeAwardTransaction::TRANSACTIONTYPE:
case PhabricatorBadgesBadgeRevokeTransaction::TRANSACTIONTYPE:
foreach ($xaction->getNewValue() as $user_phid) {
$user_phids[] = $user_phid;
}
break;
default:
$clear_everything = true;
break;
}
}
if ($clear_everything) {
$awards = id(new PhabricatorBadgesAwardQuery())
->setViewer($this->getActor())
->withBadgePHIDs(array($badge_phid))
->execute();
foreach ($awards as $award) {
$user_phids[] = $award->getRecipientPHID();
}
}
if ($user_phids) {
PhabricatorUserCache::clearCaches(
PhabricatorUserBadgesCacheType::KEY_BADGES,
$user_phids);
}
return $xactions;
}
}

View file

@ -0,0 +1,61 @@
<?php
final class PhabricatorUserBadgesCacheType
extends PhabricatorUserCacheType {
const CACHETYPE = 'badges.award';
const KEY_BADGES = 'user.badge.award.v1';
const BADGE_COUNT = 2;
public function getAutoloadKeys() {
return array(
self::KEY_BADGES,
);
}
public function canManageKey($key) {
return ($key === self::KEY_BADGES);
}
public function getValueFromStorage($value) {
return phutil_json_decode($value);
}
public function newValueForUsers($key, array $users) {
if (!$users) {
return array();
}
$user_phids = mpull($users, 'getPHID');
$results = array();
foreach ($user_phids as $user_phid) {
$awards = id(new PhabricatorBadgesAwardQuery())
->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;
}
}

View file

@ -24,6 +24,7 @@ final class PhabricatorPeopleQuery
private $needProfile;
private $needProfileImage;
private $needAvailability;
private $needBadgeAwards;
private $cacheKeys = array();
public function withIDs(array $ids) {
@ -145,6 +146,18 @@ final class PhabricatorPeopleQuery
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();
}

View file

@ -848,6 +848,11 @@ final class PhabricatorUser
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().')';

View file

@ -525,25 +525,18 @@ class PhabricatorApplicationTransactionCommentView extends AphrontView {
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;
}

View file

@ -243,37 +243,26 @@ final class PHUITimelineView extends AphrontView {
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;
$user_phid = $event->getAuthorPHID();
if (!array_key_exists($user_phid, $users)) {
continue;
}
// TODO: Pick the "best" badges in some smart way. For now, just pick
// the first two.
$badges = array_slice($badges, 0, 2);
$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);
}
}