1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-03-26 11:10:16 +01:00

Modularize transactions for Drydock Blueprints

Summary: Ref PHI243. This is a followup to D18822, which added an edit-only `drydock.blueprint.edit`. By modularizing transactions (here) and then adding a "type" transaction (next change) I intend to remove the "edit-only" limitation and make this API method fully functional.

Test Plan: Created and edited blueprints via the web UI. Edited blueprints via the API. Disabled/enabled blueprints (currently web UI only).

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Differential Revision: https://secure.phabricator.com/D18845
This commit is contained in:
epriestley 2017-12-15 08:21:20 -08:00
parent 53b25db918
commit 83c528c464
8 changed files with 133 additions and 127 deletions

View file

@ -1008,6 +1008,7 @@ phutil_register_library_map(array(
'DrydockBlueprintCustomField' => 'applications/drydock/customfield/DrydockBlueprintCustomField.php',
'DrydockBlueprintDatasource' => 'applications/drydock/typeahead/DrydockBlueprintDatasource.php',
'DrydockBlueprintDisableController' => 'applications/drydock/controller/DrydockBlueprintDisableController.php',
'DrydockBlueprintDisableTransaction' => 'applications/drydock/xaction/DrydockBlueprintDisableTransaction.php',
'DrydockBlueprintEditConduitAPIMethod' => 'applications/drydock/conduit/DrydockBlueprintEditConduitAPIMethod.php',
'DrydockBlueprintEditController' => 'applications/drydock/controller/DrydockBlueprintEditController.php',
'DrydockBlueprintEditEngine' => 'applications/drydock/editor/DrydockBlueprintEditEngine.php',
@ -1016,12 +1017,14 @@ phutil_register_library_map(array(
'DrydockBlueprintImplementationTestCase' => 'applications/drydock/blueprint/__tests__/DrydockBlueprintImplementationTestCase.php',
'DrydockBlueprintListController' => 'applications/drydock/controller/DrydockBlueprintListController.php',
'DrydockBlueprintNameNgrams' => 'applications/drydock/storage/DrydockBlueprintNameNgrams.php',
'DrydockBlueprintNameTransaction' => 'applications/drydock/xaction/DrydockBlueprintNameTransaction.php',
'DrydockBlueprintPHIDType' => 'applications/drydock/phid/DrydockBlueprintPHIDType.php',
'DrydockBlueprintQuery' => 'applications/drydock/query/DrydockBlueprintQuery.php',
'DrydockBlueprintSearchConduitAPIMethod' => 'applications/drydock/conduit/DrydockBlueprintSearchConduitAPIMethod.php',
'DrydockBlueprintSearchEngine' => 'applications/drydock/query/DrydockBlueprintSearchEngine.php',
'DrydockBlueprintTransaction' => 'applications/drydock/storage/DrydockBlueprintTransaction.php',
'DrydockBlueprintTransactionQuery' => 'applications/drydock/query/DrydockBlueprintTransactionQuery.php',
'DrydockBlueprintTransactionType' => 'applications/drydock/xaction/DrydockBlueprintTransactionType.php',
'DrydockBlueprintViewController' => 'applications/drydock/controller/DrydockBlueprintViewController.php',
'DrydockCommand' => 'applications/drydock/storage/DrydockCommand.php',
'DrydockCommandError' => 'applications/drydock/exception/DrydockCommandError.php',
@ -6102,6 +6105,7 @@ phutil_register_library_map(array(
'DrydockBlueprintCustomField' => 'PhabricatorCustomField',
'DrydockBlueprintDatasource' => 'PhabricatorTypeaheadDatasource',
'DrydockBlueprintDisableController' => 'DrydockBlueprintController',
'DrydockBlueprintDisableTransaction' => 'DrydockBlueprintTransactionType',
'DrydockBlueprintEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
'DrydockBlueprintEditController' => 'DrydockBlueprintController',
'DrydockBlueprintEditEngine' => 'PhabricatorEditEngine',
@ -6110,12 +6114,14 @@ phutil_register_library_map(array(
'DrydockBlueprintImplementationTestCase' => 'PhabricatorTestCase',
'DrydockBlueprintListController' => 'DrydockBlueprintController',
'DrydockBlueprintNameNgrams' => 'PhabricatorSearchNgrams',
'DrydockBlueprintNameTransaction' => 'DrydockBlueprintTransactionType',
'DrydockBlueprintPHIDType' => 'PhabricatorPHIDType',
'DrydockBlueprintQuery' => 'DrydockQuery',
'DrydockBlueprintSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'DrydockBlueprintSearchEngine' => 'PhabricatorApplicationSearchEngine',
'DrydockBlueprintTransaction' => 'PhabricatorApplicationTransaction',
'DrydockBlueprintTransaction' => 'PhabricatorModularTransaction',
'DrydockBlueprintTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'DrydockBlueprintTransactionType' => 'PhabricatorModularTransactionType',
'DrydockBlueprintViewController' => 'DrydockBlueprintController',
'DrydockCommand' => array(
'DrydockDAO',

View file

@ -28,7 +28,8 @@ final class DrydockBlueprintDisableController
$xactions = array();
$xactions[] = id(new DrydockBlueprintTransaction())
->setTransactionType(DrydockBlueprintTransaction::TYPE_DISABLED)
->setTransactionType(
DrydockBlueprintDisableTransaction::TRANSACTIONTYPE)
->setNewValue($is_disable ? 1 : 0);
$editor = id(new DrydockBlueprintEditor())

View file

@ -121,7 +121,7 @@ final class DrydockBlueprintEditEngine
->setKey('name')
->setLabel(pht('Name'))
->setDescription(pht('Name of the blueprint.'))
->setTransactionType(DrydockBlueprintTransaction::TYPE_NAME)
->setTransactionType(DrydockBlueprintNameTransaction::TRANSACTIONTYPE)
->setIsRequired(true)
->setValue($object->getBlueprintName()),
);

View file

@ -11,6 +11,14 @@ final class DrydockBlueprintEditor
return pht('Drydock Blueprints');
}
public function getCreateObjectTitle($author, $object) {
return pht('%s created this blueprint.', $author);
}
public function getCreateObjectTitleForFeed($author, $object) {
return pht('%s created %s.', $author, $object);
}
protected function supportsSearch() {
return true;
}
@ -21,99 +29,7 @@ final class DrydockBlueprintEditor
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
$types[] = DrydockBlueprintTransaction::TYPE_NAME;
$types[] = DrydockBlueprintTransaction::TYPE_DISABLED;
return $types;
}
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case DrydockBlueprintTransaction::TYPE_NAME:
return $object->getBlueprintName();
case DrydockBlueprintTransaction::TYPE_DISABLED:
return (int)$object->getIsDisabled();
}
return parent::getCustomTransactionOldValue($object, $xaction);
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case DrydockBlueprintTransaction::TYPE_NAME:
return $xaction->getNewValue();
case DrydockBlueprintTransaction::TYPE_DISABLED:
return (int)$xaction->getNewValue();
}
return parent::getCustomTransactionNewValue($object, $xaction);
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case DrydockBlueprintTransaction::TYPE_NAME:
$object->setBlueprintName($xaction->getNewValue());
return;
case DrydockBlueprintTransaction::TYPE_DISABLED:
$object->setIsDisabled((int)$xaction->getNewValue());
return;
}
return parent::applyCustomInternalTransaction($object, $xaction);
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case DrydockBlueprintTransaction::TYPE_NAME:
case DrydockBlueprintTransaction::TYPE_DISABLED:
return;
}
return parent::applyCustomExternalTransaction($object, $xaction);
}
protected function validateTransaction(
PhabricatorLiskDAO $object,
$type,
array $xactions) {
$errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) {
case DrydockBlueprintTransaction::TYPE_NAME:
$missing = $this->validateIsEmptyTextField(
$object->getBlueprintName(),
$xactions);
if ($missing) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Required'),
pht('You must choose a name for this blueprint.'),
nonempty(last($xactions), null));
$error->setIsMissingFieldError(true);
$errors[] = $error;
continue;
}
break;
}
return $errors;
}
}

