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 @@ -1025,6 +1025,7 @@ 'DrydockBlueprintTransaction' => 'applications/drydock/storage/DrydockBlueprintTransaction.php', 'DrydockBlueprintTransactionQuery' => 'applications/drydock/query/DrydockBlueprintTransactionQuery.php', 'DrydockBlueprintTransactionType' => 'applications/drydock/xaction/DrydockBlueprintTransactionType.php', + 'DrydockBlueprintTypeTransaction' => 'applications/drydock/xaction/DrydockBlueprintTypeTransaction.php', 'DrydockBlueprintViewController' => 'applications/drydock/controller/DrydockBlueprintViewController.php', 'DrydockCommand' => 'applications/drydock/storage/DrydockCommand.php', 'DrydockCommandError' => 'applications/drydock/exception/DrydockCommandError.php', @@ -6122,6 +6123,7 @@ 'DrydockBlueprintTransaction' => 'PhabricatorModularTransaction', 'DrydockBlueprintTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'DrydockBlueprintTransactionType' => 'PhabricatorModularTransactionType', + 'DrydockBlueprintTypeTransaction' => 'DrydockBlueprintTransactionType', 'DrydockBlueprintViewController' => 'DrydockBlueprintController', 'DrydockCommand' => array( 'DrydockDAO', diff --git a/src/applications/drydock/conduit/DrydockBlueprintEditConduitAPIMethod.php b/src/applications/drydock/conduit/DrydockBlueprintEditConduitAPIMethod.php --- a/src/applications/drydock/conduit/DrydockBlueprintEditConduitAPIMethod.php +++ b/src/applications/drydock/conduit/DrydockBlueprintEditConduitAPIMethod.php @@ -13,8 +13,7 @@ public function getMethodSummary() { return pht( - 'WARNING: Apply transactions to edit an existing blueprint. This method '. - 'can not create new blueprints.'); + 'Apply transactions to create or edit a blueprint.'); } } diff --git a/src/applications/drydock/editor/DrydockBlueprintEditEngine.php b/src/applications/drydock/editor/DrydockBlueprintEditEngine.php --- a/src/applications/drydock/editor/DrydockBlueprintEditEngine.php +++ b/src/applications/drydock/editor/DrydockBlueprintEditEngine.php @@ -51,6 +51,38 @@ return $blueprint; } + 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 Drydock blueprint via the Conduit API, you '. + 'must provide a "type" transaction to select a type.')); + } + + $map = DrydockBlueprintImplementation::getAllBlueprintImplementations(); + if (!isset($map[$type])) { + throw new Exception( + pht( + 'Blueprint type "%s" is unrecognized. Valid types are: %s.', + $type, + implode(', ', array_keys($map)))); + } + + $impl = clone $map[$type]; + $this->setBlueprintImplementation($impl); + + return $this->newEditableObject(); + } + protected function newEditableObjectForDocumentation() { // In order to generate the proper list of fields/transactions for a // blueprint, a blueprint's type needs to be known upfront, and there's @@ -112,11 +144,22 @@ $impl = $object->getImplementation(); return array( + // This field appears in the web UI id(new PhabricatorStaticEditField()) - ->setKey('type') + ->setKey('displayType') ->setLabel(pht('Blueprint Type')) ->setDescription(pht('Type of blueprint.')) ->setValue($impl->getBlueprintName()), + id(new PhabricatorTextEditField()) + ->setKey('type') + ->setLabel(pht('Type')) + ->setIsConduitOnly(true) + ->setTransactionType( + DrydockBlueprintTypeTransaction::TRANSACTIONTYPE) + ->setDescription(pht('When creating a blueprint, set the type.')) + ->setConduitDescription(pht('Set the blueprint type.')) + ->setConduitTypeDescription(pht('Blueprint type.')) + ->setValue($object->getClassName()), id(new PhabricatorTextEditField()) ->setKey('name') ->setLabel(pht('Name')) diff --git a/src/applications/drydock/xaction/DrydockBlueprintTypeTransaction.php b/src/applications/drydock/xaction/DrydockBlueprintTypeTransaction.php new file mode 100644 --- /dev/null +++ b/src/applications/drydock/xaction/DrydockBlueprintTypeTransaction.php @@ -0,0 +1,57 @@ +getClassName(); + } + + public function applyInternalEffects($object, $value) { + $object->setClassName($value); + } + + public function getTitle() { + // These transactions can only be applied during object creation and never + // generate a timeline event. + return null; + } + + public function validateTransactions($object, array $xactions) { + $errors = array(); + + $name = $object->getClassName(); + if ($this->isEmptyTextTransaction($name, $xactions)) { + $errors[] = $this->newRequiredError( + pht('You must select a blueprint type when creating a blueprint.')); + } + + $map = DrydockBlueprintImplementation::getAllBlueprintImplementations(); + + foreach ($xactions as $xaction) { + if (!$this->isNewObject()) { + $errors[] = $this->newInvalidError( + pht( + 'The type of a blueprint can not be changed once it has '. + 'been created.'), + $xaction); + continue; + } + + $new = $xaction->getNewValue(); + if (!isset($map[$new])) { + $errors[] = $this->newInvalidError( + pht( + 'Blueprint type "%s" is not valid. Valid types are: %s.', + $new, + implode(', ', array_keys($map)))); + continue; + } + } + + return $errors; + } + +}