diff --git a/src/applications/badges/controller/PhabricatorBadgesAwardController.php b/src/applications/badges/controller/PhabricatorBadgesAwardController.php index e934e4f2a1..63af70b791 100644 --- a/src/applications/badges/controller/PhabricatorBadgesAwardController.php +++ b/src/applications/badges/controller/PhabricatorBadgesAwardController.php @@ -1,78 +1,77 @@ getViewer(); $id = $request->getURIData('id'); $user = id(new PhabricatorPeopleQuery()) ->setViewer($viewer) ->withIDs(array($id)) ->executeOne(); if (!$user) { return new Aphront404Response(); } $view_uri = '/people/badges/'.$user->getID().'/'; if ($request->isFormPost()) { $badge_phids = $request->getArr('badgePHIDs'); $badges = id(new PhabricatorBadgesQuery()) ->setViewer($viewer) ->withPHIDs($badge_phids) - ->needRecipients(true) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_EDIT, PhabricatorPolicyCapability::CAN_VIEW, )) ->execute(); if (!$badges) { return new Aphront404Response(); } $award_phids = array($user->getPHID()); foreach ($badges as $badge) { $xactions = array(); $xactions[] = id(new PhabricatorBadgesTransaction()) ->setTransactionType( PhabricatorBadgesBadgeAwardTransaction::TRANSACTIONTYPE) ->setNewValue($award_phids); $editor = id(new PhabricatorBadgesEditor()) ->setActor($viewer) ->setContentSourceFromRequest($request) ->setContinueOnNoEffect(true) ->setContinueOnMissingFields(true) ->applyTransactions($badge, $xactions); } return id(new AphrontRedirectResponse()) ->setURI($view_uri); } $form = id(new AphrontFormView()) ->setUser($viewer) ->appendControl( id(new AphrontFormTokenizerControl()) ->setLabel(pht('Badge')) ->setName('badgePHIDs') ->setDatasource( id(new PhabricatorBadgesDatasource()) ->setParameters( array( 'recipientPHID' => $user->getPHID(), )))); $dialog = $this->newDialog() ->setTitle(pht('Award Badge')) ->appendForm($form) ->addCancelButton($view_uri) ->addSubmitButton(pht('Award')); return $dialog; } } diff --git a/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php b/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php index 9045869fc8..ce437f1a5d 100644 --- a/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php +++ b/src/applications/badges/controller/PhabricatorBadgesEditRecipientsController.php @@ -1,97 +1,83 @@ getViewer(); $id = $request->getURIData('id'); $xactions = array(); $badge = id(new PhabricatorBadgesQuery()) ->setViewer($viewer) ->withIDs(array($id)) - ->needRecipients(true) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_EDIT, PhabricatorPolicyCapability::CAN_VIEW, )) ->executeOne(); if (!$badge) { return new Aphront404Response(); } $view_uri = $this->getApplicationURI('recipients/'.$badge->getID().'/'); - $awards = $badge->getAwards(); - $recipient_phids = mpull($awards, 'getRecipientPHID'); if ($request->isFormPost()) { $award_phids = array(); $add_recipients = $request->getArr('phids'); if ($add_recipients) { foreach ($add_recipients as $phid) { $award_phids[] = $phid; } } $xactions[] = id(new PhabricatorBadgesTransaction()) ->setTransactionType( PhabricatorBadgesBadgeAwardTransaction::TRANSACTIONTYPE) ->setNewValue($award_phids); $editor = id(new PhabricatorBadgesEditor()) ->setActor($viewer) ->setContentSourceFromRequest($request) ->setContinueOnNoEffect(true) ->setContinueOnMissingFields(true) ->applyTransactions($badge, $xactions); return id(new AphrontRedirectResponse()) ->setURI($view_uri); } - $recipient_phids = array_reverse($recipient_phids); - $handles = $this->loadViewerHandles($recipient_phids); - - $state = array(); - foreach ($handles as $handle) { - $state[] = array( - 'phid' => $handle->getPHID(), - 'name' => $handle->getFullName(), - ); - } - $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $badge, PhabricatorPolicyCapability::CAN_EDIT); $form_box = null; $title = pht('Add Recipient'); if ($can_edit) { $header_name = pht('Edit Recipients'); $form = new AphrontFormView(); $form ->setUser($viewer) ->setFullWidth(true) ->appendControl( id(new AphrontFormTokenizerControl()) ->setName('phids') ->setLabel(pht('Recipients')) ->setDatasource(new PhabricatorPeopleDatasource())); } $dialog = id(new AphrontDialogView()) ->setUser($viewer) ->setTitle(pht('Add Recipients')) ->appendForm($form) ->addCancelButton($view_uri) ->addSubmitButton(pht('Add Recipients')); return $dialog; } } diff --git a/src/applications/badges/controller/PhabricatorBadgesRecipientsController.php b/src/applications/badges/controller/PhabricatorBadgesRecipientsController.php index 2b6bb6b10a..a28a37ac30 100644 --- a/src/applications/badges/controller/PhabricatorBadgesRecipientsController.php +++ b/src/applications/badges/controller/PhabricatorBadgesRecipientsController.php @@ -1,58 +1,61 @@ getViewer(); $id = $request->getURIData('id'); $badge = id(new PhabricatorBadgesQuery()) ->setViewer($viewer) ->withIDs(array($id)) - ->needRecipients(true) ->executeOne(); if (!$badge) { return new Aphront404Response(); } - $this->setBadge($badge); + $awards = id(new PhabricatorBadgesAwardQuery()) + ->setViewer($viewer) + ->withBadgePHIDs(array($badge->getPHID())) + ->execute(); + + $recipient_phids = mpull($awards, 'getRecipientPHID'); + $recipient_phids = array_reverse($recipient_phids); + $handles = $this->loadViewerHandles($recipient_phids); + $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Recipients')); $crumbs->setBorder(true); $title = $badge->getName(); $header = $this->buildHeaderView(); - $awards = $badge->getAwards(); - $recipient_phids = mpull($awards, 'getRecipientPHID'); - $recipient_phids = array_reverse($recipient_phids); - $handles = $this->loadViewerHandles($recipient_phids); - $recipient_list = id(new PhabricatorBadgesRecipientsListView()) ->setBadge($badge) + ->setAwards($awards) ->setHandles($handles) ->setUser($viewer); $view = id(new PHUITwoColumnView()) ->setHeader($header) ->setFooter(array( $recipient_list, )); $navigation = $this->buildSideNavView('recipients'); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) ->setPageObjectPHIDs(array($badge->getPHID())) ->setNavigation($navigation) ->appendChild($view); } } diff --git a/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php b/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php index e6638b745c..4901bf955d 100644 --- a/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php +++ b/src/applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php @@ -1,71 +1,63 @@ getViewer(); $id = $request->getURIData('id'); $badge = id(new PhabricatorBadgesQuery()) ->setViewer($viewer) ->withIDs(array($id)) - ->needRecipients(true) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, )) ->executeOne(); if (!$badge) { return new Aphront404Response(); } - $awards = $badge->getAwards(); - $recipient_phids = mpull($awards, 'getRecipientPHID'); $remove_phid = $request->getStr('phid'); - - if (!in_array($remove_phid, $recipient_phids)) { - return new Aphront404Response(); - } - $view_uri = $this->getApplicationURI('recipients/'.$badge->getID().'/'); if ($request->isFormPost()) { $xactions = array(); $xactions[] = id(new PhabricatorBadgesTransaction()) ->setTransactionType( PhabricatorBadgesBadgeRevokeTransaction::TRANSACTIONTYPE) ->setNewValue(array($remove_phid)); $editor = id(new PhabricatorBadgesEditor()) ->setActor($viewer) ->setContentSourceFromRequest($request) ->setContinueOnNoEffect(true) ->setContinueOnMissingFields(true) ->applyTransactions($badge, $xactions); return id(new AphrontRedirectResponse()) ->setURI($view_uri); } $handle = id(new PhabricatorHandleQuery()) ->setViewer($viewer) ->withPHIDs(array($remove_phid)) ->executeOne(); $dialog = id(new AphrontDialogView()) ->setUser($viewer) ->setTitle(pht('Really Revoke Badge?')) ->appendParagraph( pht( 'Really revoke the badge "%s" from %s?', phutil_tag('strong', array(), $badge->getName()), phutil_tag('strong', array(), $handle->getName()))) ->addCancelButton($view_uri) ->addSubmitButton(pht('Revoke Badge')); return $dialog; } } diff --git a/src/applications/badges/query/PhabricatorBadgesAwardQuery.php b/src/applications/badges/query/PhabricatorBadgesAwardQuery.php index 355feec066..a147af0b75 100644 --- a/src/applications/badges/query/PhabricatorBadgesAwardQuery.php +++ b/src/applications/badges/query/PhabricatorBadgesAwardQuery.php @@ -1,87 +1,85 @@ $award) { + $badge_phids[] = $award->getBadgePHID(); + } + $badges = id(new PhabricatorBadgesQuery()) ->setViewer($this->getViewer()) - ->withRecipientPHIDs(mpull($awards, null, 'getRecipientPHID')) + ->withPHIDs($badge_phids) ->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 index b6277c5f34..c977e3f826 100644 --- a/src/applications/badges/query/PhabricatorBadgesQuery.php +++ b/src/applications/badges/query/PhabricatorBadgesQuery.php @@ -1,150 +1,119 @@ ids = $ids; return $this; } public function withPHIDs(array $phids) { $this->phids = $phids; return $this; } public function withQualities(array $qualities) { $this->qualities = $qualities; return $this; } public function withStatuses(array $statuses) { $this->statuses = $statuses; return $this; } - public function withRecipientPHIDs(array $recipient_phids) { - $this->recipientPHIDs = $recipient_phids; - return $this; - } - public function withNameNgrams($ngrams) { return $this->withNgramsConstraint( id(new PhabricatorBadgesBadgeNameNgrams()), $ngrams); } - public function needRecipients($need_recipients) { - $this->needRecipients = $need_recipients; - return $this; - } - protected function loadPage() { return $this->loadStandardPage($this->newResultObject()); } protected function getPrimaryTableAlias() { return 'badges'; } public function newResultObject() { return new PhabricatorBadgesBadge(); } - protected function didFilterPage(array $badges) { - if ($this->needRecipients) { - $query = id(new PhabricatorBadgesAwardQuery()) - ->setViewer($this->getViewer()) - ->withBadgePHIDs(mpull($badges, 'getPHID')) - ->execute(); - - $awards = mgroup($query, 'getBadgePHID'); - - foreach ($badges as $badge) { - $badge_awards = idx($awards, $badge->getPHID(), array()); - $badge->attachAwards($badge_awards); - } - } - - return $badges; - } - protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn); if ($this->ids !== null) { $where[] = qsprintf( $conn, 'badges.id IN (%Ld)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf( $conn, 'badges.phid IN (%Ls)', $this->phids); } if ($this->qualities !== null) { $where[] = qsprintf( $conn, 'badges.quality IN (%Ls)', $this->qualities); } if ($this->statuses !== null) { $where[] = qsprintf( $conn, 'badges.status IN (%Ls)', $this->statuses); } return $where; } public function getQueryApplicationClass() { return 'PhabricatorBadgesApplication'; } public function getBuiltinOrders() { return array( 'quality' => array( 'vector' => array('quality', 'id'), 'name' => pht('Rarity (Rarest First)'), ), 'shoddiness' => array( 'vector' => array('-quality', '-id'), 'name' => pht('Rarity (Most Common First)'), ), ) + parent::getBuiltinOrders(); } public function getOrderableColumns() { return array( 'quality' => array( 'table' => $this->getPrimaryTableAlias(), 'column' => 'quality', 'reverse' => true, 'type' => 'int', ), ) + parent::getOrderableColumns(); } protected function getPagingValueMap($cursor, array $keys) { $badge = $this->loadCursorObject($cursor); return array( 'quality' => $badge->getQuality(), 'id' => $badge->getID(), ); } } diff --git a/src/applications/badges/storage/PhabricatorBadgesBadge.php b/src/applications/badges/storage/PhabricatorBadgesBadge.php index cf02f705ce..e2c63c1d0c 100644 --- a/src/applications/badges/storage/PhabricatorBadgesBadge.php +++ b/src/applications/badges/storage/PhabricatorBadgesBadge.php @@ -1,226 +1,215 @@ pht('Active'), self::STATUS_ARCHIVED => pht('Archived'), ); } public static function initializeNewBadge(PhabricatorUser $actor) { $app = id(new PhabricatorApplicationQuery()) ->setViewer($actor) ->withClasses(array('PhabricatorBadgesApplication')) ->executeOne(); $view_policy = PhabricatorPolicies::getMostOpenPolicy(); $edit_policy = $app->getPolicy(PhabricatorBadgesDefaultEditCapability::CAPABILITY); return id(new PhabricatorBadgesBadge()) ->setIcon(self::DEFAULT_ICON) ->setQuality(PhabricatorBadgesQuality::DEFAULT_QUALITY) ->setCreatorPHID($actor->getPHID()) ->setEditPolicy($edit_policy) ->setFlavor('') ->setDescription('') ->setStatus(self::STATUS_ACTIVE); } protected function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, self::CONFIG_COLUMN_SCHEMA => array( 'name' => 'sort255', 'flavor' => 'text255', 'description' => 'text', 'icon' => 'text255', 'quality' => 'uint32', 'status' => 'text32', 'mailKey' => 'bytes20', ), self::CONFIG_KEY_SCHEMA => array( 'key_creator' => array( 'columns' => array('creatorPHID', 'dateModified'), ), ), ) + parent::getConfiguration(); } public function generatePHID() { return PhabricatorPHID::generateNewPHID(PhabricatorBadgesPHIDType::TYPECONST); } public function isArchived() { return ($this->getStatus() == self::STATUS_ARCHIVED); } - public function attachAwards(array $awards) { - $this->awards = $awards; - return $this; - } - - public function getAwards() { - return $this->assertAttached($this->awards); - } - public function getViewURI() { return '/badges/view/'.$this->getID().'/'; } public function save() { if (!$this->getMailKey()) { $this->setMailKey(Filesystem::readRandomCharacters(20)); } return parent::save(); } /* -( PhabricatorPolicyInterface )----------------------------------------- */ public function getCapabilities() { return array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, ); } public function getPolicy($capability) { switch ($capability) { case PhabricatorPolicyCapability::CAN_VIEW: return PhabricatorPolicies::getMostOpenPolicy(); case PhabricatorPolicyCapability::CAN_EDIT: return $this->getEditPolicy(); } } public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { return false; } /* -( PhabricatorApplicationTransactionInterface )------------------------- */ public function getApplicationTransactionEditor() { return new PhabricatorBadgesEditor(); } public function getApplicationTransactionObject() { return $this; } public function getApplicationTransactionTemplate() { return new PhabricatorBadgesTransaction(); } public function willRenderTimeline( PhabricatorApplicationTransactionView $timeline, AphrontRequest $request) { return $timeline; } /* -( PhabricatorSubscribableInterface )----------------------------------- */ public function isAutomaticallySubscribed($phid) { return false; } /* -( PhabricatorDestructibleInterface )----------------------------------- */ public function destroyObjectPermanently( PhabricatorDestructionEngine $engine) { $awards = id(new PhabricatorBadgesAwardQuery()) ->setViewer($engine->getViewer()) ->withBadgePHIDs(array($this->getPHID())) ->execute(); foreach ($awards as $award) { $engine->destroyObject($award); } $this->openTransaction(); $this->delete(); $this->saveTransaction(); } /* -( PhabricatorConduitResultInterface )---------------------------------- */ public function getFieldSpecificationsForConduit() { return array( id(new PhabricatorConduitSearchFieldSpecification()) ->setKey('name') ->setType('string') ->setDescription(pht('The name of the badge.')), id(new PhabricatorConduitSearchFieldSpecification()) ->setKey('creatorPHID') ->setType('phid') ->setDescription(pht('User PHID of the creator.')), id(new PhabricatorConduitSearchFieldSpecification()) ->setKey('status') ->setType('string') ->setDescription(pht('Active or archived status of the badge.')), ); } public function getFieldValuesForConduit() { return array( 'name' => $this->getName(), 'creatorPHID' => $this->getCreatorPHID(), 'status' => $this->getStatus(), ); } public function getConduitSearchAttachments() { return array(); } /* -( PhabricatorNgramInterface )------------------------------------------ */ public function newNgrams() { return array( id(new PhabricatorBadgesBadgeNameNgrams()) ->setValue($this->getName()), ); } } diff --git a/src/applications/badges/view/PhabricatorBadgesRecipientsListView.php b/src/applications/badges/view/PhabricatorBadgesRecipientsListView.php index f221487ed2..f566cd7b7a 100644 --- a/src/applications/badges/view/PhabricatorBadgesRecipientsListView.php +++ b/src/applications/badges/view/PhabricatorBadgesRecipientsListView.php @@ -1,84 +1,90 @@ badge = $badge; return $this; } + public function setAwards(array $awards) { + $this->awards = $awards; + return $this; + } + public function setHandles(array $handles) { $this->handles = $handles; return $this; } public function render() { $viewer = $this->getViewer(); $badge = $this->badge; $handles = $this->handles; - $awards = mpull($badge->getAwards(), null, 'getRecipientPHID'); + $awards = mpull($this->awards, null, 'getRecipientPHID'); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $badge, PhabricatorPolicyCapability::CAN_EDIT); $award_button = id(new PHUIButtonView()) ->setTag('a') ->setIcon('fa-plus') ->setText(pht('Add Recipents')) ->setWorkflow(true) ->setDisabled(!$can_edit) ->setHref('/badges/recipients/'.$badge->getID().'/add/'); $header = id(new PHUIHeaderView()) ->setHeader(pht('Recipients')) ->addActionLink($award_button); $list = id(new PHUIObjectItemListView()) ->setNoDataString(pht('This badge does not have any recipients.')) ->setFlush(true); foreach ($handles as $handle) { $remove_uri = '/badges/recipients/'. $badge->getID().'/remove/?phid='.$handle->getPHID(); $award = $awards[$handle->getPHID()]; $awarder_handle = $viewer->renderHandle($award->getAwarderPHID()); $award_date = phabricator_date($award->getDateCreated(), $viewer); $awarder_info = pht( 'Awarded by %s on %s', $awarder_handle->render(), $award_date); $item = id(new PHUIObjectItemView()) ->setHeader($handle->getFullName()) ->setSubhead($awarder_info) ->setHref($handle->getURI()) ->setImageURI($handle->getImageURI()); if ($can_edit) { $item->addAction( id(new PHUIListItemView()) ->setIcon('fa-times') ->setName(pht('Remove')) ->setHref($remove_uri) ->setWorkflow(true)); } $list->addItem($item); } $box = id(new PHUIObjectBoxView()) ->setHeader($header) ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) ->setObjectList($list); return $box; } } diff --git a/src/applications/badges/xaction/PhabricatorBadgesBadgeAwardTransaction.php b/src/applications/badges/xaction/PhabricatorBadgesBadgeAwardTransaction.php index 5ecacdd441..01fad6e214 100644 --- a/src/applications/badges/xaction/PhabricatorBadgesBadgeAwardTransaction.php +++ b/src/applications/badges/xaction/PhabricatorBadgesBadgeAwardTransaction.php @@ -1,90 +1,97 @@ getAwards(), 'getRecipientPHID'); + return null; } public function applyExternalEffects($object, $value) { - $awards = $object->getAwards(); - $awards = mpull($awards, null, 'getRecipientPHID'); - foreach ($value as $phid) { - $award = idx($awards, $phid); - if (!$award) { - $award = PhabricatorBadgesAward::initializeNewBadgesAward( - $this->getActor(), - $object, - $phid); - $award->save(); - $awards[] = $award; - } + $award = PhabricatorBadgesAward::initializeNewBadgesAward( + $this->getActor(), + $object, + $phid); + $award->save(); } - $object->attachAwards($awards); return; } public function getTitle() { $new = $this->getNewValue(); if (!is_array($new)) { $new = array(); } $handles = $this->renderHandleList($new); return pht( '%s awarded this badge to %s recipient(s): %s.', $this->renderAuthor(), new PhutilNumber(count($new)), $handles); } public function getTitleForFeed() { $new = $this->getNewValue(); if (!is_array($new)) { $new = array(); } $handles = $this->renderHandleList($new); return pht( '%s awarded %s to %s recipient(s): %s.', $this->renderAuthor(), $this->renderObject(), new PhutilNumber(count($new)), $handles); } public function getIcon() { return 'fa-user-plus'; } public function validateTransactions($object, array $xactions) { $errors = array(); foreach ($xactions as $xaction) { $user_phids = $xaction->getNewValue(); if (!$user_phids) { $errors[] = $this->newRequiredError( pht('Recipient is required.')); continue; } foreach ($user_phids as $user_phid) { + // Check if a valid user $user = id(new PhabricatorPeopleQuery()) ->setViewer($this->getActor()) ->withPHIDs(array($user_phid)) ->executeOne(); if (!$user) { $errors[] = $this->newInvalidError( pht( 'Recipient PHID "%s" is not a valid user PHID.', $user_phid)); + continue; + } + + // Check if already awarded + $award = id(new PhabricatorBadgesAwardQuery()) + ->setViewer($this->getActor()) + ->withRecipientPHIDs(array($user_phid)) + ->withBadgePHIDs(array($object->getPHID())) + ->executeOne(); + if ($award) { + $errors[] = $this->newInvalidError( + pht( + '%s has already been awarded this badge.', + $user->getUsername())); } } } return $errors; } } diff --git a/src/applications/badges/xaction/PhabricatorBadgesBadgeRevokeTransaction.php b/src/applications/badges/xaction/PhabricatorBadgesBadgeRevokeTransaction.php index a3fa58a060..b028038f3f 100644 --- a/src/applications/badges/xaction/PhabricatorBadgesBadgeRevokeTransaction.php +++ b/src/applications/badges/xaction/PhabricatorBadgesBadgeRevokeTransaction.php @@ -1,83 +1,86 @@ getAwards(); + $awards = id(new PhabricatorBadgesAwardQuery()) + ->setViewer($this->getActor()) + ->withRecipientPHIDs($value) + ->withBadgePHIDs(array($object->getPHID())) + ->execute(); $awards = mpull($awards, null, 'getRecipientPHID'); foreach ($value as $phid) { $awards[$phid]->delete(); } - $object->attachAwards($awards); return; } public function getTitle() { $new = $this->getNewValue(); if (!is_array($new)) { $new = array(); } $handles = $this->renderHandleList($new); return pht( '%s revoked this badge from %s recipient(s): %s.', $this->renderAuthor(), new PhutilNumber(count($new)), $handles); } public function getTitleForFeed() { $new = $this->getNewValue(); if (!is_array($new)) { $new = array(); } $handles = $this->renderHandleList($new); return pht( '%s revoked %s from %s recipient(s): %s.', $this->renderAuthor(), $this->renderObject(), new PhutilNumber(count($new)), $handles); } public function getIcon() { return 'fa-user-times'; } public function validateTransactions($object, array $xactions) { $errors = array(); foreach ($xactions as $xaction) { $award_phids = $xaction->getNewValue(); if (!$award_phids) { $errors[] = $this->newRequiredError( pht('Recipient is required.')); continue; } foreach ($award_phids as $award_phid) { $award = id(new PhabricatorBadgesAwardQuery()) ->setViewer($this->getActor()) ->withRecipientPHIDs(array($award_phid)) ->withBadgePHIDs(array($object->getPHID())) ->executeOne(); if (!$award) { $errors[] = $this->newInvalidError( pht( 'Recipient PHID "%s" has not been awarded.', $award_phid)); } } } return $errors; } }