Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15282773
D15014.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
20 KB
Referenced Files
None
Subscribers
None
D15014.diff
View Options
diff --git a/resources/sql/autopatches/20160102.badges.award.sql b/resources/sql/autopatches/20160102.badges.award.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160102.badges.award.sql
@@ -0,0 +1,10 @@
+CREATE TABLE {$NAMESPACE}_badges.badges_award (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ badgePHID VARBINARY(64) NOT NULL,
+ recipientPHID VARBINARY(64) NOT NULL,
+ awarderPHID varbinary(64) NOT NULL,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+ UNIQUE KEY `key_badge` (badgePHID, recipientPHID),
+ KEY `key_recipient` (recipientPHID)
+) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
diff --git a/resources/sql/autopatches/20160323.badgemigrate.sql b/resources/sql/autopatches/20160323.badgemigrate.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20160323.badgemigrate.sql
@@ -0,0 +1,6 @@
+/* PhabricatorBadgeHasRecipientEdgeType::TYPECONST = 59 */
+
+INSERT IGNORE INTO {$NAMESPACE}_badges.badges_award
+ (badgePHID, recipientPHID, awarderPHID, dateCreated, dateModified)
+ SELECT src, dst, 'PHID-VOID-00000000000000000000', dateCreated, dateCreated
+ FROM {$NAMESPACE}_badges.edge WHERE type = 59;
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
@@ -1870,6 +1870,8 @@
'PhabricatorBadgeHasRecipientEdgeType' => 'applications/badges/edge/PhabricatorBadgeHasRecipientEdgeType.php',
'PhabricatorBadgesApplication' => 'applications/badges/application/PhabricatorBadgesApplication.php',
'PhabricatorBadgesArchiveController' => 'applications/badges/controller/PhabricatorBadgesArchiveController.php',
+ 'PhabricatorBadgesAward' => 'applications/badges/storage/PhabricatorBadgesAward.php',
+ 'PhabricatorBadgesAwardQuery' => 'applications/badges/query/PhabricatorBadgesAwardQuery.php',
'PhabricatorBadgesBadge' => 'applications/badges/storage/PhabricatorBadgesBadge.php',
'PhabricatorBadgesCommentController' => 'applications/badges/controller/PhabricatorBadgesCommentController.php',
'PhabricatorBadgesController' => 'applications/badges/controller/PhabricatorBadgesController.php',
@@ -6231,6 +6233,12 @@
'PhabricatorBadgeHasRecipientEdgeType' => 'PhabricatorEdgeType',
'PhabricatorBadgesApplication' => 'PhabricatorApplication',
'PhabricatorBadgesArchiveController' => 'PhabricatorBadgesController',
+ 'PhabricatorBadgesAward' => array(
+ 'PhabricatorBadgesDAO',
+ 'PhabricatorDestructibleInterface',
+ 'PhabricatorPolicyInterface',
+ ),
+ 'PhabricatorBadgesAwardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorBadgesBadge' => array(
'PhabricatorBadgesDAO',
'PhabricatorPolicyInterface',
diff --git a/src/applications/badges/controller/PhabricatorBadgesEditController.php b/src/applications/badges/controller/PhabricatorBadgesEditController.php
--- a/src/applications/badges/controller/PhabricatorBadgesEditController.php
+++ b/src/applications/badges/controller/PhabricatorBadgesEditController.php
@@ -2,7 +2,6 @@
final class PhabricatorBadgesEditController extends
PhabricatorBadgesController {
-
public function handleRequest(AphrontRequest $request) {
return id(new PhabricatorBadgesEditEngine())
->setController($this)
diff --git a/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php b/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php
--- a/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php
+++ b/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php
@@ -6,6 +6,7 @@
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
+ $xactions = array();
$badge = id(new PhabricatorBadgesQuery())
->setViewer($viewer)
@@ -21,30 +22,23 @@
return new Aphront404Response();
}
- $recipient_phids = $badge->getRecipientPHIDs();
$view_uri = $this->getApplicationURI('view/'.$badge->getID().'/');
+ $awards = $badge->getAwards();
+ $recipient_phids = mpull($awards, 'getRecipientPHID');
if ($request->isFormPost()) {
- $recipient_spec = array();
-
- $remove = $request->getStr('remove');
- if ($remove) {
- $recipient_spec['-'] = array_fuse(array($remove));
- }
+ $award_phids = array();
$add_recipients = $request->getArr('phids');
if ($add_recipients) {
- $recipient_spec['+'] = array_fuse($add_recipients);
+ foreach ($add_recipients as $phid) {
+ $award_phids[] = $phid;
+ }
}
- $type_recipient = PhabricatorBadgeHasRecipientEdgeType::EDGECONST;
-
- $xactions = array();
-
$xactions[] = id(new PhabricatorBadgesTransaction())
- ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
- ->setMetadataValue('edge:type', $type_recipient)
- ->setNewValue($recipient_spec);
+ ->setTransactionType(PhabricatorBadgesTransaction::TYPE_AWARD)
+ ->setNewValue($award_phids);
$editor = id(new PhabricatorBadgesEditor($badge))
->setActor($viewer)
diff --git a/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php b/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php
--- a/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php
+++ b/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php
@@ -21,7 +21,8 @@
return new Aphront404Response();
}
- $recipient_phids = $badge->getRecipientPHIDs();
+ $awards = $badge->getAwards();
+ $recipient_phids = mpull($awards, 'getRecipientPHID');
$remove_phid = $request->getStr('phid');
if (!in_array($remove_phid, $recipient_phids)) {
@@ -31,17 +32,10 @@
$view_uri = $this->getApplicationURI('view/'.$badge->getID().'/');
if ($request->isFormPost()) {
- $recipient_spec = array();
- $recipient_spec['-'] = array($remove_phid => $remove_phid);
-
- $type_recipient = PhabricatorBadgeHasRecipientEdgeType::EDGECONST;
-
$xactions = array();
-
$xactions[] = id(new PhabricatorBadgesTransaction())
- ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
- ->setMetadataValue('edge:type', $type_recipient)
- ->setNewValue($recipient_spec);
+ ->setTransactionType(PhabricatorBadgesTransaction::TYPE_REVOKE)
+ ->setNewValue(array($remove_phid));
$editor = id(new PhabricatorBadgesEditor($badge))
->setActor($viewer)
diff --git a/src/applications/badges/controller/PhabricatorBadgesViewController.php b/src/applications/badges/controller/PhabricatorBadgesViewController.php
--- a/src/applications/badges/controller/PhabricatorBadgesViewController.php
+++ b/src/applications/badges/controller/PhabricatorBadgesViewController.php
@@ -50,7 +50,8 @@
$badge,
new PhabricatorBadgesTransactionQuery());
- $recipient_phids = $badge->getRecipientPHIDs();
+ $awards = $badge->getAwards();
+ $recipient_phids = mpull($awards, 'getRecipientPHID');
$recipient_phids = array_reverse($recipient_phids);
$handles = $this->loadViewerHandles($recipient_phids);
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
@@ -20,6 +20,8 @@
$types[] = PhabricatorBadgesTransaction::TYPE_ICON;
$types[] = PhabricatorBadgesTransaction::TYPE_STATUS;
$types[] = PhabricatorBadgesTransaction::TYPE_QUALITY;
+ $types[] = PhabricatorBadgesTransaction::TYPE_AWARD;
+ $types[] = PhabricatorBadgesTransaction::TYPE_REVOKE;
$types[] = PhabricatorTransactions::TYPE_COMMENT;
$types[] = PhabricatorTransactions::TYPE_EDGE;
@@ -44,6 +46,11 @@
return $object->getQuality();
case PhabricatorBadgesTransaction::TYPE_STATUS:
return $object->getStatus();
+ case PhabricatorBadgesTransaction::TYPE_AWARD:
+ $award_phids = mpull($object->getAwards(), 'getRecipientPHID');
+ return $award_phids;
+ case PhabricatorBadgesTransaction::TYPE_REVOKE:
+ return null;
}
return parent::getCustomTransactionOldValue($object, $xaction);
@@ -60,6 +67,8 @@
case PhabricatorBadgesTransaction::TYPE_ICON:
case PhabricatorBadgesTransaction::TYPE_STATUS:
case PhabricatorBadgesTransaction::TYPE_QUALITY:
+ case PhabricatorBadgesTransaction::TYPE_AWARD:
+ case PhabricatorBadgesTransaction::TYPE_REVOKE:
return $xaction->getNewValue();
}
@@ -90,6 +99,9 @@
case PhabricatorBadgesTransaction::TYPE_STATUS:
$object->setStatus($xaction->getNewValue());
return;
+ case PhabricatorBadgesTransaction::TYPE_AWARD:
+ case PhabricatorBadgesTransaction::TYPE_REVOKE:
+ return;
}
return parent::applyCustomInternalTransaction($object, $xaction);
@@ -108,6 +120,34 @@
case PhabricatorBadgesTransaction::TYPE_STATUS:
case PhabricatorBadgesTransaction::TYPE_QUALITY:
return;
+ case PhabricatorBadgesTransaction::TYPE_REVOKE:
+ $revoked_recipient_phids = $xaction->getNewValue();
+ $awards = $object->getAwards();
+ $awards = mpull($awards, null, 'getRecipientPHID');
+
+ foreach ($revoked_recipient_phids as $phid) {
+ $awards[$phid]->delete();
+ }
+ $object->attachAwards($awards);
+ return;
+ case PhabricatorBadgesTransaction::TYPE_AWARD:
+ $recipient_phids = $xaction->getNewValue();
+ $awards = $object->getAwards();
+ $awards = mpull($awards, null, 'getRecipientPHID');
+
+ foreach ($recipient_phids as $phid) {
+ $award = idx($awards, $phid);
+ if (!$award) {
+ $award = PhabricatorBadgesAward::initializeNewBadgesAward(
+ $this->getActor(),
+ $object,
+ $phid);
+ $award->save();
+ $awards[] = $award;
+ }
+ }
+ $object->attachAwards($awards);
+ return;
}
return parent::applyCustomExternalTransaction($object, $xaction);
diff --git a/src/applications/badges/query/PhabricatorBadgesAwardQuery.php b/src/applications/badges/query/PhabricatorBadgesAwardQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/badges/query/PhabricatorBadgesAwardQuery.php
@@ -0,0 +1,87 @@
+<?php
+
+final class PhabricatorBadgesAwardQuery
+ extends PhabricatorCursorPagedPolicyAwareQuery {
+
+ private $badgePHIDs;
+ private $recipientPHIDs;
+ private $awarderPHIDs;
+
+
+ protected function willFilterPage(array $awards) {
+ $badges = id(new PhabricatorBadgesQuery())
+ ->setViewer($this->getViewer())
+ ->withRecipientPHIDs(mpull($awards, null, 'getRecipientPHID'))
+ ->execute();
+
+ $badges = mpull($badges, null, 'getPHID');
+
+ foreach ($awards as $key => $award) {
+ $award_badge = idx($badges, $award->getBadgePHID());
+ if ($award_badge === null) {
+ $this->didRejectResult($award);
+ unset($awards[$key]);
+ continue;
+ }
+
+ $award->attachBadge($award_badge);
+ }
+
+ return $awards;
+ }
+
+ public function withBadgePHIDs(array $phids) {
+ $this->badgePHIDs = $phids;
+ return $this;
+ }
+
+ public function withRecipientPHIDs(array $phids) {
+ $this->recipientPHIDs = $phids;
+ return $this;
+ }
+
+ public function withAwarderPHIDs(array $phids) {
+ $this->awarderPHIDs = $phids;
+ return $this;
+ }
+
+ protected function loadPage() {
+ return $this->loadStandardPage($this->newResultObject());
+ }
+
+ public function newResultObject() {
+ return new PhabricatorBadgesAward();
+ }
+
+ protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
+ $where = parent::buildWhereClauseParts($conn);
+
+ if ($this->badgePHIDs !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'badgePHID IN (%Ls)',
+ $this->badgePHIDs);
+ }
+
+ if ($this->recipientPHIDs !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'recipientPHID IN (%Ls)',
+ $this->recipientPHIDs);
+ }
+
+ if ($this->awarderPHIDs !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'awarderPHID IN (%Ls)',
+ $this->awarderPHIDs);
+ }
+
+ return $where;
+ }
+
+ public function getQueryApplicationClass() {
+ return 'PhabricatorBadgesApplication';
+ }
+
+}
diff --git a/src/applications/badges/query/PhabricatorBadgesQuery.php b/src/applications/badges/query/PhabricatorBadgesQuery.php
--- a/src/applications/badges/query/PhabricatorBadgesQuery.php
+++ b/src/applications/badges/query/PhabricatorBadgesQuery.php
@@ -50,22 +50,17 @@
}
protected function didFilterPage(array $badges) {
-
if ($this->needRecipients) {
- $edge_query = id(new PhabricatorEdgeQuery())
- ->withSourcePHIDs(mpull($badges, 'getPHID'))
- ->withEdgeTypes(
- array(
- PhabricatorBadgeHasRecipientEdgeType::EDGECONST,
- ));
- $edge_query->execute();
+ $query = id(new PhabricatorBadgesAwardQuery())
+ ->setViewer($this->getViewer())
+ ->withBadgePHIDs(mpull($badges, 'getPHID'))
+ ->execute();
+
+ $awards = mgroup($query, 'getBadgePHID');
foreach ($badges as $badge) {
- $phids = $edge_query->getDestinationPHIDs(
- array(
- $badge->getPHID(),
- ));
- $badge->attachRecipientPHIDs($phids);
+ $badge_awards = idx($awards, $badge->getPHID(), array());
+ $badge->attachAwards($badge_awards);
}
}
diff --git a/src/applications/badges/storage/PhabricatorBadgesAward.php b/src/applications/badges/storage/PhabricatorBadgesAward.php
new file mode 100644
--- /dev/null
+++ b/src/applications/badges/storage/PhabricatorBadgesAward.php
@@ -0,0 +1,83 @@
+<?php
+
+final class PhabricatorBadgesAward extends PhabricatorBadgesDAO
+ implements
+ PhabricatorDestructibleInterface,
+ PhabricatorPolicyInterface {
+
+ protected $badgePHID;
+ protected $recipientPHID;
+ protected $awarderPHID;
+
+ private $badge = self::ATTACHABLE;
+
+ public static function initializeNewBadgesAward(
+ PhabricatorUser $actor,
+ PhabricatorBadgesBadge $badge,
+ $recipient_phid) {
+ return id(new self())
+ ->setRecipientPHID($recipient_phid)
+ ->setBadgePHID($badge->getPHID())
+ ->setAwarderPHID($actor->getPHID())
+ ->attachBadge($badge);
+ }
+
+ protected function getConfiguration() {
+ return array(
+ self::CONFIG_KEY_SCHEMA => array(
+ 'key_badge' => array(
+ 'columns' => array('badgePHID', 'recipientPHID'),
+ 'unique' => true,
+ ),
+ 'key_recipient' => array(
+ 'columns' => array('recipientPHID'),
+ ),
+ ),
+ ) + parent::getConfiguration();
+ }
+
+ public function attachBadge(PhabricatorBadgesBadge $badge) {
+ $this->badge = $badge;
+ return $this;
+ }
+
+ public function getBadge() {
+ return $this->assertAttached($this->badge);
+ }
+
+
+/* -( PhabricatorDestructibleInterface )----------------------------------- */
+
+
+ public function destroyObjectPermanently(
+ PhabricatorDestructionEngine $engine) {
+
+ $this->openTransaction();
+ $this->delete();
+ $this->saveTransaction();
+ }
+
+
+/* -( PhabricatorPolicyInterface )----------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ );
+ }
+
+ public function getPolicy($capability) {
+ return $this->getBadge()->getPolicy($capability);
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+ return false;
+ }
+
+ public function describeAutomaticCapability($capability) {
+ return null;
+ }
+
+}
diff --git a/src/applications/badges/storage/PhabricatorBadgesBadge.php b/src/applications/badges/storage/PhabricatorBadgesBadge.php
--- a/src/applications/badges/storage/PhabricatorBadgesBadge.php
+++ b/src/applications/badges/storage/PhabricatorBadgesBadge.php
@@ -19,7 +19,7 @@
protected $status;
protected $creatorPHID;
- private $recipientPHIDs = self::ATTACHABLE;
+ private $awards = self::ATTACHABLE;
const STATUS_ACTIVE = 'open';
const STATUS_ARCHIVED = 'closed';
@@ -102,13 +102,13 @@
return ($this->getStatus() == self::STATUS_ARCHIVED);
}
- public function attachRecipientPHIDs(array $phids) {
- $this->recipientPHIDs = $phids;
+ public function attachAwards(array $awards) {
+ $this->awards = $awards;
return $this;
}
- public function getRecipientPHIDs() {
- return $this->assertAttached($this->recipientPHIDs);
+ public function getAwards() {
+ return $this->assertAttached($this->awards);
}
public function getViewURI() {
@@ -197,6 +197,15 @@
public function destroyObjectPermanently(
PhabricatorDestructionEngine $engine) {
+ $awards = id(new PhabricatorBadgesAwardQuery())
+ ->setViewer($engine->getViewer())
+ ->withBadgePHIDs(array($this->getPHID()))
+ ->execute();
+
+ foreach ($awards as $award) {
+ $engine->destroyObjectPermanently($award);
+ }
+
$this->openTransaction();
$this->delete();
$this->saveTransaction();
diff --git a/src/applications/badges/storage/PhabricatorBadgesTransaction.php b/src/applications/badges/storage/PhabricatorBadgesTransaction.php
--- a/src/applications/badges/storage/PhabricatorBadgesTransaction.php
+++ b/src/applications/badges/storage/PhabricatorBadgesTransaction.php
@@ -9,6 +9,8 @@
const TYPE_ICON = 'badges:icon';
const TYPE_STATUS = 'badges:status';
const TYPE_FLAVOR = 'badges:flavor';
+ const TYPE_AWARD = 'badges:award';
+ const TYPE_REVOKE = 'badges:revoke';
const MAILTAG_DETAILS = 'badges:details';
const MAILTAG_COMMENT = 'badges:comment';
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
@@ -155,20 +155,17 @@
}
if ($this->needBadges) {
- $edge_query = id(new PhabricatorEdgeQuery())
- ->withSourcePHIDs(mpull($users, 'getPHID'))
- ->withEdgeTypes(
- array(
- PhabricatorRecipientHasBadgeEdgeType::EDGECONST,
- ));
- $edge_query->execute();
+ $awards = id(new PhabricatorBadgesAwardQuery())
+ ->setViewer($this->getViewer())
+ ->withRecipientPHIDs(mpull($users, 'getPHID'))
+ ->execute();
+
+ $awards = mgroup($awards, 'getRecipientPHID');
foreach ($users as $user) {
- $phids = $edge_query->getDestinationPHIDs(
- array(
- $user->getPHID(),
- ));
- $user->attachBadgePHIDs($phids);
+ $user_awards = idx($awards, $user->getPHID(), array());
+ $badge_phids = mpull($user_awards, 'getBadgePHID');
+ $user->attachBadgePHIDs($badge_phids);
}
}
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
@@ -250,31 +250,28 @@
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)
- ->withStatuses(array(PhabricatorBadgesBadge::STATUS_ACTIVE))
+ $awards = id(new PhabricatorBadgesAwardQuery())
+ ->setViewer($this->getViewer())
+ ->withRecipientPHIDs($user_phids)
->execute();
- $all_badges = mpull($all_badges, null, 'getPHID');
+
+ $awards = mgroup($awards, 'getRecipientPHID');
foreach ($events as $event) {
- $author_phid = $event->getAuthorPHID();
- $event_phids = $edges->getDestinationPHIDs(array($author_phid));
- $badges = array_select_keys($all_badges, $event_phids);
+ $author_awards = idx($awards, $event->getAuthorPHID(), array());
+ $badges = array();
+ foreach ($author_awards as $award) {
+ $badge = $award->getBadge();
+ if ($badge->getStatus() == PhabricatorBadgesBadge::STATUS_ACTIVE) {
+ $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);
+
foreach ($badges as $badge) {
$badge_view = id(new PHUIBadgeMiniView())
->setIcon($badge->getIcon())
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 5, 2:13 AM (1 d, 3 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7223349
Default Alt Text
D15014.diff (20 KB)
Attached To
Mode
D15014: Converting badge recipients from Edge to BadgeAward table
Attached
Detach File
Event Timeline
Log In to Comment