diff --git a/src/applications/transactions/conduit/TransactionSearchConduitAPIMethod.php b/src/applications/transactions/conduit/TransactionSearchConduitAPIMethod.php --- a/src/applications/transactions/conduit/TransactionSearchConduitAPIMethod.php +++ b/src/applications/transactions/conduit/TransactionSearchConduitAPIMethod.php @@ -45,6 +45,10 @@ can quickly find an unknown type constant by looking at the PHID of an object of that type.) +All supported values for `objectType`: + +%s + Constraints =========== @@ -73,7 +77,11 @@ useful, reasonable fields) as we become aware of use cases for them. EOREMARKUP - ); +, +// Showing the supported 'objectType'(s) and their label is ideal in this APi +// documentation, and it's probably really cheaper than having users +// randomly flooding our API to figure out the supported values. +$this->getSupportedObjectTypeRemarkupDocumentation()); $markup = $this->newRemarkupDocumentationView($markup); @@ -378,16 +386,24 @@ $all_types = PhabricatorPHIDType::getAllTypes(); if (!isset($all_types[$object_type])) { - ksort($all_types); throw new Exception( pht( 'In call to "transaction.search", specified "objectType" ("%s") '. 'is unknown. Valid object types are: %s.', $object_type, - implode(', ', array_keys($all_types)))); + implode(', ', $this->getSupportedObjectTypeKeys($all_types)))); } $object = $all_types[$object_type]->newObject(); + if (!$object) { + throw new Exception( + pht( + 'In call to "transaction.search", specified "objectType" ("%s") '. + 'is not supported because it does not implement "newObject()". '. + 'Valid object types are: %s.', + $object_type, + implode(', ', $this->getSupportedObjectTypeKeys($all_types)))); + } } else { $object = id(new PhabricatorObjectQuery()) ->setViewer($viewer) @@ -414,4 +430,62 @@ return $object; } + /** + * Get a cute Remarkup table to document the supported 'objectType'(s). + */ + private function getSupportedObjectTypeRemarkupDocumentation(): string { + $lines = array(); + $type = pht('Object Type'); + $name = pht('Name'); + $lines[] = "| {$type} | $name |"; + $lines[] = '|---------|--------|'; + foreach ($this->getSupportedObjectTypesAndName() as $type => $name) { + $lines[] = "| `{$type}` | $name |"; + } + return implode("\n", $lines); + } + + /** + * Get all the supported 'objectType' API parameters, ordered and with name. + * @return array Array of object type names, indexed by type. + */ + private function getSupportedObjectTypesAndName(): array { + $all_types = PhabricatorPHIDType::getAllTypes(); + ksort($all_types); + + $supporteds = []; + foreach ($all_types as $key => $type) { + if ($this->isObjectTypeSupported($type)) { + $supporteds[$key] = $type->getTypeName(); + } + } + return $supporteds; + } + + /** + * Find the supported 'objectType' API parameters from a map of PHID types. + * @param $types array PHID types, by code. + * @return array + */ + private function getSupportedObjectTypeKeys(array $types): array { + $supported_keys = []; + foreach ($types as $key => $type) { + if ($this->isObjectTypeSupported($type)) { + $supported_keys[] = $key; + } + } + return $supported_keys; + } + + /** + * Get a new object from a 'objectType' API parameter. + * @param $type PhabricatorPHIDType + * @return PhabricatorApplicationTransactionInterface|null + * Get the new object, or null when the type is not supported. + */ + private function isObjectTypeSupported($type) { + $obj = $type->newObject(); + return $obj && $obj instanceof PhabricatorApplicationTransactionInterface; + } + }