1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-03-28 04:00:17 +01:00

Modularize PhabricatorEditEngineConfigurationTransaction

Summary: Ref T13319. Ref PHI1302. Migrate `PhabricatorEditEngineConfigurationTransaction` to modular transactions and add some additional transaction rendering to make these edits less opaque.

Test Plan: Hit all the form edit controllers, viewed resulting transaction timeline.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T13319

Differential Revision: https://secure.phabricator.com/D20595
This commit is contained in:
Austin McKinley 2019-06-19 15:16:16 -07:00
parent c0dc411d23
commit 6b9f4a918b
28 changed files with 701 additions and 591 deletions

View file

@ -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',

View file

@ -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());
}
}

View file

@ -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();

View file

@ -52,7 +52,7 @@ final class PhabricatorEditEngineConfigurationDefaultsController
$field->readValueFromSubmit($request);
}
$type = PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT;
$type = PhabricatorEditEngineDefaultTransaction::TRANSACTIONTYPE;
$xactions = array();
foreach ($fields as $field) {

View file

@ -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();

View file

@ -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();

View file

@ -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);

View file

@ -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);

View file

@ -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())

View file

@ -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);

View file

@ -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()),
);
}

View file

@ -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);
}
}

View file

@ -1,19 +1,7 @@
<?php
final class PhabricatorEditEngineConfigurationTransaction
extends PhabricatorApplicationTransaction {
const TYPE_NAME = 'editengine.config.name';
const TYPE_PREAMBLE = 'editengine.config.preamble';
const TYPE_ORDER = 'editengine.config.order';
const TYPE_DEFAULT = 'editengine.config.default';
const TYPE_LOCKS = 'editengine.config.locks';
const TYPE_DEFAULTCREATE = 'editengine.config.default.create';
const TYPE_ISEDIT = 'editengine.config.isedit';
const TYPE_DISABLE = 'editengine.config.disable';
const TYPE_CREATEORDER = 'editengine.order.create';
const TYPE_EDITORDER = 'editengine.order.edit';
const TYPE_SUBTYPE = 'editengine.config.subtype';
extends PhabricatorModularTransaction {
public function getApplicationName() {
return 'search';
@ -23,203 +11,8 @@ final class PhabricatorEditEngineConfigurationTransaction
return PhabricatorEditEngineConfigurationPHIDType::TYPECONST;
}
public function getTitle() {
$author_phid = $this->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';
}
}

View file

@ -0,0 +1,172 @@
<?php
abstract class PhabricatorApplicationTransactionDetailView
extends AphrontView {
protected $oldText;
protected $newText;
public function setNewText($new_text) {
$this->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 "<br />" 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);
}
}

View file

@ -0,0 +1,17 @@
<?php
final class PhabricatorApplicationTransactionJSONDiffDetailView
extends PhabricatorApplicationTransactionDetailView {
public function setNew($new_object) {
$json = new PhutilJSON();
$this->setNewText($json->encodeFormatted($new_object));
return $this;
}
public function setOld($old_object) {
$json = new PhutilJSON();
$this->setOldText($json->encodeFormatted($old_object));
return $this;
}
}

View file

@ -1,174 +1,4 @@
<?php
final class PhabricatorApplicationTransactionTextDiffDetailView
extends AphrontView {
private $oldText;
private $newText;
public function setNewText($new_text) {
$this->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 "<br />" 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 {}

View file

@ -0,0 +1,26 @@
<?php
final class PhabricatorEditEngineCreateOrderTransaction
extends PhabricatorEditEngineTransactionType {
const TRANSACTIONTYPE = 'editengine.order.create';
public function generateOldValue($object) {
return (int)$object->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());
}
}

View file

@ -0,0 +1,35 @@
<?php
final class PhabricatorEditEngineDefaultCreateTransaction
extends PhabricatorEditEngineTransactionType {
const TRANSACTIONTYPE = 'editengine.config.default.create';
public function generateOldValue($object) {
return (int)$object->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());
}
}
}

View file

@ -0,0 +1,71 @@
<?php
final class PhabricatorEditEngineDefaultTransaction
extends PhabricatorEditEngineTransactionType {
const TRANSACTIONTYPE = 'editengine.config.default';
public function generateOldValue($object) {
$field_key = $this->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);
}
}

View file

@ -0,0 +1,51 @@
<?php
final class PhabricatorEditEngineDisableTransaction
extends PhabricatorEditEngineTransactionType {
const TRANSACTIONTYPE = 'editengine.config.disable';
public function generateOldValue($object) {
return (int)$object->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';
}
}
}

View file

@ -0,0 +1,26 @@
<?php
final class PhabricatorEditEngineEditOrderTransaction
extends PhabricatorEditEngineTransactionType {
const TRANSACTIONTYPE = 'editengine.order.edit';
public function generateOldValue($object) {
return (int)$object->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());
}
}

View file

@ -0,0 +1,34 @@
<?php
final class PhabricatorEditEngineIsEditTransaction
extends PhabricatorEditEngineTransactionType {
const TRANSACTIONTYPE = 'editengine.config.isedit';
public function generateOldValue($object) {
return (int)$object->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());
}
}
}

View file

@ -0,0 +1,35 @@
<?php
final class PhabricatorEditEngineLocksTransaction
extends PhabricatorEditEngineTransactionType {
const TRANSACTIONTYPE = 'editengine.config.locks';
public function generateOldValue($object) {
return $object->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());
}
}

View file

@ -0,0 +1,54 @@
<?php
final class PhabricatorEditEngineNameTransaction
extends PhabricatorEditEngineTransactionType {
const TRANSACTIONTYPE = 'editengine.config.name';
public function generateOldValue($object) {
return $object->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;
}
}

View file

@ -0,0 +1,35 @@
<?php
final class PhabricatorEditEngineOrderTransaction
extends PhabricatorEditEngineTransactionType {
const TRANSACTIONTYPE = 'editengine.config.order';
public function generateOldValue($object) {
return $object->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());
}
}

View file

@ -0,0 +1,45 @@
<?php
final class PhabricatorEditEnginePreambleTransaction
extends PhabricatorEditEngineTransactionType {
const TRANSACTIONTYPE = 'editengine.config.preamble';
public function generateOldValue($object) {
return $object->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;
}
}

View file

@ -0,0 +1,48 @@
<?php
final class PhabricatorEditEngineSubtypeTransaction
extends PhabricatorEditEngineTransactionType {
const TRANSACTIONTYPE = 'editengine.config.subtype';
public function generateOldValue($object) {
return $object->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;
}
}

View file

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