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

Implement a basic project.search third-generation API method

Summary: Ref T10010. This still needs support for attachments (to get members) and more constraints (like slugs), but mostly works.

Test Plan: Ran query, saw basically sensible results.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10010

Differential Revision: https://secure.phabricator.com/D14889
This commit is contained in:
epriestley 2015-12-27 02:44:07 -08:00
parent 211a6c0d55
commit d1f1d3ec33
5 changed files with 85 additions and 3 deletions

View file

@ -3747,6 +3747,7 @@ phutil_register_library_map(array(
'ProjectRemarkupRule' => 'applications/project/remarkup/ProjectRemarkupRule.php', 'ProjectRemarkupRule' => 'applications/project/remarkup/ProjectRemarkupRule.php',
'ProjectRemarkupRuleTestCase' => 'applications/project/remarkup/__tests__/ProjectRemarkupRuleTestCase.php', 'ProjectRemarkupRuleTestCase' => 'applications/project/remarkup/__tests__/ProjectRemarkupRuleTestCase.php',
'ProjectReplyHandler' => 'applications/project/mail/ProjectReplyHandler.php', 'ProjectReplyHandler' => 'applications/project/mail/ProjectReplyHandler.php',
'ProjectSearchConduitAPIMethod' => 'applications/project/conduit/ProjectSearchConduitAPIMethod.php',
'QueryFormattingTestCase' => 'infrastructure/storage/__tests__/QueryFormattingTestCase.php', 'QueryFormattingTestCase' => 'infrastructure/storage/__tests__/QueryFormattingTestCase.php',
'ReleephAuthorFieldSpecification' => 'applications/releeph/field/specification/ReleephAuthorFieldSpecification.php', 'ReleephAuthorFieldSpecification' => 'applications/releeph/field/specification/ReleephAuthorFieldSpecification.php',
'ReleephBranch' => 'applications/releeph/storage/ReleephBranch.php', 'ReleephBranch' => 'applications/releeph/storage/ReleephBranch.php',
@ -7146,6 +7147,7 @@ phutil_register_library_map(array(
'PhabricatorCustomFieldInterface', 'PhabricatorCustomFieldInterface',
'PhabricatorDestructibleInterface', 'PhabricatorDestructibleInterface',
'PhabricatorFulltextInterface', 'PhabricatorFulltextInterface',
'PhabricatorConduitResultInterface',
), ),
'PhabricatorProjectAddHeraldAction' => 'PhabricatorProjectHeraldAction', 'PhabricatorProjectAddHeraldAction' => 'PhabricatorProjectHeraldAction',
'PhabricatorProjectApplication' => 'PhabricatorApplication', 'PhabricatorProjectApplication' => 'PhabricatorApplication',
@ -8296,6 +8298,7 @@ phutil_register_library_map(array(
'ProjectRemarkupRule' => 'PhabricatorObjectRemarkupRule', 'ProjectRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'ProjectRemarkupRuleTestCase' => 'PhabricatorTestCase', 'ProjectRemarkupRuleTestCase' => 'PhabricatorTestCase',
'ProjectReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler', 'ProjectReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
'ProjectSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'QueryFormattingTestCase' => 'PhabricatorTestCase', 'QueryFormattingTestCase' => 'PhabricatorTestCase',
'ReleephAuthorFieldSpecification' => 'ReleephFieldSpecification', 'ReleephAuthorFieldSpecification' => 'ReleephFieldSpecification',
'ReleephBranch' => array( 'ReleephBranch' => array(

View file

@ -0,0 +1,24 @@
<?php
final class ProjectSearchConduitAPIMethod
extends PhabricatorSearchEngineAPIMethod {
public function getAPIMethodName() {
return 'project.search';
}
public function newSearchEngine() {
return new PhabricatorProjectSearchEngine();
}
public function getMethodSummary() {
return pht('Read information about projects.');
}
protected function getCustomQueryMaps($query) {
return array(
'slugMap' => $query->getSlugMap(),
);
}
}

View file

@ -9,7 +9,8 @@ final class PhabricatorProject extends PhabricatorProjectDAO
PhabricatorSubscribableInterface, PhabricatorSubscribableInterface,
PhabricatorCustomFieldInterface, PhabricatorCustomFieldInterface,
PhabricatorDestructibleInterface, PhabricatorDestructibleInterface,
PhabricatorFulltextInterface { PhabricatorFulltextInterface,
PhabricatorConduitResultInterface {
protected $name; protected $name;
protected $status = PhabricatorProjectStatus::STATUS_ACTIVE; protected $status = PhabricatorProjectStatus::STATUS_ACTIVE;
@ -525,4 +526,32 @@ final class PhabricatorProject extends PhabricatorProjectDAO
return new PhabricatorProjectFulltextEngine(); return new PhabricatorProjectFulltextEngine();
} }
/* -( PhabricatorConduitResultInterface )---------------------------------- */
public function getFieldSpecificationsForConduit() {
return array(
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('name')
->setType('string')
->setDescription(pht('The name of the project.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('slug')
->setType('string')
->setDescription(pht('Primary slug/hashtag.')),
);
}
public function getFieldValuesForConduit() {
return array(
'name' => $this->getName(),
'slug' => $this->getPrimarySlug(),
);
}
public function getConduitSearchAttachments() {
return array();
}
} }

View file

@ -1081,7 +1081,9 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
return $fields; return $fields;
} }
public function buildConduitResponse(ConduitAPIRequest $request) { public function buildConduitResponse(
ConduitAPIRequest $request,
ConduitAPIMethod $method) {
$viewer = $this->requireViewer(); $viewer = $this->requireViewer();
$query_key = $request->getValue('queryKey'); $query_key = $request->getValue('queryKey');
@ -1172,6 +1174,12 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
$attachment_specs[$key]); $attachment_specs[$key]);
} }
// If this is empty, we still want to emit a JSON object, not a
// JSON list.
if (!$attachment_map) {
$attachment_map = (object)$attachment_map;
}
$id = (int)$object->getID(); $id = (int)$object->getID();
$phid = $object->getPHID(); $phid = $object->getPHID();
@ -1187,6 +1195,7 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
return array( return array(
'data' => $data, 'data' => $data,
'maps' => $method->getQueryMaps($query),
'query' => array( 'query' => array(
'queryKey' => $saved_query->getQueryKey(), 'queryKey' => $saved_query->getQueryKey(),
), ),

View file

@ -5,6 +5,23 @@ abstract class PhabricatorSearchEngineAPIMethod
abstract public function newSearchEngine(); abstract public function newSearchEngine();
final public function getQueryMaps($query) {
$maps = $this->getCustomQueryMaps($query);
// Make sure we emit empty maps as objects, not lists.
foreach ($maps as $key => $map) {
if (!$map) {
$maps[$key] = (object)$map;
}
}
return $maps;
}
protected function getCustomQueryMaps($query) {
return array();
}
public function getApplication() { public function getApplication() {
$engine = $this->newSearchEngine(); $engine = $this->newSearchEngine();
$class = $engine->getApplicationClassName(); $class = $engine->getApplicationClassName();
@ -36,7 +53,7 @@ abstract class PhabricatorSearchEngineAPIMethod
$engine = $this->newSearchEngine() $engine = $this->newSearchEngine()
->setViewer($request->getUser()); ->setViewer($request->getUser());
return $engine->buildConduitResponse($request); return $engine->buildConduitResponse($request, $this);
} }
final public function getMethodDescription() { final public function getMethodDescription() {