@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
3/**
4 * @extends PhabricatorCursorPagedPolicyAwareQuery<PhabricatorEditEngineConfiguration>
5 */
6final class PhabricatorEditEngineConfigurationQuery
7 extends PhabricatorCursorPagedPolicyAwareQuery {
8
9 private $ids;
10 private $phids;
11 private $engineKeys;
12 private $builtinKeys;
13 private $identifiers;
14 private $default;
15 private $isEdit;
16 private $disabled;
17 private $ignoreDatabaseConfigurations;
18 private $subtypes;
19
20 public function withIDs(array $ids) {
21 $this->ids = $ids;
22 return $this;
23 }
24
25 public function withPHIDs(array $phids) {
26 $this->phids = $phids;
27 return $this;
28 }
29
30 public function withEngineKeys(array $engine_keys) {
31 $this->engineKeys = $engine_keys;
32 return $this;
33 }
34
35 public function withBuiltinKeys(array $builtin_keys) {
36 $this->builtinKeys = $builtin_keys;
37 return $this;
38 }
39
40 public function withIdentifiers(array $identifiers) {
41 $this->identifiers = $identifiers;
42 return $this;
43 }
44
45 public function withIsDefault($default) {
46 $this->default = $default;
47 return $this;
48 }
49
50 public function withIsEdit($edit) {
51 $this->isEdit = $edit;
52 return $this;
53 }
54
55 public function withIsDisabled($disabled) {
56 $this->disabled = $disabled;
57 return $this;
58 }
59
60 public function withIgnoreDatabaseConfigurations($ignore) {
61 $this->ignoreDatabaseConfigurations = $ignore;
62 return $this;
63 }
64
65 public function withSubtypes(array $subtypes) {
66 $this->subtypes = $subtypes;
67 return $this;
68 }
69
70 public function newResultObject() {
71 return new PhabricatorEditEngineConfiguration();
72 }
73
74 protected function loadPage() {
75 // TODO: The logic here is a little flimsy and won't survive pagination.
76 // For now, I'm just not bothering with pagination since I believe it will
77 // take some time before any install manages to produce a large enough
78 // number of edit forms for any particular engine for the lack of UI
79 // pagination to become a problem.
80
81 if ($this->ignoreDatabaseConfigurations) {
82 $page = array();
83 } else {
84 $page = $this->loadStandardPage($this->newResultObject());
85 }
86
87 // Now that we've loaded the real results from the database, we're going
88 // to load builtins from the edit engines and add them to the list.
89
90 $engines = PhabricatorEditEngine::getAllEditEngines();
91
92 if ($this->engineKeys) {
93 $engines = array_select_keys($engines, $this->engineKeys);
94 }
95
96 foreach ($engines as $engine) {
97 $engine->setViewer($this->getViewer());
98 }
99
100 // List all the builtins which have already been saved to the database as
101 // real objects.
102 $concrete = array();
103 foreach ($page as $config) {
104 $builtin_key = $config->getBuiltinKey();
105 if ($builtin_key !== null) {
106 $engine_key = $config->getEngineKey();
107 $concrete[$engine_key][$builtin_key] = $config;
108 }
109 }
110
111 $builtins = array();
112 foreach ($engines as $engine_key => $engine) {
113 $engine_builtins = $engine->getBuiltinEngineConfigurations();
114 foreach ($engine_builtins as $engine_builtin) {
115 $builtin_key = $engine_builtin->getBuiltinKey();
116 if (isset($concrete[$engine_key][$builtin_key])) {
117 continue;
118 } else {
119 $builtins[] = $engine_builtin;
120 }
121 }
122 }
123
124 foreach ($builtins as $builtin) {
125 $page[] = $builtin;
126 }
127
128 // Now we have to do some extra filtering to make sure everything we're
129 // about to return really satisfies the query.
130
131 if ($this->ids !== null) {
132 $ids = array_fuse($this->ids);
133 foreach ($page as $key => $config) {
134 if (!$config->getID() || empty($ids[$config->getID()])) {
135 unset($page[$key]);
136 }
137 }
138 }
139
140 if ($this->phids !== null) {
141 $phids = array_fuse($this->phids);
142 foreach ($page as $key => $config) {
143 if (!$config->getPHID() || empty($phids[$config->getPHID()])) {
144 unset($page[$key]);
145 }
146 }
147 }
148
149 if ($this->builtinKeys !== null) {
150 $builtin_keys = array_fuse($this->builtinKeys);
151 foreach ($page as $key => $config) {
152 if (empty($builtin_keys[$config->getBuiltinKey()])) {
153 unset($page[$key]);
154 }
155 }
156 }
157
158 if ($this->default !== null) {
159 foreach ($page as $key => $config) {
160 if ($config->getIsDefault() != $this->default) {
161 unset($page[$key]);
162 }
163 }
164 }
165
166 if ($this->isEdit !== null) {
167 foreach ($page as $key => $config) {
168 if ($config->getIsEdit() != $this->isEdit) {
169 unset($page[$key]);
170 }
171 }
172 }
173
174 if ($this->disabled !== null) {
175 foreach ($page as $key => $config) {
176 if ($config->getIsDisabled() != $this->disabled) {
177 unset($page[$key]);
178 }
179 }
180 }
181
182 if ($this->identifiers !== null) {
183 $identifiers = array_fuse($this->identifiers);
184 foreach ($page as $key => $config) {
185 if (isset($identifiers[$config->getBuiltinKey()])) {
186 continue;
187 }
188 if (isset($identifiers[$config->getID()])) {
189 continue;
190 }
191 unset($page[$key]);
192 }
193 }
194
195 if ($this->subtypes !== null) {
196 $subtypes = array_fuse($this->subtypes);
197 foreach ($page as $key => $config) {
198 if (isset($subtypes[$config->getSubtype()])) {
199 continue;
200 }
201
202 unset($page[$key]);
203 }
204 }
205
206 return $page;
207 }
208
209 protected function willFilterPage(array $configs) {
210 $engine_keys = mpull($configs, 'getEngineKey');
211
212 $engines = id(new PhabricatorEditEngineQuery())
213 ->setParentQuery($this)
214 ->setViewer($this->getViewer())
215 ->withEngineKeys($engine_keys)
216 ->execute();
217 $engines = mpull($engines, null, 'getEngineKey');
218
219 foreach ($configs as $key => $config) {
220 $engine = idx($engines, $config->getEngineKey());
221
222 if (!$engine) {
223 $this->didRejectResult($config);
224 unset($configs[$key]);
225 continue;
226 }
227
228 $config->attachEngine($engine);
229 }
230
231 return $configs;
232 }
233
234 protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
235 $where = parent::buildWhereClauseParts($conn);
236
237 if ($this->ids !== null) {
238 $where[] = qsprintf(
239 $conn,
240 'id IN (%Ld)',
241 $this->ids);
242 }
243
244 if ($this->phids !== null) {
245 $where[] = qsprintf(
246 $conn,
247 'phid IN (%Ls)',
248 $this->phids);
249 }
250
251 if ($this->engineKeys !== null) {
252 $where[] = qsprintf(
253 $conn,
254 'engineKey IN (%Ls)',
255 $this->engineKeys);
256 }
257
258 if ($this->builtinKeys !== null) {
259 $where[] = qsprintf(
260 $conn,
261 'builtinKey IN (%Ls)',
262 $this->builtinKeys);
263 }
264
265 if ($this->identifiers !== null) {
266 $where[] = qsprintf(
267 $conn,
268 '(id IN (%Ls) OR builtinKey IN (%Ls))',
269 $this->identifiers,
270 $this->identifiers);
271 }
272
273 if ($this->subtypes !== null) {
274 $where[] = qsprintf(
275 $conn,
276 'subtype IN (%Ls)',
277 $this->subtypes);
278 }
279
280 return $where;
281 }
282
283 public function getQueryApplicationClass() {
284 return PhabricatorTransactionsApplication::class;
285 }
286
287}