@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
at recaptime-dev/main 210 lines 5.0 kB view raw
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}