@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 240 lines 5.6 kB view raw
1<?php 2 3/** 4 * @extends DrydockQuery<DrydockBlueprint> 5 */ 6final class DrydockBlueprintQuery extends DrydockQuery { 7 8 private $ids; 9 private $phids; 10 private $blueprintClasses; 11 private $datasourceQuery; 12 private $disabled; 13 private $authorizedPHIDs; 14 15 private $identifiers; 16 private $identifierIDs; 17 private $identifierPHIDs; 18 private $identifierMap; 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 withBlueprintClasses(array $classes) { 31 $this->blueprintClasses = $classes; 32 return $this; 33 } 34 35 public function withDatasourceQuery($query) { 36 $this->datasourceQuery = $query; 37 return $this; 38 } 39 40 public function withDisabled($disabled) { 41 $this->disabled = $disabled; 42 return $this; 43 } 44 45 public function withAuthorizedPHIDs(array $phids) { 46 $this->authorizedPHIDs = $phids; 47 return $this; 48 } 49 50 public function withNameNgrams($ngrams) { 51 return $this->withNgramsConstraint( 52 new DrydockBlueprintNameNgrams(), 53 $ngrams); 54 } 55 56 public function withIdentifiers(array $identifiers) { 57 if (!$identifiers) { 58 throw new Exception( 59 pht( 60 'Can not issue a query with an empty identifier list.')); 61 } 62 63 $this->identifiers = $identifiers; 64 65 $ids = array(); 66 $phids = array(); 67 68 foreach ($identifiers as $identifier) { 69 if (ctype_digit($identifier)) { 70 $ids[] = $identifier; 71 } else { 72 $phids[] = $identifier; 73 } 74 } 75 76 $this->identifierIDs = $ids; 77 $this->identifierPHIDs = $phids; 78 79 return $this; 80 } 81 82 public function getIdentifierMap() { 83 if ($this->identifierMap === null) { 84 throw new Exception( 85 pht( 86 'Execute a query with identifiers before getting the '. 87 'identifier map.')); 88 } 89 90 return $this->identifierMap; 91 } 92 93 public function newResultObject() { 94 return new DrydockBlueprint(); 95 } 96 97 protected function getPrimaryTableAlias() { 98 return 'blueprint'; 99 } 100 101 protected function willExecute() { 102 if ($this->identifiers) { 103 $this->identifierMap = array(); 104 } else { 105 $this->identifierMap = null; 106 } 107 } 108 109 protected function willFilterPage(array $blueprints) { 110 $impls = DrydockBlueprintImplementation::getAllBlueprintImplementations(); 111 foreach ($blueprints as $key => $blueprint) { 112 $impl = idx($impls, $blueprint->getClassName()); 113 if (!$impl) { 114 $this->didRejectResult($blueprint); 115 unset($blueprints[$key]); 116 continue; 117 } 118 $impl = clone $impl; 119 $blueprint->attachImplementation($impl); 120 } 121 122 if ($this->identifiers) { 123 $id_map = mpull($blueprints, null, 'getID'); 124 $phid_map = mpull($blueprints, null, 'getPHID'); 125 126 $map = $this->identifierMap; 127 128 foreach ($this->identifierIDs as $id) { 129 if (isset($id_map[$id])) { 130 $map[$id] = $id_map[$id]; 131 } 132 } 133 134 foreach ($this->identifierPHIDs as $phid) { 135 if (isset($phid_map[$phid])) { 136 $map[$phid] = $phid_map[$phid]; 137 } 138 } 139 140 // Just for consistency, reorder the map to match input order. 141 $map = array_select_keys($map, $this->identifiers); 142 143 $this->identifierMap = $map; 144 } 145 146 return $blueprints; 147 } 148 149 protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { 150 $where = parent::buildWhereClauseParts($conn); 151 152 if ($this->ids !== null) { 153 $where[] = qsprintf( 154 $conn, 155 'blueprint.id IN (%Ld)', 156 $this->ids); 157 } 158 159 if ($this->phids !== null) { 160 $where[] = qsprintf( 161 $conn, 162 'blueprint.phid IN (%Ls)', 163 $this->phids); 164 } 165 166 if ($this->datasourceQuery !== null) { 167 $where[] = qsprintf( 168 $conn, 169 'blueprint.blueprintName LIKE %>', 170 $this->datasourceQuery); 171 } 172 173 if ($this->blueprintClasses !== null) { 174 $where[] = qsprintf( 175 $conn, 176 'blueprint.className IN (%Ls)', 177 $this->blueprintClasses); 178 } 179 180 if ($this->disabled !== null) { 181 $where[] = qsprintf( 182 $conn, 183 'blueprint.isDisabled = %d', 184 (int)$this->disabled); 185 } 186 187 if ($this->identifiers !== null) { 188 $parts = array(); 189 190 if ($this->identifierIDs) { 191 $parts[] = qsprintf( 192 $conn, 193 'blueprint.id IN (%Ld)', 194 $this->identifierIDs); 195 } 196 197 if ($this->identifierPHIDs) { 198 $parts[] = qsprintf( 199 $conn, 200 'blueprint.phid IN (%Ls)', 201 $this->identifierPHIDs); 202 } 203 204 $where[] = qsprintf( 205 $conn, 206 '%LO', 207 $parts); 208 } 209 210 return $where; 211 } 212 213 protected function shouldGroupQueryResultRows() { 214 if ($this->authorizedPHIDs !== null) { 215 return true; 216 } 217 return parent::shouldGroupQueryResultRows(); 218 } 219 220 protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { 221 $joins = parent::buildJoinClauseParts($conn); 222 223 if ($this->authorizedPHIDs !== null) { 224 $joins[] = qsprintf( 225 $conn, 226 'JOIN %T authorization 227 ON authorization.blueprintPHID = blueprint.phid 228 AND authorization.objectPHID IN (%Ls) 229 AND authorization.objectAuthorizationState = %s 230 AND authorization.blueprintAuthorizationState = %s', 231 id(new DrydockAuthorization())->getTableName(), 232 $this->authorizedPHIDs, 233 DrydockAuthorization::OBJECTAUTH_ACTIVE, 234 DrydockAuthorization::BLUEPRINTAUTH_AUTHORIZED); 235 } 236 237 return $joins; 238 } 239 240}