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

Update Phortune payment account interfaces to handle merchant vs customer views

Summary: Depends on D20716. Ref T13366. This implements the new policy behavior cleanly in all top-level Phortune payment account interfaces.

Test Plan: As a merchant with an account relationship (not an account member) and an account member, browsed all account interfaces and attempted to perform edits. As a merchant, saw a reduced-strength view.

Maniphest Tasks: T13366

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

+277 -149
+3 -3
src/__phutil_library_map__.php
··· 5222 5222 'PhortuneAccountAddManagerController' => 'applications/phortune/controller/account/PhortuneAccountAddManagerController.php', 5223 5223 'PhortuneAccountBillingAddressTransaction' => 'applications/phortune/xaction/PhortuneAccountBillingAddressTransaction.php', 5224 5224 'PhortuneAccountBillingNameTransaction' => 'applications/phortune/xaction/PhortuneAccountBillingNameTransaction.php', 5225 - 'PhortuneAccountChargeListController' => 'applications/phortune/controller/account/PhortuneAccountChargeListController.php', 5226 5225 'PhortuneAccountChargesController' => 'applications/phortune/controller/account/PhortuneAccountChargesController.php', 5227 5226 'PhortuneAccountController' => 'applications/phortune/controller/account/PhortuneAccountController.php', 5228 5227 'PhortuneAccountDetailsController' => 'applications/phortune/controller/account/PhortuneAccountDetailsController.php', ··· 5277 5276 'PhortuneCartUpdateController' => 'applications/phortune/controller/cart/PhortuneCartUpdateController.php', 5278 5277 'PhortuneCartViewController' => 'applications/phortune/controller/cart/PhortuneCartViewController.php', 5279 5278 'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php', 5279 + 'PhortuneChargeListController' => 'applications/phortune/controller/charge/PhortuneChargeListController.php', 5280 5280 'PhortuneChargePHIDType' => 'applications/phortune/phid/PhortuneChargePHIDType.php', 5281 5281 'PhortuneChargeQuery' => 'applications/phortune/query/PhortuneChargeQuery.php', 5282 5282 'PhortuneChargeSearchEngine' => 'applications/phortune/query/PhortuneChargeSearchEngine.php', ··· 11769 11769 'PhabricatorApplicationTransactionInterface', 11770 11770 'PhabricatorPolicyInterface', 11771 11771 ), 11772 - 'PhortuneAccountAddManagerController' => 'PhortuneController', 11772 + 'PhortuneAccountAddManagerController' => 'PhortuneAccountController', 11773 11773 'PhortuneAccountBillingAddressTransaction' => 'PhortuneAccountTransactionType', 11774 11774 'PhortuneAccountBillingNameTransaction' => 'PhortuneAccountTransactionType', 11775 - 'PhortuneAccountChargeListController' => 'PhortuneController', 11776 11775 'PhortuneAccountChargesController' => 'PhortuneAccountProfileController', 11777 11776 'PhortuneAccountController' => 'PhortuneController', 11778 11777 'PhortuneAccountDetailsController' => 'PhortuneAccountProfileController', ··· 11839 11838 'PhortuneDAO', 11840 11839 'PhabricatorPolicyInterface', 11841 11840 ), 11841 + 'PhortuneChargeListController' => 'PhortuneController', 11842 11842 'PhortuneChargePHIDType' => 'PhabricatorPHIDType', 11843 11843 'PhortuneChargeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 11844 11844 'PhortuneChargeSearchEngine' => 'PhabricatorApplicationSearchEngine',
+4 -8
src/applications/phortune/application/PhabricatorPhortuneApplication.php
··· 39 39 'card/' => array( 40 40 'new/' => 'PhortunePaymentMethodCreateController', 41 41 ), 42 - 'order/(?:query/(?P<queryKey>[^/]+)/)?' 43 - => 'PhortuneCartListController', 44 42 'subscription/' => array( 45 43 '(?:query/(?P<queryKey>[^/]+)/)?' 46 44 => 'PhortuneSubscriptionListController', ··· 51 49 'order/(?P<subscriptionID>\d+)/' 52 50 => 'PhortuneCartListController', 53 51 ), 52 + 'order/(?:query/(?P<queryKey>[^/]+)/)?' 53 + => 'PhortuneCartListController', 54 54 'charge/(?:query/(?P<queryKey>[^/]+)/)?' 55 - => 'PhortuneAccountChargeListController', 55 + => 'PhortuneChargeListController', 56 56 ), 57 57 'card/(?P<id>\d+)/' => array( 58 58 'edit/' => 'PhortunePaymentMethodEditController', ··· 82 82 ), 83 83 'addresses/' => array( 84 84 '' => 'PhortuneAccountEmailAddressesController', 85 + '(?P<id>\d+)/' => 'PhortuneAccountEmailViewController', 85 86 $this->getEditRoutePattern('edit/') 86 87 => 'PhortuneAccountEmailEditController', 87 88 ), 88 89 ), 89 - ), 90 - 'address/' => array( 91 - '(?P<id>\d+)/' => 'PhortuneAccountEmailViewController', 92 - $this->getEditRoutePattern('edit/') 93 - => 'PhortuneAccountEmailEditController', 94 90 ), 95 91 'product/' => array( 96 92 '' => 'PhortuneProductListController',
+23 -18
src/applications/phortune/controller/account/PhortuneAccountAddManagerController.php
··· 1 1 <?php 2 2 3 - final class PhortuneAccountAddManagerController extends PhortuneController { 3 + final class PhortuneAccountAddManagerController 4 + extends PhortuneAccountController { 5 + 6 + protected function shouldRequireAccountEditCapability() { 7 + return true; 8 + } 4 9 5 - public function handleRequest(AphrontRequest $request) { 10 + protected function handleAccountRequest(AphrontRequest $request) { 6 11 $viewer = $request->getViewer(); 7 - $id = $request->getURIData('accountID'); 12 + $account = $this->getAccount(); 8 13 9 - $account = id(new PhortuneAccountQuery()) 10 - ->setViewer($viewer) 11 - ->withIDs(array($id)) 12 - ->requireCapabilities( 13 - array( 14 - PhabricatorPolicyCapability::CAN_VIEW, 15 - PhabricatorPolicyCapability::CAN_EDIT, 16 - )) 17 - ->executeOne(); 18 - if (!$account) { 19 - return new Aphront404Response(); 20 - } 14 + $id = $account->getID(); 21 15 22 16 $v_managers = array(); 23 17 $e_managers = null; ··· 53 47 } 54 48 } 55 49 50 + $account_phid = $account->getPHID(); 51 + $handles = $viewer->loadHandles(array($account_phid)); 52 + $handle = $handles[$account_phid]; 53 + 56 54 $form = id(new AphrontFormView()) 57 - ->setUser($viewer) 55 + ->setViewer($viewer) 56 + ->appendInstructions( 57 + pht( 58 + 'Choose one or more users to add as account managers. Managers '. 59 + 'have full control of the account.')) 60 + ->appendControl( 61 + id(new AphrontFormStaticControl()) 62 + ->setLabel(pht('Payment Account')) 63 + ->setValue($handle->renderLink())) 58 64 ->appendControl( 59 65 id(new AphrontFormTokenizerControl()) 60 66 ->setDatasource(new PhabricatorPeopleDatasource()) 61 - ->setLabel(pht('Managers')) 67 + ->setLabel(pht('Add Managers')) 62 68 ->setName('managerPHIDs') 63 69 ->setValue($v_managers) 64 70 ->setError($e_managers)); ··· 69 75 ->setWidth(AphrontDialogView::WIDTH_FORM) 70 76 ->addCancelButton($account_uri) 71 77 ->addSubmitButton(pht('Add Managers')); 72 - 73 78 } 74 79 75 80 }
+1 -1
src/applications/phortune/controller/account/PhortuneAccountChargeListController.php src/applications/phortune/controller/charge/PhortuneChargeListController.php
··· 1 1 <?php 2 2 3 - final class PhortuneAccountChargeListController 3 + final class PhortuneChargeListController 4 4 extends PhortuneController { 5 5 6 6 private $account;
+9 -7
src/applications/phortune/controller/account/PhortuneAccountChargesController.php
··· 3 3 final class PhortuneAccountChargesController 4 4 extends PhortuneAccountProfileController { 5 5 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadAccount(); 8 - if ($response) { 9 - return $response; 10 - } 6 + protected function shouldRequireAccountEditCapability() { 7 + return false; 8 + } 11 9 10 + protected function handleAccountRequest(AphrontRequest $request) { 12 11 $account = $this->getAccount(); 13 12 $title = $account->getName(); 14 13 15 - $crumbs = $this->buildApplicationCrumbs(); 16 - $crumbs->addTextCrumb(pht('Order History')); 14 + $crumbs = $this->buildApplicationCrumbs() 15 + ->addTextCrumb(pht('Order History')) 16 + ->setBorder(true); 17 17 18 18 $header = $this->buildHeaderView(); 19 + $authority = $this->newAccountAuthorityView(); 19 20 $charge_history = $this->buildChargeHistorySection($account); 20 21 21 22 $view = id(new PHUITwoColumnView()) 22 23 ->setHeader($header) 23 24 ->setFooter( 24 25 array( 26 + $authority, 25 27 $charge_history, 26 28 )); 27 29
+112 -24
src/applications/phortune/controller/account/PhortuneAccountController.php
··· 4 4 extends PhortuneController { 5 5 6 6 private $account; 7 + private $merchants; 7 8 8 - protected function getAccount() { 9 - return $this->account; 9 + final public function handleRequest(AphrontRequest $request) { 10 + if ($this->shouldRequireAccountEditCapability()) { 11 + $response = $this->loadAccountForEdit(); 12 + } else { 13 + $response = $this->loadAccountForView(); 14 + } 15 + 16 + if ($response) { 17 + return $response; 18 + } 19 + 20 + return $this->handleAccountRequest($request); 10 21 } 11 22 12 - protected function setAccount(PhortuneAccount $account) { 13 - $this->account = $account; 14 - return $this; 23 + abstract protected function shouldRequireAccountEditCapability(); 24 + abstract protected function handleAccountRequest(AphrontRequest $request); 25 + 26 + final protected function getAccount() { 27 + if ($this->account === null) { 28 + throw new Exception( 29 + pht( 30 + 'Unable to "getAccount()" before loading or setting account '. 31 + 'context.')); 32 + } 33 + 34 + return $this->account; 15 35 } 16 36 17 37 protected function buildApplicationCrumbs() { ··· 25 45 return $crumbs; 26 46 } 27 47 28 - protected function loadAccount() { 29 - // TODO: Currently, you must be able to edit an account to view the detail 30 - // page, because the account must be broadly visible so merchants can 31 - // process orders but merchants should not be able to see all the details 32 - // of an account. Ideally the profile pages should be visible to merchants, 33 - // too, just with less information. 34 - return $this->loadAccountForEdit(); 48 + private function loadAccountForEdit() { 49 + return $this->loadAccountWithCapabilities( 50 + array( 51 + PhabricatorPolicyCapability::CAN_VIEW, 52 + PhabricatorPolicyCapability::CAN_EDIT, 53 + )); 54 + } 55 + 56 + private function loadAccountForView() { 57 + return $this->loadAccountWithCapabilities( 58 + array( 59 + PhabricatorPolicyCapability::CAN_VIEW, 60 + )); 35 61 } 36 62 37 - protected function loadAccountForEdit() { 63 + private function loadAccountWithCapabilities(array $capabilities) { 38 64 $viewer = $this->getViewer(); 39 65 $request = $this->getRequest(); 40 66 41 67 $account_id = $request->getURIData('accountID'); 42 68 if (!$account_id) { 43 - $account_id = $request->getURIData('id'); 44 - } 45 - 46 - if (!$account_id) { 47 - return new Aphront404Response(); 69 + throw new Exception( 70 + pht( 71 + 'Controller ("%s") extends controller "%s", but is reachable '. 72 + 'with no "accountID" in URI.', 73 + get_class($this), 74 + __CLASS__)); 48 75 } 49 76 50 77 $account = id(new PhortuneAccountQuery()) 51 78 ->setViewer($viewer) 52 79 ->withIDs(array($account_id)) 53 - ->requireCapabilities( 54 - array( 55 - PhabricatorPolicyCapability::CAN_VIEW, 56 - PhabricatorPolicyCapability::CAN_EDIT, 57 - )) 80 + ->requireCapabilities($capabilities) 58 81 ->executeOne(); 59 82 if (!$account) { 60 83 return new Aphront404Response(); 61 84 } 62 85 86 + $this->setAccount($account); 87 + 88 + return null; 89 + } 90 + 91 + private function setAccount(PhortuneAccount $account) { 63 92 $this->account = $account; 64 93 65 - return null; 94 + $viewer = $this->getViewer(); 95 + if (!$account->isUserAccountMember($viewer)) { 96 + $merchant_phids = $account->getMerchantPHIDs(); 97 + $merchants = id(new PhortuneMerchantQuery()) 98 + ->setViewer($viewer) 99 + ->withPHIDs($merchant_phids) 100 + ->withMemberPHIDs(array($viewer->getPHID())) 101 + ->requireCapabilities( 102 + array( 103 + PhabricatorPolicyCapability::CAN_VIEW, 104 + PhabricatorPolicyCapability::CAN_EDIT, 105 + )) 106 + ->execute(); 107 + 108 + $this->merchants = $merchants; 109 + } else { 110 + $this->merchants = array(); 111 + } 112 + 113 + return $this; 114 + } 115 + 116 + final protected function getMerchants() { 117 + if ($this->merchants === null) { 118 + throw new Exception( 119 + pht( 120 + 'Unable to "getMerchants()" before loading or setting account '. 121 + 'context.')); 122 + } 123 + 124 + return $this->merchants; 125 + } 126 + 127 + final protected function newAccountAuthorityView() { 128 + $viewer = $this->getViewer(); 129 + 130 + $merchants = $this->getMerchants(); 131 + if (!$merchants) { 132 + return null; 133 + } 134 + 135 + $merchant_phids = mpull($merchants, 'getPHID'); 136 + $merchant_handles = $viewer->loadHandles($merchant_phids); 137 + $merchant_handles = iterator_to_array($merchant_handles); 138 + 139 + $merchant_list = mpull($merchant_handles, 'renderLink'); 140 + $merchant_list = phutil_implode_html(', ', $merchant_list); 141 + 142 + $merchant_message = pht( 143 + 'You can view this account because you control %d merchant(s) it '. 144 + 'has a relationship with: %s.', 145 + phutil_count($merchants), 146 + $merchant_list); 147 + 148 + return id(new PHUIInfoView()) 149 + ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) 150 + ->setErrors( 151 + array( 152 + $merchant_message, 153 + )); 66 154 } 67 155 68 156 }
+6 -5
src/applications/phortune/controller/account/PhortuneAccountDetailsController.php
··· 3 3 final class PhortuneAccountDetailsController 4 4 extends PhortuneAccountProfileController { 5 5 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadAccount(); 8 - if ($response) { 9 - return $response; 10 - } 6 + protected function shouldRequireAccountEditCapability() { 7 + return true; 8 + } 11 9 10 + protected function handleAccountRequest(AphrontRequest $request) { 12 11 $account = $this->getAccount(); 13 12 $title = $account->getName(); 14 13 ··· 26 25 27 26 $header = $this->buildHeaderView(); 28 27 28 + $authority = $this->newAccountAuthorityView(); 29 29 $details = $this->newDetailsView($account); 30 30 31 31 $curtain = $this->buildCurtainView($account); ··· 41 41 ->setCurtain($curtain) 42 42 ->setMainColumn( 43 43 array( 44 + $authority, 44 45 $details, 45 46 $timeline, 46 47 ));
+9 -7
src/applications/phortune/controller/account/PhortuneAccountEmailAddressesController.php
··· 3 3 final class PhortuneAccountEmailAddressesController 4 4 extends PhortuneAccountProfileController { 5 5 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadAccount(); 8 - if ($response) { 9 - return $response; 10 - } 6 + protected function shouldRequireAccountEditCapability() { 7 + return true; 8 + } 11 9 10 + protected function handleAccountRequest(AphrontRequest $request) { 12 11 $account = $this->getAccount(); 13 12 $title = $account->getName(); 14 13 15 - $crumbs = $this->buildApplicationCrumbs(); 16 - $crumbs->addTextCrumb(pht('Email Addresses')); 14 + $crumbs = $this->buildApplicationCrumbs() 15 + ->addTextCrumb(pht('Email Addresses')) 16 + ->setBorder(true); 17 17 18 18 $header = $this->buildHeaderView(); 19 + $authority = $this->newAccountAuthorityView(); 19 20 $addresses = $this->buildAddressesSection($account); 20 21 21 22 $view = id(new PHUITwoColumnView()) 22 23 ->setHeader($header) 23 24 ->setFooter( 24 25 array( 26 + $authority, 25 27 $addresses, 26 28 )); 27 29
+7 -13
src/applications/phortune/controller/account/PhortuneAccountEmailEditController.php
··· 3 3 final class PhortuneAccountEmailEditController 4 4 extends PhortuneAccountController { 5 5 6 - public function handleRequest(AphrontRequest $request) { 6 + protected function shouldRequireAccountEditCapability() { 7 + return true; 8 + } 9 + 10 + protected function handleAccountRequest(AphrontRequest $request) { 11 + $account = $this->getAccount(); 12 + 7 13 $engine = id(new PhortuneAccountEmailEditEngine()) 8 14 ->setController($this); 9 15 10 16 if (!$request->getURIData('id')) { 11 - 12 - if (!$request->getURIData('accountID')) { 13 - return new Aphront404Response(); 14 - } 15 - 16 - $response = $this->loadAccount(); 17 - if ($response) { 18 - return $response; 19 - } 20 - 21 - $account = $this->getAccount(); 22 - 23 17 $engine->setAccount($account); 24 18 } 25 19
+9 -5
src/applications/phortune/controller/account/PhortuneAccountEmailViewController.php
··· 3 3 final class PhortuneAccountEmailViewController 4 4 extends PhortuneAccountController { 5 5 6 - public function handleRequest(AphrontRequest $request) { 6 + protected function shouldRequireAccountEditCapability() { 7 + return true; 8 + } 9 + 10 + protected function handleAccountRequest(AphrontRequest $request) { 7 11 $viewer = $this->getViewer(); 12 + $account = $this->getAccount(); 8 13 9 14 $address = id(new PhortuneAccountEmailQuery()) 10 15 ->setViewer($viewer) 16 + ->withAccountPHIDs(array($account->getPHID())) 11 17 ->withIDs(array($request->getURIData('id'))) 12 18 ->executeOne(); 13 19 if (!$address) { 14 20 return new Aphront404Response(); 15 21 } 16 - 17 - $account = $address->getAccount(); 18 - $this->setAccount($account); 19 22 20 23 $crumbs = $this->buildApplicationCrumbs() 21 24 ->addTextCrumb(pht('Email Addresses'), $account->getEmailAddressesURI()) ··· 61 64 62 65 $edit_uri = $this->getApplicationURI( 63 66 urisprintf( 64 - 'address/edit/%d/', 67 + 'account/%d/addresses/edit/%d/', 68 + $account->getID(), 65 69 $address->getID())); 66 70 67 71 $curtain = $this->newCurtainView($account);
+13 -10
src/applications/phortune/controller/account/PhortuneAccountManagersController.php
··· 3 3 final class PhortuneAccountManagersController 4 4 extends PhortuneAccountProfileController { 5 5 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadAccount(); 8 - if ($response) { 9 - return $response; 10 - } 6 + protected function shouldRequireAccountEditCapability() { 7 + return false; 8 + } 11 9 10 + protected function handleAccountRequest(AphrontRequest $request) { 12 11 $account = $this->getAccount(); 13 12 $title = $account->getName(); 14 13 15 - $crumbs = $this->buildApplicationCrumbs(); 16 - $crumbs->addTextCrumb(pht('Managers')); 14 + $crumbs = $this->buildApplicationCrumbs() 15 + ->addTextCrumb(pht('Managers')) 16 + ->setBorder(true); 17 17 18 18 $header = $this->buildHeaderView(); 19 + $authority = $this->newAccountAuthorityView(); 19 20 $members = $this->buildMembersSection($account); 20 21 21 22 $view = id(new PHUITwoColumnView()) 22 23 ->setHeader($header) 23 - ->setFooter(array( 24 - $members, 25 - )); 24 + ->setFooter( 25 + array( 26 + $authority, 27 + $members, 28 + )); 26 29 27 30 $navigation = $this->buildSideNavView('managers'); 28 31
+10 -7
src/applications/phortune/controller/account/PhortuneAccountOrdersController.php
··· 3 3 final class PhortuneAccountOrdersController 4 4 extends PhortuneAccountProfileController { 5 5 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadAccount(); 8 - if ($response) { 9 - return $response; 10 - } 6 + protected function shouldRequireAccountEditCapability() { 7 + return false; 8 + } 11 9 10 + protected function handleAccountRequest(AphrontRequest $request) { 12 11 $account = $this->getAccount(); 13 12 $title = $account->getName(); 14 13 15 - $crumbs = $this->buildApplicationCrumbs(); 16 - $crumbs->addTextCrumb(pht('Order History')); 14 + $crumbs = $this->buildApplicationCrumbs() 15 + ->addTextCrumb(pht('Order History')) 16 + ->setBorder(true); 17 17 18 18 $header = $this->buildHeaderView(); 19 + $authority = $this->newAccountAuthorityView(); 20 + 19 21 $order_history = $this->newRecentOrdersView($account, 100); 20 22 21 23 $view = id(new PHUITwoColumnView()) 22 24 ->setHeader($header) 23 25 ->setFooter( 24 26 array( 27 + $authority, 25 28 $order_history, 26 29 )); 27 30
+6 -5
src/applications/phortune/controller/account/PhortuneAccountOverviewController.php
··· 3 3 final class PhortuneAccountOverviewController 4 4 extends PhortuneAccountProfileController { 5 5 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadAccount(); 8 - if ($response) { 9 - return $response; 10 - } 6 + protected function shouldRequireAccountEditCapability() { 7 + return false; 8 + } 11 9 10 + protected function handleAccountRequest(AphrontRequest $request) { 12 11 $account = $this->getAccount(); 13 12 $title = $account->getName(); 14 13 ··· 26 25 27 26 $header = $this->buildHeaderView(); 28 27 28 + $authority = $this->newAccountAuthorityView(); 29 29 $status = $this->buildStatusView($account, $invoices); 30 30 $invoices = $this->buildInvoicesSection($account, $invoices); 31 31 $purchase_history = $this->newRecentOrdersView($account, 10); ··· 34 34 ->setHeader($header) 35 35 ->setFooter( 36 36 array( 37 + $authority, 37 38 $status, 38 39 $invoices, 39 40 $purchase_history,
+9 -7
src/applications/phortune/controller/account/PhortuneAccountPaymentMethodsController.php
··· 3 3 final class PhortuneAccountPaymentMethodsController 4 4 extends PhortuneAccountProfileController { 5 5 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadAccount(); 8 - if ($response) { 9 - return $response; 10 - } 6 + protected function shouldRequireAccountEditCapability() { 7 + return false; 8 + } 11 9 10 + protected function handleAccountRequest(AphrontRequest $request) { 12 11 $account = $this->getAccount(); 13 12 $title = $account->getName(); 14 13 15 - $crumbs = $this->buildApplicationCrumbs(); 16 - $crumbs->addTextCrumb(pht('Payment Methods')); 14 + $crumbs = $this->buildApplicationCrumbs() 15 + ->addTextCrumb(pht('Payment Methods')) 16 + ->setBorder(true); 17 17 18 + $authority = $this->newAccountAuthorityView(); 18 19 $header = $this->buildHeaderView(); 19 20 $methods = $this->buildPaymentMethodsSection($account); 20 21 ··· 22 23 ->setHeader($header) 23 24 ->setFooter( 24 25 array( 26 + $authority, 25 27 $methods, 26 28 )); 27 29
+23 -16
src/applications/phortune/controller/account/PhortuneAccountProfileController.php
··· 17 17 ->setHeader($title) 18 18 ->setHeaderIcon('fa-user-circle'); 19 19 20 - return $header; 21 - } 20 + if ($this->getMerchants()) { 21 + $customer_tag = id(new PHUITagView()) 22 + ->setType(PHUITagView::TYPE_SHADE) 23 + ->setName(pht('Customer Account')) 24 + ->setColor('indigo') 25 + ->setIcon('fa-credit-card'); 26 + $header->addTag($customer_tag); 27 + } 22 28 23 - protected function buildApplicationCrumbs() { 24 - $crumbs = parent::buildApplicationCrumbs(); 25 - $crumbs->setBorder(true); 26 - return $crumbs; 29 + return $header; 27 30 } 28 31 29 32 protected function buildSideNavView($filter = null) { 30 33 $viewer = $this->getViewer(); 31 34 $account = $this->getAccount(); 32 35 $id = $account->getID(); 36 + 37 + $can_edit = !$this->getMerchants(); 33 38 34 39 $nav = id(new AphrontSideNavFilterView()) 35 40 ->setBaseURI(new PhutilURI($this->getApplicationURI())); ··· 42 47 $this->getApplicationURI("/{$id}/"), 43 48 'fa-user-circle'); 44 49 45 - $nav->addFilter( 46 - 'details', 47 - pht('Account Details'), 48 - $this->getApplicationURI("/account/{$id}/details/"), 49 - 'fa-address-card-o'); 50 + $nav->newLink('details') 51 + ->setName(pht('Account Details')) 52 + ->setHref($this->getApplicationURI("/account/{$id}/details/")) 53 + ->setIcon('fa-address-card-o') 54 + ->setWorkflow(!$can_edit) 55 + ->setDisabled(!$can_edit); 50 56 51 57 $nav->addLabel(pht('Payments')); 52 58 ··· 82 88 $this->getApplicationURI("/account/{$id}/managers/"), 83 89 'fa-group'); 84 90 85 - $nav->addFilter( 86 - 'addresses', 87 - pht('Email Addresses'), 88 - $this->getApplicationURI("/account/{$id}/addresses/"), 89 - 'fa-envelope-o'); 91 + $nav->newLink('addresses') 92 + ->setname(pht('Email Addresses')) 93 + ->setHref($this->getApplicationURI("/account/{$id}/addresses/")) 94 + ->setIcon('fa-envelope-o') 95 + ->setWorkflow(!$can_edit) 96 + ->setDisabled(!$can_edit); 90 97 91 98 $nav->selectFilter($filter); 92 99
+14 -10
src/applications/phortune/controller/account/PhortuneAccountSubscriptionController.php
··· 3 3 final class PhortuneAccountSubscriptionController 4 4 extends PhortuneAccountProfileController { 5 5 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadAccount(); 8 - if ($response) { 9 - return $response; 10 - } 6 + protected function shouldRequireAccountEditCapability() { 7 + return false; 8 + } 11 9 10 + protected function handleAccountRequest(AphrontRequest $request) { 12 11 $account = $this->getAccount(); 13 12 $title = $account->getName(); 14 13 15 - $crumbs = $this->buildApplicationCrumbs(); 16 - $crumbs->addTextCrumb(pht('Subscriptions')); 14 + $crumbs = $this->buildApplicationCrumbs() 15 + ->addTextCrumb(pht('Subscriptions')) 16 + ->setBorder(true); 17 17 18 18 $header = $this->buildHeaderView(); 19 + $authority = $this->newAccountAuthorityView(); 20 + 19 21 $subscriptions = $this->buildSubscriptionsSection($account); 20 22 21 23 $view = id(new PHUITwoColumnView()) 22 24 ->setHeader($header) 23 - ->setFooter(array( 24 - $subscriptions, 25 - )); 25 + ->setFooter( 26 + array( 27 + $authority, 28 + $subscriptions, 29 + )); 26 30 27 31 $navigation = $this->buildSideNavView('subscriptions'); 28 32
+12 -2
src/applications/phortune/storage/PhortuneAccount.php
··· 138 138 return $this; 139 139 } 140 140 141 + public function isUserAccountMember(PhabricatorUser $user) { 142 + $user_phid = $user->getPHID(); 143 + if (!$user_phid) { 144 + return null; 145 + } 146 + 147 + $member_map = array_fuse($this->getMemberPHIDs()); 148 + 149 + return isset($member_map[$user_phid]); 150 + } 151 + 141 152 /* -( PhabricatorApplicationTransactionInterface )------------------------- */ 142 153 143 154 ··· 174 185 } 175 186 176 187 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { 177 - $members = array_fuse($this->getMemberPHIDs()); 178 - if (isset($members[$viewer->getPHID()])) { 188 + if ($this->isUserAccountMember($viewer)) { 179 189 return true; 180 190 } 181 191
+2 -1
src/applications/phortune/storage/PhortuneAccountEmail.php
··· 73 73 74 74 public function getURI() { 75 75 return urisprintf( 76 - '/phortune/address/%d/', 76 + '/phortune/account/%d/addresses/%d/', 77 + $this->getAccount()->getID(), 77 78 $this->getID()); 78 79 } 79 80
+5
src/view/layout/AphrontSideNavFilterView.php
··· 111 111 $key, $name, $uri, PHUIListItemView::TYPE_BUTTON); 112 112 } 113 113 114 + public function newLink($key) { 115 + $this->addFilter($key, ''); 116 + return $this->getMenuView()->getItem($key); 117 + } 118 + 114 119 private function addThing($key, $name, $uri, $type, $icon = null) { 115 120 $item = id(new PHUIListItemView()) 116 121 ->setName($name)