mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 08:52:39 +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:
parent
65de9e9f5e
commit
aef2a39a81
7 changed files with 141 additions and 37 deletions
|
@ -4067,6 +4067,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorUnknownContentSource' => 'infrastructure/contentsource/PhabricatorUnknownContentSource.php',
|
'PhabricatorUnknownContentSource' => 'infrastructure/contentsource/PhabricatorUnknownContentSource.php',
|
||||||
'PhabricatorUnsubscribedFromObjectEdgeType' => 'applications/transactions/edges/PhabricatorUnsubscribedFromObjectEdgeType.php',
|
'PhabricatorUnsubscribedFromObjectEdgeType' => 'applications/transactions/edges/PhabricatorUnsubscribedFromObjectEdgeType.php',
|
||||||
'PhabricatorUser' => 'applications/people/storage/PhabricatorUser.php',
|
'PhabricatorUser' => 'applications/people/storage/PhabricatorUser.php',
|
||||||
|
'PhabricatorUserBadgesCacheType' => 'applications/people/cache/PhabricatorUserBadgesCacheType.php',
|
||||||
'PhabricatorUserBlurbField' => 'applications/people/customfield/PhabricatorUserBlurbField.php',
|
'PhabricatorUserBlurbField' => 'applications/people/customfield/PhabricatorUserBlurbField.php',
|
||||||
'PhabricatorUserCache' => 'applications/people/storage/PhabricatorUserCache.php',
|
'PhabricatorUserCache' => 'applications/people/storage/PhabricatorUserCache.php',
|
||||||
'PhabricatorUserCacheType' => 'applications/people/cache/PhabricatorUserCacheType.php',
|
'PhabricatorUserCacheType' => 'applications/people/cache/PhabricatorUserCacheType.php',
|
||||||
|
@ -9415,6 +9416,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorFulltextInterface',
|
'PhabricatorFulltextInterface',
|
||||||
'PhabricatorConduitResultInterface',
|
'PhabricatorConduitResultInterface',
|
||||||
),
|
),
|
||||||
|
'PhabricatorUserBadgesCacheType' => 'PhabricatorUserCacheType',
|
||||||
'PhabricatorUserBlurbField' => 'PhabricatorUserCustomField',
|
'PhabricatorUserBlurbField' => 'PhabricatorUserCustomField',
|
||||||
'PhabricatorUserCache' => 'PhabricatorUserDAO',
|
'PhabricatorUserCache' => 'PhabricatorUserDAO',
|
||||||
'PhabricatorUserCacheType' => 'Phobject',
|
'PhabricatorUserCacheType' => 'Phobject',
|
||||||
|
|
|
@ -118,4 +118,45 @@ final class PhabricatorBadgesEditor
|
||||||
return pht('[Badge]');
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
61
src/applications/people/cache/PhabricatorUserBadgesCacheType.php
vendored
Normal file
61
src/applications/people/cache/PhabricatorUserBadgesCacheType.php
vendored
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ final class PhabricatorPeopleQuery
|
||||||
private $needProfile;
|
private $needProfile;
|
||||||
private $needProfileImage;
|
private $needProfileImage;
|
||||||
private $needAvailability;
|
private $needAvailability;
|
||||||
|
private $needBadgeAwards;
|
||||||
private $cacheKeys = array();
|
private $cacheKeys = array();
|
||||||
|
|
||||||
public function withIDs(array $ids) {
|
public function withIDs(array $ids) {
|
||||||
|
@ -145,6 +146,18 @@ final class PhabricatorPeopleQuery
|
||||||
return $this;
|
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() {
|
public function newResultObject() {
|
||||||
return new PhabricatorUser();
|
return new PhabricatorUser();
|
||||||
}
|
}
|
||||||
|
|
|
@ -848,6 +848,11 @@ final class PhabricatorUser
|
||||||
return $this->requireCacheData($message_key);
|
return $this->requireCacheData($message_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getRecentBadgeAwards() {
|
||||||
|
$badges_key = PhabricatorUserBadgesCacheType::KEY_BADGES;
|
||||||
|
return $this->requireCacheData($badges_key);
|
||||||
|
}
|
||||||
|
|
||||||
public function getFullName() {
|
public function getFullName() {
|
||||||
if (strlen($this->getRealName())) {
|
if (strlen($this->getRealName())) {
|
||||||
return $this->getUsername().' ('.$this->getRealName().')';
|
return $this->getUsername().' ('.$this->getRealName().')';
|
||||||
|
|
|
@ -525,25 +525,18 @@ class PhabricatorApplicationTransactionCommentView extends AphrontView {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$awards = id(new PhabricatorBadgesAwardQuery())
|
// Pull Badges from UserCache
|
||||||
->setViewer($this->getUser())
|
$badges = $user->getRecentBadgeAwards();
|
||||||
->withRecipientPHIDs(array($user->getPHID()))
|
|
||||||
->withBadgeStatuses(array(PhabricatorBadgesBadge::STATUS_ACTIVE))
|
|
||||||
->setLimit(2)
|
|
||||||
->execute();
|
|
||||||
|
|
||||||
$badges = mpull($awards, 'getBadge');
|
|
||||||
|
|
||||||
$badge_view = null;
|
$badge_view = null;
|
||||||
if ($badges) {
|
if ($badges) {
|
||||||
$badge_list = array();
|
$badge_list = array();
|
||||||
foreach ($badges as $badge) {
|
foreach ($badges as $badge) {
|
||||||
$badge_view = id(new PHUIBadgeMiniView())
|
$badge_view = id(new PHUIBadgeMiniView())
|
||||||
->setIcon($badge->getIcon())
|
->setIcon($badge['icon'])
|
||||||
->setQuality($badge->getQuality())
|
->setQuality($badge['quality'])
|
||||||
->setHeader($badge->getName())
|
->setHeader($badge['name'])
|
||||||
->setTipDirection('E')
|
->setTipDirection('E')
|
||||||
->setHref('/badges/view/'.$badge->getID());
|
->setHref('/badges/view/'.$badge['id'].'/');
|
||||||
|
|
||||||
$badge_list[] = $badge_view;
|
$badge_list[] = $badge_view;
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,37 +243,26 @@ final class PHUITimelineView extends AphrontView {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$users = id(new PhabricatorPeopleQuery())
|
||||||
$awards = id(new PhabricatorBadgesAwardQuery())
|
->setViewer($viewer)
|
||||||
->setViewer($this->getViewer())
|
->withPHIDs($user_phids)
|
||||||
->withRecipientPHIDs($user_phids)
|
->needBadgeAwards(true)
|
||||||
->withBadgeStatuses(array(PhabricatorBadgesBadge::STATUS_ACTIVE))
|
|
||||||
->execute();
|
->execute();
|
||||||
|
$users = mpull($users, null, 'getPHID');
|
||||||
$awards = mgroup($awards, 'getRecipientPHID');
|
|
||||||
|
|
||||||
foreach ($events as $event) {
|
foreach ($events as $event) {
|
||||||
|
$user_phid = $event->getAuthorPHID();
|
||||||
$author_awards = idx($awards, $event->getAuthorPHID(), array());
|
if (!array_key_exists($user_phid, $users)) {
|
||||||
|
continue;
|
||||||
$badges = array();
|
|
||||||
foreach ($author_awards as $award) {
|
|
||||||
$badge = $award->getBadge();
|
|
||||||
$badges[$award->getBadgePHID()] = $badge;
|
|
||||||
}
|
}
|
||||||
|
$badges = $users[$user_phid]->getRecentBadgeAwards();
|
||||||
// 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) {
|
foreach ($badges as $badge) {
|
||||||
$badge_view = id(new PHUIBadgeMiniView())
|
$badge_view = id(new PHUIBadgeMiniView())
|
||||||
->setIcon($badge->getIcon())
|
->setIcon($badge['icon'])
|
||||||
->setQuality($badge->getQuality())
|
->setQuality($badge['quality'])
|
||||||
->setHeader($badge->getName())
|
->setHeader($badge['name'])
|
||||||
->setTipDirection('E')
|
->setTipDirection('E')
|
||||||
->setHref('/badges/view/'.$badge->getID());
|
->setHref('/badges/view/'.$badge['id'].'/');
|
||||||
|
|
||||||
$event->addBadge($badge_view);
|
$event->addBadge($badge_view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue