1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-27 09:12:41 +01:00

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
This commit is contained in:
epriestley 2017-01-08 12:12:12 -08:00
parent 9fa7355edc
commit ad3745c801
4 changed files with 94 additions and 1 deletions

View file

@ -2025,6 +2025,7 @@ phutil_register_library_map(array(
'PhabricatorBcryptPasswordHasher' => 'infrastructure/util/password/PhabricatorBcryptPasswordHasher.php', 'PhabricatorBcryptPasswordHasher' => 'infrastructure/util/password/PhabricatorBcryptPasswordHasher.php',
'PhabricatorBinariesSetupCheck' => 'applications/config/check/PhabricatorBinariesSetupCheck.php', 'PhabricatorBinariesSetupCheck' => 'applications/config/check/PhabricatorBinariesSetupCheck.php',
'PhabricatorBitbucketAuthProvider' => 'applications/auth/provider/PhabricatorBitbucketAuthProvider.php', 'PhabricatorBitbucketAuthProvider' => 'applications/auth/provider/PhabricatorBitbucketAuthProvider.php',
'PhabricatorBoardColumnsSearchEngineAttachment' => 'applications/project/engineextension/PhabricatorBoardColumnsSearchEngineAttachment.php',
'PhabricatorBoardLayoutEngine' => 'applications/project/engine/PhabricatorBoardLayoutEngine.php', 'PhabricatorBoardLayoutEngine' => 'applications/project/engine/PhabricatorBoardLayoutEngine.php',
'PhabricatorBoardRenderingEngine' => 'applications/project/engine/PhabricatorBoardRenderingEngine.php', 'PhabricatorBoardRenderingEngine' => 'applications/project/engine/PhabricatorBoardRenderingEngine.php',
'PhabricatorBoardResponseEngine' => 'applications/project/engine/PhabricatorBoardResponseEngine.php', 'PhabricatorBoardResponseEngine' => 'applications/project/engine/PhabricatorBoardResponseEngine.php',
@ -6926,6 +6927,7 @@ phutil_register_library_map(array(
'PhabricatorBcryptPasswordHasher' => 'PhabricatorPasswordHasher', 'PhabricatorBcryptPasswordHasher' => 'PhabricatorPasswordHasher',
'PhabricatorBinariesSetupCheck' => 'PhabricatorSetupCheck', 'PhabricatorBinariesSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorBitbucketAuthProvider' => 'PhabricatorOAuth1AuthProvider', 'PhabricatorBitbucketAuthProvider' => 'PhabricatorOAuth1AuthProvider',
'PhabricatorBoardColumnsSearchEngineAttachment' => 'PhabricatorSearchEngineAttachment',
'PhabricatorBoardLayoutEngine' => 'Phobject', 'PhabricatorBoardLayoutEngine' => 'Phobject',
'PhabricatorBoardRenderingEngine' => 'Phobject', 'PhabricatorBoardRenderingEngine' => 'Phobject',
'PhabricatorBoardResponseEngine' => 'Phobject', 'PhabricatorBoardResponseEngine' => 'Phobject',

View file

@ -505,7 +505,10 @@ final class ManiphestTask extends ManiphestDAO
} }
public function getConduitSearchAttachments() { public function getConduitSearchAttachments() {
return array(); return array(
id(new PhabricatorBoardColumnsSearchEngineAttachment())
->setAttachmentKey('columns'),
);
} }

View file

@ -0,0 +1,80 @@
<?php
final class PhabricatorBoardColumnsSearchEngineAttachment
extends PhabricatorSearchEngineAttachment {
public function getAttachmentName() {
return pht('Workboard Columns');
}
public function getAttachmentDescription() {
return pht('Get the workboard columns where an object appears.');
}
public function loadAttachmentData(array $objects, $spec) {
$viewer = $this->getViewer();
$objects = mpull($objects, null, 'getPHID');
$object_phids = array_keys($objects);
$edge_query = id(new PhabricatorEdgeQuery())
->withSourcePHIDs($object_phids)
->withEdgeTypes(
array(
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
));
$edge_query->execute();
$project_phids = $edge_query->getDestinationPHIDs();
$engine = id(new PhabricatorBoardLayoutEngine())
->setViewer($viewer)
->setBoardPHIDs($project_phids)
->setObjectPHIDs($object_phids)
->executeLayout();
$results = array();
foreach ($objects as $phid => $object) {
$board_phids = $edge_query->getDestinationPHIDs(array($phid));
$boards = array();
foreach ($board_phids as $board_phid) {
$columns = array();
foreach ($engine->getObjectColumns($board_phid, $phid) as $column) {
if ($column->getProxyPHID()) {
// When an object is in a proxy column, don't return it on this
// attachment. This information can be reconstructed from other
// queries, is something of an implementation detail, and seems
// unlikely to be interesting to API consumers.
continue 2;
}
$columns[] = $column->getRefForConduit();
}
// If a project has no workboard, the object won't appear on any
// columns. Just omit it from the result set.
if (!$columns) {
continue;
}
$boards[$board_phid] = array(
'columns' => $columns,
);
}
$results[$phid] = $boards;
}
return $results;
}
public function getAttachmentForObject($object, $data, $spec) {
$boards = idx($data, $object->getPHID(), array());
return array(
'boards' => $boards,
);
}
}

View file

@ -183,6 +183,14 @@ final class PhabricatorProjectColumn
return sprintf('%s%012d', $group, $sequence); return sprintf('%s%012d', $group, $sequence);
} }
public function getRefForConduit() {
return array(
'id' => (int)$this->getID(),
'phid' => $this->getPHID(),
'name' => $this->getDisplayName(),
);
}
/* -( PhabricatorApplicationTransactionInterface )------------------------- */ /* -( PhabricatorApplicationTransactionInterface )------------------------- */