diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2550,6 +2550,7 @@ 'PhortuneAccount' => 'applications/phortune/storage/PhortuneAccount.php', 'PhortuneAccountEditController' => 'applications/phortune/controller/PhortuneAccountEditController.php', 'PhortuneAccountEditor' => 'applications/phortune/editor/PhortuneAccountEditor.php', + 'PhortuneAccountHasMemberEdgeType' => 'applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php', 'PhortuneAccountListController' => 'applications/phortune/controller/PhortuneAccountListController.php', 'PhortuneAccountPHIDType' => 'applications/phortune/phid/PhortuneAccountPHIDType.php', 'PhortuneAccountQuery' => 'applications/phortune/query/PhortuneAccountQuery.php', @@ -2581,6 +2582,7 @@ 'PhortuneDAO' => 'applications/phortune/storage/PhortuneDAO.php', 'PhortuneErrCode' => 'applications/phortune/constants/PhortuneErrCode.php', 'PhortuneLandingController' => 'applications/phortune/controller/PhortuneLandingController.php', + 'PhortuneMemberHasAccountEdgeType' => 'applications/phortune/edge/PhortuneMemberHasAccountEdgeType.php', 'PhortuneMerchant' => 'applications/phortune/storage/PhortuneMerchant.php', 'PhortuneMerchantCapability' => 'applications/phortune/capability/PhortuneMerchantCapability.php', 'PhortuneMerchantController' => 'applications/phortune/controller/PhortuneMerchantController.php', @@ -5608,6 +5610,7 @@ ), 'PhortuneAccountEditController' => 'PhortuneController', 'PhortuneAccountEditor' => 'PhabricatorApplicationTransactionEditor', + 'PhortuneAccountHasMemberEdgeType' => 'PhabricatorEdgeType', 'PhortuneAccountListController' => 'PhortuneController', 'PhortuneAccountPHIDType' => 'PhabricatorPHIDType', 'PhortuneAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', @@ -5642,6 +5645,7 @@ 'PhortuneDAO' => 'PhabricatorLiskDAO', 'PhortuneErrCode' => 'PhortuneConstants', 'PhortuneLandingController' => 'PhortuneController', + 'PhortuneMemberHasAccountEdgeType' => 'PhabricatorEdgeType', 'PhortuneMerchant' => array( 'PhortuneDAO', 'PhabricatorPolicyInterface', diff --git a/src/applications/phortune/controller/PhortuneAccountEditController.php b/src/applications/phortune/controller/PhortuneAccountEditController.php --- a/src/applications/phortune/controller/PhortuneAccountEditController.php +++ b/src/applications/phortune/controller/PhortuneAccountEditController.php @@ -28,34 +28,39 @@ $is_new = false; } else { $account = PhortuneAccount::initializeNewAccount($viewer); + $account->attachMemberPHIDs(array($viewer->getPHID())); $is_new = true; } $v_name = $account->getName(); $e_name = true; + + $v_members = $account->getMemberPHIDs(); + $e_members = null; + $validation_exception = null; if ($request->isFormPost()) { $v_name = $request->getStr('name'); + $v_members = $request->getArr('memberPHIDs'); $type_name = PhortuneAccountTransaction::TYPE_NAME; + $type_edge = PhabricatorTransactions::TYPE_EDGE; $xactions = array(); $xactions[] = id(new PhortuneAccountTransaction()) ->setTransactionType($type_name) ->setNewValue($v_name); - if ($is_new) { - $xactions[] = id(new PhortuneAccountTransaction()) - ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) - ->setMetadataValue( - 'edge:type', - PhabricatorEdgeConfig::TYPE_ACCOUNT_HAS_MEMBER) - ->setNewValue( - array( - '=' => array($viewer->getPHID() => $viewer->getPHID()), - )); - } + $xactions[] = id(new PhortuneAccountTransaction()) + ->setTransactionType($type_edge) + ->setMetadataValue( + 'edge:type', + PhortuneAccountHasMemberEdgeType::EDGECONST) + ->setNewValue( + array( + '=' => array_fuse($v_members), + )); $editor = id(new PhortuneAccountEditor()) ->setActor($viewer) @@ -70,6 +75,7 @@ } catch (PhabricatorApplicationTransactionValidationException $ex) { $validation_exception = $ex; $e_name = $ex->getShortMessage($type_name); + $e_members = $ex->getShortMessage($type_edge); } } @@ -91,6 +97,8 @@ $submit_button = pht('Save Changes'); } + $member_handles = $this->loadViewerHandles($v_members); + $form = id(new AphrontFormView()) ->setUser($viewer) ->appendChild( @@ -100,6 +108,13 @@ ->setValue($v_name) ->setError($e_name)) ->appendChild( + id(new AphrontFormTokenizerControl()) + ->setDatasource(new PhabricatorPeopleDatasource()) + ->setLabel(pht('Members')) + ->setName('memberPHIDs') + ->setValue($member_handles) + ->setError($e_members)) + ->appendChild( id(new AphrontFormSubmitControl()) ->setValue($submit_button) ->addCancelButton($cancel_uri)); diff --git a/src/applications/phortune/controller/PhortuneAccountViewController.php b/src/applications/phortune/controller/PhortuneAccountViewController.php --- a/src/applications/phortune/controller/PhortuneAccountViewController.php +++ b/src/applications/phortune/controller/PhortuneAccountViewController.php @@ -53,13 +53,7 @@ ->setIcon('fa-pencil') ->setHref($edit_uri) ->setDisabled(!$can_edit) - ->setWorkflow(!$can_edit)) - ->addAction( - id(new PhabricatorActionView()) - ->setName(pht('Edit Members')) - ->setIcon('fa-users') - ->setHref('#') - ->setDisabled(true)); + ->setWorkflow(!$can_edit)); $crumbs->setActionList($actions); @@ -67,6 +61,12 @@ ->setObject($account) ->setUser($user); + $this->loadHandles($account->getMemberPHIDs()); + + $properties->addProperty( + pht('Members'), + $this->renderHandlesForPHIDs($account->getMemberPHIDs())); + $properties->setActionList($actions); $payment_methods = $this->buildPaymentMethodsSection($account); diff --git a/src/applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php b/src/applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php new file mode 100644 --- /dev/null +++ b/src/applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php @@ -0,0 +1,101 @@ +getMetadataValue('edge:type')) { + case PhortuneAccountHasMemberEdgeType::EDGECONST: + // TODO: This is a bit cumbersome, but validation happens before + // transaction normalization. Maybe provide a cleaner attack on + // this eventually? There's no way to generate "+" or "-" + // transactions right now. + $new = $xaction->getNewValue(); + $set = idx($new, '=', array()); + + if (empty($set[$this->requireActor()->getPHID()])) { + $error = new PhabricatorApplicationTransactionValidationError( + $type, + pht('Invalid'), + pht('You can not remove yourself as an account member.'), + $xaction); + $errors[] = $error; + } + break; + } + } + break; } return $errors; diff --git a/src/applications/phortune/query/PhortuneAccountQuery.php b/src/applications/phortune/query/PhortuneAccountQuery.php --- a/src/applications/phortune/query/PhortuneAccountQuery.php +++ b/src/applications/phortune/query/PhortuneAccountQuery.php @@ -79,11 +79,12 @@ protected function willFilterPage(array $accounts) { $query = id(new PhabricatorEdgeQuery()) ->withSourcePHIDs(mpull($accounts, 'getPHID')) - ->withEdgeTypes(array(PhabricatorEdgeConfig::TYPE_ACCOUNT_HAS_MEMBER)); + ->withEdgeTypes(array(PhortuneAccountHasMemberEdgeType::EDGECONST)); $query->execute(); foreach ($accounts as $account) { $member_phids = $query->getDestinationPHIDs(array($account->getPHID())); + $member_phids = array_reverse($member_phids); $account->attachMemberPHIDs($member_phids); } @@ -127,7 +128,7 @@ $conn, 'LEFT JOIN %T m ON a.phid = m.src AND m.type = %d', PhabricatorEdgeConfig::TABLE_NAME_EDGE, - PhabricatorEdgeConfig::TYPE_ACCOUNT_HAS_MEMBER); + PhortuneAccountHasMemberEdgeType::EDGECONST); } return implode(' ', $joins); diff --git a/src/applications/phortune/storage/PhortuneAccount.php b/src/applications/phortune/storage/PhortuneAccount.php --- a/src/applications/phortune/storage/PhortuneAccount.php +++ b/src/applications/phortune/storage/PhortuneAccount.php @@ -36,7 +36,7 @@ ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) ->setMetadataValue( 'edge:type', - PhabricatorEdgeConfig::TYPE_ACCOUNT_HAS_MEMBER) + PhortuneAccountHasMemberEdgeType::EDGECONST) ->setNewValue( array( '=' => array($actor->getPHID() => $actor->getPHID()), diff --git a/src/applications/phortune/storage/PhortuneAccountTransaction.php b/src/applications/phortune/storage/PhortuneAccountTransaction.php --- a/src/applications/phortune/storage/PhortuneAccountTransaction.php +++ b/src/applications/phortune/storage/PhortuneAccountTransaction.php @@ -37,31 +37,6 @@ $new); } break; - case PhabricatorTransactions::TYPE_EDGE: - switch ($this->getMetadataValue('edge:type')) { - case PhabricatorEdgeConfig::TYPE_ACCOUNT_HAS_MEMBER: - $add = array_diff(array_keys($new), array_keys($old)); - $rem = array_diff(array_keys($old), array_keys($new)); - if ($add && $rem) { - return pht( - '%s changed account members, added %s; removed %s.', - $this->renderHandleLink($author_phid), - $this->renderHandleList($add), - $this->renderHandleList($rem)); - } else if ($add) { - return pht( - '%s added account members: %s', - $this->renderHandleLink($author_phid), - $this->renderHandleList($add)); - } else { - return pht( - '%s removed account members: %s', - $this->renderHandleLink($author_phid), - $this->renderHandleList($add)); - } - break; - } - break; } return parent::getTitle(); diff --git a/src/infrastructure/edges/constants/PhabricatorEdgeConfig.php b/src/infrastructure/edges/constants/PhabricatorEdgeConfig.php --- a/src/infrastructure/edges/constants/PhabricatorEdgeConfig.php +++ b/src/infrastructure/edges/constants/PhabricatorEdgeConfig.php @@ -36,9 +36,6 @@ const TYPE_OBJECT_HAS_FILE = 25; const TYPE_FILE_HAS_OBJECT = 26; - const TYPE_ACCOUNT_HAS_MEMBER = 27; - const TYPE_MEMBER_HAS_ACCOUNT = 28; - const TYPE_PURCAHSE_HAS_CHARGE = 29; const TYPE_CHARGE_HAS_PURCHASE = 30; @@ -103,6 +100,9 @@ array(9000), range(80000, 80005)); + $exclude[] = 27; // Was TYPE_ACCOUNT_HAS_MEMBER + $exclude[] = 28; // Was TYPE_MEMBER_HAS_ACCOUNT + $exclude[] = 43; // Was TYPE_OBJECT_HAS_COLUMN $exclude[] = 44; // Was TYPE_COLUMN_HAS_OBJECT @@ -164,9 +164,6 @@ self::TYPE_OBJECT_HAS_FILE => self::TYPE_FILE_HAS_OBJECT, self::TYPE_FILE_HAS_OBJECT => self::TYPE_OBJECT_HAS_FILE, - self::TYPE_ACCOUNT_HAS_MEMBER => self::TYPE_MEMBER_HAS_ACCOUNT, - self::TYPE_MEMBER_HAS_ACCOUNT => self::TYPE_ACCOUNT_HAS_MEMBER, - self::TYPE_DREV_HAS_COMMIT => self::TYPE_COMMIT_HAS_DREV, self::TYPE_COMMIT_HAS_DREV => self::TYPE_DREV_HAS_COMMIT, @@ -284,10 +281,6 @@ return '%s edited unsubcriber(s), added %d: %s; removed %d: %s.'; case self::TYPE_OBJECT_HAS_FILE: return '%s edited file(s), added %d: %s; removed %d: %s.'; - case self::TYPE_ACCOUNT_HAS_MEMBER: - return '%s edited member(s), added %d: %s; removed %d: %s.'; - case self::TYPE_MEMBER_HAS_ACCOUNT: - return '%s edited account(s), added %d: %s; removed %d: %s.'; case self::TYPE_PURCAHSE_HAS_CHARGE: return '%s edited charge(s), added %d: %s; removed %d: %s.'; case self::TYPE_CHARGE_HAS_PURCHASE: @@ -354,10 +347,6 @@ return '%s added %d unsubcriber(s): %s.'; case self::TYPE_OBJECT_HAS_FILE: return '%s added %d file(s): %s.'; - case self::TYPE_ACCOUNT_HAS_MEMBER: - return '%s added %d member(s): %s.'; - case self::TYPE_MEMBER_HAS_ACCOUNT: - return '%s added %d account(s): %s.'; case self::TYPE_PURCAHSE_HAS_CHARGE: return '%s added %d charge(s): %s.'; case self::TYPE_CHARGE_HAS_PURCHASE: @@ -427,10 +416,6 @@ return '%s removed %d unsubcriber(s): %s.'; case self::TYPE_OBJECT_HAS_FILE: return '%s removed %d file(s): %s.'; - case self::TYPE_ACCOUNT_HAS_MEMBER: - return '%s removed %d member(s): %s.'; - case self::TYPE_MEMBER_HAS_ACCOUNT: - return '%s removed %d account(s): %s.'; case self::TYPE_PURCAHSE_HAS_CHARGE: return '%s removed %d charge(s): %s.'; case self::TYPE_CHARGE_HAS_PURCHASE: @@ -496,10 +481,6 @@ return '%s updated unsubcribers of %s.'; case self::TYPE_OBJECT_HAS_FILE: return '%s updated files of %s.'; - case self::TYPE_ACCOUNT_HAS_MEMBER: - return '%s updated members of %s.'; - case self::TYPE_MEMBER_HAS_ACCOUNT: - return '%s updated accounts of %s.'; case self::TYPE_PURCAHSE_HAS_CHARGE: return '%s updated charges of %s.'; case self::TYPE_CHARGE_HAS_PURCHASE: