Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15331922
D14763.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
18 KB
Referenced Files
None
Subscribers
None
D14763.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -231,14 +231,18 @@
'ConduitException' => 'applications/conduit/protocol/exception/ConduitException.php',
'ConduitGetCapabilitiesConduitAPIMethod' => 'applications/conduit/method/ConduitGetCapabilitiesConduitAPIMethod.php',
'ConduitGetCertificateConduitAPIMethod' => 'applications/conduit/method/ConduitGetCertificateConduitAPIMethod.php',
+ 'ConduitListParameterType' => 'applications/conduit/parametertype/ConduitListParameterType.php',
'ConduitLogGarbageCollector' => 'applications/conduit/garbagecollector/ConduitLogGarbageCollector.php',
'ConduitMethodDoesNotExistException' => 'applications/conduit/protocol/exception/ConduitMethodDoesNotExistException.php',
'ConduitMethodNotFoundException' => 'applications/conduit/protocol/exception/ConduitMethodNotFoundException.php',
+ 'ConduitParameterType' => 'applications/conduit/parametertype/ConduitParameterType.php',
'ConduitPingConduitAPIMethod' => 'applications/conduit/method/ConduitPingConduitAPIMethod.php',
'ConduitQueryConduitAPIMethod' => 'applications/conduit/method/ConduitQueryConduitAPIMethod.php',
'ConduitResultSearchEngineExtension' => 'applications/conduit/query/ConduitResultSearchEngineExtension.php',
'ConduitSSHWorkflow' => 'applications/conduit/ssh/ConduitSSHWorkflow.php',
+ 'ConduitStringListParameterType' => 'applications/conduit/parametertype/ConduitStringListParameterType.php',
'ConduitTokenGarbageCollector' => 'applications/conduit/garbagecollector/ConduitTokenGarbageCollector.php',
+ 'ConduitUserListParameterType' => 'applications/conduit/parametertype/ConduitUserListParameterType.php',
'ConpherenceColumnViewController' => 'applications/conpherence/controller/ConpherenceColumnViewController.php',
'ConpherenceConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceConduitAPIMethod.php',
'ConpherenceConfigOptions' => 'applications/conpherence/config/ConpherenceConfigOptions.php',
@@ -4071,14 +4075,18 @@
'ConduitException' => 'Exception',
'ConduitGetCapabilitiesConduitAPIMethod' => 'ConduitAPIMethod',
'ConduitGetCertificateConduitAPIMethod' => 'ConduitAPIMethod',
+ 'ConduitListParameterType' => 'ConduitParameterType',
'ConduitLogGarbageCollector' => 'PhabricatorGarbageCollector',
'ConduitMethodDoesNotExistException' => 'ConduitMethodNotFoundException',
'ConduitMethodNotFoundException' => 'ConduitException',
+ 'ConduitParameterType' => 'Phobject',
'ConduitPingConduitAPIMethod' => 'ConduitAPIMethod',
'ConduitQueryConduitAPIMethod' => 'ConduitAPIMethod',
'ConduitResultSearchEngineExtension' => 'PhabricatorSearchEngineExtension',
'ConduitSSHWorkflow' => 'PhabricatorSSHWorkflow',
+ 'ConduitStringListParameterType' => 'ConduitListParameterType',
'ConduitTokenGarbageCollector' => 'PhabricatorGarbageCollector',
+ 'ConduitUserListParameterType' => 'ConduitListParameterType',
'ConpherenceColumnViewController' => 'ConpherenceController',
'ConpherenceConduitAPIMethod' => 'ConduitAPIMethod',
'ConpherenceConfigOptions' => 'PhabricatorApplicationConfigOptions',
diff --git a/src/applications/conduit/parametertype/ConduitListParameterType.php b/src/applications/conduit/parametertype/ConduitListParameterType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/conduit/parametertype/ConduitListParameterType.php
@@ -0,0 +1,37 @@
+<?php
+
+abstract class ConduitListParameterType
+ extends ConduitParameterType {
+
+ protected function getParameterValue(array $request, $key) {
+ $value = parent::getParameterValue();
+
+ if (!is_array($value)) {
+ $this->raiseValidationException(
+ $request,
+ $key,
+ pht('Expected a list, but value is not a list.'));
+ }
+
+ $actual_keys = array_keys($value);
+ if ($value) {
+ $natural_keys = range(0, count($value) - 1);
+ } else {
+ $natural_keys = array();
+ }
+
+ if ($actual_keys !== $natural_keys) {
+ $this->raiseValidationException(
+ $request,
+ $key,
+ pht('Expected a list, but value is an object.'));
+ }
+
+ return $value;
+ }
+
+ protected function getParameterDefault() {
+ return array();
+ }
+
+}
diff --git a/src/applications/conduit/parametertype/ConduitParameterType.php b/src/applications/conduit/parametertype/ConduitParameterType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/conduit/parametertype/ConduitParameterType.php
@@ -0,0 +1,97 @@
+<?php
+
+/**
+ * Defines how to read a value from a Conduit request.
+ *
+ * This class behaves like @{class:AphrontHTTPParameterType}, but for Conduit.
+ */
+abstract class ConduitParameterType extends Phobject {
+
+
+ private $viewer;
+
+
+ final public function setViewer(PhabricatorUser $viewer) {
+ $this->viewer = $viewer;
+ return $this;
+ }
+
+
+ final public function getViewer() {
+ if (!$this->viewer) {
+ throw new PhutilInvalidStateException('setViewer');
+ }
+ return $this->viewer;
+ }
+
+
+ final public function getExists(array $request, $key) {
+ return $this->getValueExists($request, $key);
+ }
+
+
+ final public function getValue(array $request, $key) {
+ if (!$this->getExists($request, $key)) {
+ return $this->getParameterDefault();
+ }
+
+ return $this->getParameterValue($request, $key);
+ }
+
+
+ final public function getDefaultValue() {
+ return $this->getParameterDefault();
+ }
+
+
+ final public function getTypeName() {
+ return $this->getParameterTypeName();
+ }
+
+
+ final public function getFormatDescriptions() {
+ return $this->getParameterFormatDescriptions();
+ }
+
+
+ final public function getExamples() {
+ return $this->getParameterExamples();
+ }
+
+ protected function raiseValidationException(array $request, $key, $message) {
+ // TODO: Specialize this so we can give users more tailored messages from
+ // Conduit.
+ throw new Exception($message);
+ }
+
+
+ final public static function getAllTypes() {
+ return id(new PhutilClassMapQuery())
+ ->setAncestorClass(__CLASS__)
+ ->setUniqueMethod('getTypeName')
+ ->setSortMethod('getTypeName')
+ ->execute();
+ }
+
+
+ protected function getParameterExists(array $request, $key) {
+ return array_key_exists($key, $request);
+ }
+
+ protected function getParameterValue(array $request, $key) {
+ return $request[$key];
+ }
+
+ abstract protected function getParameterTypeName();
+
+
+ abstract protected function getParameterFormatDescriptions();
+
+
+ abstract protected function getParameterExamples();
+
+ protected function getParameterDefault() {
+ return null;
+ }
+
+}
diff --git a/src/applications/conduit/parametertype/ConduitStringListParameterType.php b/src/applications/conduit/parametertype/ConduitStringListParameterType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/conduit/parametertype/ConduitStringListParameterType.php
@@ -0,0 +1,40 @@
+<?php
+
+final class ConduitStringListParameterType
+ extends ConduitListParameterType {
+
+ protected function getParameterValue(array $request, $key) {
+ $list = parent::getParameterValue();
+
+ foreach ($list as $idx => $item) {
+ if (!is_string($item)) {
+ $this->raiseValidationException(
+ $request,
+ $key,
+ pht(
+ 'Expected a list of strings, but item with index "%s" is '.
+ 'not a string.',
+ $idx));
+ }
+ }
+
+ return $list;
+ }
+
+ protected function getParameterTypeName() {
+ return 'list<string>';
+ }
+
+ protected function getParameterFormatDescriptions() {
+ return array(
+ pht('List of strings.'),
+ );
+ }
+
+ protected function getParameterExamples() {
+ return array(
+ '["mango", "nectarine"]',
+ );
+ }
+
+}
diff --git a/src/applications/conduit/parametertype/ConduitUserListParameterType.php b/src/applications/conduit/parametertype/ConduitUserListParameterType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/conduit/parametertype/ConduitUserListParameterType.php
@@ -0,0 +1,33 @@
+<?php
+
+final class ConduitUserListParameterType
+ extends ConduitListParameterType {
+
+ protected function getParameterValue(array $request, $key) {
+ $list = parent::getParameterValue();
+ return id(new PhabricatorUserPHIDResolver())
+ ->setViewer($this->getViewer())
+ ->resolvePHIDs($list);
+ }
+
+ protected function getParameterTypeName() {
+ return 'list<user>';
+ }
+
+ protected function getParameterFormatDescriptions() {
+ return array(
+ pht('List of user PHIDs.'),
+ pht('List of usernames.'),
+ pht('List with a mixture of PHIDs and usernames.'),
+ );
+ }
+
+ protected function getParameterExamples() {
+ return array(
+ '["PHID-USER-1111"]',
+ '["alincoln"]',
+ '["PHID-USER-2222", "alincoln"]',
+ );
+ }
+
+}
diff --git a/src/applications/conduit/protocol/ConduitAPIRequest.php b/src/applications/conduit/protocol/ConduitAPIRequest.php
--- a/src/applications/conduit/protocol/ConduitAPIRequest.php
+++ b/src/applications/conduit/protocol/ConduitAPIRequest.php
@@ -14,6 +14,10 @@
return coalesce(idx($this->params, $key), $default);
}
+ public function getValueExists($key) {
+ return array_key_exists($key, $this->params);
+ }
+
public function getAllParameters() {
return $this->params;
}
diff --git a/src/applications/paste/query/PhabricatorPasteSearchEngine.php b/src/applications/paste/query/PhabricatorPasteSearchEngine.php
--- a/src/applications/paste/query/PhabricatorPasteSearchEngine.php
+++ b/src/applications/paste/query/PhabricatorPasteSearchEngine.php
@@ -47,6 +47,7 @@
id(new PhabricatorUsersSearchField())
->setAliases(array('authors'))
->setKey('authorPHIDs')
+ ->setConduitKey('authors')
->setLabel(pht('Authors')),
id(new PhabricatorSearchStringListField())
->setKey('languages')
diff --git a/src/applications/people/searchfield/PhabricatorUsersSearchField.php b/src/applications/people/searchfield/PhabricatorUsersSearchField.php
--- a/src/applications/people/searchfield/PhabricatorUsersSearchField.php
+++ b/src/applications/people/searchfield/PhabricatorUsersSearchField.php
@@ -15,4 +15,8 @@
return new PhabricatorPeopleUserFunctionDatasource();
}
+ protected function newConduitParameterType() {
+ return new ConduitUserListParameterType();
+ }
+
}
diff --git a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
--- a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
+++ b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
@@ -1173,7 +1173,34 @@
}
public function getSearchFieldsForConduit() {
- $fields = $this->buildSearchFields();
+ $standard_fields = $this->buildSearchFields();
+
+ $fields = array();
+ foreach ($standard_fields as $field_key => $field) {
+ $conduit_key = $field->getConduitKey();
+
+ if (isset($fields[$conduit_key])) {
+ $other = $fields[$conduit_key];
+ $other_key = $other->getKey();
+
+ throw new Exception(
+ pht(
+ 'SearchFields "%s" (of class "%s") and "%s" (of class "%s") both '.
+ 'define the same Conduit key ("%s"). Keys must be unique.',
+ $field_key,
+ get_class($field),
+ $other_key,
+ get_class($other),
+ $conduit_key));
+ }
+
+ $fields[$conduit_key] = $field;
+ }
+
+ $viewer = $this->requireViewer();
+ foreach ($fields as $key => $field) {
+ $field->setViewer($viewer);
+ }
// These are handled separately for Conduit, so don't show them as
// supported.
@@ -1187,7 +1214,6 @@
public function buildConduitResponse(ConduitAPIRequest $request) {
$viewer = $this->requireViewer();
- $fields = $this->buildSearchFields();
$query_key = $request->getValue('queryKey');
if (!strlen($query_key)) {
@@ -1207,12 +1233,16 @@
}
}
- foreach ($fields as $field) {
- $field->setViewer($viewer);
- }
-
$constraints = $request->getValue('constraints', array());
+ $fields = $this->getSearchFieldsForConduit();
+
+ foreach ($fields as $key => $field) {
+ if (!$field->getConduitParameterType()) {
+ unset($fields[$key]);
+ }
+ }
+
foreach ($fields as $field) {
if (!$field->getValueExistsInConduitRequest($constraints)) {
continue;
diff --git a/src/applications/search/engine/PhabricatorSearchEngineAPIMethod.php b/src/applications/search/engine/PhabricatorSearchEngineAPIMethod.php
--- a/src/applications/search/engine/PhabricatorSearchEngineAPIMethod.php
+++ b/src/applications/search/engine/PhabricatorSearchEngineAPIMethod.php
@@ -154,14 +154,20 @@
$table[] = "| `ids` | **IDs** | `list<int>` | {$desc_ids} |";
$table[] = "| `phids` | **PHIDs** | `list<phid>` | {$desc_phids} |";
foreach ($fields as $field) {
- $key = $field->getKeyForConduit();
+ $key = $field->getConduitKey();
$label = $field->getLabel();
- // TODO: Support generating and surfacing this information.
- $type = pht('TODO');
- $description = pht('TODO');
+ $type_object = $field->getConduitParameterType();
+ if ($type_object) {
+ $type = '`'.$type_object->getTypeName().'`';
+ // TODO: Support generating and surfacing this information.
+ $description = pht('TODO');
+ } else {
+ $type = '';
+ $description = '//'.pht('Not Supported').'//';
+ }
- $table[] = "| `{$key}` | **{$label}** | `{$type}` | {$description}";
+ $table[] = "| `{$key}` | **{$label}** | {$type} | {$description}";
}
$table = implode("\n", $table);
$out[] = $table;
diff --git a/src/applications/search/field/PhabricatorSearchCheckboxesField.php b/src/applications/search/field/PhabricatorSearchCheckboxesField.php
--- a/src/applications/search/field/PhabricatorSearchCheckboxesField.php
+++ b/src/applications/search/field/PhabricatorSearchCheckboxesField.php
@@ -37,4 +37,8 @@
return $control;
}
+ protected function newConduitParameterType() {
+ return new ConduitStringListParameterType();
+ }
+
}
diff --git a/src/applications/search/field/PhabricatorSearchCustomFieldProxyField.php b/src/applications/search/field/PhabricatorSearchCustomFieldProxyField.php
--- a/src/applications/search/field/PhabricatorSearchCustomFieldProxyField.php
+++ b/src/applications/search/field/PhabricatorSearchCustomFieldProxyField.php
@@ -38,7 +38,7 @@
return null;
}
- public function getKeyForConduit() {
+ public function getConduitKey() {
return $this->getCustomField()->getModernFieldKey();
}
diff --git a/src/applications/search/field/PhabricatorSearchField.php b/src/applications/search/field/PhabricatorSearchField.php
--- a/src/applications/search/field/PhabricatorSearchField.php
+++ b/src/applications/search/field/PhabricatorSearchField.php
@@ -4,11 +4,13 @@
* @task config Configuring Fields
* @task error Handling Errors
* @task io Reading and Writing Field Values
+ * @task conduit Integration with Conduit
* @task util Utility Methods
*/
abstract class PhabricatorSearchField extends Phobject {
private $key;
+ private $conduitKey;
private $viewer;
private $value;
private $label;
@@ -130,6 +132,37 @@
}
+ /**
+ * Provide an alternate field key for Conduit.
+ *
+ * This can allow you to choose a more usable key for API endpoints.
+ * If no key is provided, the main key is used.
+ *
+ * @param string Alternate key for Conduit.
+ * @return this
+ * @task config
+ */
+ public function setConduitKey($conduit_key) {
+ $this->conduitKey = $conduit_key;
+ return $this;
+ }
+
+
+ /**
+ * Get the field key for use in Conduit.
+ *
+ * @return string Conduit key for this field.
+ * @task config
+ */
+ public function getConduitKey() {
+ if ($this->conduitKey !== null) {
+ return $this->conduitKey;
+ }
+
+ return $this->getKey();
+ }
+
+
/* -( Handling Errors )---------------------------------------------------- */
@@ -205,14 +238,6 @@
return $value;
}
- public function getValueExistsInConduitRequest(array $constraints) {
- return array_key_exists($this->getKey(), $constraints);
- }
-
- public function readValueFromConduitRequest(array $constraints) {
- return idx($constraints, $this->getKey());
- }
-
/* -( Rendering Controls )------------------------------------------------- */
@@ -238,6 +263,39 @@
}
+/* -( Integration with Conduit )------------------------------------------- */
+
+
+ /**
+ * @task conduit
+ */
+ final public function getConduitParameterType() {
+ $type = $this->newConduitParameterType();
+
+ if ($type) {
+ $type->setViewer($this->getViewer());
+ }
+
+ return $type;
+ }
+
+ protected function newConduitParameterType() {
+ return null;
+ }
+
+ public function getValueExistsInConduitRequest(array $constraints) {
+ return $this->getConduitParameterType()->getExists(
+ $constraints,
+ $this->getConduitKey());
+ }
+
+ public function readValueFromConduitRequest(array $constraints) {
+ return $this->getConduitParameterType()->getValue(
+ $constraints,
+ $this->getConduitKey());
+ }
+
+
/* -( Utility Methods )----------------------------------------------------- */
@@ -273,12 +331,5 @@
}
- public function getKeyForConduit() {
- // TODO: This shouldn't really be different, but internal handling of
- // custom field keys is a bit of a mess for now.
- return $this->getKey();
- }
-
-
}
diff --git a/src/applications/search/field/PhabricatorSearchStringListField.php b/src/applications/search/field/PhabricatorSearchStringListField.php
--- a/src/applications/search/field/PhabricatorSearchStringListField.php
+++ b/src/applications/search/field/PhabricatorSearchStringListField.php
@@ -19,4 +19,8 @@
return implode(', ', parent::getValueForControl());
}
+ protected function newConduitParameterType() {
+ return new ConduitStringListParameterType();
+ }
+
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 8, 3:19 PM (3 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7223185
Default Alt Text
D14763.diff (18 KB)
Attached To
Mode
D14763: Add basic typechecking support to Conduit
Attached
Detach File
Event Timeline
Log In to Comment