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

Make Phortune account members editable and modernize the edge constant

Summary:
Ref T2787.

- Account members can add and remove other members (major use case is corporate accounts).
- Use a modern edge constant setup.

Test Plan: See screenshots.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T2787

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

+180 -68
+4
src/__phutil_library_map__.php
··· 2550 2550 'PhortuneAccount' => 'applications/phortune/storage/PhortuneAccount.php', 2551 2551 'PhortuneAccountEditController' => 'applications/phortune/controller/PhortuneAccountEditController.php', 2552 2552 'PhortuneAccountEditor' => 'applications/phortune/editor/PhortuneAccountEditor.php', 2553 + 'PhortuneAccountHasMemberEdgeType' => 'applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php', 2553 2554 'PhortuneAccountListController' => 'applications/phortune/controller/PhortuneAccountListController.php', 2554 2555 'PhortuneAccountPHIDType' => 'applications/phortune/phid/PhortuneAccountPHIDType.php', 2555 2556 'PhortuneAccountQuery' => 'applications/phortune/query/PhortuneAccountQuery.php', ··· 2581 2582 'PhortuneDAO' => 'applications/phortune/storage/PhortuneDAO.php', 2582 2583 'PhortuneErrCode' => 'applications/phortune/constants/PhortuneErrCode.php', 2583 2584 'PhortuneLandingController' => 'applications/phortune/controller/PhortuneLandingController.php', 2585 + 'PhortuneMemberHasAccountEdgeType' => 'applications/phortune/edge/PhortuneMemberHasAccountEdgeType.php', 2584 2586 'PhortuneMerchant' => 'applications/phortune/storage/PhortuneMerchant.php', 2585 2587 'PhortuneMerchantCapability' => 'applications/phortune/capability/PhortuneMerchantCapability.php', 2586 2588 'PhortuneMerchantController' => 'applications/phortune/controller/PhortuneMerchantController.php', ··· 5608 5610 ), 5609 5611 'PhortuneAccountEditController' => 'PhortuneController', 5610 5612 'PhortuneAccountEditor' => 'PhabricatorApplicationTransactionEditor', 5613 + 'PhortuneAccountHasMemberEdgeType' => 'PhabricatorEdgeType', 5611 5614 'PhortuneAccountListController' => 'PhortuneController', 5612 5615 'PhortuneAccountPHIDType' => 'PhabricatorPHIDType', 5613 5616 'PhortuneAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', ··· 5642 5645 'PhortuneDAO' => 'PhabricatorLiskDAO', 5643 5646 'PhortuneErrCode' => 'PhortuneConstants', 5644 5647 'PhortuneLandingController' => 'PhortuneController', 5648 + 'PhortuneMemberHasAccountEdgeType' => 'PhabricatorEdgeType', 5645 5649 'PhortuneMerchant' => array( 5646 5650 'PhortuneDAO', 5647 5651 'PhabricatorPolicyInterface',
+26 -11
src/applications/phortune/controller/PhortuneAccountEditController.php
··· 28 28 $is_new = false; 29 29 } else { 30 30 $account = PhortuneAccount::initializeNewAccount($viewer); 31 + $account->attachMemberPHIDs(array($viewer->getPHID())); 31 32 $is_new = true; 32 33 } 33 34 34 35 $v_name = $account->getName(); 35 36 $e_name = true; 37 + 38 + $v_members = $account->getMemberPHIDs(); 39 + $e_members = null; 40 + 36 41 $validation_exception = null; 37 42 38 43 if ($request->isFormPost()) { 39 44 $v_name = $request->getStr('name'); 45 + $v_members = $request->getArr('memberPHIDs'); 40 46 41 47 $type_name = PhortuneAccountTransaction::TYPE_NAME; 48 + $type_edge = PhabricatorTransactions::TYPE_EDGE; 42 49 43 50 $xactions = array(); 44 51 $xactions[] = id(new PhortuneAccountTransaction()) 45 52 ->setTransactionType($type_name) 46 53 ->setNewValue($v_name); 47 54 48 - if ($is_new) { 49 - $xactions[] = id(new PhortuneAccountTransaction()) 50 - ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) 51 - ->setMetadataValue( 52 - 'edge:type', 53 - PhabricatorEdgeConfig::TYPE_ACCOUNT_HAS_MEMBER) 54 - ->setNewValue( 55 - array( 56 - '=' => array($viewer->getPHID() => $viewer->getPHID()), 57 - )); 58 - } 55 + $xactions[] = id(new PhortuneAccountTransaction()) 56 + ->setTransactionType($type_edge) 57 + ->setMetadataValue( 58 + 'edge:type', 59 + PhortuneAccountHasMemberEdgeType::EDGECONST) 60 + ->setNewValue( 61 + array( 62 + '=' => array_fuse($v_members), 63 + )); 59 64 60 65 $editor = id(new PhortuneAccountEditor()) 61 66 ->setActor($viewer) ··· 70 75 } catch (PhabricatorApplicationTransactionValidationException $ex) { 71 76 $validation_exception = $ex; 72 77 $e_name = $ex->getShortMessage($type_name); 78 + $e_members = $ex->getShortMessage($type_edge); 73 79 } 74 80 } 75 81 ··· 91 97 $submit_button = pht('Save Changes'); 92 98 } 93 99 100 + $member_handles = $this->loadViewerHandles($v_members); 101 + 94 102 $form = id(new AphrontFormView()) 95 103 ->setUser($viewer) 96 104 ->appendChild( ··· 99 107 ->setLabel(pht('Name')) 100 108 ->setValue($v_name) 101 109 ->setError($e_name)) 110 + ->appendChild( 111 + id(new AphrontFormTokenizerControl()) 112 + ->setDatasource(new PhabricatorPeopleDatasource()) 113 + ->setLabel(pht('Members')) 114 + ->setName('memberPHIDs') 115 + ->setValue($member_handles) 116 + ->setError($e_members)) 102 117 ->appendChild( 103 118 id(new AphrontFormSubmitControl()) 104 119 ->setValue($submit_button)
+7 -7
src/applications/phortune/controller/PhortuneAccountViewController.php
··· 53 53 ->setIcon('fa-pencil') 54 54 ->setHref($edit_uri) 55 55 ->setDisabled(!$can_edit) 56 - ->setWorkflow(!$can_edit)) 57 - ->addAction( 58 - id(new PhabricatorActionView()) 59 - ->setName(pht('Edit Members')) 60 - ->setIcon('fa-users') 61 - ->setHref('#') 62 - ->setDisabled(true)); 56 + ->setWorkflow(!$can_edit)); 63 57 64 58 $crumbs->setActionList($actions); 65 59 66 60 $properties = id(new PHUIPropertyListView()) 67 61 ->setObject($account) 68 62 ->setUser($user); 63 + 64 + $this->loadHandles($account->getMemberPHIDs()); 65 + 66 + $properties->addProperty( 67 + pht('Members'), 68 + $this->renderHandlesForPHIDs($account->getMemberPHIDs())); 69 69 70 70 $properties->setActionList($actions); 71 71
+101
src/applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php
··· 1 + <?php 2 + 3 + final class PhortuneAccountHasMemberEdgeType extends PhabricatorEdgeType { 4 + 5 + const EDGECONST = 27; 6 + 7 + public function getInverseEdgeConstant() { 8 + return PhortuneMemberHasAccountEdgeType::EDGECONST; 9 + } 10 + 11 + public function getTransactionAddString( 12 + $actor, 13 + $add_count, 14 + $add_edges) { 15 + 16 + return pht( 17 + '%s added %s account member(s): %s.', 18 + $actor, 19 + $add_count, 20 + $add_edges); 21 + } 22 + 23 + public function getTransactionRemoveString( 24 + $actor, 25 + $rem_count, 26 + $rem_edges) { 27 + 28 + return pht( 29 + '%s removed %s account member(s): %s.', 30 + $actor, 31 + $rem_count, 32 + $rem_edges); 33 + } 34 + 35 + public function getTransactionEditString( 36 + $actor, 37 + $total_count, 38 + $add_count, 39 + $add_edges, 40 + $rem_count, 41 + $rem_edges) { 42 + 43 + return pht( 44 + '%s edited %s account member(s), added %s: %s; removed %s: %s.', 45 + $actor, 46 + $total_count, 47 + $add_count, 48 + $add_edges, 49 + $rem_count, 50 + $rem_edges); 51 + } 52 + 53 + public function getFeedAddString( 54 + $actor, 55 + $object, 56 + $add_count, 57 + $add_edges) { 58 + 59 + return pht( 60 + '%s added %s account member(s) to %s: %s.', 61 + $actor, 62 + $add_count, 63 + $object, 64 + $add_edges); 65 + } 66 + 67 + public function getFeedRemoveString( 68 + $actor, 69 + $object, 70 + $rem_count, 71 + $rem_edges) { 72 + 73 + return pht( 74 + '%s removed %s account member(s) from %s: %s.', 75 + $actor, 76 + $rem_count, 77 + $object, 78 + $rem_edges); 79 + } 80 + 81 + public function getFeedEditString( 82 + $actor, 83 + $object, 84 + $total_count, 85 + $add_count, 86 + $add_edges, 87 + $rem_count, 88 + $rem_edges) { 89 + 90 + return pht( 91 + '%s edited %s account member(s) for %s, added %s: %s; removed %s: %s.', 92 + $actor, 93 + $total_count, 94 + $object, 95 + $add_count, 96 + $add_edges, 97 + $rem_count, 98 + $rem_edges); 99 + } 100 + 101 + }
+12
src/applications/phortune/edge/PhortuneMemberHasAccountEdgeType.php
··· 1 + <?php 2 + 3 + final class PhortuneMemberHasAccountEdgeType 4 + extends PhabricatorEdgeType { 5 + 6 + const EDGECONST = 28; 7 + 8 + public function getInverseEdgeConstant() { 9 + return PhortuneAccountHasMemberEdgeType::EDGECONST; 10 + } 11 + 12 + }
+23
src/applications/phortune/editor/PhortuneAccountEditor.php
··· 91 91 $errors[] = $error; 92 92 } 93 93 break; 94 + case PhabricatorTransactions::TYPE_EDGE: 95 + foreach ($xactions as $xaction) { 96 + switch ($xaction->getMetadataValue('edge:type')) { 97 + case PhortuneAccountHasMemberEdgeType::EDGECONST: 98 + // TODO: This is a bit cumbersome, but validation happens before 99 + // transaction normalization. Maybe provide a cleaner attack on 100 + // this eventually? There's no way to generate "+" or "-" 101 + // transactions right now. 102 + $new = $xaction->getNewValue(); 103 + $set = idx($new, '=', array()); 104 + 105 + if (empty($set[$this->requireActor()->getPHID()])) { 106 + $error = new PhabricatorApplicationTransactionValidationError( 107 + $type, 108 + pht('Invalid'), 109 + pht('You can not remove yourself as an account member.'), 110 + $xaction); 111 + $errors[] = $error; 112 + } 113 + break; 114 + } 115 + } 116 + break; 94 117 } 95 118 96 119 return $errors;
+3 -2
src/applications/phortune/query/PhortuneAccountQuery.php
··· 79 79 protected function willFilterPage(array $accounts) { 80 80 $query = id(new PhabricatorEdgeQuery()) 81 81 ->withSourcePHIDs(mpull($accounts, 'getPHID')) 82 - ->withEdgeTypes(array(PhabricatorEdgeConfig::TYPE_ACCOUNT_HAS_MEMBER)); 82 + ->withEdgeTypes(array(PhortuneAccountHasMemberEdgeType::EDGECONST)); 83 83 $query->execute(); 84 84 85 85 foreach ($accounts as $account) { 86 86 $member_phids = $query->getDestinationPHIDs(array($account->getPHID())); 87 + $member_phids = array_reverse($member_phids); 87 88 $account->attachMemberPHIDs($member_phids); 88 89 } 89 90 ··· 127 128 $conn, 128 129 'LEFT JOIN %T m ON a.phid = m.src AND m.type = %d', 129 130 PhabricatorEdgeConfig::TABLE_NAME_EDGE, 130 - PhabricatorEdgeConfig::TYPE_ACCOUNT_HAS_MEMBER); 131 + PhortuneAccountHasMemberEdgeType::EDGECONST); 131 132 } 132 133 133 134 return implode(' ', $joins);
+1 -1
src/applications/phortune/storage/PhortuneAccount.php
··· 36 36 ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) 37 37 ->setMetadataValue( 38 38 'edge:type', 39 - PhabricatorEdgeConfig::TYPE_ACCOUNT_HAS_MEMBER) 39 + PhortuneAccountHasMemberEdgeType::EDGECONST) 40 40 ->setNewValue( 41 41 array( 42 42 '=' => array($actor->getPHID() => $actor->getPHID()),
-25
src/applications/phortune/storage/PhortuneAccountTransaction.php
··· 37 37 $new); 38 38 } 39 39 break; 40 - case PhabricatorTransactions::TYPE_EDGE: 41 - switch ($this->getMetadataValue('edge:type')) { 42 - case PhabricatorEdgeConfig::TYPE_ACCOUNT_HAS_MEMBER: 43 - $add = array_diff(array_keys($new), array_keys($old)); 44 - $rem = array_diff(array_keys($old), array_keys($new)); 45 - if ($add && $rem) { 46 - return pht( 47 - '%s changed account members, added %s; removed %s.', 48 - $this->renderHandleLink($author_phid), 49 - $this->renderHandleList($add), 50 - $this->renderHandleList($rem)); 51 - } else if ($add) { 52 - return pht( 53 - '%s added account members: %s', 54 - $this->renderHandleLink($author_phid), 55 - $this->renderHandleList($add)); 56 - } else { 57 - return pht( 58 - '%s removed account members: %s', 59 - $this->renderHandleLink($author_phid), 60 - $this->renderHandleList($add)); 61 - } 62 - break; 63 - } 64 - break; 65 40 } 66 41 67 42 return parent::getTitle();
+3 -22
src/infrastructure/edges/constants/PhabricatorEdgeConfig.php
··· 36 36 const TYPE_OBJECT_HAS_FILE = 25; 37 37 const TYPE_FILE_HAS_OBJECT = 26; 38 38 39 - const TYPE_ACCOUNT_HAS_MEMBER = 27; 40 - const TYPE_MEMBER_HAS_ACCOUNT = 28; 41 - 42 39 const TYPE_PURCAHSE_HAS_CHARGE = 29; 43 40 const TYPE_CHARGE_HAS_PURCHASE = 30; 44 41 ··· 103 100 array(9000), 104 101 range(80000, 80005)); 105 102 103 + $exclude[] = 27; // Was TYPE_ACCOUNT_HAS_MEMBER 104 + $exclude[] = 28; // Was TYPE_MEMBER_HAS_ACCOUNT 105 + 106 106 $exclude[] = 43; // Was TYPE_OBJECT_HAS_COLUMN 107 107 $exclude[] = 44; // Was TYPE_COLUMN_HAS_OBJECT 108 108 ··· 164 164 self::TYPE_OBJECT_HAS_FILE => self::TYPE_FILE_HAS_OBJECT, 165 165 self::TYPE_FILE_HAS_OBJECT => self::TYPE_OBJECT_HAS_FILE, 166 166 167 - self::TYPE_ACCOUNT_HAS_MEMBER => self::TYPE_MEMBER_HAS_ACCOUNT, 168 - self::TYPE_MEMBER_HAS_ACCOUNT => self::TYPE_ACCOUNT_HAS_MEMBER, 169 - 170 167 self::TYPE_DREV_HAS_COMMIT => self::TYPE_COMMIT_HAS_DREV, 171 168 self::TYPE_COMMIT_HAS_DREV => self::TYPE_DREV_HAS_COMMIT, 172 169 ··· 284 281 return '%s edited unsubcriber(s), added %d: %s; removed %d: %s.'; 285 282 case self::TYPE_OBJECT_HAS_FILE: 286 283 return '%s edited file(s), added %d: %s; removed %d: %s.'; 287 - case self::TYPE_ACCOUNT_HAS_MEMBER: 288 - return '%s edited member(s), added %d: %s; removed %d: %s.'; 289 - case self::TYPE_MEMBER_HAS_ACCOUNT: 290 - return '%s edited account(s), added %d: %s; removed %d: %s.'; 291 284 case self::TYPE_PURCAHSE_HAS_CHARGE: 292 285 return '%s edited charge(s), added %d: %s; removed %d: %s.'; 293 286 case self::TYPE_CHARGE_HAS_PURCHASE: ··· 354 347 return '%s added %d unsubcriber(s): %s.'; 355 348 case self::TYPE_OBJECT_HAS_FILE: 356 349 return '%s added %d file(s): %s.'; 357 - case self::TYPE_ACCOUNT_HAS_MEMBER: 358 - return '%s added %d member(s): %s.'; 359 - case self::TYPE_MEMBER_HAS_ACCOUNT: 360 - return '%s added %d account(s): %s.'; 361 350 case self::TYPE_PURCAHSE_HAS_CHARGE: 362 351 return '%s added %d charge(s): %s.'; 363 352 case self::TYPE_CHARGE_HAS_PURCHASE: ··· 427 416 return '%s removed %d unsubcriber(s): %s.'; 428 417 case self::TYPE_OBJECT_HAS_FILE: 429 418 return '%s removed %d file(s): %s.'; 430 - case self::TYPE_ACCOUNT_HAS_MEMBER: 431 - return '%s removed %d member(s): %s.'; 432 - case self::TYPE_MEMBER_HAS_ACCOUNT: 433 - return '%s removed %d account(s): %s.'; 434 419 case self::TYPE_PURCAHSE_HAS_CHARGE: 435 420 return '%s removed %d charge(s): %s.'; 436 421 case self::TYPE_CHARGE_HAS_PURCHASE: ··· 496 481 return '%s updated unsubcribers of %s.'; 497 482 case self::TYPE_OBJECT_HAS_FILE: 498 483 return '%s updated files of %s.'; 499 - case self::TYPE_ACCOUNT_HAS_MEMBER: 500 - return '%s updated members of %s.'; 501 - case self::TYPE_MEMBER_HAS_ACCOUNT: 502 - return '%s updated accounts of %s.'; 503 484 case self::TYPE_PURCAHSE_HAS_CHARGE: 504 485 return '%s updated charges of %s.'; 505 486 case self::TYPE_CHARGE_HAS_PURCHASE: