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

Move user approval to modular transactions

Summary: See https://discourse.phabricator-community.org/t/how-to-approve-user-via-conduit-api/2189. This particular use case doesn't seem very compelling, but moving this logic out of `PhabricatorUserEditor` is a win anyway.

Test Plan: Registered a new user, approved/unapproved them conduit, approved from the UI.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

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

+120 -61
+2
src/__phutil_library_map__.php
··· 4597 4597 'PhabricatorUnknownContentSource' => 'infrastructure/contentsource/PhabricatorUnknownContentSource.php', 4598 4598 'PhabricatorUnsubscribedFromObjectEdgeType' => 'applications/transactions/edges/PhabricatorUnsubscribedFromObjectEdgeType.php', 4599 4599 'PhabricatorUser' => 'applications/people/storage/PhabricatorUser.php', 4600 + 'PhabricatorUserApproveTransaction' => 'applications/people/xaction/PhabricatorUserApproveTransaction.php', 4600 4601 'PhabricatorUserBadgesCacheType' => 'applications/people/cache/PhabricatorUserBadgesCacheType.php', 4601 4602 'PhabricatorUserBlurbField' => 'applications/people/customfield/PhabricatorUserBlurbField.php', 4602 4603 'PhabricatorUserCache' => 'applications/people/storage/PhabricatorUserCache.php', ··· 10645 10646 'PhabricatorConduitResultInterface', 10646 10647 'PhabricatorAuthPasswordHashInterface', 10647 10648 ), 10649 + 'PhabricatorUserApproveTransaction' => 'PhabricatorUserTransactionType', 10648 10650 'PhabricatorUserBadgesCacheType' => 'PhabricatorUserCacheType', 10649 10651 'PhabricatorUserBlurbField' => 'PhabricatorUserCustomField', 10650 10652 'PhabricatorUserCache' => 'PhabricatorUserDAO',
+10 -22
src/applications/people/controller/PhabricatorPeopleApproveController.php
··· 24 24 } 25 25 26 26 if ($request->isFormPost()) { 27 - id(new PhabricatorUserEditor()) 28 - ->setActor($viewer) 29 - ->approveUser($user, true); 30 - 31 - $title = pht( 32 - 'Phabricator Account "%s" Approved', 33 - $user->getUsername()); 27 + $xactions = array(); 34 28 35 - $body = sprintf( 36 - "%s\n\n %s\n\n", 37 - pht( 38 - 'Your Phabricator account (%s) has been approved by %s. You can '. 39 - 'login here:', 40 - $user->getUsername(), 41 - $viewer->getUsername()), 42 - PhabricatorEnv::getProductionURI('/')); 29 + $xactions[] = id(new PhabricatorUserTransaction()) 30 + ->setTransactionType(PhabricatorUserApproveTransaction::TRANSACTIONTYPE) 31 + ->setNewValue(true); 43 32 44 - $mail = id(new PhabricatorMetaMTAMail()) 45 - ->addTos(array($user->getPHID())) 46 - ->addCCs(array($viewer->getPHID())) 47 - ->setSubject('[Phabricator] '.$title) 48 - ->setForceDelivery(true) 49 - ->setBody($body) 50 - ->saveAndSend(); 33 + id(new PhabricatorUserTransactionEditor()) 34 + ->setActor($viewer) 35 + ->setContentSourceFromRequest($request) 36 + ->setContinueOnMissingFields(true) 37 + ->setContinueOnNoEffect(true) 38 + ->applyTransactions($user, $xactions); 51 39 52 40 return id(new AphrontRedirectResponse())->setURI($done_uri); 53 41 }
+10
src/applications/people/editor/PhabricatorUserEditEngine.php
··· 75 75 ->setConduitDescription(pht('Disable or enable the user.')) 76 76 ->setConduitTypeDescription(pht('True to disable the user.')) 77 77 ->setValue($object->getIsDisabled()), 78 + id(new PhabricatorBoolEditField()) 79 + ->setKey('approved') 80 + ->setOptions(pht('Approved'), pht('Unapproved')) 81 + ->setLabel(pht('Approved')) 82 + ->setDescription(pht('Approve the user.')) 83 + ->setTransactionType(PhabricatorUserApproveTransaction::TRANSACTIONTYPE) 84 + ->setIsFormField(false) 85 + ->setConduitDescription(pht('Approve or reject the user.')) 86 + ->setConduitTypeDescription(pht('True to approve the user.')) 87 + ->setValue($object->getIsApproved()), 78 88 ); 79 89 } 80 90
-39
src/applications/people/editor/PhabricatorUserEditor.php
··· 293 293 return $this; 294 294 } 295 295 296 - /** 297 - * @task role 298 - */ 299 - public function approveUser(PhabricatorUser $user, $approve) { 300 - $actor = $this->requireActor(); 301 - 302 - if (!$user->getID()) { 303 - throw new Exception(pht('User has not been created yet!')); 304 - } 305 - 306 - $user->openTransaction(); 307 - $user->beginWriteLocking(); 308 - 309 - $user->reload(); 310 - if ($user->getIsApproved() == $approve) { 311 - $user->endWriteLocking(); 312 - $user->killTransaction(); 313 - return $this; 314 - } 315 - 316 - $log = PhabricatorUserLog::initializeNewLog( 317 - $actor, 318 - $user->getPHID(), 319 - PhabricatorUserLog::ACTION_APPROVE); 320 - $log->setOldValue($user->getIsApproved()); 321 - $log->setNewValue($approve); 322 - 323 - $user->setIsApproved($approve); 324 - $user->save(); 325 - 326 - $log->save(); 327 - 328 - $user->endWriteLocking(); 329 - $user->saveTransaction(); 330 - 331 - return $this; 332 - } 333 - 334 - 335 296 /* -( Adding, Removing and Changing Email )-------------------------------- */ 336 297 337 298
+96
src/applications/people/xaction/PhabricatorUserApproveTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorUserApproveTransaction 4 + extends PhabricatorUserTransactionType { 5 + 6 + const TRANSACTIONTYPE = 'user.approve'; 7 + 8 + public function generateOldValue($object) { 9 + return (bool)$object->getIsApproved(); 10 + } 11 + 12 + public function generateNewValue($object, $value) { 13 + return (bool)$value; 14 + } 15 + 16 + public function applyInternalEffects($object, $value) { 17 + $object->setIsApproved((int)$value); 18 + } 19 + 20 + public function applyExternalEffects($object, $value) { 21 + $user = $object; 22 + $this->newUserLog(PhabricatorUserLog::ACTION_APPROVE) 23 + ->setOldValue((bool)$user->getIsApproved()) 24 + ->setNewValue((bool)$value) 25 + ->save(); 26 + 27 + $actor = $this->getActor(); 28 + $title = pht( 29 + 'Phabricator Account "%s" Approved', 30 + $user->getUsername()); 31 + 32 + $body = sprintf( 33 + "%s\n\n %s\n\n", 34 + pht( 35 + 'Your Phabricator account (%s) has been approved by %s. You can '. 36 + 'login here:', 37 + $user->getUsername(), 38 + $actor->getUsername()), 39 + PhabricatorEnv::getProductionURI('/')); 40 + 41 + $mail = id(new PhabricatorMetaMTAMail()) 42 + ->addTos(array($user->getPHID())) 43 + ->addCCs(array($actor->getPHID())) 44 + ->setSubject('[Phabricator] '.$title) 45 + ->setForceDelivery(true) 46 + ->setBody($body) 47 + ->saveAndSend(); 48 + } 49 + 50 + public function getTitle() { 51 + $new = $this->getNewValue(); 52 + if ($new) { 53 + return pht( 54 + '%s approved this user.', 55 + $this->renderAuthor()); 56 + } else { 57 + return pht( 58 + '%s rejected this user.', 59 + $this->renderAuthor()); 60 + } 61 + } 62 + 63 + public function shouldHideForFeed() { 64 + return true; 65 + } 66 + 67 + public function validateTransactions($object, array $xactions) { 68 + $actor = $this->getActor(); 69 + $errors = array(); 70 + 71 + foreach ($xactions as $xaction) { 72 + $is_approved = (bool)$object->getIsApproved(); 73 + 74 + if ((bool)$xaction->getNewValue() === $is_approved) { 75 + continue; 76 + } 77 + 78 + if (!$actor->getIsAdmin()) { 79 + $errors[] = $this->newInvalidError( 80 + pht('You must be an administrator to approve users.')); 81 + } 82 + } 83 + 84 + return $errors; 85 + } 86 + 87 + public function getRequiredCapabilities( 88 + $object, 89 + PhabricatorApplicationTransaction $xaction) { 90 + 91 + // Unlike normal user edits, approvals require admin permissions, which 92 + // is enforced by validateTransactions(). 93 + 94 + return null; 95 + } 96 + }
+2
src/applications/people/xaction/PhabricatorUserDisableTransaction.php
··· 15 15 16 16 public function applyInternalEffects($object, $value) { 17 17 $object->setIsDisabled((int)$value); 18 + } 18 19 20 + public function applyExternalEffects($object, $value) { 19 21 $this->newUserLog(PhabricatorUserLog::ACTION_DISABLE) 20 22 ->setOldValue((bool)$object->getIsDisabled()) 21 23 ->setNewValue((bool)$value)