Commit c0bec6c0 authored by epriestley's avatar epriestley
Browse files

Add "parent" and "ancestor" information to the API

Ref T12074.

  - Adds a new "parent" property on main results. This shows an abbreviated version of the project's parent, or `null` if the project is a root project.
  - Adds a new "ancestor" attachment to pull the entire ancestor list.
  - Adds a new "depth" property on main results.
  - You can use "parent" or "depth" to tell if a project is a subproject or not.

These attempt to balance convenience, power, and performance: the full ancestor list can be big so I made it an attachment, but the other stuff isn't too big and is cheap and seems reasonable to always include.

Test Plan:
In API results:

  - Saw null parent (root projects) and non-null parent (subprojects/milestones).
  - Used "ancestors" attchment, got full list of ancestors.
  - Saw appropriate "depth" values.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T12074

Differential Revision:
parent e03103f3
......@@ -3514,6 +3514,7 @@ phutil_register_library_map(array(
'PhabricatorProjectWatcherListView' => 'applications/project/view/PhabricatorProjectWatcherListView.php',
'PhabricatorProjectWorkboardBackgroundColor' => 'applications/project/constants/PhabricatorProjectWorkboardBackgroundColor.php',
'PhabricatorProjectWorkboardProfileMenuItem' => 'applications/project/menuitem/PhabricatorProjectWorkboardProfileMenuItem.php',
'PhabricatorProjectsAncestorsSearchEngineAttachment' => 'applications/project/engineextension/PhabricatorProjectsAncestorsSearchEngineAttachment.php',
'PhabricatorProjectsCurtainExtension' => 'applications/project/engineextension/PhabricatorProjectsCurtainExtension.php',
'PhabricatorProjectsEditEngineExtension' => 'applications/project/engineextension/PhabricatorProjectsEditEngineExtension.php',
'PhabricatorProjectsEditField' => 'applications/transactions/editfield/PhabricatorProjectsEditField.php',
......@@ -8666,6 +8667,7 @@ phutil_register_library_map(array(
'PhabricatorProjectWatcherListView' => 'PhabricatorProjectUserListView',
'PhabricatorProjectWorkboardBackgroundColor' => 'Phobject',
'PhabricatorProjectWorkboardProfileMenuItem' => 'PhabricatorProfileMenuItem',
'PhabricatorProjectsAncestorsSearchEngineAttachment' => 'PhabricatorSearchEngineAttachment',
'PhabricatorProjectsCurtainExtension' => 'PHUICurtainExtension',
'PhabricatorProjectsEditEngineExtension' => 'PhabricatorEditEngineExtension',
'PhabricatorProjectsEditField' => 'PhabricatorTokenizerEditField',
final class PhabricatorProjectsAncestorsSearchEngineAttachment
extends PhabricatorSearchEngineAttachment {
public function getAttachmentName() {
return pht('Project Ancestors');
public function getAttachmentDescription() {
return pht('Get the full ancestor list for each project.');
public function getAttachmentForObject($object, $data, $spec) {
$ancestors = $object->getAncestorProjects();
// Order ancestors by depth, ascending.
$ancestors = array_reverse($ancestors);
$results = array();
foreach ($ancestors as $ancestor) {
$results[] = $ancestor->getRefForConduit();
return array(
'ancestors' => $results,
......@@ -745,6 +745,20 @@ final class PhabricatorProject extends PhabricatorProjectDAO
->setDescription(pht('For milestones, milestone sequence number.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setType('map<string, wild>?')
'For subprojects and milestones, a brief description of the '.
'parent project.')),
id(new PhabricatorConduitSearchFieldSpecification())
'For subprojects and milestones, depth of this project in the '.
'tree. Root projects have depth 0.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setType('map<string, wild>')
......@@ -766,10 +780,19 @@ final class PhabricatorProject extends PhabricatorProjectDAO
$milestone = null;
$parent = $this->getParentProject();
if ($parent) {
$parent_ref = $parent->getRefForConduit();
} else {
$parent_ref = null;
return array(
'name' => $this->getName(),
'slug' => $this->getPrimarySlug(),
'milestone' => $milestone,
'depth' => (int)$this->getProjectDepth(),
'parent' => $parent_ref,
'icon' => array(
'key' => $this->getDisplayIconKey(),
'name' => $this->getDisplayIconName(),
......@@ -788,6 +811,20 @@ final class PhabricatorProject extends PhabricatorProjectDAO
id(new PhabricatorProjectsWatchersSearchEngineAttachment())
id(new PhabricatorProjectsAncestorsSearchEngineAttachment())
* Get an abbreviated representation of this project for use in providing
* "parent" and "ancestor" information.
public function getRefForConduit() {
return array(
'id' => (int)$this->getID(),
'phid' => $this->getPHID(),
'name' => $this->getName(),
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