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

Add a "columns" attachment to the maniphest.search API method

Summary:
Ref T12074. This allows callers to identify which columns an object appears in (currently, always tasks).

There are a few major cases:

- Object is in a normal column: we return column information.
- Object is in a proxy column (subproject or milestone). For example, when you look at the board for "Some Parent Project", the task might show up in a milestone column. I've chosen to not return anything in this case: you can figure out that the task is there by looking at the project structure, and this is kind of an internal artifact of the implementation and probably not useful to callers.
- Project does not have a workboard: we return nothing.

These seem fairly reasonable, I think?

Test Plan:
- Queried for tasks, using the "columns" attachment.
- Dragged a task across a board, querying it repeatedly. Got expected results for normal column (the column), subprojects with no board (nothing), milestones with no board (nothing) and mielstones/subprojects with a board (the column on //that// board, only, not the proxy column on the parent).

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T12074

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

+94 -1
+2
src/__phutil_library_map__.php
··· 2025 2025 'PhabricatorBcryptPasswordHasher' => 'infrastructure/util/password/PhabricatorBcryptPasswordHasher.php', 2026 2026 'PhabricatorBinariesSetupCheck' => 'applications/config/check/PhabricatorBinariesSetupCheck.php', 2027 2027 'PhabricatorBitbucketAuthProvider' => 'applications/auth/provider/PhabricatorBitbucketAuthProvider.php', 2028 + 'PhabricatorBoardColumnsSearchEngineAttachment' => 'applications/project/engineextension/PhabricatorBoardColumnsSearchEngineAttachment.php', 2028 2029 'PhabricatorBoardLayoutEngine' => 'applications/project/engine/PhabricatorBoardLayoutEngine.php', 2029 2030 'PhabricatorBoardRenderingEngine' => 'applications/project/engine/PhabricatorBoardRenderingEngine.php', 2030 2031 'PhabricatorBoardResponseEngine' => 'applications/project/engine/PhabricatorBoardResponseEngine.php', ··· 6926 6927 'PhabricatorBcryptPasswordHasher' => 'PhabricatorPasswordHasher', 6927 6928 'PhabricatorBinariesSetupCheck' => 'PhabricatorSetupCheck', 6928 6929 'PhabricatorBitbucketAuthProvider' => 'PhabricatorOAuth1AuthProvider', 6930 + 'PhabricatorBoardColumnsSearchEngineAttachment' => 'PhabricatorSearchEngineAttachment', 6929 6931 'PhabricatorBoardLayoutEngine' => 'Phobject', 6930 6932 'PhabricatorBoardRenderingEngine' => 'Phobject', 6931 6933 'PhabricatorBoardResponseEngine' => 'Phobject',
+4 -1
src/applications/maniphest/storage/ManiphestTask.php
··· 505 505 } 506 506 507 507 public function getConduitSearchAttachments() { 508 - return array(); 508 + return array( 509 + id(new PhabricatorBoardColumnsSearchEngineAttachment()) 510 + ->setAttachmentKey('columns'), 511 + ); 509 512 } 510 513 511 514
+80
src/applications/project/engineextension/PhabricatorBoardColumnsSearchEngineAttachment.php
··· 1 + <?php 2 + 3 + final class PhabricatorBoardColumnsSearchEngineAttachment 4 + extends PhabricatorSearchEngineAttachment { 5 + 6 + public function getAttachmentName() { 7 + return pht('Workboard Columns'); 8 + } 9 + 10 + public function getAttachmentDescription() { 11 + return pht('Get the workboard columns where an object appears.'); 12 + } 13 + 14 + public function loadAttachmentData(array $objects, $spec) { 15 + $viewer = $this->getViewer(); 16 + 17 + $objects = mpull($objects, null, 'getPHID'); 18 + $object_phids = array_keys($objects); 19 + 20 + $edge_query = id(new PhabricatorEdgeQuery()) 21 + ->withSourcePHIDs($object_phids) 22 + ->withEdgeTypes( 23 + array( 24 + PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, 25 + )); 26 + $edge_query->execute(); 27 + 28 + $project_phids = $edge_query->getDestinationPHIDs(); 29 + 30 + $engine = id(new PhabricatorBoardLayoutEngine()) 31 + ->setViewer($viewer) 32 + ->setBoardPHIDs($project_phids) 33 + ->setObjectPHIDs($object_phids) 34 + ->executeLayout(); 35 + 36 + $results = array(); 37 + foreach ($objects as $phid => $object) { 38 + $board_phids = $edge_query->getDestinationPHIDs(array($phid)); 39 + 40 + $boards = array(); 41 + foreach ($board_phids as $board_phid) { 42 + $columns = array(); 43 + foreach ($engine->getObjectColumns($board_phid, $phid) as $column) { 44 + if ($column->getProxyPHID()) { 45 + // When an object is in a proxy column, don't return it on this 46 + // attachment. This information can be reconstructed from other 47 + // queries, is something of an implementation detail, and seems 48 + // unlikely to be interesting to API consumers. 49 + continue 2; 50 + } 51 + 52 + $columns[] = $column->getRefForConduit(); 53 + } 54 + 55 + // If a project has no workboard, the object won't appear on any 56 + // columns. Just omit it from the result set. 57 + if (!$columns) { 58 + continue; 59 + } 60 + 61 + $boards[$board_phid] = array( 62 + 'columns' => $columns, 63 + ); 64 + } 65 + 66 + $results[$phid] = $boards; 67 + } 68 + 69 + return $results; 70 + } 71 + 72 + public function getAttachmentForObject($object, $data, $spec) { 73 + $boards = idx($data, $object->getPHID(), array()); 74 + 75 + return array( 76 + 'boards' => $boards, 77 + ); 78 + } 79 + 80 + }
+8
src/applications/project/storage/PhabricatorProjectColumn.php
··· 183 183 return sprintf('%s%012d', $group, $sequence); 184 184 } 185 185 186 + public function getRefForConduit() { 187 + return array( 188 + 'id' => (int)$this->getID(), 189 + 'phid' => $this->getPHID(), 190 + 'name' => $this->getDisplayName(), 191 + ); 192 + } 193 + 186 194 187 195 /* -( PhabricatorApplicationTransactionInterface )------------------------- */ 188 196