@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
3final class PhortuneMerchantQuery
4 extends PhabricatorCursorPagedPolicyAwareQuery {
5
6 private $ids;
7 private $phids;
8 private $memberPHIDs;
9 private $needProfileImage;
10
11 public function withIDs(array $ids) {
12 $this->ids = $ids;
13 return $this;
14 }
15
16 public function withPHIDs(array $phids) {
17 $this->phids = $phids;
18 return $this;
19 }
20
21 public function withMemberPHIDs(array $member_phids) {
22 $this->memberPHIDs = $member_phids;
23 return $this;
24 }
25
26 public function needProfileImage($need) {
27 $this->needProfileImage = $need;
28 return $this;
29 }
30
31 public function newResultObject() {
32 return new PhortuneMerchant();
33 }
34
35 protected function willFilterPage(array $merchants) {
36 $query = id(new PhabricatorEdgeQuery())
37 ->withSourcePHIDs(mpull($merchants, 'getPHID'))
38 ->withEdgeTypes(array(PhortuneMerchantHasMemberEdgeType::EDGECONST));
39 $query->execute();
40
41 foreach ($merchants as $merchant) {
42 $member_phids = $query->getDestinationPHIDs(array($merchant->getPHID()));
43 $member_phids = array_reverse($member_phids);
44 $merchant->attachMemberPHIDs($member_phids);
45 }
46
47 if ($this->needProfileImage) {
48 $default = null;
49 $file_phids = mpull($merchants, 'getProfileImagePHID');
50 $file_phids = array_filter($file_phids);
51 if ($file_phids) {
52 $files = id(new PhabricatorFileQuery())
53 ->setParentQuery($this)
54 ->setViewer($this->getViewer())
55 ->withPHIDs($file_phids)
56 ->execute();
57 $files = mpull($files, null, 'getPHID');
58 } else {
59 $files = array();
60 }
61
62 foreach ($merchants as $merchant) {
63 $file = idx($files, $merchant->getProfileImagePHID());
64 if (!$file) {
65 if (!$default) {
66 $default = PhabricatorFile::loadBuiltin(
67 $this->getViewer(),
68 'merchant.png');
69 }
70 $file = $default;
71 }
72 $merchant->attachProfileImageFile($file);
73 }
74 }
75
76 return $merchants;
77 }
78
79 protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
80 $where = parent::buildWhereClauseParts($conn);
81
82 if ($this->ids !== null) {
83 $where[] = qsprintf(
84 $conn,
85 'merchant.id IN (%Ld)',
86 $this->ids);
87 }
88
89 if ($this->phids !== null) {
90 $where[] = qsprintf(
91 $conn,
92 'merchant.phid IN (%Ls)',
93 $this->phids);
94 }
95
96 if ($this->memberPHIDs !== null) {
97 $where[] = qsprintf(
98 $conn,
99 'e.dst IN (%Ls)',
100 $this->memberPHIDs);
101 }
102
103 return $where;
104 }
105
106 protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {
107 $joins = parent::buildJoinClauseParts($conn);
108
109 if ($this->memberPHIDs !== null) {
110 $joins[] = qsprintf(
111 $conn,
112 'LEFT JOIN %T e ON merchant.phid = e.src AND e.type = %d',
113 PhabricatorEdgeConfig::TABLE_NAME_EDGE,
114 PhortuneMerchantHasMemberEdgeType::EDGECONST);
115 }
116
117 return $joins;
118 }
119
120 public function getQueryApplicationClass() {
121 return PhabricatorPhortuneApplication::class;
122 }
123
124 protected function getPrimaryTableAlias() {
125 return 'merchant';
126 }
127
128 public static function canViewersEditMerchants(
129 array $viewer_phids,
130 array $merchant_phids) {
131
132 // See T13366 for some discussion. This is an unusual caching construct to
133 // make policy filtering of Accounts easier.
134
135 foreach ($viewer_phids as $key => $viewer_phid) {
136 if (!$viewer_phid) {
137 unset($viewer_phids[$key]);
138 }
139 }
140
141 if (!$viewer_phids) {
142 return array();
143 }
144
145 $cache_key = 'phortune.merchant.can-edit';
146 $cache = PhabricatorCaches::getRequestCache();
147
148 $cache_data = $cache->getKey($cache_key);
149 if (!$cache_data) {
150 $cache_data = array();
151 }
152
153 $load_phids = array();
154 foreach ($viewer_phids as $viewer_phid) {
155 if (!isset($cache_data[$viewer_phid])) {
156 $load_phids[] = $viewer_phid;
157 }
158 }
159
160 $did_write = false;
161 foreach ($load_phids as $load_phid) {
162 $merchants = id(new self())
163 ->setViewer(PhabricatorUser::getOmnipotentUser())
164 ->withMemberPHIDs(array($load_phid))
165 ->execute();
166 foreach ($merchants as $merchant) {
167 $cache_data[$load_phid][$merchant->getPHID()] = true;
168 $did_write = true;
169 }
170 }
171
172 if ($did_write) {
173 $cache->setKey($cache_key, $cache_data);
174 }
175
176 $results = array();
177 foreach ($viewer_phids as $viewer_phid) {
178 foreach ($merchant_phids as $merchant_phid) {
179 if (!isset($cache_data[$viewer_phid][$merchant_phid])) {
180 continue;
181 }
182 $results[$viewer_phid][$merchant_phid] = true;
183 }
184 }
185
186 return $results;
187 }
188
189}