mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-29 18:22:41 +01:00
Allow Almanac properties to be set and deleted via Conduit
Summary: Depends on D19342. Ref T12414. Ref T13120. This adds an EditEngine extension for editing Almanac properties. The actual wire format is a little weird. Normally, we'd have a transaction for each property, but since you can pick any property names you want we can't really do that (we'd have to generate infinite transactions). The transaction wire format anticipates that transactions may eventually get some kind of metadata -- each transaction looks like this: ``` { "type": "title", "value": "Example title" } ``` ...and we can add more keys there. For example, I could have made this transaction look like this: ``` { "type": "property.set", "almanac.property.key": "some-key", "value": "some-value" } ``` However, I don't want to just accept any possible key freely, and it might be a decent chunk of work to formalize this better. It also doesn't feel great. I just built special transaction types intead, so you: ``` { "type": "property.set", "value": { "some-key": "some-value", ... } } ``` Internally, we may generate more than one transaction as a result (if the "value" has more than one key). This feels a bit more natural and is probably easier for clients to use anyway. Test Plan: Set and deleted Service, Device and Binding properties via the API. Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T13120, T12414 Differential Revision: https://secure.phabricator.com/D19343
This commit is contained in:
parent
c1558031c2
commit
ea9187ea92
9 changed files with 168 additions and 3 deletions
|
@ -44,6 +44,8 @@ phutil_register_library_map(array(
|
||||||
'AlmanacCreateServicesCapability' => 'applications/almanac/capability/AlmanacCreateServicesCapability.php',
|
'AlmanacCreateServicesCapability' => 'applications/almanac/capability/AlmanacCreateServicesCapability.php',
|
||||||
'AlmanacCustomServiceType' => 'applications/almanac/servicetype/AlmanacCustomServiceType.php',
|
'AlmanacCustomServiceType' => 'applications/almanac/servicetype/AlmanacCustomServiceType.php',
|
||||||
'AlmanacDAO' => 'applications/almanac/storage/AlmanacDAO.php',
|
'AlmanacDAO' => 'applications/almanac/storage/AlmanacDAO.php',
|
||||||
|
'AlmanacDeletePropertyEditField' => 'applications/almanac/engineextension/AlmanacDeletePropertyEditField.php',
|
||||||
|
'AlmanacDeletePropertyEditType' => 'applications/almanac/engineextension/AlmanacDeletePropertyEditType.php',
|
||||||
'AlmanacDevice' => 'applications/almanac/storage/AlmanacDevice.php',
|
'AlmanacDevice' => 'applications/almanac/storage/AlmanacDevice.php',
|
||||||
'AlmanacDeviceController' => 'applications/almanac/controller/AlmanacDeviceController.php',
|
'AlmanacDeviceController' => 'applications/almanac/controller/AlmanacDeviceController.php',
|
||||||
'AlmanacDeviceDeletePropertyTransaction' => 'applications/almanac/xaction/AlmanacDeviceDeletePropertyTransaction.php',
|
'AlmanacDeviceDeletePropertyTransaction' => 'applications/almanac/xaction/AlmanacDeviceDeletePropertyTransaction.php',
|
||||||
|
@ -129,6 +131,7 @@ phutil_register_library_map(array(
|
||||||
'AlmanacNetworkTransactionType' => 'applications/almanac/xaction/AlmanacNetworkTransactionType.php',
|
'AlmanacNetworkTransactionType' => 'applications/almanac/xaction/AlmanacNetworkTransactionType.php',
|
||||||
'AlmanacNetworkViewController' => 'applications/almanac/controller/AlmanacNetworkViewController.php',
|
'AlmanacNetworkViewController' => 'applications/almanac/controller/AlmanacNetworkViewController.php',
|
||||||
'AlmanacPropertiesDestructionEngineExtension' => 'applications/almanac/engineextension/AlmanacPropertiesDestructionEngineExtension.php',
|
'AlmanacPropertiesDestructionEngineExtension' => 'applications/almanac/engineextension/AlmanacPropertiesDestructionEngineExtension.php',
|
||||||
|
'AlmanacPropertiesEditEngineExtension' => 'applications/almanac/engineextension/AlmanacPropertiesEditEngineExtension.php',
|
||||||
'AlmanacPropertiesSearchEngineAttachment' => 'applications/almanac/engineextension/AlmanacPropertiesSearchEngineAttachment.php',
|
'AlmanacPropertiesSearchEngineAttachment' => 'applications/almanac/engineextension/AlmanacPropertiesSearchEngineAttachment.php',
|
||||||
'AlmanacProperty' => 'applications/almanac/storage/AlmanacProperty.php',
|
'AlmanacProperty' => 'applications/almanac/storage/AlmanacProperty.php',
|
||||||
'AlmanacPropertyController' => 'applications/almanac/controller/AlmanacPropertyController.php',
|
'AlmanacPropertyController' => 'applications/almanac/controller/AlmanacPropertyController.php',
|
||||||
|
@ -165,6 +168,8 @@ phutil_register_library_map(array(
|
||||||
'AlmanacServiceTypeTestCase' => 'applications/almanac/servicetype/__tests__/AlmanacServiceTypeTestCase.php',
|
'AlmanacServiceTypeTestCase' => 'applications/almanac/servicetype/__tests__/AlmanacServiceTypeTestCase.php',
|
||||||
'AlmanacServiceTypeTransaction' => 'applications/almanac/xaction/AlmanacServiceTypeTransaction.php',
|
'AlmanacServiceTypeTransaction' => 'applications/almanac/xaction/AlmanacServiceTypeTransaction.php',
|
||||||
'AlmanacServiceViewController' => 'applications/almanac/controller/AlmanacServiceViewController.php',
|
'AlmanacServiceViewController' => 'applications/almanac/controller/AlmanacServiceViewController.php',
|
||||||
|
'AlmanacSetPropertyEditField' => 'applications/almanac/engineextension/AlmanacSetPropertyEditField.php',
|
||||||
|
'AlmanacSetPropertyEditType' => 'applications/almanac/engineextension/AlmanacSetPropertyEditType.php',
|
||||||
'AlmanacTransactionType' => 'applications/almanac/xaction/AlmanacTransactionType.php',
|
'AlmanacTransactionType' => 'applications/almanac/xaction/AlmanacTransactionType.php',
|
||||||
'AphlictDropdownDataQuery' => 'applications/aphlict/query/AphlictDropdownDataQuery.php',
|
'AphlictDropdownDataQuery' => 'applications/aphlict/query/AphlictDropdownDataQuery.php',
|
||||||
'Aphront304Response' => 'aphront/response/Aphront304Response.php',
|
'Aphront304Response' => 'aphront/response/Aphront304Response.php',
|
||||||
|
@ -5246,6 +5251,8 @@ phutil_register_library_map(array(
|
||||||
'AlmanacCreateServicesCapability' => 'PhabricatorPolicyCapability',
|
'AlmanacCreateServicesCapability' => 'PhabricatorPolicyCapability',
|
||||||
'AlmanacCustomServiceType' => 'AlmanacServiceType',
|
'AlmanacCustomServiceType' => 'AlmanacServiceType',
|
||||||
'AlmanacDAO' => 'PhabricatorLiskDAO',
|
'AlmanacDAO' => 'PhabricatorLiskDAO',
|
||||||
|
'AlmanacDeletePropertyEditField' => 'PhabricatorEditField',
|
||||||
|
'AlmanacDeletePropertyEditType' => 'PhabricatorEditType',
|
||||||
'AlmanacDevice' => array(
|
'AlmanacDevice' => array(
|
||||||
'AlmanacDAO',
|
'AlmanacDAO',
|
||||||
'PhabricatorPolicyInterface',
|
'PhabricatorPolicyInterface',
|
||||||
|
@ -5365,6 +5372,7 @@ phutil_register_library_map(array(
|
||||||
'AlmanacNetworkTransactionType' => 'AlmanacTransactionType',
|
'AlmanacNetworkTransactionType' => 'AlmanacTransactionType',
|
||||||
'AlmanacNetworkViewController' => 'AlmanacNetworkController',
|
'AlmanacNetworkViewController' => 'AlmanacNetworkController',
|
||||||
'AlmanacPropertiesDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
|
'AlmanacPropertiesDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
|
||||||
|
'AlmanacPropertiesEditEngineExtension' => 'PhabricatorEditEngineExtension',
|
||||||
'AlmanacPropertiesSearchEngineAttachment' => 'AlmanacSearchEngineAttachment',
|
'AlmanacPropertiesSearchEngineAttachment' => 'AlmanacSearchEngineAttachment',
|
||||||
'AlmanacProperty' => array(
|
'AlmanacProperty' => array(
|
||||||
'AlmanacDAO',
|
'AlmanacDAO',
|
||||||
|
@ -5413,6 +5421,8 @@ phutil_register_library_map(array(
|
||||||
'AlmanacServiceTypeTestCase' => 'PhabricatorTestCase',
|
'AlmanacServiceTypeTestCase' => 'PhabricatorTestCase',
|
||||||
'AlmanacServiceTypeTransaction' => 'AlmanacServiceTransactionType',
|
'AlmanacServiceTypeTransaction' => 'AlmanacServiceTransactionType',
|
||||||
'AlmanacServiceViewController' => 'AlmanacServiceController',
|
'AlmanacServiceViewController' => 'AlmanacServiceController',
|
||||||
|
'AlmanacSetPropertyEditField' => 'PhabricatorEditField',
|
||||||
|
'AlmanacSetPropertyEditType' => 'PhabricatorEditType',
|
||||||
'AlmanacTransactionType' => 'PhabricatorModularTransactionType',
|
'AlmanacTransactionType' => 'PhabricatorModularTransactionType',
|
||||||
'AphlictDropdownDataQuery' => 'Phobject',
|
'AphlictDropdownDataQuery' => 'Phobject',
|
||||||
'Aphront304Response' => 'AphrontResponse',
|
'Aphront304Response' => 'AphrontResponse',
|
||||||
|
|
|
@ -91,7 +91,8 @@ final class AlmanacBindingEditEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function newObjectQuery() {
|
protected function newObjectQuery() {
|
||||||
return new AlmanacBindingQuery();
|
return id(new AlmanacBindingQuery())
|
||||||
|
->needProperties(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getObjectCreateTitleText($object) {
|
protected function getObjectCreateTitleText($object) {
|
||||||
|
|
|
@ -30,7 +30,8 @@ final class AlmanacDeviceEditEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function newObjectQuery() {
|
protected function newObjectQuery() {
|
||||||
return new AlmanacDeviceQuery();
|
return id(new AlmanacDeviceQuery())
|
||||||
|
->needProperties(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getObjectCreateTitleText($object) {
|
protected function getObjectCreateTitleText($object) {
|
||||||
|
|
|
@ -79,7 +79,8 @@ final class AlmanacServiceEditEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function newObjectQuery() {
|
protected function newObjectQuery() {
|
||||||
return new AlmanacServiceQuery();
|
return id(new AlmanacServiceQuery())
|
||||||
|
->needProperties(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getObjectCreateTitleText($object) {
|
protected function getObjectCreateTitleText($object) {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class AlmanacDeletePropertyEditField
|
||||||
|
extends PhabricatorEditField {
|
||||||
|
|
||||||
|
protected function newControl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newHTTPParameterType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newConduitParameterType() {
|
||||||
|
return new ConduitStringListParameterType();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newEditType() {
|
||||||
|
return new AlmanacDeletePropertyEditType();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class AlmanacDeletePropertyEditType
|
||||||
|
extends PhabricatorEditType {
|
||||||
|
|
||||||
|
public function generateTransactions(
|
||||||
|
PhabricatorApplicationTransaction $template,
|
||||||
|
array $spec) {
|
||||||
|
|
||||||
|
$value = idx($spec, 'value');
|
||||||
|
if (!is_array($value)) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Transaction value when deleting Almanac properties must be a list '.
|
||||||
|
'of property names.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$xactions = array();
|
||||||
|
foreach ($value as $idx => $property_key) {
|
||||||
|
if (!is_string($property_key)) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'When deleting Almanac properties, each property name must '.
|
||||||
|
'be a string. The value at index "%s" is not a string.',
|
||||||
|
$idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
$xactions[] = $this->newTransaction($template)
|
||||||
|
->setMetadataValue('almanac.property', $property_key)
|
||||||
|
->setNewValue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $xactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class AlmanacPropertiesEditEngineExtension
|
||||||
|
extends PhabricatorEditEngineExtension {
|
||||||
|
|
||||||
|
const EXTENSIONKEY = 'almanac.properties';
|
||||||
|
|
||||||
|
public function isExtensionEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExtensionName() {
|
||||||
|
return pht('Almanac Properties');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function supportsObject(
|
||||||
|
PhabricatorEditEngine $engine,
|
||||||
|
PhabricatorApplicationTransactionInterface $object) {
|
||||||
|
return ($object instanceof AlmanacPropertyInterface);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildCustomEditFields(
|
||||||
|
PhabricatorEditEngine $engine,
|
||||||
|
PhabricatorApplicationTransactionInterface $object) {
|
||||||
|
|
||||||
|
return array(
|
||||||
|
id(new AlmanacSetPropertyEditField())
|
||||||
|
->setKey('property.set')
|
||||||
|
->setTransactionType($object->getAlmanacPropertySetTransactionType())
|
||||||
|
->setConduitDescription(
|
||||||
|
pht('Pass a map of values to set one or more properties.'))
|
||||||
|
->setConduitTypeDescription(pht('Map of property names to values.'))
|
||||||
|
->setIsConduitOnly(true),
|
||||||
|
id(new AlmanacDeletePropertyEditField())
|
||||||
|
->setKey('property.delete')
|
||||||
|
->setTransactionType($object->getAlmanacPropertyDeleteTransactionType())
|
||||||
|
->setConduitDescription(
|
||||||
|
pht('Pass a list of property names to delete properties.'))
|
||||||
|
->setConduitTypeDescription(pht('List of property names.'))
|
||||||
|
->setIsConduitOnly(true),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class AlmanacSetPropertyEditField
|
||||||
|
extends PhabricatorEditField {
|
||||||
|
|
||||||
|
protected function newControl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newHTTPParameterType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newConduitParameterType() {
|
||||||
|
return new ConduitWildParameterType();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newEditType() {
|
||||||
|
return new AlmanacSetPropertyEditType();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class AlmanacSetPropertyEditType
|
||||||
|
extends PhabricatorEditType {
|
||||||
|
|
||||||
|
public function generateTransactions(
|
||||||
|
PhabricatorApplicationTransaction $template,
|
||||||
|
array $spec) {
|
||||||
|
|
||||||
|
$value = idx($spec, 'value');
|
||||||
|
if (!is_array($value)) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Transaction value when setting Almanac properties must be a map '.
|
||||||
|
'with property names as keys.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$xactions = array();
|
||||||
|
foreach ($value as $property_key => $property_value) {
|
||||||
|
$xactions[] = $this->newTransaction($template)
|
||||||
|
->setMetadataValue('almanac.property', $property_key)
|
||||||
|
->setNewValue($property_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $xactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue