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

Formalize custom Conduit fields on objects

Summary: Ref T9964. This just adds more structure to application fields, to make it harder to make typos and easier to validate them later.

Test Plan: Viewed APIs, called some APIs, saw good documentation and correct results.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T9964

Differential Revision: https://secure.phabricator.com/D14776
This commit is contained in:
epriestley 2015-12-14 06:42:21 -08:00
parent 10cdc55cf7
commit 0a50219f1b
12 changed files with 141 additions and 90 deletions

View file

@ -1897,6 +1897,7 @@ phutil_register_library_map(array(
'PhabricatorConduitRequestExceptionHandler' => 'aphront/handler/PhabricatorConduitRequestExceptionHandler.php', 'PhabricatorConduitRequestExceptionHandler' => 'aphront/handler/PhabricatorConduitRequestExceptionHandler.php',
'PhabricatorConduitResultInterface' => 'applications/conduit/interface/PhabricatorConduitResultInterface.php', 'PhabricatorConduitResultInterface' => 'applications/conduit/interface/PhabricatorConduitResultInterface.php',
'PhabricatorConduitSearchEngine' => 'applications/conduit/query/PhabricatorConduitSearchEngine.php', 'PhabricatorConduitSearchEngine' => 'applications/conduit/query/PhabricatorConduitSearchEngine.php',
'PhabricatorConduitSearchFieldSpecification' => 'applications/conduit/interface/PhabricatorConduitSearchFieldSpecification.php',
'PhabricatorConduitTestCase' => '__tests__/PhabricatorConduitTestCase.php', 'PhabricatorConduitTestCase' => '__tests__/PhabricatorConduitTestCase.php',
'PhabricatorConduitToken' => 'applications/conduit/storage/PhabricatorConduitToken.php', 'PhabricatorConduitToken' => 'applications/conduit/storage/PhabricatorConduitToken.php',
'PhabricatorConduitTokenController' => 'applications/conduit/controller/PhabricatorConduitTokenController.php', 'PhabricatorConduitTokenController' => 'applications/conduit/controller/PhabricatorConduitTokenController.php',
@ -6014,6 +6015,7 @@ phutil_register_library_map(array(
'PhabricatorConduitRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler', 'PhabricatorConduitRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler',
'PhabricatorConduitResultInterface' => 'PhabricatorPHIDInterface', 'PhabricatorConduitResultInterface' => 'PhabricatorPHIDInterface',
'PhabricatorConduitSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorConduitSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorConduitSearchFieldSpecification' => 'Phobject',
'PhabricatorConduitTestCase' => 'PhabricatorTestCase', 'PhabricatorConduitTestCase' => 'PhabricatorTestCase',
'PhabricatorConduitToken' => array( 'PhabricatorConduitToken' => array(
'PhabricatorConduitDAO', 'PhabricatorConduitDAO',

View file

@ -16,10 +16,10 @@ interface PhabricatorConduitResultInterface
public function getFieldSpecificationsForConduit() { public function getFieldSpecificationsForConduit() {
return array( return array(
'name' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'string', ->setKey('name')
'description' => pht('The name of the object.'), ->setType('string')
), ->setDescription(pht('The name of the object.')),
); );
} }

View file

@ -0,0 +1,37 @@
<?php
final class PhabricatorConduitSearchFieldSpecification
extends Phobject {
private $key;
private $type;
private $description;
public function setKey($key) {
$this->key = $key;
return $this;
}
public function getKey() {
return $this->key;
}
public function setType($type) {
$this->type = $type;
return $this;
}
public function getType() {
return $this->type;
}
public function setDescription($description) {
$this->description = $description;
return $this;
}
public function getDescription() {
return $this->description;
}
}

View file

@ -399,30 +399,30 @@ final class ManiphestTask extends ManiphestDAO
public function getFieldSpecificationsForConduit() { public function getFieldSpecificationsForConduit() {
return array( return array(
'title' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'string', ->setKey('title')
'description' => pht('The name of the object.'), ->setType('string')
), ->setDescription(pht('The title of the task.')),
'authorPHID' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'phid', ->setKey('authorPHID')
'description' => pht('Original task author.'), ->setType('phid')
), ->setDescription(pht('Original task author.')),
'ownerPHID' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'phid?', ->setKey('ownerPHID')
'description' => pht('Current task owner.'), ->setType('phid?')
), ->setDescription(pht('Current task owner, if task is assigned.')),
'status' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'string', ->setKey('status')
'description' => pht('Current task status.'), ->setType('string')
), ->setDescription(pht('Task status.')),
'priority' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'int', ->setKey('priority')
'description' => pht('Task priority.'), ->setType('int')
), ->setDescription(pht('Task priority.')),
'subpriority' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'double', ->setKey('subpriority')
'description' => pht('Order within priority level.'), ->setType('double')
), ->setDescription(pht('Order within priority level.')),
); );
} }

View file

@ -391,22 +391,22 @@ final class PhabricatorOwnersPackage
public function getFieldSpecificationsForConduit() { public function getFieldSpecificationsForConduit() {
return array( return array(
'name' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'string', ->setKey('name')
'description' => pht('The name of the package.'), ->setType('string')
), ->setDescription(pht('The name of the package.')),
'description' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'string', ->setKey('description')
'description' => pht('The package description.'), ->setType('string')
), ->setDescription(pht('The package description.')),
'status' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'string', ->setKey('status')
'description' => pht('Active or archived status of the package.'), ->setType('string')
), ->setDescription(pht('Active or archived status of the package.')),
'owners' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'list<map<string, wild>>', ->setKey('owners')
'description' => pht('List of package owners.'), ->setType('list<map<string, wild>>')
), ->setDescription(pht('List of package owners.')),
); );
} }

