@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
fork

Configure Feed

Select the types of activity you want to include in your feed.

Remove old position-on-read board column code

Summary: Ref T10010. This retires the old way of doing things inside ColumnPositionQuery. It is now obsolete and lives in BoardLayoutEngine instead.

Test Plan:
- Moved cards, created cards, swapped filters, orders, etc.
- Some degree of unit testing coming in the next diff.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10010

Differential Revision: https://secure.phabricator.com/D15177

+15 -243
+2 -1
src/applications/maniphest/editor/ManiphestEditEngine.php
··· 287 287 288 288 $positions = id(new PhabricatorProjectColumnPositionQuery()) 289 289 ->setViewer($viewer) 290 - ->withColumns(array($column)) 290 + ->withBoardPHIDs(array($column->getProjectPHID())) 291 + ->withColumnPHIDs(array($column->getPHID())) 291 292 ->execute(); 292 293 $task_phids = mpull($positions, 'getObjectPHID'); 293 294
+13 -242
src/applications/project/query/PhabricatorProjectColumnPositionQuery.php
··· 6 6 private $ids; 7 7 private $boardPHIDs; 8 8 private $objectPHIDs; 9 - private $columns; 10 - 11 - private $needColumns; 12 - private $skipImplicitCreate; 9 + private $columnPHIDs; 13 10 14 11 public function withIDs(array $ids) { 15 12 $this->ids = $ids; ··· 26 23 return $this; 27 24 } 28 25 29 - /** 30 - * Find objects in specific columns. 31 - * 32 - * NOTE: Using this method activates logic which constructs virtual 33 - * column positions for objects not in any column, if you pass a default 34 - * column. Normally these results are not returned. 35 - * 36 - * @param list<PhabricatorProjectColumn> Columns to look for objects in. 37 - * @return this 38 - */ 39 - public function withColumns(array $columns) { 40 - assert_instances_of($columns, 'PhabricatorProjectColumn'); 41 - $this->columns = $columns; 42 - return $this; 43 - } 44 - 45 - public function needColumns($need_columns) { 46 - $this->needColumns = true; 47 - return $this; 48 - } 49 - 50 - 51 - /** 52 - * Skip implicit creation of column positions which are implied but do not 53 - * yet exist. 54 - * 55 - * This is primarily useful internally. 56 - * 57 - * @param bool True to skip implicit creation of column positions. 58 - * @return this 59 - */ 60 - public function setSkipImplicitCreate($skip) { 61 - $this->skipImplicitCreate = $skip; 26 + public function withColumnPHIDs(array $column_phids) { 27 + $this->columnPHIDs = $column_phids; 62 28 return $this; 63 29 } 64 30 65 - // NOTE: For now, boards are always attached to projects. However, they might 66 - // not be in the future. This generalization just anticipates a future where 67 - // we let other types of objects (like users) have boards, or let boards 68 - // contain other types of objects. 69 - 70 - private function newPositionObject() { 31 + public function newResultObject() { 71 32 return new PhabricatorProjectColumnPosition(); 72 33 } 73 34 74 - private function newColumnQuery() { 75 - return new PhabricatorProjectColumnQuery(); 76 - } 77 - 78 - private function getBoardMembershipEdgeTypes() { 79 - return array( 80 - PhabricatorProjectProjectHasObjectEdgeType::EDGECONST, 81 - ); 82 - } 83 - 84 - private function getBoardMembershipPHIDTypes() { 85 - return array( 86 - ManiphestTaskPHIDType::TYPECONST, 87 - ); 88 - } 89 - 90 35 protected function loadPage() { 91 - $table = $this->newPositionObject(); 92 - $conn_r = $table->establishConnection('r'); 93 - 94 - // We're going to find results by combining two queries: one query finds 95 - // objects on a board column, while the other query finds objects not on 96 - // any board column and virtually puts them on the default column. 97 - 98 - $unions = array(); 99 - 100 - // First, find all the stuff that's actually on a column. 101 - 102 - $unions[] = qsprintf( 103 - $conn_r, 104 - 'SELECT * FROM %T %Q', 105 - $table->getTableName(), 106 - $this->buildWhereClause($conn_r)); 107 - 108 - // If we have a default column, find all the stuff that's not in any 109 - // column and put it in the default column. 110 - 111 - $must_type_filter = false; 112 - if ($this->columns && !$this->skipImplicitCreate) { 113 - $default_map = array(); 114 - foreach ($this->columns as $column) { 115 - if ($column->isDefaultColumn()) { 116 - $default_map[$column->getProjectPHID()] = $column->getPHID(); 117 - } 118 - } 119 - 120 - if ($default_map) { 121 - $where = array(); 122 - 123 - // Find the edges attached to the boards we have default columns for. 124 - 125 - $where[] = qsprintf( 126 - $conn_r, 127 - 'e.src IN (%Ls)', 128 - array_keys($default_map)); 129 - 130 - // Find only edges which describe a board relationship. 131 - 132 - $where[] = qsprintf( 133 - $conn_r, 134 - 'e.type IN (%Ld)', 135 - $this->getBoardMembershipEdgeTypes()); 136 - 137 - if ($this->boardPHIDs !== null) { 138 - // This should normally be redundant, but construct it anyway if 139 - // the caller has told us to. 140 - $where[] = qsprintf( 141 - $conn_r, 142 - 'e.src IN (%Ls)', 143 - $this->boardPHIDs); 144 - } 145 - 146 - if ($this->objectPHIDs !== null) { 147 - $where[] = qsprintf( 148 - $conn_r, 149 - 'e.dst IN (%Ls)', 150 - $this->objectPHIDs); 151 - } 152 - 153 - $where[] = qsprintf( 154 - $conn_r, 155 - 'p.id IS NULL'); 156 - 157 - $where = $this->formatWhereClause($where); 158 - 159 - $unions[] = qsprintf( 160 - $conn_r, 161 - 'SELECT NULL id, e.src boardPHID, NULL columnPHID, e.dst objectPHID, 162 - 0 sequence 163 - FROM %T e LEFT JOIN %T p 164 - ON e.src = p.boardPHID AND e.dst = p.objectPHID 165 - %Q', 166 - PhabricatorEdgeConfig::TABLE_NAME_EDGE, 167 - $table->getTableName(), 168 - $where); 169 - 170 - $must_type_filter = true; 171 - } 172 - } 173 - 174 - $data = queryfx_all( 175 - $conn_r, 176 - '%Q %Q %Q', 177 - implode(' UNION ALL ', $unions), 178 - $this->buildOrderClause($conn_r), 179 - $this->buildLimitClause($conn_r)); 180 - 181 - // If we've picked up objects not in any column, we need to filter out any 182 - // matched objects which have the wrong edge type. 183 - if ($must_type_filter) { 184 - $allowed_types = array_fuse($this->getBoardMembershipPHIDTypes()); 185 - foreach ($data as $id => $row) { 186 - if ($row['columnPHID'] === null) { 187 - $object_phid = $row['objectPHID']; 188 - if (empty($allowed_types[phid_get_type($object_phid)])) { 189 - unset($data[$id]); 190 - } 191 - } 192 - } 193 - } 194 - 195 - $positions = $table->loadAllFromArray($data); 196 - 197 - // Find the implied positions which don't exist yet. If there are any, 198 - // we're going to create them. 199 - $create = array(); 200 - foreach ($positions as $position) { 201 - if ($position->getColumnPHID() === null) { 202 - $column_phid = idx($default_map, $position->getBoardPHID()); 203 - $position->setColumnPHID($column_phid); 204 - 205 - $create[] = $position; 206 - } 207 - } 208 - 209 - if ($create) { 210 - // If we're adding several objects to a column, insert the column 211 - // position objects in object ID order. This means that newly added 212 - // objects float to the top, and when a group of newly added objects 213 - // float up at the same time, the most recently created ones end up 214 - // highest in the list. 215 - 216 - $objects = id(new PhabricatorObjectQuery()) 217 - ->setViewer(PhabricatorUser::getOmnipotentUser()) 218 - ->withPHIDs(mpull($create, 'getObjectPHID')) 219 - ->execute(); 220 - $objects = mpull($objects, null, 'getPHID'); 221 - $objects = msort($objects, 'getID'); 222 - 223 - $create = mgroup($create, 'getObjectPHID'); 224 - $create = array_select_keys($create, array_keys($objects)) + $create; 225 - 226 - $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); 227 - 228 - foreach ($create as $object_phid => $create_positions) { 229 - foreach ($create_positions as $create_position) { 230 - $create_position->save(); 231 - } 232 - } 233 - 234 - unset($unguarded); 235 - } 236 - 237 - return $positions; 36 + return $this->loadStandardPage($this->newResultObject()); 238 37 } 239 38 240 - protected function willFilterPage(array $page) { 241 - 242 - if ($this->needColumns) { 243 - $column_phids = mpull($page, 'getColumnPHID'); 244 - $columns = $this->newColumnQuery() 245 - ->setParentQuery($this) 246 - ->setViewer($this->getViewer()) 247 - ->withPHIDs($column_phids) 248 - ->execute(); 249 - $columns = mpull($columns, null, 'getPHID'); 250 - 251 - foreach ($page as $key => $position) { 252 - $column = idx($columns, $position->getColumnPHID()); 253 - if (!$column) { 254 - unset($page[$key]); 255 - continue; 256 - } 257 - 258 - $position->attachColumn($column); 259 - } 260 - } 261 - 262 - return $page; 263 - } 264 - 265 - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { 39 + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { 266 40 $where = array(); 267 41 268 42 if ($this->ids !== null) { 269 43 $where[] = qsprintf( 270 - $conn_r, 44 + $conn, 271 45 'id IN (%Ld)', 272 46 $this->ids); 273 47 } 274 48 275 49 if ($this->boardPHIDs !== null) { 276 50 $where[] = qsprintf( 277 - $conn_r, 51 + $conn, 278 52 'boardPHID IN (%Ls)', 279 53 $this->boardPHIDs); 280 54 } 281 55 282 56 if ($this->objectPHIDs !== null) { 283 57 $where[] = qsprintf( 284 - $conn_r, 58 + $conn, 285 59 'objectPHID IN (%Ls)', 286 60 $this->objectPHIDs); 287 61 } 288 62 289 - if ($this->columns !== null) { 63 + if ($this->columnPHIDs !== null) { 290 64 $where[] = qsprintf( 291 - $conn_r, 65 + $conn, 292 66 'columnPHID IN (%Ls)', 293 - mpull($this->columns, 'getPHID')); 67 + $this->columnPHIDs); 294 68 } 295 69 296 - // NOTE: Explicitly not building the paging clause here, since it won't 297 - // work with the UNION. 298 - 299 - return $this->formatWhereClause($where); 70 + return $where; 300 71 } 301 72 302 73 public function getQueryApplicationClass() {