@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.

Remove needRecipients and needAwards from Badges

Summary: Fixes T10798. Separates these two since they don't need to be combined and it allows for more flexibility / scalability.

Test Plan:
- Add Badge
- Edit Badge
- Add myself as Recipient
- Remove myself
- Go to my profile
- Award Badge from there
- Assign myself a badge, try to re-assign it, see validation error.

Also, validation errors on dialog forms are ugly.

{F3495630}

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T10798, T12270

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

+49 -97
-1
src/applications/badges/controller/PhabricatorBadgesAwardController.php
··· 22 22 $badges = id(new PhabricatorBadgesQuery()) 23 23 ->setViewer($viewer) 24 24 ->withPHIDs($badge_phids) 25 - ->needRecipients(true) 26 25 ->requireCapabilities( 27 26 array( 28 27 PhabricatorPolicyCapability::CAN_EDIT,
-14
src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php
··· 11 11 $badge = id(new PhabricatorBadgesQuery()) 12 12 ->setViewer($viewer) 13 13 ->withIDs(array($id)) 14 - ->needRecipients(true) 15 14 ->requireCapabilities( 16 15 array( 17 16 PhabricatorPolicyCapability::CAN_EDIT, ··· 23 22 } 24 23 25 24 $view_uri = $this->getApplicationURI('recipients/'.$badge->getID().'/'); 26 - $awards = $badge->getAwards(); 27 - $recipient_phids = mpull($awards, 'getRecipientPHID'); 28 25 29 26 if ($request->isFormPost()) { 30 27 $award_phids = array(); ··· 50 47 51 48 return id(new AphrontRedirectResponse()) 52 49 ->setURI($view_uri); 53 - } 54 - 55 - $recipient_phids = array_reverse($recipient_phids); 56 - $handles = $this->loadViewerHandles($recipient_phids); 57 - 58 - $state = array(); 59 - foreach ($handles as $handle) { 60 - $state[] = array( 61 - 'phid' => $handle->getPHID(), 62 - 'name' => $handle->getFullName(), 63 - ); 64 50 } 65 51 66 52 $can_edit = PhabricatorPolicyFilter::hasCapability(
+10 -7
src/applications/badges/controller/PhabricatorBadgesRecipientsController.php
··· 14 14 $badge = id(new PhabricatorBadgesQuery()) 15 15 ->setViewer($viewer) 16 16 ->withIDs(array($id)) 17 - ->needRecipients(true) 18 17 ->executeOne(); 19 18 if (!$badge) { 20 19 return new Aphront404Response(); 21 20 } 21 + $this->setBadge($badge); 22 22 23 - $this->setBadge($badge); 23 + $awards = id(new PhabricatorBadgesAwardQuery()) 24 + ->setViewer($viewer) 25 + ->withBadgePHIDs(array($badge->getPHID())) 26 + ->execute(); 27 + 28 + $recipient_phids = mpull($awards, 'getRecipientPHID'); 29 + $recipient_phids = array_reverse($recipient_phids); 30 + $handles = $this->loadViewerHandles($recipient_phids); 24 31 25 32 $crumbs = $this->buildApplicationCrumbs(); 26 33 $crumbs->addTextCrumb(pht('Recipients')); ··· 29 36 30 37 $header = $this->buildHeaderView(); 31 38 32 - $awards = $badge->getAwards(); 33 - $recipient_phids = mpull($awards, 'getRecipientPHID'); 34 - $recipient_phids = array_reverse($recipient_phids); 35 - $handles = $this->loadViewerHandles($recipient_phids); 36 - 37 39 $recipient_list = id(new PhabricatorBadgesRecipientsListView()) 38 40 ->setBadge($badge) 41 + ->setAwards($awards) 39 42 ->setHandles($handles) 40 43 ->setUser($viewer); 41 44
-8
src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php
··· 10 10 $badge = id(new PhabricatorBadgesQuery()) 11 11 ->setViewer($viewer) 12 12 ->withIDs(array($id)) 13 - ->needRecipients(true) 14 13 ->requireCapabilities( 15 14 array( 16 15 PhabricatorPolicyCapability::CAN_VIEW, ··· 21 20 return new Aphront404Response(); 22 21 } 23 22 24 - $awards = $badge->getAwards(); 25 - $recipient_phids = mpull($awards, 'getRecipientPHID'); 26 23 $remove_phid = $request->getStr('phid'); 27 - 28 - if (!in_array($remove_phid, $recipient_phids)) { 29 - return new Aphront404Response(); 30 - } 31 - 32 24 $view_uri = $this->getApplicationURI('recipients/'.$badge->getID().'/'); 33 25 34 26 if ($request->isFormPost()) {
+6 -8
src/applications/badges/query/PhabricatorBadgesAwardQuery.php
··· 9 9 10 10 11 11 protected function willFilterPage(array $awards) { 12 + $badge_phids = array(); 13 + foreach ($awards as $key => $award) { 14 + $badge_phids[] = $award->getBadgePHID(); 15 + } 16 + 12 17 $badges = id(new PhabricatorBadgesQuery()) 13 18 ->setViewer($this->getViewer()) 14 - ->withRecipientPHIDs(mpull($awards, null, 'getRecipientPHID')) 19 + ->withPHIDs($badge_phids) 15 20 ->execute(); 16 21 17 22 $badges = mpull($badges, null, 'getPHID'); 18 - 19 23 foreach ($awards as $key => $award) { 20 24 $award_badge = idx($badges, $award->getBadgePHID()); 21 - if ($award_badge === null) { 22 - $this->didRejectResult($award); 23 - unset($awards[$key]); 24 - continue; 25 - } 26 - 27 25 $award->attachBadge($award_badge); 28 26 } 29 27
-31
src/applications/badges/query/PhabricatorBadgesQuery.php
··· 7 7 private $phids; 8 8 private $qualities; 9 9 private $statuses; 10 - private $recipientPHIDs; 11 - 12 - private $needRecipients; 13 10 14 11 public function withIDs(array $ids) { 15 12 $this->ids = $ids; ··· 28 25 29 26 public function withStatuses(array $statuses) { 30 27 $this->statuses = $statuses; 31 - return $this; 32 - } 33 - 34 - public function withRecipientPHIDs(array $recipient_phids) { 35 - $this->recipientPHIDs = $recipient_phids; 36 28 return $this; 37 29 } 38 30 ··· 42 34 $ngrams); 43 35 } 44 36 45 - public function needRecipients($need_recipients) { 46 - $this->needRecipients = $need_recipients; 47 - return $this; 48 - } 49 - 50 37 protected function loadPage() { 51 38 return $this->loadStandardPage($this->newResultObject()); 52 39 } ··· 57 44 58 45 public function newResultObject() { 59 46 return new PhabricatorBadgesBadge(); 60 - } 61 - 62 - protected function didFilterPage(array $badges) { 63 - if ($this->needRecipients) { 64 - $query = id(new PhabricatorBadgesAwardQuery()) 65 - ->setViewer($this->getViewer()) 66 - ->withBadgePHIDs(mpull($badges, 'getPHID')) 67 - ->execute(); 68 - 69 - $awards = mgroup($query, 'getBadgePHID'); 70 - 71 - foreach ($badges as $badge) { 72 - $badge_awards = idx($awards, $badge->getPHID(), array()); 73 - $badge->attachAwards($badge_awards); 74 - } 75 - } 76 - 77 - return $badges; 78 47 } 79 48 80 49 protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
-11
src/applications/badges/storage/PhabricatorBadgesBadge.php
··· 20 20 protected $status; 21 21 protected $creatorPHID; 22 22 23 - private $awards = self::ATTACHABLE; 24 - 25 23 const STATUS_ACTIVE = 'open'; 26 24 const STATUS_ARCHIVED = 'closed'; 27 25 ··· 82 80 83 81 public function isArchived() { 84 82 return ($this->getStatus() == self::STATUS_ARCHIVED); 85 - } 86 - 87 - public function attachAwards(array $awards) { 88 - $this->awards = $awards; 89 - return $this; 90 - } 91 - 92 - public function getAwards() { 93 - return $this->assertAttached($this->awards); 94 83 } 95 84 96 85 public function getViewURI() {
+7 -1
src/applications/badges/view/PhabricatorBadgesRecipientsListView.php
··· 3 3 final class PhabricatorBadgesRecipientsListView extends AphrontView { 4 4 5 5 private $badge; 6 + private $awards; 6 7 private $handles; 7 8 8 9 public function setBadge(PhabricatorBadgesBadge $badge) { 9 10 $this->badge = $badge; 11 + return $this; 12 + } 13 + 14 + public function setAwards(array $awards) { 15 + $this->awards = $awards; 10 16 return $this; 11 17 } 12 18 ··· 20 26 21 27 $badge = $this->badge; 22 28 $handles = $this->handles; 23 - $awards = mpull($badge->getAwards(), null, 'getRecipientPHID'); 29 + $awards = mpull($this->awards, null, 'getRecipientPHID'); 24 30 25 31 $can_edit = PhabricatorPolicyFilter::hasCapability( 26 32 $viewer,
+21 -14
src/applications/badges/xaction/PhabricatorBadgesBadgeAwardTransaction.php
··· 6 6 const TRANSACTIONTYPE = 'badge.award'; 7 7 8 8 public function generateOldValue($object) { 9 - return mpull($object->getAwards(), 'getRecipientPHID'); 9 + return null; 10 10 } 11 11 12 12 public function applyExternalEffects($object, $value) { 13 - $awards = $object->getAwards(); 14 - $awards = mpull($awards, null, 'getRecipientPHID'); 15 - 16 13 foreach ($value as $phid) { 17 - $award = idx($awards, $phid); 18 - if (!$award) { 19 - $award = PhabricatorBadgesAward::initializeNewBadgesAward( 20 - $this->getActor(), 21 - $object, 22 - $phid); 23 - $award->save(); 24 - $awards[] = $award; 25 - } 14 + $award = PhabricatorBadgesAward::initializeNewBadgesAward( 15 + $this->getActor(), 16 + $object, 17 + $phid); 18 + $award->save(); 26 19 } 27 - $object->attachAwards($awards); 28 20 return; 29 21 } 30 22 ··· 71 63 } 72 64 73 65 foreach ($user_phids as $user_phid) { 66 + // Check if a valid user 74 67 $user = id(new PhabricatorPeopleQuery()) 75 68 ->setViewer($this->getActor()) 76 69 ->withPHIDs(array($user_phid)) ··· 80 73 pht( 81 74 'Recipient PHID "%s" is not a valid user PHID.', 82 75 $user_phid)); 76 + continue; 77 + } 78 + 79 + // Check if already awarded 80 + $award = id(new PhabricatorBadgesAwardQuery()) 81 + ->setViewer($this->getActor()) 82 + ->withRecipientPHIDs(array($user_phid)) 83 + ->withBadgePHIDs(array($object->getPHID())) 84 + ->executeOne(); 85 + if ($award) { 86 + $errors[] = $this->newInvalidError( 87 + pht( 88 + '%s has already been awarded this badge.', 89 + $user->getUsername())); 83 90 } 84 91 } 85 92 }
+5 -2
src/applications/badges/xaction/PhabricatorBadgesBadgeRevokeTransaction.php
··· 10 10 } 11 11 12 12 public function applyExternalEffects($object, $value) { 13 - $awards = $object->getAwards(); 13 + $awards = id(new PhabricatorBadgesAwardQuery()) 14 + ->setViewer($this->getActor()) 15 + ->withRecipientPHIDs($value) 16 + ->withBadgePHIDs(array($object->getPHID())) 17 + ->execute(); 14 18 $awards = mpull($awards, null, 'getRecipientPHID'); 15 19 16 20 foreach ($value as $phid) { 17 21 $awards[$phid]->delete(); 18 22 } 19 - $object->attachAwards($awards); 20 23 return; 21 24 } 22 25