diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index 424d885caa..ab5a58dda6 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2172,9 +2172,11 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionCommentView' => 'applications/transactions/view/PhabricatorApplicationTransactionCommentView.php',
'PhabricatorApplicationTransactionController' => 'applications/transactions/controller/PhabricatorApplicationTransactionController.php',
'PhabricatorApplicationTransactionDetailController' => 'applications/transactions/controller/PhabricatorApplicationTransactionDetailController.php',
+ 'PhabricatorApplicationTransactionDetailView' => 'applications/transactions/view/PhabricatorApplicationTransactionDetailView.php',
'PhabricatorApplicationTransactionEditor' => 'applications/transactions/editor/PhabricatorApplicationTransactionEditor.php',
'PhabricatorApplicationTransactionFeedStory' => 'applications/transactions/feed/PhabricatorApplicationTransactionFeedStory.php',
'PhabricatorApplicationTransactionInterface' => 'applications/transactions/interface/PhabricatorApplicationTransactionInterface.php',
+ 'PhabricatorApplicationTransactionJSONDiffDetailView' => 'applications/transactions/view/PhabricatorApplicationTransactionJSONDiffDetailView.php',
'PhabricatorApplicationTransactionNoEffectException' => 'applications/transactions/exception/PhabricatorApplicationTransactionNoEffectException.php',
'PhabricatorApplicationTransactionNoEffectResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionNoEffectResponse.php',
'PhabricatorApplicationTransactionPublishWorker' => 'applications/transactions/worker/PhabricatorApplicationTransactionPublishWorker.php',
@@ -3151,16 +3153,26 @@ phutil_register_library_map(array(
'PhabricatorEditEngineConfigurationTransactionQuery' => 'applications/transactions/query/PhabricatorEditEngineConfigurationTransactionQuery.php',
'PhabricatorEditEngineConfigurationViewController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php',
'PhabricatorEditEngineController' => 'applications/transactions/controller/PhabricatorEditEngineController.php',
+ 'PhabricatorEditEngineCreateOrderTransaction' => 'applications/transactions/xaction/PhabricatorEditEngineCreateOrderTransaction.php',
'PhabricatorEditEngineDatasource' => 'applications/transactions/typeahead/PhabricatorEditEngineDatasource.php',
+ 'PhabricatorEditEngineDefaultCreateTransaction' => 'applications/transactions/xaction/PhabricatorEditEngineDefaultCreateTransaction.php',
'PhabricatorEditEngineDefaultLock' => 'applications/transactions/editengine/PhabricatorEditEngineDefaultLock.php',
+ 'PhabricatorEditEngineDefaultTransaction' => 'applications/transactions/xaction/PhabricatorEditEngineDefaultTransaction.php',
+ 'PhabricatorEditEngineDisableTransaction' => 'applications/transactions/xaction/PhabricatorEditEngineDisableTransaction.php',
+ 'PhabricatorEditEngineEditOrderTransaction' => 'applications/transactions/xaction/PhabricatorEditEngineEditOrderTransaction.php',
'PhabricatorEditEngineExtension' => 'applications/transactions/engineextension/PhabricatorEditEngineExtension.php',
'PhabricatorEditEngineExtensionModule' => 'applications/transactions/engineextension/PhabricatorEditEngineExtensionModule.php',
+ 'PhabricatorEditEngineIsEditTransaction' => 'applications/transactions/xaction/PhabricatorEditEngineIsEditTransaction.php',
'PhabricatorEditEngineListController' => 'applications/transactions/controller/PhabricatorEditEngineListController.php',
'PhabricatorEditEngineLock' => 'applications/transactions/editengine/PhabricatorEditEngineLock.php',
'PhabricatorEditEngineLockableInterface' => 'applications/transactions/editengine/PhabricatorEditEngineLockableInterface.php',
+ 'PhabricatorEditEngineLocksTransaction' => 'applications/transactions/xaction/PhabricatorEditEngineLocksTransaction.php',
'PhabricatorEditEngineMFAEngine' => 'applications/transactions/editengine/PhabricatorEditEngineMFAEngine.php',
'PhabricatorEditEngineMFAInterface' => 'applications/transactions/editengine/PhabricatorEditEngineMFAInterface.php',
+ 'PhabricatorEditEngineNameTransaction' => 'applications/transactions/xaction/PhabricatorEditEngineNameTransaction.php',
+ 'PhabricatorEditEngineOrderTransaction' => 'applications/transactions/xaction/PhabricatorEditEngineOrderTransaction.php',
'PhabricatorEditEnginePointsCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEnginePointsCommentAction.php',
+ 'PhabricatorEditEnginePreambleTransaction' => 'applications/transactions/xaction/PhabricatorEditEnginePreambleTransaction.php',
'PhabricatorEditEngineProfileMenuItem' => 'applications/search/menuitem/PhabricatorEditEngineProfileMenuItem.php',
'PhabricatorEditEngineQuery' => 'applications/transactions/query/PhabricatorEditEngineQuery.php',
'PhabricatorEditEngineSearchEngine' => 'applications/transactions/query/PhabricatorEditEngineSearchEngine.php',
@@ -3171,7 +3183,9 @@ phutil_register_library_map(array(
'PhabricatorEditEngineSubtypeInterface' => 'applications/transactions/editengine/PhabricatorEditEngineSubtypeInterface.php',
'PhabricatorEditEngineSubtypeMap' => 'applications/transactions/editengine/PhabricatorEditEngineSubtypeMap.php',
'PhabricatorEditEngineSubtypeTestCase' => 'applications/transactions/editengine/__tests__/PhabricatorEditEngineSubtypeTestCase.php',
+ 'PhabricatorEditEngineSubtypeTransaction' => 'applications/transactions/xaction/PhabricatorEditEngineSubtypeTransaction.php',
'PhabricatorEditEngineTokenizerCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineTokenizerCommentAction.php',
+ 'PhabricatorEditEngineTransactionType' => 'applications/transactions/xaction/PhabricatorEditEngineTransactionType.php',
'PhabricatorEditField' => 'applications/transactions/editfield/PhabricatorEditField.php',
'PhabricatorEditPage' => 'applications/transactions/editengine/PhabricatorEditPage.php',
'PhabricatorEditType' => 'applications/transactions/edittype/PhabricatorEditType.php',
@@ -8091,8 +8105,10 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionCommentView' => 'AphrontView',
'PhabricatorApplicationTransactionController' => 'PhabricatorController',
'PhabricatorApplicationTransactionDetailController' => 'PhabricatorApplicationTransactionController',
+ 'PhabricatorApplicationTransactionDetailView' => 'AphrontView',
'PhabricatorApplicationTransactionEditor' => 'PhabricatorEditor',
'PhabricatorApplicationTransactionFeedStory' => 'PhabricatorFeedStory',
+ 'PhabricatorApplicationTransactionJSONDiffDetailView' => 'PhabricatorApplicationTransactionDetailView',
'PhabricatorApplicationTransactionNoEffectException' => 'Exception',
'PhabricatorApplicationTransactionNoEffectResponse' => 'AphrontProxyResponse',
'PhabricatorApplicationTransactionPublishWorker' => 'PhabricatorWorker',
@@ -8103,7 +8119,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionShowOlderController' => 'PhabricatorApplicationTransactionController',
'PhabricatorApplicationTransactionStructureException' => 'Exception',
'PhabricatorApplicationTransactionTemplatedCommentQuery' => 'PhabricatorApplicationTransactionCommentQuery',
- 'PhabricatorApplicationTransactionTextDiffDetailView' => 'AphrontView',
+ 'PhabricatorApplicationTransactionTextDiffDetailView' => 'PhabricatorApplicationTransactionDetailView',
'PhabricatorApplicationTransactionTransactionPHIDType' => 'PhabricatorPHIDType',
'PhabricatorApplicationTransactionType' => 'PhabricatorModularTransactionType',
'PhabricatorApplicationTransactionValidationError' => 'Phobject',
@@ -9228,18 +9244,28 @@ phutil_register_library_map(array(
'PhabricatorEditEngineConfigurationSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorEditEngineConfigurationSortController' => 'PhabricatorEditEngineController',
'PhabricatorEditEngineConfigurationSubtypeController' => 'PhabricatorEditEngineController',
- 'PhabricatorEditEngineConfigurationTransaction' => 'PhabricatorApplicationTransaction',
+ 'PhabricatorEditEngineConfigurationTransaction' => 'PhabricatorModularTransaction',
'PhabricatorEditEngineConfigurationTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorEditEngineConfigurationViewController' => 'PhabricatorEditEngineController',
'PhabricatorEditEngineController' => 'PhabricatorApplicationTransactionController',
+ 'PhabricatorEditEngineCreateOrderTransaction' => 'PhabricatorEditEngineTransactionType',
'PhabricatorEditEngineDatasource' => 'PhabricatorTypeaheadDatasource',
+ 'PhabricatorEditEngineDefaultCreateTransaction' => 'PhabricatorEditEngineTransactionType',
'PhabricatorEditEngineDefaultLock' => 'PhabricatorEditEngineLock',
+ 'PhabricatorEditEngineDefaultTransaction' => 'PhabricatorEditEngineTransactionType',
+ 'PhabricatorEditEngineDisableTransaction' => 'PhabricatorEditEngineTransactionType',
+ 'PhabricatorEditEngineEditOrderTransaction' => 'PhabricatorEditEngineTransactionType',
'PhabricatorEditEngineExtension' => 'Phobject',
'PhabricatorEditEngineExtensionModule' => 'PhabricatorConfigModule',
+ 'PhabricatorEditEngineIsEditTransaction' => 'PhabricatorEditEngineTransactionType',
'PhabricatorEditEngineListController' => 'PhabricatorEditEngineController',
'PhabricatorEditEngineLock' => 'Phobject',
+ 'PhabricatorEditEngineLocksTransaction' => 'PhabricatorEditEngineTransactionType',
'PhabricatorEditEngineMFAEngine' => 'Phobject',
+ 'PhabricatorEditEngineNameTransaction' => 'PhabricatorEditEngineTransactionType',
+ 'PhabricatorEditEngineOrderTransaction' => 'PhabricatorEditEngineTransactionType',
'PhabricatorEditEnginePointsCommentAction' => 'PhabricatorEditEngineCommentAction',
+ 'PhabricatorEditEnginePreambleTransaction' => 'PhabricatorEditEngineTransactionType',
'PhabricatorEditEngineProfileMenuItem' => 'PhabricatorProfileMenuItem',
'PhabricatorEditEngineQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorEditEngineSearchEngine' => 'PhabricatorApplicationSearchEngine',
@@ -9249,7 +9275,9 @@ phutil_register_library_map(array(
'PhabricatorEditEngineSubtype' => 'Phobject',
'PhabricatorEditEngineSubtypeMap' => 'Phobject',
'PhabricatorEditEngineSubtypeTestCase' => 'PhabricatorTestCase',
+ 'PhabricatorEditEngineSubtypeTransaction' => 'PhabricatorEditEngineTransactionType',
'PhabricatorEditEngineTokenizerCommentAction' => 'PhabricatorEditEngineCommentAction',
+ 'PhabricatorEditEngineTransactionType' => 'PhabricatorModularTransactionType',
'PhabricatorEditField' => 'Phobject',
'PhabricatorEditPage' => 'Phobject',
'PhabricatorEditType' => 'Phobject',
diff --git a/src/applications/herald/xaction/HeraldRuleEditTransaction.php b/src/applications/herald/xaction/HeraldRuleEditTransaction.php
index c4b03983fb..653d300906 100644
--- a/src/applications/herald/xaction/HeraldRuleEditTransaction.php
+++ b/src/applications/herald/xaction/HeraldRuleEditTransaction.php
@@ -40,17 +40,10 @@ final class HeraldRuleEditTransaction
public function newChangeDetailView() {
$viewer = $this->getViewer();
- $old = $this->getOldValue();
- $new = $this->getNewValue();
-
- $json = new PhutilJSON();
- $old_json = $json->encodeFormatted($old);
- $new_json = $json->encodeFormatted($new);
-
- return id(new PhabricatorApplicationTransactionTextDiffDetailView())
+ return id(new PhabricatorApplicationTransactionJSONDiffDetailView())
->setViewer($viewer)
- ->setOldText($old_json)
- ->setNewText($new_json);
+ ->setOld($this->getOldValue())
+ ->setNew($this->getNewValue());
}
}
diff --git a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultCreateController.php b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultCreateController.php
index d7ea8810a5..039bfb0f44 100644
--- a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultCreateController.php
+++ b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultCreateController.php
@@ -15,7 +15,7 @@ final class PhabricatorEditEngineConfigurationDefaultCreateController
$key = $config->getIdentifier();
$cancel_uri = "/transactions/editengine/{$engine_key}/view/{$key}/";
- $type = PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE;
+ $type = PhabricatorEditEngineDefaultCreateTransaction::TRANSACTIONTYPE;
if ($request->isFormPost()) {
$xactions = array();
diff --git a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultsController.php b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultsController.php
index f7361d50cf..3d63a4a098 100644
--- a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultsController.php
+++ b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultsController.php
@@ -52,7 +52,7 @@ final class PhabricatorEditEngineConfigurationDefaultsController
$field->readValueFromSubmit($request);
}
- $type = PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT;
+ $type = PhabricatorEditEngineDefaultTransaction::TRANSACTIONTYPE;
$xactions = array();
foreach ($fields as $field) {
diff --git a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDisableController.php b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDisableController.php
index 24a32c5598..a3311b2d49 100644
--- a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDisableController.php
+++ b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationDisableController.php
@@ -15,7 +15,7 @@ final class PhabricatorEditEngineConfigurationDisableController
$key = $config->getIdentifier();
$cancel_uri = "/transactions/editengine/{$engine_key}/view/{$key}/";
- $type = PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE;
+ $type = PhabricatorEditEngineDisableTransaction::TRANSACTIONTYPE;
if ($request->isFormPost()) {
$xactions = array();
diff --git a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationIsEditController.php b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationIsEditController.php
index 970a2512f1..b93390ff66 100644
--- a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationIsEditController.php
+++ b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationIsEditController.php
@@ -15,8 +15,7 @@ final class PhabricatorEditEngineConfigurationIsEditController
$key = $config->getIdentifier();
$cancel_uri = "/transactions/editengine/{$engine_key}/view/{$key}/";
- $type = PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT;
-
+ $type = PhabricatorEditEngineIsEditTransaction::TRANSACTIONTYPE;
if ($request->isFormPost()) {
$xactions = array();
diff --git a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationLockController.php b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationLockController.php
index 34b099b9f0..1375124585 100644
--- a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationLockController.php
+++ b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationLockController.php
@@ -30,8 +30,7 @@ final class PhabricatorEditEngineConfigurationLockController
$xactions = array();
$locks = $request->getArr('locks');
- $type_locks = PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS;
-
+ $type_locks = PhabricatorEditEngineLocksTransaction::TRANSACTIONTYPE;
$xactions[] = id(new PhabricatorEditEngineConfigurationTransaction())
->setTransactionType($type_locks)
->setNewValue($locks);
diff --git a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationReorderController.php b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationReorderController.php
index 6ff36cdfa4..563c3141b2 100644
--- a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationReorderController.php
+++ b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationReorderController.php
@@ -31,8 +31,7 @@ final class PhabricatorEditEngineConfigurationReorderController
$xactions = array();
$key_order = $request->getStrList('keyOrder');
- $type_order = PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER;
-
+ $type_order = PhabricatorEditEngineOrderTransaction::TRANSACTIONTYPE;
$xactions[] = id(new PhabricatorEditEngineConfigurationTransaction())
->setTransactionType($type_order)
->setNewValue($key_order);
diff --git a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationSortController.php b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationSortController.php
index 613a847326..5e8680b651 100644
--- a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationSortController.php
+++ b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationSortController.php
@@ -70,10 +70,10 @@ final class PhabricatorEditEngineConfigurationSortController
if ($is_create) {
$xaction_type =
- PhabricatorEditEngineConfigurationTransaction::TYPE_CREATEORDER;
+ PhabricatorEditEngineCreateOrderTransaction::TRANSACTIONTYPE;
} else {
$xaction_type =
- PhabricatorEditEngineConfigurationTransaction::TYPE_EDITORDER;
+ PhabricatorEditEngineEditOrderTransaction::TRANSACTIONTYPE;
}
$xactions[] = id(new PhabricatorEditEngineConfigurationTransaction())
diff --git a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationSubtypeController.php b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationSubtypeController.php
index 9ce8d7a0e5..918782cd81 100644
--- a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationSubtypeController.php
+++ b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationSubtypeController.php
@@ -35,9 +35,7 @@ final class PhabricatorEditEngineConfigurationSubtypeController
$xactions = array();
$subtype = $request->getStr('subtype');
- $type_subtype =
- PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE;
-
+ $type_subtype = PhabricatorEditEngineSubtypeTransaction::TRANSACTIONTYPE;
$xactions[] = id(new PhabricatorEditEngineConfigurationTransaction())
->setTransactionType($type_subtype)
->setNewValue($subtype);
diff --git a/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditEngine.php b/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditEngine.php
index a9d96337ed..5a30fbfdde 100644
--- a/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditEngine.php
+++ b/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditEngine.php
@@ -99,14 +99,14 @@ final class PhabricatorEditEngineConfigurationEditEngine
->setLabel(pht('Name'))
->setDescription(pht('Name of the form.'))
->setTransactionType(
- PhabricatorEditEngineConfigurationTransaction::TYPE_NAME)
+ PhabricatorEditEngineNameTransaction::TRANSACTIONTYPE)
->setValue($object->getName()),
id(new PhabricatorRemarkupEditField())
->setKey('preamble')
->setLabel(pht('Preamble'))
->setDescription(pht('Optional instructions, shown above the form.'))
->setTransactionType(
- PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE)
+ PhabricatorEditEnginePreambleTransaction::TRANSACTIONTYPE)
->setValue($object->getPreamble()),
);
}
diff --git a/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php b/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php
index ccadf9b819..34b7653001 100644
--- a/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php
+++ b/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php
@@ -13,191 +13,9 @@ final class PhabricatorEditEngineConfigurationEditor
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
-
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
- $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_NAME;
- $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE;
- $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER;
- $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT;
- $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS;
- $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE;
- $types[] =
- PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE;
- $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT;
- $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE;
-
- $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_CREATEORDER;
- $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_EDITORDER;
-
return $types;
}
- protected function validateTransaction(
- PhabricatorLiskDAO $object,
- $type,
- array $xactions) {
-
- $errors = parent::validateTransaction($object, $type, $xactions);
- switch ($type) {
- case PhabricatorEditEngineConfigurationTransaction::TYPE_NAME:
- $missing = $this->validateIsEmptyTextField(
- $object->getName(),
- $xactions);
-
- if ($missing) {
- $error = new PhabricatorApplicationTransactionValidationError(
- $type,
- pht('Required'),
- pht('Form name is required.'),
- nonempty(last($xactions), null));
-
- $error->setIsMissingFieldError(true);
- $errors[] = $error;
- }
- break;
- case PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE:
- if ($xactions) {
- $map = $object->getEngine()
- ->setViewer($this->getActor())
- ->newSubtypeMap();
- foreach ($xactions as $xaction) {
- $new = $xaction->getNewValue();
-
- if ($map->isValidSubtype($new)) {
- continue;
- }
-
- $errors[] = new PhabricatorApplicationTransactionValidationError(
- $type,
- pht('Invalid'),
- pht('Subtype "%s" is not a valid subtype.', $new),
- $xaction);
- }
- }
- break;
- }
-
- return $errors;
- }
-
- protected function getCustomTransactionOldValue(
- PhabricatorLiskDAO $object,
- PhabricatorApplicationTransaction $xaction) {
-
- switch ($xaction->getTransactionType()) {
- case PhabricatorEditEngineConfigurationTransaction::TYPE_NAME:
- return $object->getName();
- case PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE;
- return $object->getPreamble();
- case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER:
- return $object->getFieldOrder();
- case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT:
- $field_key = $xaction->getMetadataValue('field.key');
- return $object->getFieldDefault($field_key);
- case PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS:
- return $object->getFieldLocks();
- case PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE:
- return $object->getSubtype();
- case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE:
- return (int)$object->getIsDefault();
- case PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT:
- return (int)$object->getIsEdit();
- case PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE:
- return (int)$object->getIsDisabled();
- case PhabricatorEditEngineConfigurationTransaction::TYPE_CREATEORDER:
- return (int)$object->getCreateOrder();
- case PhabricatorEditEngineConfigurationTransaction::TYPE_EDITORDER:
- return (int)$object->getEditOrder();
-
- }
- }
-
- protected function getCustomTransactionNewValue(
- PhabricatorLiskDAO $object,
- PhabricatorApplicationTransaction $xaction) {
-
- switch ($xaction->getTransactionType()) {
- case PhabricatorEditEngineConfigurationTransaction::TYPE_NAME:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE;
- case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE:
- return $xaction->getNewValue();
- case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_CREATEORDER:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_EDITORDER:
- return (int)$xaction->getNewValue();
- }
- }
-
- protected function applyCustomInternalTransaction(
- PhabricatorLiskDAO $object,
- PhabricatorApplicationTransaction $xaction) {
-
- switch ($xaction->getTransactionType()) {
- case PhabricatorEditEngineConfigurationTransaction::TYPE_NAME:
- $object->setName($xaction->getNewValue());
- return;
- case PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE;
- $object->setPreamble($xaction->getNewValue());
- return;
- case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER:
- $object->setFieldOrder($xaction->getNewValue());
- return;
- case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT:
- $field_key = $xaction->getMetadataValue('field.key');
- $object->setFieldDefault($field_key, $xaction->getNewValue());
- return;
- case PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS:
- $object->setFieldLocks($xaction->getNewValue());
- return;
- case PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE:
- $object->setSubtype($xaction->getNewValue());
- return;
- case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE:
- $object->setIsDefault($xaction->getNewValue());
- return;
- case PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT:
- $object->setIsEdit($xaction->getNewValue());
- return;
- case PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE:
- $object->setIsDisabled($xaction->getNewValue());
- return;
- case PhabricatorEditEngineConfigurationTransaction::TYPE_CREATEORDER:
- $object->setCreateOrder($xaction->getNewValue());
- return;
- case PhabricatorEditEngineConfigurationTransaction::TYPE_EDITORDER:
- $object->setEditOrder($xaction->getNewValue());
- return;
- }
-
- return parent::applyCustomInternalTransaction($object, $xaction);
- }
-
- protected function applyCustomExternalTransaction(
- PhabricatorLiskDAO $object,
- PhabricatorApplicationTransaction $xaction) {
-
- switch ($xaction->getTransactionType()) {
- case PhabricatorEditEngineConfigurationTransaction::TYPE_NAME:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE;
- case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER;
- case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_ISEDIT:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_SUBTYPE:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_CREATEORDER:
- case PhabricatorEditEngineConfigurationTransaction::TYPE_EDITORDER:
- return;
- }
-
- return parent::applyCustomExternalTransaction($object, $xaction);
- }
-
}
diff --git a/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php b/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php
index bf23bd3b4a..a9dca32e3d 100644
--- a/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php
+++ b/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php
@@ -1,19 +1,7 @@
getAuthorPHID();
-
- $old = $this->getOldValue();
- $new = $this->getNewValue();
-
- $type = $this->getTransactionType();
- switch ($type) {
- case PhabricatorTransactions::TYPE_CREATE:
- return pht(
- '%s created this form configuration.',
- $this->renderHandleLink($author_phid));
- case self::TYPE_NAME:
- if (strlen($old)) {
- return pht(
- '%s renamed this form from "%s" to "%s".',
- $this->renderHandleLink($author_phid),
- $old,
- $new);
- } else {
- return pht(
- '%s named this form "%s".',
- $this->renderHandleLink($author_phid),
- $new);
- }
- case self::TYPE_PREAMBLE:
- return pht(
- '%s updated the preamble for this form.',
- $this->renderHandleLink($author_phid));
- case self::TYPE_ORDER:
- return pht(
- '%s reordered the fields in this form.',
- $this->renderHandleLink($author_phid));
- case self::TYPE_DEFAULT:
- $key = $this->getMetadataValue('field.key');
-
- $object = $this->getObject();
- $engine = $object->getEngine();
- $fields = $engine->getFieldsForConfig($object);
-
- $field = idx($fields, $key);
- if (!$field) {
- return pht(
- '%s changed the default value for field "%s".',
- $this->renderHandleLink($author_phid),
- $key);
- }
-
- return pht(
- '%s changed the default value for field "%s".',
- $this->renderHandleLink($author_phid),
- $field->getLabel());
- case self::TYPE_LOCKS:
- return pht(
- '%s changed locked and hidden fields.',
- $this->renderHandleLink($author_phid));
- case self::TYPE_DEFAULTCREATE:
- if ($new) {
- return pht(
- '%s added this form to the "Create" menu.',
- $this->renderHandleLink($author_phid));
- } else {
- return pht(
- '%s removed this form from the "Create" menu.',
- $this->renderHandleLink($author_phid));
- }
- case self::TYPE_ISEDIT:
- if ($new) {
- return pht(
- '%s marked this form as an edit form.',
- $this->renderHandleLink($author_phid));
- } else {
- return pht(
- '%s unmarked this form as an edit form.',
- $this->renderHandleLink($author_phid));
- }
- case self::TYPE_DISABLE:
- if ($new) {
- return pht(
- '%s disabled this form.',
- $this->renderHandleLink($author_phid));
- } else {
- return pht(
- '%s enabled this form.',
- $this->renderHandleLink($author_phid));
- }
- case self::TYPE_SUBTYPE:
- return pht(
- '%s changed the subtype of this form from "%s" to "%s".',
- $this->renderHandleLink($author_phid),
- $old,
- $new);
- }
-
- return parent::getTitle();
- }
-
- public function getColor() {
- $author_phid = $this->getAuthorPHID();
-
- $old = $this->getOldValue();
- $new = $this->getNewValue();
-
- $type = $this->getTransactionType();
- switch ($type) {
- case PhabricatorTransactions::TYPE_CREATE:
- return 'green';
- case self::TYPE_DISABLE:
- if ($new) {
- return 'indigo';
- } else {
- return 'green';
- }
- }
-
- return parent::getColor();
- }
-
- public function getIcon() {
- $author_phid = $this->getAuthorPHID();
-
- $old = $this->getOldValue();
- $new = $this->getNewValue();
-
- $type = $this->getTransactionType();
- switch ($type) {
- case PhabricatorTransactions::TYPE_CREATE:
- return 'fa-plus';
- case self::TYPE_DISABLE:
- if ($new) {
- return 'fa-ban';
- } else {
- return 'fa-check';
- }
- }
-
- return parent::getIcon();
- }
-
- protected function newRemarkupChanges() {
- $changes = array();
-
- $type = $this->getTransactionType();
- switch ($type) {
- case self::TYPE_PREAMBLE:
- $changes[] = $this->newRemarkupChange()
- ->setOldValue($this->getOldValue())
- ->setNewValue($this->getNewValue());
- break;
- }
-
- return $changes;
- }
-
- public function hasChangeDetails() {
- switch ($this->getTransactionType()) {
- case self::TYPE_DEFAULT:
- return true;
- }
-
- return parent::hasChangeDetails();
- }
-
- public function renderChangeDetails(PhabricatorUser $viewer) {
- switch ($this->getTransactionType()) {
- case self::TYPE_DEFAULT:
- $old_value = $this->getOldValue();
- $new_value = $this->getNewValue();
-
- $old_value = $this->renderDefaultValueAsFallbackText($old_value);
- $new_value = $this->renderDefaultValueAsFallbackText($new_value);
-
- return $this->renderTextCorpusChangeDetails(
- $viewer,
- $old_value,
- $new_value);
- }
-
- return parent::renderChangeDetails($viewer);
- }
-
- private function renderDefaultValueAsFallbackText($default_value) {
- // See T13319. When rendering an "alice changed the default value for
- // field X." story on custom forms, we may fall back to a generic
- // rendering. Try to present the value change in a comprehensible way
- // even if it isn't especially human readable (for example, it may
- // contain PHIDs or other internal identifiers).
-
- if (is_scalar($default_value) || is_null($default_value)) {
- return $default_value;
- }
-
- if (phutil_is_natural_list($default_value)) {
- return id(new PhutilJSON())->encodeAsList($default_value);
- }
-
- return id(new PhutilJSON())->encodeAsObject($default_value);
+ public function getBaseTransactionClass() {
+ return 'PhabricatorEditEngineTransactionType';
}
}
diff --git a/src/applications/transactions/view/PhabricatorApplicationTransactionDetailView.php b/src/applications/transactions/view/PhabricatorApplicationTransactionDetailView.php
new file mode 100644
index 0000000000..1220e5bc7f
--- /dev/null
+++ b/src/applications/transactions/view/PhabricatorApplicationTransactionDetailView.php
@@ -0,0 +1,172 @@
+newText = $new_text;
+ return $this;
+ }
+
+ public function setOldText($old_text) {
+ $this->oldText = $old_text;
+ return $this;
+ }
+
+ public function renderForMail() {
+ $diff = $this->buildDiff();
+
+ $viewer = $this->getViewer();
+ $old_bright = $viewer->getCSSValue('old-bright');
+ $new_bright = $viewer->getCSSValue('new-bright');
+
+ $old_styles = array(
+ 'padding: 0 2px;',
+ 'color: #333333;',
+ "background: {$old_bright};",
+ );
+ $old_styles = implode(' ', $old_styles);
+
+ $new_styles = array(
+ 'padding: 0 2px;',
+ 'color: #333333;',
+ "background: {$new_bright};",
+ );
+ $new_styles = implode(' ', $new_styles);
+
+ $omit_styles = array(
+ 'padding: 8px 0;',
+ );
+ $omit_styles = implode(' ', $omit_styles);
+
+ $result = array();
+ foreach ($diff->getSummaryParts() as $part) {
+ $type = $part['type'];
+ $text = $part['text'];
+ switch ($type) {
+ case '.':
+ $result[] = phutil_tag(
+ 'div',
+ array(
+ 'style' => $omit_styles,
+ ),
+ pht('...'));
+ break;
+ case '-':
+ $result[] = phutil_tag(
+ 'span',
+ array(
+ 'style' => $old_styles,
+ ),
+ $text);
+ break;
+ case '+':
+ $result[] = phutil_tag(
+ 'span',
+ array(
+ 'style' => $new_styles,
+ ),
+ $text);
+ break;
+ case '=':
+ $result[] = $text;
+ break;
+ }
+ }
+
+ $styles = array(
+ 'white-space: pre-wrap;',
+ 'color: #74777D;',
+ );
+
+ // Beyond applying "pre-wrap", convert newlines to "
" explicitly
+ // to improve behavior in clients like Airmail.
+ $result = phutil_escape_html_newlines($result);
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'style' => implode(' ', $styles),
+ ),
+ $result);
+ }
+
+ public function render() {
+ $diff = $this->buildDiff();
+
+ require_celerity_resource('differential-changeset-view-css');
+
+ $result = array();
+ foreach ($diff->getParts() as $part) {
+ $type = $part['type'];
+ $text = $part['text'];
+ switch ($type) {
+ case '-':
+ $result[] = phutil_tag(
+ 'span',
+ array(
+ 'class' => 'old',
+ ),
+ $text);
+ break;
+ case '+':
+ $result[] = phutil_tag(
+ 'span',
+ array(
+ 'class' => 'new',
+ ),
+ $text);
+ break;
+ case '=':
+ $result[] = $text;
+ break;
+ }
+ }
+
+ $diff_view = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'prose-diff',
+ ),
+ $result);
+
+ $old_view = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'prose-diff',
+ ),
+ $this->oldText);
+
+ $new_view = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'prose-diff',
+ ),
+ $this->newText);
+
+ return id(new PHUITabGroupView())
+ ->addTab(
+ id(new PHUITabView())
+ ->setKey('old')
+ ->setName(pht('Old'))
+ ->appendChild($old_view))
+ ->addTab(
+ id(new PHUITabView())
+ ->setKey('new')
+ ->setName(pht('New'))
+ ->appendChild($new_view))
+ ->addTab(
+ id(new PHUITabView())
+ ->setKey('diff')
+ ->setName(pht('Diff'))
+ ->appendChild($diff_view))
+ ->selectTab('diff');
+ }
+
+ private function buildDiff() {
+ $engine = new PhutilProseDifferenceEngine();
+ return $engine->getDiff($this->oldText, $this->newText);
+ }
+}
diff --git a/src/applications/transactions/view/PhabricatorApplicationTransactionJSONDiffDetailView.php b/src/applications/transactions/view/PhabricatorApplicationTransactionJSONDiffDetailView.php
new file mode 100644
index 0000000000..91111c1e0b
--- /dev/null
+++ b/src/applications/transactions/view/PhabricatorApplicationTransactionJSONDiffDetailView.php
@@ -0,0 +1,17 @@
+setNewText($json->encodeFormatted($new_object));
+ return $this;
+ }
+
+ public function setOld($old_object) {
+ $json = new PhutilJSON();
+ $this->setOldText($json->encodeFormatted($old_object));
+ return $this;
+ }
+}
diff --git a/src/applications/transactions/view/PhabricatorApplicationTransactionTextDiffDetailView.php b/src/applications/transactions/view/PhabricatorApplicationTransactionTextDiffDetailView.php
index 755d6a9fcf..d778d8e95d 100644
--- a/src/applications/transactions/view/PhabricatorApplicationTransactionTextDiffDetailView.php
+++ b/src/applications/transactions/view/PhabricatorApplicationTransactionTextDiffDetailView.php
@@ -1,174 +1,4 @@
newText = $new_text;
- return $this;
- }
-
- public function setOldText($old_text) {
- $this->oldText = $old_text;
- return $this;
- }
-
- public function renderForMail() {
- $diff = $this->buildDiff();
-
- $viewer = $this->getViewer();
- $old_bright = $viewer->getCSSValue('old-bright');
- $new_bright = $viewer->getCSSValue('new-bright');
-
- $old_styles = array(
- 'padding: 0 2px;',
- 'color: #333333;',
- "background: {$old_bright};",
- );
- $old_styles = implode(' ', $old_styles);
-
- $new_styles = array(
- 'padding: 0 2px;',
- 'color: #333333;',
- "background: {$new_bright};",
- );
- $new_styles = implode(' ', $new_styles);
-
- $omit_styles = array(
- 'padding: 8px 0;',
- );
- $omit_styles = implode(' ', $omit_styles);
-
- $result = array();
- foreach ($diff->getSummaryParts() as $part) {
- $type = $part['type'];
- $text = $part['text'];
- switch ($type) {
- case '.':
- $result[] = phutil_tag(
- 'div',
- array(
- 'style' => $omit_styles,
- ),
- pht('...'));
- break;
- case '-':
- $result[] = phutil_tag(
- 'span',
- array(
- 'style' => $old_styles,
- ),
- $text);
- break;
- case '+':
- $result[] = phutil_tag(
- 'span',
- array(
- 'style' => $new_styles,
- ),
- $text);
- break;
- case '=':
- $result[] = $text;
- break;
- }
- }
-
- $styles = array(
- 'white-space: pre-wrap;',
- 'color: #74777D;',
- );
-
- // Beyond applying "pre-wrap", convert newlines to "
" explicitly
- // to improve behavior in clients like Airmail.
- $result = phutil_escape_html_newlines($result);
-
- return phutil_tag(
- 'div',
- array(
- 'style' => implode(' ', $styles),
- ),
- $result);
- }
-
- public function render() {
- $diff = $this->buildDiff();
-
- require_celerity_resource('differential-changeset-view-css');
-
- $result = array();
- foreach ($diff->getParts() as $part) {
- $type = $part['type'];
- $text = $part['text'];
- switch ($type) {
- case '-':
- $result[] = phutil_tag(
- 'span',
- array(
- 'class' => 'old',
- ),
- $text);
- break;
- case '+':
- $result[] = phutil_tag(
- 'span',
- array(
- 'class' => 'new',
- ),
- $text);
- break;
- case '=':
- $result[] = $text;
- break;
- }
- }
-
- $diff_view = phutil_tag(
- 'div',
- array(
- 'class' => 'prose-diff',
- ),
- $result);
-
- $old_view = phutil_tag(
- 'div',
- array(
- 'class' => 'prose-diff',
- ),
- $this->oldText);
-
- $new_view = phutil_tag(
- 'div',
- array(
- 'class' => 'prose-diff',
- ),
- $this->newText);
-
- return id(new PHUITabGroupView())
- ->addTab(
- id(new PHUITabView())
- ->setKey('old')
- ->setName(pht('Old'))
- ->appendChild($old_view))
- ->addTab(
- id(new PHUITabView())
- ->setKey('new')
- ->setName(pht('New'))
- ->appendChild($new_view))
- ->addTab(
- id(new PHUITabView())
- ->setKey('diff')
- ->setName(pht('Diff'))
- ->appendChild($diff_view))
- ->selectTab('diff');
- }
-
- private function buildDiff() {
- $engine = new PhutilProseDifferenceEngine();
- return $engine->getDiff($this->oldText, $this->newText);
- }
-
-}
+ extends PhabricatorApplicationTransactionDetailView {}
diff --git a/src/applications/transactions/xaction/PhabricatorEditEngineCreateOrderTransaction.php b/src/applications/transactions/xaction/PhabricatorEditEngineCreateOrderTransaction.php
new file mode 100644
index 0000000000..9a9483c227
--- /dev/null
+++ b/src/applications/transactions/xaction/PhabricatorEditEngineCreateOrderTransaction.php
@@ -0,0 +1,26 @@
+getCreateOrder();
+ }
+
+ public function generateNewValue($object, $value) {
+ return (int)$value;
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setCreateOrder($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s changed the order in which this form appears in the "Create" menu.',
+ $this->renderAuthor());
+ }
+
+}
diff --git a/src/applications/transactions/xaction/PhabricatorEditEngineDefaultCreateTransaction.php b/src/applications/transactions/xaction/PhabricatorEditEngineDefaultCreateTransaction.php
new file mode 100644
index 0000000000..2c4a544013
--- /dev/null
+++ b/src/applications/transactions/xaction/PhabricatorEditEngineDefaultCreateTransaction.php
@@ -0,0 +1,35 @@
+getIsDefault();
+ }
+
+ public function generateNewValue($object, $value) {
+ return (int)$value;
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setIsDefault($value);
+ }
+
+ public function getTitle() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ if ($new) {
+ return pht(
+ '%s added this form to the "Create" menu.',
+ $this->renderAuthor());
+ } else {
+ return pht(
+ '%s removed this form from the "Create" menu.',
+ $this->renderAuthor());
+ }
+ }
+
+}
diff --git a/src/applications/transactions/xaction/PhabricatorEditEngineDefaultTransaction.php b/src/applications/transactions/xaction/PhabricatorEditEngineDefaultTransaction.php
new file mode 100644
index 0000000000..7b980cdb1a
--- /dev/null
+++ b/src/applications/transactions/xaction/PhabricatorEditEngineDefaultTransaction.php
@@ -0,0 +1,71 @@
+getMetadataValue('field.key');
+ return $object->getFieldDefault($field_key);
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $field_key = $this->getMetadataValue('field.key');
+ $object->setFieldDefault($field_key, $value);
+ }
+
+ public function getTitle() {
+ $key = $this->getMetadataValue('field.key');
+ $object = $this->getObject();
+ $engine = $object->getEngine();
+ $fields = $engine->getFieldsForConfig($object);
+ $field = idx($fields, $key);
+
+ if (!$field) {
+ return pht(
+ '%s changed the default values for field %s.',
+ $this->renderAuthor(),
+ $this->renderValue($key));
+ }
+
+ return pht(
+ '%s changed the default value for field %s.',
+ $this->renderAuthor(),
+ $this->renderValue($field->getLabel()));
+ }
+
+ public function hasChangeDetailView() {
+ return true;
+ }
+
+ public function newChangeDetailView() {
+ $viewer = $this->getViewer();
+ $old = $this->renderDefaultValueAsFallbackText($this->getOldValue());
+ $new = $this->renderDefaultValueAsFallbackText($this->getNewValue());
+
+ return id(new PhabricatorApplicationTransactionTextDiffDetailView())
+ ->setViewer($viewer)
+ ->setOldText($old)
+ ->setNewText($new);
+ }
+
+ private function renderDefaultValueAsFallbackText($default_value) {
+ // See T13319. When rendering an "alice changed the default value for
+ // field X." story on custom forms, we may fall back to a generic
+ // rendering. Try to present the value change in a comprehensible way
+ // even if it isn't especially human readable (for example, it may
+ // contain PHIDs or other internal identifiers).
+
+ if (is_scalar($default_value) || is_null($default_value)) {
+ return $default_value;
+ }
+
+ if (phutil_is_natural_list($default_value)) {
+ return id(new PhutilJSON())->encodeAsList($default_value);
+ }
+
+ return id(new PhutilJSON())->encodeAsObject($default_value);
+ }
+
+}
diff --git a/src/applications/transactions/xaction/PhabricatorEditEngineDisableTransaction.php b/src/applications/transactions/xaction/PhabricatorEditEngineDisableTransaction.php
new file mode 100644
index 0000000000..ef64c20974
--- /dev/null
+++ b/src/applications/transactions/xaction/PhabricatorEditEngineDisableTransaction.php
@@ -0,0 +1,51 @@
+getIsDisabled();
+ }
+
+ public function generateNewValue($object, $value) {
+ return (int)$value;
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setIsDisabled($value);
+ }
+
+ public function getTitle() {
+ $new = $this->getNewValue();
+ if ($new) {
+ return pht(
+ '%s disabled this form.',
+ $this->renderAuthor());
+ } else {
+ return pht(
+ '%s enabled this form.',
+ $this->renderAuthor());
+ }
+ }
+
+ public function getColor() {
+ $new = $this->getNewValue();
+ if ($new) {
+ return 'indigo';
+ } else {
+ return 'green';
+ }
+ }
+
+ public function getIcon() {
+ $new = $this->getNewValue();
+ if ($new) {
+ return 'fa-ban';
+ } else {
+ return 'fa-check';
+ }
+ }
+
+}
diff --git a/src/applications/transactions/xaction/PhabricatorEditEngineEditOrderTransaction.php b/src/applications/transactions/xaction/PhabricatorEditEngineEditOrderTransaction.php
new file mode 100644
index 0000000000..a9109e6475
--- /dev/null
+++ b/src/applications/transactions/xaction/PhabricatorEditEngineEditOrderTransaction.php
@@ -0,0 +1,26 @@
+getEditOrder();
+ }
+
+ public function generateNewValue($object, $value) {
+ return (int)$value;
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setEditOrder($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s changed the order in which this form appears in the "Edit" menu.',
+ $this->renderAuthor());
+ }
+
+}
diff --git a/src/applications/transactions/xaction/PhabricatorEditEngineIsEditTransaction.php b/src/applications/transactions/xaction/PhabricatorEditEngineIsEditTransaction.php
new file mode 100644
index 0000000000..a4a3a38543
--- /dev/null
+++ b/src/applications/transactions/xaction/PhabricatorEditEngineIsEditTransaction.php
@@ -0,0 +1,34 @@
+getIsEdit();
+ }
+
+ public function generateNewValue($object, $value) {
+ return (int)$value;
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setIsEdit($value);
+ }
+
+ public function getTitle() {
+ $new = $this->getNewValue();
+
+ if ($new) {
+ return pht(
+ '%s marked this form as an edit form.',
+ $this->renderAuthor());
+ } else {
+ return pht(
+ '%s unmarked this form as an edit form.',
+ $this->renderAuthor());
+ }
+ }
+
+}
diff --git a/src/applications/transactions/xaction/PhabricatorEditEngineLocksTransaction.php b/src/applications/transactions/xaction/PhabricatorEditEngineLocksTransaction.php
new file mode 100644
index 0000000000..b919a4de08
--- /dev/null
+++ b/src/applications/transactions/xaction/PhabricatorEditEngineLocksTransaction.php
@@ -0,0 +1,35 @@
+getFieldLocks();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setFieldLocks($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s changed locked and hidden fields.',
+ $this->renderAuthor());
+ }
+
+ public function hasChangeDetailView() {
+ return true;
+ }
+
+ public function newChangeDetailView() {
+ $viewer = $this->getViewer();
+
+ return id(new PhabricatorApplicationTransactionJSONDiffDetailView())
+ ->setViewer($viewer)
+ ->setOld($this->getOldValue())
+ ->setNew($this->getNewValue());
+ }
+
+}
diff --git a/src/applications/transactions/xaction/PhabricatorEditEngineNameTransaction.php b/src/applications/transactions/xaction/PhabricatorEditEngineNameTransaction.php
new file mode 100644
index 0000000000..0ab4b7029f
--- /dev/null
+++ b/src/applications/transactions/xaction/PhabricatorEditEngineNameTransaction.php
@@ -0,0 +1,54 @@
+getName();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setName($value);
+ }
+
+ public function getTitle() {
+ if (strlen($this->getOldValue())) {
+ return pht(
+ '%s renamed this form from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderOldValue(),
+ $this->renderNewValue());
+ } else {
+ return pht(
+ '%s named this form %s.',
+ $this->renderAuthor(),
+ $this->renderNewValue());
+ }
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $errors = array();
+
+ foreach ($xactions as $xaction) {
+ $new = $xaction->getNewValue();
+ if (!strlen($new)) {
+ $errors[] = $this->newRequiredError(
+ pht('Form name is required.'),
+ $xaction);
+ continue;
+ }
+ }
+
+ if (!$errors) {
+ if ($this->isEmptyTextTransaction($object->getName(), $xactions)) {
+ $errors[] = $this->newRequiredError(
+ pht('Forms must have a name.'));
+ }
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/transactions/xaction/PhabricatorEditEngineOrderTransaction.php b/src/applications/transactions/xaction/PhabricatorEditEngineOrderTransaction.php
new file mode 100644
index 0000000000..96376113c4
--- /dev/null
+++ b/src/applications/transactions/xaction/PhabricatorEditEngineOrderTransaction.php
@@ -0,0 +1,35 @@
+getFieldOrder();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setFieldOrder($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s reordered the fields in this form.',
+ $this->renderAuthor());
+ }
+
+ public function hasChangeDetailView() {
+ return true;
+ }
+
+ public function newChangeDetailView() {
+ $viewer = $this->getViewer();
+
+ return id(new PhabricatorApplicationTransactionJSONDiffDetailView())
+ ->setViewer($viewer)
+ ->setOld($this->getOldValue())
+ ->setNew($this->getNewValue());
+ }
+
+}
diff --git a/src/applications/transactions/xaction/PhabricatorEditEnginePreambleTransaction.php b/src/applications/transactions/xaction/PhabricatorEditEnginePreambleTransaction.php
new file mode 100644
index 0000000000..e450bc592d
--- /dev/null
+++ b/src/applications/transactions/xaction/PhabricatorEditEnginePreambleTransaction.php
@@ -0,0 +1,45 @@
+getPreamble();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setPreamble($value);
+ }
+
+ public function getTitle() {
+ return pht(
+ '%s updated the preamble for this form.',
+ $this->renderAuthor());
+ }
+
+ public function hasChangeDetailView() {
+ return true;
+ }
+
+ public function newChangeDetailView() {
+ $viewer = $this->getViewer();
+
+ return id(new PhabricatorApplicationTransactionTextDiffDetailView())
+ ->setViewer($viewer)
+ ->setOldText($this->getOldValue())
+ ->setNewText($this->getNewValue());
+ }
+
+ public function newRemarkupChanges() {
+ $changes = array();
+
+ $changes[] = $this->newRemarkupChange()
+ ->setOldValue($this->getOldValue())
+ ->setNewValue($this->getNewValue());
+
+ return $changes;
+ }
+
+}
diff --git a/src/applications/transactions/xaction/PhabricatorEditEngineSubtypeTransaction.php b/src/applications/transactions/xaction/PhabricatorEditEngineSubtypeTransaction.php
new file mode 100644
index 0000000000..53ec221631
--- /dev/null
+++ b/src/applications/transactions/xaction/PhabricatorEditEngineSubtypeTransaction.php
@@ -0,0 +1,48 @@
+getSubtype();
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setSubtype($value);
+ }
+
+ public function getTitle() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ return pht(
+ '%s changed the subtype of this form from %s to %s.',
+ $this->renderAuthor(),
+ $this->renderOldValue(),
+ $this->renderNewValue());
+ }
+
+ public function validateTransactions($object, array $xactions) {
+ $map = $object->getEngine()
+ ->setViewer($this->getActor())
+ ->newSubtypeMap();
+
+ $errors = array();
+ foreach ($xactions as $xaction) {
+ $new = $xaction->getNewValue();
+
+ if ($map->isValidSubtype($new)) {
+ continue;
+ }
+
+ $errors[] = $this->newInvalidError(
+ pht('Subtype "%s" is not a valid subtype.', $new),
+ $xaction);
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/transactions/xaction/PhabricatorEditEngineTransactionType.php b/src/applications/transactions/xaction/PhabricatorEditEngineTransactionType.php
new file mode 100644
index 0000000000..c49d1e4654
--- /dev/null
+++ b/src/applications/transactions/xaction/PhabricatorEditEngineTransactionType.php
@@ -0,0 +1,4 @@
+