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 @@ -126,6 +126,7 @@ 'AlmanacServiceType' => 'applications/almanac/servicetype/AlmanacServiceType.php', 'AlmanacServiceTypeDatasource' => 'applications/almanac/typeahead/AlmanacServiceTypeDatasource.php', 'AlmanacServiceTypeTestCase' => 'applications/almanac/servicetype/__tests__/AlmanacServiceTypeTestCase.php', + 'AlmanacServiceTypeTransaction' => 'applications/almanac/xaction/AlmanacServiceTypeTransaction.php', 'AlmanacServiceViewController' => 'applications/almanac/controller/AlmanacServiceViewController.php', 'AlmanacTransaction' => 'applications/almanac/storage/AlmanacTransaction.php', 'AlmanacTransactionType' => 'applications/almanac/xaction/AlmanacTransactionType.php', @@ -5331,6 +5332,7 @@ 'AlmanacServiceType' => 'Phobject', 'AlmanacServiceTypeDatasource' => 'PhabricatorTypeaheadDatasource', 'AlmanacServiceTypeTestCase' => 'PhabricatorTestCase', + 'AlmanacServiceTypeTransaction' => 'AlmanacServiceTransactionType', 'AlmanacServiceViewController' => 'AlmanacServiceController', 'AlmanacTransaction' => 'PhabricatorApplicationTransaction', 'AlmanacTransactionType' => 'PhabricatorModularTransactionType', diff --git a/src/applications/almanac/editor/AlmanacServiceEditEngine.php b/src/applications/almanac/editor/AlmanacServiceEditEngine.php --- a/src/applications/almanac/editor/AlmanacServiceEditEngine.php +++ b/src/applications/almanac/editor/AlmanacServiceEditEngine.php @@ -41,6 +41,37 @@ return AlmanacService::initializeNewService($service_type); } + protected function newEditableObjectFromConduit(array $raw_xactions) { + $type = null; + foreach ($raw_xactions as $raw_xaction) { + if ($raw_xaction['type'] !== 'type') { + continue; + } + + $type = $raw_xaction['value']; + } + + if ($type === null) { + throw new Exception( + pht( + 'When creating a new Almanac service via the Conduit API, you '. + 'must provide a "type" transaction to select a type.')); + } + + $map = AlmanacServiceType::getAllServiceTypes(); + if (!isset($map[$type])) { + throw new Exception( + pht( + 'Service type "%s" is unrecognized. Valid types are: %s.', + $type, + implode(', ', array_keys($map)))); + } + + $this->setServiceType($type); + + return $this->newEditableObject(); + } + protected function newEditableObjectForDocumentation() { $service_type = new AlmanacCustomServiceType(); $this->setServiceType($service_type->getServiceTypeConstant()); @@ -101,6 +132,16 @@ ->setTransactionType(AlmanacServiceNameTransaction::TRANSACTIONTYPE) ->setIsRequired(true) ->setValue($object->getName()), + id(new PhabricatorTextEditField()) + ->setKey('type') + ->setLabel(pht('Type')) + ->setIsConduitOnly(true) + ->setTransactionType( + AlmanacServiceTypeTransaction::TRANSACTIONTYPE) + ->setDescription(pht('When creating a service, set the type.')) + ->setConduitDescription(pht('Set the service type.')) + ->setConduitTypeDescription(pht('Service type.')) + ->setValue($object->getServiceType()), ); } diff --git a/src/applications/almanac/xaction/AlmanacServiceNameTransaction.php b/src/applications/almanac/xaction/AlmanacServiceNameTransaction.php --- a/src/applications/almanac/xaction/AlmanacServiceNameTransaction.php +++ b/src/applications/almanac/xaction/AlmanacServiceNameTransaction.php @@ -16,7 +16,7 @@ public function getTitle() { return pht( '%s renamed this service from %s to %s.', - $this->renderAuthorLink(), + $this->renderAuthor(), $this->renderOldValue(), $this->renderNewValue()); } @@ -24,7 +24,7 @@ public function getTitleForFeed() { return pht( '%s renamed %s from %s to %s.', - $this->renderAuthorLink(), + $this->renderAuthor(), $this->renderObject(), $this->renderOldValue(), $this->renderNewValue()); diff --git a/src/applications/almanac/xaction/AlmanacServiceTypeTransaction.php b/src/applications/almanac/xaction/AlmanacServiceTypeTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/almanac/xaction/AlmanacServiceTypeTransaction.php @@ -0,0 +1,55 @@ +getServiceType(); + } + + public function applyInternalEffects($object, $value) { + $object->setServiceType($value); + } + + public function getTitle() { + // This transaction can only be applied during object creation via + // Conduit and never generates a timeline event. + return null; + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + if ($this->isEmptyTextTransaction($object->getServiceType(), $xactions)) { + $errors[] = $this->newRequiredError( + pht('You must select a service type when creating a service.')); + } + + $map = AlmanacServiceType::getAllServiceTypes(); + + foreach ($xactions as $xaction) { + if (!$this->isNewObject()) { + $errors[] = $this->newInvalidError( + pht( + 'The type of a service can not be changed once it has '. + 'been created.'), + $xaction); + continue; + } + + $new = $xaction->getNewValue(); + if (!isset($map[$new])) { + $errors[] = $this->newInvalidError( + pht( + 'Service type "%s" is not valid. Valid types are: %s.', + $new, + implode(', ', array_keys($map)))); + continue; + } + } + + return $errors; + } +}