Commit ad3745c8 authored by epriestley's avatar epriestley
Browse files

Add a "columns" attachment to the API method

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:
parent 9fa7355e
......@@ -2025,6 +2025,7 @@ phutil_register_library_map(array(
'PhabricatorBcryptPasswordHasher' => 'infrastructure/util/password/PhabricatorBcryptPasswordHasher.php',
'PhabricatorBinariesSetupCheck' => 'applications/config/check/PhabricatorBinariesSetupCheck.php',
'PhabricatorBitbucketAuthProvider' => 'applications/auth/provider/PhabricatorBitbucketAuthProvider.php',
'PhabricatorBoardColumnsSearchEngineAttachment' => 'applications/project/engineextension/PhabricatorBoardColumnsSearchEngineAttachment.php',
'PhabricatorBoardLayoutEngine' => 'applications/project/engine/PhabricatorBoardLayoutEngine.php',
'PhabricatorBoardRenderingEngine' => 'applications/project/engine/PhabricatorBoardRenderingEngine.php',
'PhabricatorBoardResponseEngine' => 'applications/project/engine/PhabricatorBoardResponseEngine.php',
......@@ -6926,6 +6927,7 @@ phutil_register_library_map(array(
'PhabricatorBcryptPasswordHasher' => 'PhabricatorPasswordHasher',
'PhabricatorBinariesSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorBitbucketAuthProvider' => 'PhabricatorOAuth1AuthProvider',
'PhabricatorBoardColumnsSearchEngineAttachment' => 'PhabricatorSearchEngineAttachment',
'PhabricatorBoardLayoutEngine' => 'Phobject',
'PhabricatorBoardRenderingEngine' => 'Phobject',
'PhabricatorBoardResponseEngine' => 'Phobject',
......@@ -505,7 +505,10 @@ final class ManiphestTask extends ManiphestDAO
public function getConduitSearchAttachments() {
return array();
return array(
id(new PhabricatorBoardColumnsSearchEngineAttachment())
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())
$project_phids = $edge_query->getDestinationPHIDs();
$engine = id(new PhabricatorBoardLayoutEngine())
$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) {
$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,
......@@ -183,6 +183,14 @@ final class PhabricatorProjectColumn
return sprintf('%s%012d', $group, $sequence);
public function getRefForConduit() {
return array(
'id' => (int)$this->getID(),
'phid' => $this->getPHID(),
'name' => $this->getDisplayName(),
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment