From 2386705873bdd56030c2c8c6dd479a31e0b6690d Mon Sep 17 00:00:00 2001 From: Chad Little Date: Thu, 31 Mar 2016 20:39:06 +0000 Subject: [PATCH] Allow awarding Badges from the profile Summary: [WIP] Allows awarding a badge from a user profile. Unsure of the interactions here if a user can't award any badges, or if we should just hide this. Fixes T10688 Fixes T10318 Test Plan: Award some badges. Steal them back. Reviewers: lpriestley, epriestley Reviewed By: epriestley Subscribers: Korvin Maniphest Tasks: T10318, T10688 Differential Revision: https://secure.phabricator.com/D15544 --- src/__phutil_library_map__.php | 2 + .../PhabricatorBadgesApplication.php | 2 + .../PhabricatorBadgesAwardController.php | 85 +++++++++++++++++++ ...PhabricatorPeopleProfileViewController.php | 34 +++++++- 4 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 src/applications/badges/controller/PhabricatorBadgesAwardController.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index fafa0bdbe0..a718c4edfc 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1865,6 +1865,7 @@ phutil_register_library_map(array( 'PhabricatorBadgesApplication' => 'applications/badges/application/PhabricatorBadgesApplication.php', 'PhabricatorBadgesArchiveController' => 'applications/badges/controller/PhabricatorBadgesArchiveController.php', 'PhabricatorBadgesAward' => 'applications/badges/storage/PhabricatorBadgesAward.php', + 'PhabricatorBadgesAwardController' => 'applications/badges/controller/PhabricatorBadgesAwardController.php', 'PhabricatorBadgesAwardQuery' => 'applications/badges/query/PhabricatorBadgesAwardQuery.php', 'PhabricatorBadgesBadge' => 'applications/badges/storage/PhabricatorBadgesBadge.php', 'PhabricatorBadgesCommentController' => 'applications/badges/controller/PhabricatorBadgesCommentController.php', @@ -6223,6 +6224,7 @@ phutil_register_library_map(array( 'PhabricatorDestructibleInterface', 'PhabricatorPolicyInterface', ), + 'PhabricatorBadgesAwardController' => 'PhabricatorBadgesController', 'PhabricatorBadgesAwardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorBadgesBadge' => array( 'PhabricatorBadgesDAO', diff --git a/src/applications/badges/application/PhabricatorBadgesApplication.php b/src/applications/badges/application/PhabricatorBadgesApplication.php index 887a11833d..0de150ee2d 100644 --- a/src/applications/badges/application/PhabricatorBadgesApplication.php +++ b/src/applications/badges/application/PhabricatorBadgesApplication.php @@ -39,6 +39,8 @@ final class PhabricatorBadgesApplication extends PhabricatorApplication { '/badges/' => array( '(?:query/(?P[^/]+)/)?' => 'PhabricatorBadgesListController', + 'award/(?:(?P\d+)/)?' + => 'PhabricatorBadgesAwardController', 'create/' => 'PhabricatorBadgesEditController', 'comment/(?P[1-9]\d*)/' diff --git a/src/applications/badges/controller/PhabricatorBadgesAwardController.php b/src/applications/badges/controller/PhabricatorBadgesAwardController.php new file mode 100644 index 0000000000..0475dd6277 --- /dev/null +++ b/src/applications/badges/controller/PhabricatorBadgesAwardController.php @@ -0,0 +1,85 @@ +getViewer(); + $id = $request->getURIData('id'); + + $user = id(new PhabricatorPeopleQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->executeOne(); + if (!$user) { + return new Aphront404Response(); + } + + $view_uri = '/p/'.$user->getUsername(); + + if ($request->isFormPost()) { + $xactions = array(); + $badge_phid = $request->getStr('badgePHID'); + $badge = id(new PhabricatorBadgesQuery()) + ->setViewer($viewer) + ->withPHIDs(array($badge_phid)) + ->needRecipients(true) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_EDIT, + PhabricatorPolicyCapability::CAN_VIEW, + )) + ->executeOne(); + if (!$badge) { + return new Aphront404Response(); + } + $award_phids = array($user->getPHID()); + + $xactions[] = id(new PhabricatorBadgesTransaction()) + ->setTransactionType(PhabricatorBadgesTransaction::TYPE_AWARD) + ->setNewValue($award_phids); + + $editor = id(new PhabricatorBadgesEditor($badge)) + ->setActor($viewer) + ->setContentSourceFromRequest($request) + ->setContinueOnNoEffect(true) + ->setContinueOnMissingFields(true) + ->applyTransactions($badge, $xactions); + + return id(new AphrontRedirectResponse()) + ->setURI($view_uri); + } + + $badges = id(new PhabricatorBadgesQuery()) + ->setViewer($viewer) + ->withStatuses(array( + PhabricatorBadgesBadge::STATUS_ACTIVE, + )) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->execute(); + + $options = mpull($badges, 'getName', 'getPHID'); + asort($options); + + $form = id(new AphrontFormView()) + ->setUser($viewer) + ->appendChild( + id(new AphrontFormSelectControl()) + ->setLabel(pht('Badge')) + ->setName('badgePHID') + ->setOptions($options)); + + $dialog = $this->newDialog() + ->setTitle(pht('Grant Badge')) + ->appendForm($form) + ->addCancelButton($view_uri) + ->addSubmitButton(pht('Award')); + + return $dialog; + } + +} diff --git a/src/applications/people/controller/PhabricatorPeopleProfileViewController.php b/src/applications/people/controller/PhabricatorPeopleProfileViewController.php index 213fc94b0e..cb9c558d5a 100644 --- a/src/applications/people/controller/PhabricatorPeopleProfileViewController.php +++ b/src/applications/people/controller/PhabricatorPeopleProfileViewController.php @@ -211,8 +211,40 @@ final class PhabricatorPeopleProfileViewController ->appendChild($error); } + // Best option? + $badges = id(new PhabricatorBadgesQuery()) + ->setViewer($viewer) + ->withStatuses(array( + PhabricatorBadgesBadge::STATUS_ACTIVE, + )) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->execute(); + + $button = id(new PHUIButtonView()) + ->setTag('a') + ->setIcon('fa-plus') + ->setText(pht('Award')) + ->setWorkflow(true) + ->setHref('/badges/award/'.$user->getID().'/'); + + $can_award = false; + if (count($badges)) { + $can_award = true; + } + + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Badges')); + + if (count($badges)) { + $header->addActionLink($button); + } + $box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Badges')) + ->setHeader($header) ->addClass('project-view-badges') ->appendChild($flex) ->setBackground(PHUIObjectBoxView::GREY);