@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<?php
2
3abstract class PhortuneAccountController
4 extends PhortuneController {
5
6 private $account;
7 private $merchants;
8
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);
21 }
22
23 abstract protected function shouldRequireAccountEditCapability();
24 abstract protected function handleAccountRequest(AphrontRequest $request);
25
26 final protected function hasAccount() {
27 return (bool)$this->account;
28 }
29
30 final protected function getAccount() {
31 if ($this->account === null) {
32 throw new Exception(
33 pht(
34 'Unable to "getAccount()" before loading or setting account '.
35 'context.'));
36 }
37
38 return $this->account;
39 }
40
41 protected function buildApplicationCrumbs() {
42 $crumbs = parent::buildApplicationCrumbs();
43
44 // If we hit a policy exception, we can make it here without finding
45 // an account.
46 if ($this->hasAccount()) {
47 $account = $this->getAccount();
48 $crumbs->addTextCrumb($account->getName(), $account->getURI());
49 }
50
51 return $crumbs;
52 }
53
54 private function loadAccountForEdit() {
55 return $this->loadAccountWithCapabilities(
56 array(
57 PhabricatorPolicyCapability::CAN_VIEW,
58 PhabricatorPolicyCapability::CAN_EDIT,
59 ));
60 }
61
62 private function loadAccountForView() {
63 return $this->loadAccountWithCapabilities(
64 array(
65 PhabricatorPolicyCapability::CAN_VIEW,
66 ));
67 }
68
69 private function loadAccountWithCapabilities(array $capabilities) {
70 $viewer = $this->getViewer();
71 $request = $this->getRequest();
72
73 $account_id = $request->getURIData('accountID');
74 if (!$account_id) {
75 throw new Exception(
76 pht(
77 'Controller ("%s") extends controller "%s", but is reachable '.
78 'with no "accountID" in URI.',
79 get_class($this),
80 __CLASS__));
81 }
82
83 $account = id(new PhortuneAccountQuery())
84 ->setViewer($viewer)
85 ->withIDs(array($account_id))
86 ->requireCapabilities($capabilities)
87 ->executeOne();
88 if (!$account) {
89 return new Aphront404Response();
90 }
91
92 $this->setAccount($account);
93
94 return null;
95 }
96
97 private function setAccount(PhortuneAccount $account) {
98 $this->account = $account;
99
100 $viewer = $this->getViewer();
101 if (!$account->isUserAccountMember($viewer)) {
102 $merchant_phids = $account->getMerchantPHIDs();
103 $merchants = id(new PhortuneMerchantQuery())
104 ->setViewer($viewer)
105 ->withPHIDs($merchant_phids)
106 ->withMemberPHIDs(array($viewer->getPHID()))
107 ->requireCapabilities(
108 array(
109 PhabricatorPolicyCapability::CAN_VIEW,
110 PhabricatorPolicyCapability::CAN_EDIT,
111 ))
112 ->execute();
113
114 $this->merchants = $merchants;
115 } else {
116 $this->merchants = array();
117 }
118
119 return $this;
120 }
121
122 final protected function getMerchants() {
123 if ($this->merchants === null) {
124 throw new Exception(
125 pht(
126 'Unable to "getMerchants()" before loading or setting account '.
127 'context.'));
128 }
129
130 return $this->merchants;
131 }
132
133 final protected function newAccountAuthorityView() {
134 $viewer = $this->getViewer();
135
136 $merchants = $this->getMerchants();
137 if (!$merchants) {
138 return null;
139 }
140
141 $merchant_phids = mpull($merchants, 'getPHID');
142 $merchant_handles = $viewer->loadHandles($merchant_phids);
143 $merchant_handles = iterator_to_array($merchant_handles);
144
145 $merchant_list = mpull($merchant_handles, 'renderLink');
146 $merchant_list = phutil_implode_html(', ', $merchant_list);
147
148 $merchant_message = pht(
149 'You can view this account because you control %s merchant(s) it '.
150 'has a relationship with: %s.',
151 phutil_count($merchants),
152 $merchant_list);
153
154 return id(new PHUIInfoView())
155 ->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
156 ->setErrors(
157 array(
158 $merchant_message,
159 ));
160 }
161
162}