View file

@ -1,7 +1,7 @@
<?php
final class DrydockBlueprintTransaction
extends PhabricatorApplicationTransaction {
extends PhabricatorModularTransaction {
const TYPE_NAME = 'drydock:blueprint:name';
const TYPE_DISABLED = 'drydock:blueprint:disabled';
@ -14,37 +14,8 @@ final class DrydockBlueprintTransaction
return DrydockBlueprintPHIDType::TYPECONST;
}
public function getTitle() {
$old = $this->getOldValue();
$new = $this->getNewValue();
$author_handle = $this->renderHandleLink($this->getAuthorPHID());
switch ($this->getTransactionType()) {
case self::TYPE_NAME:
if (!strlen($old)) {
return pht(
'%s created this blueprint.',
$author_handle);
} else {
return pht(
'%s renamed this blueprint from "%s" to "%s".',
$author_handle,
$old,
$new);
}
case self::TYPE_DISABLED:
if ($new) {
return pht(
'%s disabled this blueprint.',
$author_handle);
} else {
return pht(
'%s enabled this blueprint.',
$author_handle);
}
}
return parent::getTitle();
public function getBaseTransactionClass() {
return 'DrydockBlueprintTransactionType';
}
}

View file

@ -0,0 +1,48 @@
<?php
final class DrydockBlueprintDisableTransaction
extends DrydockBlueprintTransactionType {
const TRANSACTIONTYPE = 'drydock:blueprint:disabled';
public function generateOldValue($object) {
return (bool)$object->getIsDisabled();
}
public function generateNewValue($object, $value) {
return (bool)$value;
}
public function applyInternalEffects($object, $value) {
$object->setIsDisabled((int)$value);
}
public function getTitle() {
$new = $this->getNewValue();
if ($new) {
return pht(
'%s disabled this blueprint.',
$this->renderAuthor());
} else {
return pht(
'%s enabled this blueprint.',
$this->renderAuthor());
}
}
public function getTitleForFeed() {
$new = $this->getNewValue();
if ($new) {
return pht(
'%s disabled %s.',
$this->renderAuthor(),
$this->renderObject());
} else {
return pht(
'%s enabled %s.',
$this->renderAuthor(),
$this->renderObject());
}
}
}

View file

@ -0,0 +1,60 @@
<?php
final class DrydockBlueprintNameTransaction
extends DrydockBlueprintTransactionType {
const TRANSACTIONTYPE = 'drydock:blueprint:name';
public function generateOldValue($object) {
return $object->getBlueprintName();
}
public function applyInternalEffects($object, $value) {
$object->setBlueprintName($value);
}
public function getTitle() {
return pht(
'%s renamed this blueprint from %s to %s.',
$this->renderAuthor(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function getTitleForFeed() {
$old = $this->getOldValue();
$new = $this->getNewValue();
return pht(
'%s renamed %s from %s to %s.',
$this->renderAuthor(),
$this->renderObject(),
$this->renderOldValue(),
$this->renderNewValue());
}
public function validateTransactions($object, array $xactions) {
$errors = array();
$name = $object->getBlueprintName();
if ($this->isEmptyTextTransaction($name, $xactions)) {
$errors[] = $this->newRequiredError(
pht('Blueprints must have a name.'));
}
$max_length = $object->getColumnMaximumByteLength('blueprintName');
foreach ($xactions as $xaction) {
$new_value = $xaction->getNewValue();
$new_length = strlen($new_value);
if ($new_length > $max_length) {
$errors[] = $this->newInvalidError(
pht('Blueprint names can be no longer than %s characters.',
new PhutilNumber($max_length)));
}
}
return $errors;
}
}

View file

@ -0,0 +1,4 @@
<?php
abstract class DrydockBlueprintTransactionType
extends PhabricatorModularTransactionType {}