View file

@ -257,22 +257,22 @@ final class PhabricatorPaste extends PhabricatorPasteDAO
public function getFieldSpecificationsForConduit() { public function getFieldSpecificationsForConduit() {
return array( return array(
'title' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'string', ->setKey('title')
'description' => pht('The name of the object.'), ->setType('string')
), ->setDescription(pht('The title of the paste.')),
'authorPHID' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'phid', ->setKey('authorPHID')
'description' => pht('User PHID of the author.'), ->setType('phid')
), ->setDescription(pht('User PHID of the author.')),
'language' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'string?', ->setKey('language')
'description' => pht('Language to use for syntax highlighting.'), ->setType('string?')
), ->setDescription(pht('Language to use for syntax highlighting.')),
'status' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'string', ->setKey('status')
'description' => pht('Active or archived status of the paste.'), ->setType('string')
), ->setDescription(pht('Active or arhived status of the paste.')),
); );
} }

View file

@ -23,11 +23,10 @@ final class PhabricatorPolicySearchEngineExtension
public function getFieldSpecificationsForConduit($object) { public function getFieldSpecificationsForConduit($object) {
return array( return array(
'policy' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'map<string, wild>', ->setKey('policy')
'description' => pht( ->setType('map<string, wild>')
'Map of capabilities to current policies.'), ->setDescription(pht('Map of capabilities to current policies.')),
),
); );
} }

View file

@ -1129,7 +1129,7 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
$attachments = $this->getConduitSearchAttachments(); $attachments = $this->getConduitSearchAttachments();
// TODO: Validate this better. // TODO: Validate this better.
$attachment_specs = $request->getValue('attachments'); $attachment_specs = $request->getValue('attachments', array());
$attachments = array_select_keys( $attachments = array_select_keys(
$attachments, $attachments,
array_keys($attachment_specs)); array_keys($attachment_specs));
@ -1203,12 +1203,23 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
$extensions = $this->getConduitFieldExtensions(); $extensions = $this->getConduitFieldExtensions();
$object = $this->newQuery()->newResultObject(); $object = $this->newQuery()->newResultObject();
$specifications = array(); $map = array();
foreach ($extensions as $extension) { foreach ($extensions as $extension) {
$specifications += $extension->getFieldSpecificationsForConduit($object); $specifications = $extension->getFieldSpecificationsForConduit($object);
foreach ($specifications as $specification) {
$key = $specification->getKey();
if (isset($map[$key])) {
throw new Exception(
pht(
'Two field specifications share the same key ("%s"). Each '.
'specification must have a unique key.',
$key));
}
$map[$key] = $specification;
}
} }
return $specifications; return $map;
} }
private function getEngineExtensions() { private function getEngineExtensions() {

View file

@ -373,8 +373,8 @@ EOTEXT
$rows = array(); $rows = array();
foreach ($specs as $key => $spec) { foreach ($specs as $key => $spec) {
$type = idx($spec, 'type'); $type = $spec->getType();
$description = idx($spec, 'description'); $description = $spec->getDescription();
$rows[] = array( $rows[] = array(
$key, $key,
$type, $type,

View file

@ -31,16 +31,16 @@ final class PhabricatorLiskSearchEngineExtension
public function getFieldSpecificationsForConduit($object) { public function getFieldSpecificationsForConduit($object) {
return array( return array(
'dateCreated' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'int', ->setKey('dateCreated')
'description' => pht( ->setType('int')
'Epoch timestamp when the object was created.'), ->setDescription(
), pht('Epoch timestamp when the object was created.')),
'dateModified' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'int', ->setKey('dateModified')
'description' => pht( ->setType('int')
'Epoch timestamp when the object was last updated.'), ->setDescription(
), pht('Epoch timestamp when the object was last updated.')),
); );
} }

View file

@ -55,11 +55,11 @@ final class PhabricatorSpacesSearchEngineExtension
public function getFieldSpecificationsForConduit($object) { public function getFieldSpecificationsForConduit($object) {
return array( return array(
'spacePHID' => array( id(new PhabricatorConduitSearchFieldSpecification())
'type' => 'phid?', ->setKey('spacePHID')
'description' => pht( ->setType('phid?')
'PHID of the policy space this object is part of.'), ->setDescription(
), pht('PHID of the policy space this object is part of.')),
); );
} }

View file

@ -69,10 +69,12 @@ final class PhabricatorCustomFieldSearchEngineExtension
$map = array(); $map = array();
foreach ($fields->getFields() as $field) { foreach ($fields->getFields() as $field) {
$key = $field->getModernFieldKey(); $key = $field->getModernFieldKey();
$map[$key] = array(
'type' => 'wild', // TODO: These should have proper types.
'description' => $field->getFieldDescription(), $map[] = id(new PhabricatorConduitSearchFieldSpecification())
); ->setKey($key)
->setType('wild')
->setDescription($field->getFieldDescription());
} }
return $map; return $map;