Differential D20717 Diff 49434 src/applications/phortune/controller/account/PhortuneAccountController.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/phortune/controller/account/PhortuneAccountController.php
<?php | <?php | ||||
abstract class PhortuneAccountController | abstract class PhortuneAccountController | ||||
extends PhortuneController { | extends PhortuneController { | ||||
private $account; | private $account; | ||||
private $merchants; | |||||
protected function getAccount() { | final public function handleRequest(AphrontRequest $request) { | ||||
return $this->account; | if ($this->shouldRequireAccountEditCapability()) { | ||||
$response = $this->loadAccountForEdit(); | |||||
} else { | |||||
$response = $this->loadAccountForView(); | |||||
} | } | ||||
protected function setAccount(PhortuneAccount $account) { | if ($response) { | ||||
$this->account = $account; | return $response; | ||||
return $this; | } | ||||
return $this->handleAccountRequest($request); | |||||
} | |||||
abstract protected function shouldRequireAccountEditCapability(); | |||||
abstract protected function handleAccountRequest(AphrontRequest $request); | |||||
final protected function getAccount() { | |||||
if ($this->account === null) { | |||||
throw new Exception( | |||||
pht( | |||||
'Unable to "getAccount()" before loading or setting account '. | |||||
'context.')); | |||||
} | |||||
return $this->account; | |||||
} | } | ||||
protected function buildApplicationCrumbs() { | protected function buildApplicationCrumbs() { | ||||
$crumbs = parent::buildApplicationCrumbs(); | $crumbs = parent::buildApplicationCrumbs(); | ||||
$account = $this->getAccount(); | $account = $this->getAccount(); | ||||
if ($account) { | if ($account) { | ||||
$crumbs->addTextCrumb($account->getName(), $account->getURI()); | $crumbs->addTextCrumb($account->getName(), $account->getURI()); | ||||
} | } | ||||
return $crumbs; | return $crumbs; | ||||
} | } | ||||
protected function loadAccount() { | private function loadAccountForEdit() { | ||||
// TODO: Currently, you must be able to edit an account to view the detail | return $this->loadAccountWithCapabilities( | ||||
// page, because the account must be broadly visible so merchants can | array( | ||||
// process orders but merchants should not be able to see all the details | PhabricatorPolicyCapability::CAN_VIEW, | ||||
// of an account. Ideally the profile pages should be visible to merchants, | PhabricatorPolicyCapability::CAN_EDIT, | ||||
// too, just with less information. | )); | ||||
return $this->loadAccountForEdit(); | } | ||||
private function loadAccountForView() { | |||||
return $this->loadAccountWithCapabilities( | |||||
array( | |||||
PhabricatorPolicyCapability::CAN_VIEW, | |||||
)); | |||||
} | } | ||||
protected function loadAccountForEdit() { | private function loadAccountWithCapabilities(array $capabilities) { | ||||
$viewer = $this->getViewer(); | $viewer = $this->getViewer(); | ||||
$request = $this->getRequest(); | $request = $this->getRequest(); | ||||
$account_id = $request->getURIData('accountID'); | $account_id = $request->getURIData('accountID'); | ||||
if (!$account_id) { | if (!$account_id) { | ||||
$account_id = $request->getURIData('id'); | throw new Exception( | ||||
pht( | |||||
'Controller ("%s") extends controller "%s", but is reachable '. | |||||
'with no "accountID" in URI.', | |||||
get_class($this), | |||||
__CLASS__)); | |||||
} | } | ||||
if (!$account_id) { | $account = id(new PhortuneAccountQuery()) | ||||
->setViewer($viewer) | |||||
->withIDs(array($account_id)) | |||||
->requireCapabilities($capabilities) | |||||
->executeOne(); | |||||
if (!$account) { | |||||
return new Aphront404Response(); | return new Aphront404Response(); | ||||
} | } | ||||
$account = id(new PhortuneAccountQuery()) | $this->setAccount($account); | ||||
return null; | |||||
} | |||||
private function setAccount(PhortuneAccount $account) { | |||||
$this->account = $account; | |||||
$viewer = $this->getViewer(); | |||||
if (!$account->isUserAccountMember($viewer)) { | |||||
$merchant_phids = $account->getMerchantPHIDs(); | |||||
$merchants = id(new PhortuneMerchantQuery()) | |||||
->setViewer($viewer) | ->setViewer($viewer) | ||||
->withIDs(array($account_id)) | ->withPHIDs($merchant_phids) | ||||
->withMemberPHIDs(array($viewer->getPHID())) | |||||
->requireCapabilities( | ->requireCapabilities( | ||||
array( | array( | ||||
PhabricatorPolicyCapability::CAN_VIEW, | PhabricatorPolicyCapability::CAN_VIEW, | ||||
PhabricatorPolicyCapability::CAN_EDIT, | PhabricatorPolicyCapability::CAN_EDIT, | ||||
)) | )) | ||||
->executeOne(); | ->execute(); | ||||
if (!$account) { | |||||
return new Aphront404Response(); | $this->merchants = $merchants; | ||||
} else { | |||||
$this->merchants = array(); | |||||
} | } | ||||
$this->account = $account; | return $this; | ||||
} | |||||
final protected function getMerchants() { | |||||
if ($this->merchants === null) { | |||||
throw new Exception( | |||||
pht( | |||||
'Unable to "getMerchants()" before loading or setting account '. | |||||
'context.')); | |||||
} | |||||
return $this->merchants; | |||||
} | |||||
final protected function newAccountAuthorityView() { | |||||
$viewer = $this->getViewer(); | |||||
$merchants = $this->getMerchants(); | |||||
if (!$merchants) { | |||||
return null; | return null; | ||||
} | } | ||||
$merchant_phids = mpull($merchants, 'getPHID'); | |||||
$merchant_handles = $viewer->loadHandles($merchant_phids); | |||||
$merchant_handles = iterator_to_array($merchant_handles); | |||||
$merchant_list = mpull($merchant_handles, 'renderLink'); | |||||
$merchant_list = phutil_implode_html(', ', $merchant_list); | |||||
$merchant_message = pht( | |||||
'You can view this account because you control %d merchant(s) it '. | |||||
'has a relationship with: %s.', | |||||
phutil_count($merchants), | |||||
$merchant_list); | |||||
return id(new PHUIInfoView()) | |||||
->setSeverity(PHUIInfoView::SEVERITY_NOTICE) | |||||
->setErrors( | |||||
array( | |||||
$merchant_message, | |||||
)); | |||||
} | |||||
} | } |