@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<ConduitAPIMethod>
5 */
6final class PhabricatorConduitMethodQuery
7 extends PhabricatorCursorPagedPolicyAwareQuery {
8
9 private $isDeprecated;
10 private $isStable;
11 private $isUnstable;
12 private $applicationNames;
13 private $nameContains;
14 private $methods;
15 private $isInternal;
16
17 public function withMethods(array $methods) {
18 $this->methods = $methods;
19 return $this;
20 }
21
22 public function withNameContains($name_contains) {
23 $this->nameContains = $name_contains;
24 return $this;
25 }
26
27 public function withIsStable($is_stable) {
28 $this->isStable = $is_stable;
29 return $this;
30 }
31
32 public function withIsUnstable($is_unstable) {
33 $this->isUnstable = $is_unstable;
34 return $this;
35 }
36
37 public function withIsDeprecated($is_deprecated) {
38 $this->isDeprecated = $is_deprecated;
39 return $this;
40 }
41
42 public function withIsInternal($is_internal) {
43 $this->isInternal = $is_internal;
44 return $this;
45 }
46
47 protected function loadPage() {
48 $methods = $this->getAllMethods();
49 $methods = $this->filterMethods($methods);
50 return $methods;
51 }
52
53 private function getAllMethods() {
54 return id(new PhutilClassMapQuery())
55 ->setAncestorClass(ConduitAPIMethod::class)
56 ->setSortMethod('getSortOrder')
57 ->execute();
58 }
59
60 private function filterMethods(array $methods) {
61 foreach ($methods as $key => $method) {
62 $application = $method->getApplication();
63 if (!$application) {
64 continue;
65 }
66 if (!$application->isInstalled()) {
67 unset($methods[$key]);
68 }
69 }
70
71 $status = array(
72 ConduitAPIMethod::METHOD_STATUS_STABLE => $this->isStable,
73 ConduitAPIMethod::METHOD_STATUS_FROZEN => $this->isStable,
74 ConduitAPIMethod::METHOD_STATUS_DEPRECATED => $this->isDeprecated,
75 ConduitAPIMethod::METHOD_STATUS_UNSTABLE => $this->isUnstable,
76 );
77
78 // Only apply status filters if any of them are set.
79 if (array_filter($status)) {
80 foreach ($methods as $key => $method) {
81 $keep = idx($status, $method->getMethodStatus());
82 if (!$keep) {
83 unset($methods[$key]);
84 }
85 }
86 }
87
88 if ($this->nameContains) {
89 $needle = phutil_utf8_strtolower($this->nameContains);
90 foreach ($methods as $key => $method) {
91 $haystack = $method->getAPIMethodName();
92 $haystack = phutil_utf8_strtolower($haystack);
93 if (strpos($haystack, $needle) === false) {
94 unset($methods[$key]);
95 }
96 }
97 }
98
99 if ($this->methods) {
100 $map = array_fuse($this->methods);
101 foreach ($methods as $key => $method) {
102 $needle = $method->getAPIMethodName();
103 if (empty($map[$needle])) {
104 unset($methods[$key]);
105 }
106 }
107 }
108
109 if ($this->isInternal !== null) {
110 foreach ($methods as $key => $method) {
111 if ($method->isInternalAPI() !== $this->isInternal) {
112 unset($methods[$key]);
113 }
114 }
115 }
116
117 return $methods;
118 }
119
120 protected function willFilterPage(array $methods) {
121 $application_phids = array();
122 foreach ($methods as $method) {
123 $application = $method->getApplication();
124 if ($application === null) {
125 continue;
126 }
127 $application_phids[] = $application->getPHID();
128 }
129
130 if ($application_phids) {
131 $applications = id(new PhabricatorApplicationQuery())
132 ->setParentQuery($this)
133 ->setViewer($this->getViewer())
134 ->withPHIDs($application_phids)
135 ->execute();
136 $applications = mpull($applications, null, 'getPHID');
137 } else {
138 $applications = array();
139 }
140
141 // Remove methods which belong to an application the viewer can not see.
142 foreach ($methods as $key => $method) {
143 $application = $method->getApplication();
144 if ($application === null) {
145 continue;
146 }
147
148 if (empty($applications[$application->getPHID()])) {
149 $this->didRejectResult($method);
150 unset($methods[$key]);
151 }
152 }
153
154 return $methods;
155 }
156
157 public function getQueryApplicationClass() {
158 return PhabricatorConduitApplication::class;
159 }
160
161}