@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 AlmanacQuery<AlmanacInterface>
5 */
6final class AlmanacInterfaceQuery
7 extends AlmanacQuery {
8
9 private $ids;
10 private $phids;
11 private $networkPHIDs;
12 private $devicePHIDs;
13 private $addresses;
14
15 public function withIDs(array $ids) {
16 $this->ids = $ids;
17 return $this;
18 }
19
20 public function withPHIDs(array $phids) {
21 $this->phids = $phids;
22 return $this;
23 }
24
25 public function withNetworkPHIDs(array $phids) {
26 $this->networkPHIDs = $phids;
27 return $this;
28 }
29
30 public function withDevicePHIDs(array $phids) {
31 $this->devicePHIDs = $phids;
32 return $this;
33 }
34
35 public function withAddresses(array $addresses) {
36 $this->addresses = $addresses;
37 return $this;
38 }
39
40 public function newResultObject() {
41 return new AlmanacInterface();
42 }
43
44 protected function willFilterPage(array $interfaces) {
45 $network_phids = mpull($interfaces, 'getNetworkPHID');
46 $device_phids = mpull($interfaces, 'getDevicePHID');
47
48 $networks = id(new AlmanacNetworkQuery())
49 ->setParentQuery($this)
50 ->setViewer($this->getViewer())
51 ->withPHIDs($network_phids)
52 ->needProperties($this->getNeedProperties())
53 ->execute();
54 $networks = mpull($networks, null, 'getPHID');
55
56 $devices = id(new AlmanacDeviceQuery())
57 ->setParentQuery($this)
58 ->setViewer($this->getViewer())
59 ->withPHIDs($device_phids)
60 ->needProperties($this->getNeedProperties())
61 ->execute();
62 $devices = mpull($devices, null, 'getPHID');
63
64 foreach ($interfaces as $key => $interface) {
65 $network = idx($networks, $interface->getNetworkPHID());
66 $device = idx($devices, $interface->getDevicePHID());
67 if (!$network || !$device) {
68 $this->didRejectResult($interface);
69 unset($interfaces[$key]);
70 continue;
71 }
72
73 $interface->attachNetwork($network);
74 $interface->attachDevice($device);
75 }
76
77 return $interfaces;
78 }
79
80 protected function buildSelectClauseParts(AphrontDatabaseConnection $conn) {
81 $select = parent::buildSelectClauseParts($conn);
82
83 if ($this->shouldJoinDeviceTable()) {
84 $select[] = qsprintf($conn, 'device.name');
85 }
86
87 return $select;
88 }
89
90 protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
91 $where = parent::buildWhereClauseParts($conn);
92
93 if ($this->ids !== null) {
94 $where[] = qsprintf(
95 $conn,
96 'interface.id IN (%Ld)',
97 $this->ids);
98 }
99
100 if ($this->phids !== null) {
101 $where[] = qsprintf(
102 $conn,
103 'interface.phid IN (%Ls)',
104 $this->phids);
105 }
106
107 if ($this->networkPHIDs !== null) {
108 $where[] = qsprintf(
109 $conn,
110 'interface.networkPHID IN (%Ls)',
111 $this->networkPHIDs);
112 }
113
114 if ($this->devicePHIDs !== null) {
115 $where[] = qsprintf(
116 $conn,
117 'interface.devicePHID IN (%Ls)',
118 $this->devicePHIDs);
119 }
120
121 if ($this->addresses !== null) {
122 $parts = array();
123 foreach ($this->addresses as $address) {
124 $parts[] = qsprintf(
125 $conn,
126 '(interface.networkPHID = %s '.
127 'AND interface.address = %s '.
128 'AND interface.port = %d)',
129 $address->getNetworkPHID(),
130 $address->getAddress(),
131 $address->getPort());
132 }
133 $where[] = qsprintf($conn, '%LO', $parts);
134 }
135
136 return $where;
137 }
138
139 protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {
140 $joins = parent::buildJoinClauseParts($conn);
141
142 if ($this->shouldJoinDeviceTable()) {
143 $joins[] = qsprintf(
144 $conn,
145 'JOIN %T device ON device.phid = interface.devicePHID',
146 id(new AlmanacDevice())->getTableName());
147 }
148
149 return $joins;
150 }
151
152 protected function shouldGroupQueryResultRows() {
153 if ($this->shouldJoinDeviceTable()) {
154 return true;
155 }
156
157 return parent::shouldGroupQueryResultRows();
158 }
159
160 private function shouldJoinDeviceTable() {
161 $vector = $this->getOrderVector();
162
163 if ($vector->containsKey('name')) {
164 return true;
165 }
166
167 return false;
168 }
169
170 protected function getPrimaryTableAlias() {
171 return 'interface';
172 }
173
174 public function getQueryApplicationClass() {
175 return PhabricatorAlmanacApplication::class;
176 }
177
178 public function getBuiltinOrders() {
179 return array(
180 'name' => array(
181 'vector' => array('name', 'id'),
182 'name' => pht('Device Name'),
183 ),
184 ) + parent::getBuiltinOrders();
185 }
186
187 public function getOrderableColumns() {
188 return parent::getOrderableColumns() + array(
189 'name' => array(
190 'table' => 'device',
191 'column' => 'name',
192 'type' => 'string',
193 'reverse' => true,
194 ),
195 );
196 }
197
198 protected function newPagingMapFromCursorObject(
199 PhabricatorQueryCursor $cursor,
200 array $keys) {
201
202 $interface = $cursor->getObject();
203
204 return array(
205 'id' => (int)$interface->getID(),
206 'name' => $cursor->getRawRowProperty('device.name'),
207 );
208 }
209
210}