1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 14:00:56 +01:00

Allow "drydock.blueprint.edit" to create blueprints

Summary:
Depends on D18848. Ref PHI243. This puts a bit of logic up front to figure out the blueprint type before we actually start editing it.

This implementation is a little messy but it keeps the API clean. Eventually, the implementation could probably go in the TransactionTypes so more code is shared, but I'd like to wait for a couple more of these first.

This capability probably isn't too useful, but just pays down a bit of technical debt from the caveat introduced in D18822.

Test Plan:
  - Created a new blueprint with the API.
  - Tried to create a blueprint without a "type" (got a helpful error).
  - Created and edited blueprints via the web UI.
  - Tried to change the "type" of an existing blueprint (got a helpful error).

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Differential Revision: https://secure.phabricator.com/D18849
This commit is contained in:
epriestley 2017-12-26 10:17:27 -08:00
parent 6d9776fa89
commit f3f1f9dc57
4 changed files with 104 additions and 3 deletions

View file

@ -1025,6 +1025,7 @@ phutil_register_library_map(array(
'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 @@ phutil_register_library_map(array(
'DrydockBlueprintTransaction' => 'PhabricatorModularTransaction',
'DrydockBlueprintTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'DrydockBlueprintTransactionType' => 'PhabricatorModularTransactionType',
'DrydockBlueprintTypeTransaction' => 'DrydockBlueprintTransactionType',
'DrydockBlueprintViewController' => 'DrydockBlueprintController',
'DrydockCommand' => array(
'DrydockDAO',

View file

@ -13,8 +13,7 @@ final class DrydockBlueprintEditConduitAPIMethod
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.');
}
}

View file

@ -51,6 +51,38 @@ final class DrydockBlueprintEditEngine
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 @@ final class DrydockBlueprintEditEngine
$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'))

View file

@ -0,0 +1,57 @@
<?php
final class DrydockBlueprintTypeTransaction
extends DrydockBlueprintTransactionType {
const TRANSACTIONTYPE = 'drydock.blueprint.type';
public function generateOldValue($object) {
return $object->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;
}
}