mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 16:52:41 +01:00
Convert Nuance Items to Modular Transactions
Summary: Ref T12738. Moves existing non-modular transactions to modular transactions. Some of these are pretty flimsy, but a lot of them don't actually work or do anything in Nuance yet anyway. Test Plan: Gently poked Nuance, nothing fell over. Reviewers: chad Reviewed By: chad Maniphest Tasks: T12738 Differential Revision: https://secure.phabricator.com/D17990
This commit is contained in:
parent
03d4d674f8
commit
1069c2bff9
17 changed files with 180 additions and 162 deletions
|
@ -1620,16 +1620,23 @@ phutil_register_library_map(array(
|
|||
'NuanceItemActionController' => 'applications/nuance/controller/NuanceItemActionController.php',
|
||||
'NuanceItemCommand' => 'applications/nuance/storage/NuanceItemCommand.php',
|
||||
'NuanceItemCommandQuery' => 'applications/nuance/query/NuanceItemCommandQuery.php',
|
||||
'NuanceItemCommandTransaction' => 'applications/nuance/xaction/NuanceItemCommandTransaction.php',
|
||||
'NuanceItemController' => 'applications/nuance/controller/NuanceItemController.php',
|
||||
'NuanceItemEditor' => 'applications/nuance/editor/NuanceItemEditor.php',
|
||||
'NuanceItemListController' => 'applications/nuance/controller/NuanceItemListController.php',
|
||||
'NuanceItemManageController' => 'applications/nuance/controller/NuanceItemManageController.php',
|
||||
'NuanceItemOwnerTransaction' => 'applications/nuance/xaction/NuanceItemOwnerTransaction.php',
|
||||
'NuanceItemPHIDType' => 'applications/nuance/phid/NuanceItemPHIDType.php',
|
||||
'NuanceItemPropertyTransaction' => 'applications/nuance/xaction/NuanceItemPropertyTransaction.php',
|
||||
'NuanceItemQuery' => 'applications/nuance/query/NuanceItemQuery.php',
|
||||
'NuanceItemQueueTransaction' => 'applications/nuance/xaction/NuanceItemQueueTransaction.php',
|
||||
'NuanceItemRequestorTransaction' => 'applications/nuance/xaction/NuanceItemRequestorTransaction.php',
|
||||
'NuanceItemSearchEngine' => 'applications/nuance/query/NuanceItemSearchEngine.php',
|
||||
'NuanceItemSourceTransaction' => 'applications/nuance/xaction/NuanceItemSourceTransaction.php',
|
||||
'NuanceItemTransaction' => 'applications/nuance/storage/NuanceItemTransaction.php',
|
||||
'NuanceItemTransactionComment' => 'applications/nuance/storage/NuanceItemTransactionComment.php',
|
||||
'NuanceItemTransactionQuery' => 'applications/nuance/query/NuanceItemTransactionQuery.php',
|
||||
'NuanceItemTransactionType' => 'applications/nuance/xaction/NuanceItemTransactionType.php',
|
||||
'NuanceItemType' => 'applications/nuance/item/NuanceItemType.php',
|
||||
'NuanceItemUpdateWorker' => 'applications/nuance/worker/NuanceItemUpdateWorker.php',
|
||||
'NuanceItemViewController' => 'applications/nuance/controller/NuanceItemViewController.php',
|
||||
|
@ -1651,6 +1658,7 @@ phutil_register_library_map(array(
|
|||
'NuanceQueueTransaction' => 'applications/nuance/storage/NuanceQueueTransaction.php',
|
||||
'NuanceQueueTransactionComment' => 'applications/nuance/storage/NuanceQueueTransactionComment.php',
|
||||
'NuanceQueueTransactionQuery' => 'applications/nuance/query/NuanceQueueTransactionQuery.php',
|
||||
'NuanceQueueTransactionType' => 'applications/nuance/xaction/NuanceQueueTransactionType.php',
|
||||
'NuanceQueueViewController' => 'applications/nuance/controller/NuanceQueueViewController.php',
|
||||
'NuanceSchemaSpec' => 'applications/nuance/storage/NuanceSchemaSpec.php',
|
||||
'NuanceSource' => 'applications/nuance/storage/NuanceSource.php',
|
||||
|
@ -1672,6 +1680,7 @@ phutil_register_library_map(array(
|
|||
'NuanceSourceTransaction' => 'applications/nuance/storage/NuanceSourceTransaction.php',
|
||||
'NuanceSourceTransactionComment' => 'applications/nuance/storage/NuanceSourceTransactionComment.php',
|
||||
'NuanceSourceTransactionQuery' => 'applications/nuance/query/NuanceSourceTransactionQuery.php',
|
||||
'NuanceSourceTransactionType' => 'applications/nuance/xaction/NuanceSourceTransactionType.php',
|
||||
'NuanceSourceViewController' => 'applications/nuance/controller/NuanceSourceViewController.php',
|
||||
'NuanceTransaction' => 'applications/nuance/storage/NuanceTransaction.php',
|
||||
'NuanceWorker' => 'applications/nuance/worker/NuanceWorker.php',
|
||||
|
@ -6720,16 +6729,23 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPolicyInterface',
|
||||
),
|
||||
'NuanceItemCommandQuery' => 'NuanceQuery',
|
||||
'NuanceItemCommandTransaction' => 'NuanceItemTransactionType',
|
||||
'NuanceItemController' => 'NuanceController',
|
||||
'NuanceItemEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'NuanceItemListController' => 'NuanceItemController',
|
||||
'NuanceItemManageController' => 'NuanceController',
|
||||
'NuanceItemOwnerTransaction' => 'NuanceItemTransactionType',
|
||||
'NuanceItemPHIDType' => 'PhabricatorPHIDType',
|
||||
'NuanceItemPropertyTransaction' => 'NuanceItemTransactionType',
|
||||
'NuanceItemQuery' => 'NuanceQuery',
|
||||
'NuanceItemQueueTransaction' => 'NuanceItemTransactionType',
|
||||
'NuanceItemRequestorTransaction' => 'NuanceItemTransactionType',
|
||||
'NuanceItemSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'NuanceItemSourceTransaction' => 'NuanceItemTransactionType',
|
||||
'NuanceItemTransaction' => 'NuanceTransaction',
|
||||
'NuanceItemTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||
'NuanceItemTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'NuanceItemTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'NuanceItemType' => 'Phobject',
|
||||
'NuanceItemUpdateWorker' => 'NuanceWorker',
|
||||
'NuanceItemViewController' => 'NuanceController',
|
||||
|
@ -6755,6 +6771,7 @@ phutil_register_library_map(array(
|
|||
'NuanceQueueTransaction' => 'NuanceTransaction',
|
||||
'NuanceQueueTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||
'NuanceQueueTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'NuanceQueueTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'NuanceQueueViewController' => 'NuanceQueueController',
|
||||
'NuanceSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||
'NuanceSource' => array(
|
||||
|
@ -6781,8 +6798,9 @@ phutil_register_library_map(array(
|
|||
'NuanceSourceTransaction' => 'NuanceTransaction',
|
||||
'NuanceSourceTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||
'NuanceSourceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'NuanceSourceTransactionType' => 'PhabricatorModularTransactionType',
|
||||
'NuanceSourceViewController' => 'NuanceSourceController',
|
||||
'NuanceTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'NuanceTransaction' => 'PhabricatorModularTransaction',
|
||||
'NuanceWorker' => 'PhabricatorWorker',
|
||||
'OwnersConduitAPIMethod' => 'ConduitAPIMethod',
|
||||
'OwnersEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
|
||||
|
|
|
@ -14,104 +14,10 @@ final class NuanceItemEditor
|
|||
public function getTransactionTypes() {
|
||||
$types = parent::getTransactionTypes();
|
||||
|
||||
$types[] = NuanceItemTransaction::TYPE_OWNER;
|
||||
$types[] = NuanceItemTransaction::TYPE_SOURCE;
|
||||
$types[] = NuanceItemTransaction::TYPE_REQUESTOR;
|
||||
$types[] = NuanceItemTransaction::TYPE_PROPERTY;
|
||||
$types[] = NuanceItemTransaction::TYPE_QUEUE;
|
||||
$types[] = NuanceItemTransaction::TYPE_COMMAND;
|
||||
|
||||
$types[] = PhabricatorTransactions::TYPE_EDGE;
|
||||
$types[] = PhabricatorTransactions::TYPE_COMMENT;
|
||||
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
|
||||
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
protected function getCustomTransactionOldValue(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case NuanceItemTransaction::TYPE_REQUESTOR:
|
||||
return $object->getRequestorPHID();
|
||||
case NuanceItemTransaction::TYPE_SOURCE:
|
||||
return $object->getSourcePHID();
|
||||
case NuanceItemTransaction::TYPE_OWNER:
|
||||
return $object->getOwnerPHID();
|
||||
case NuanceItemTransaction::TYPE_QUEUE:
|
||||
return $object->getQueuePHID();
|
||||
case NuanceItemTransaction::TYPE_PROPERTY:
|
||||
$key = $xaction->getMetadataValue(
|
||||
NuanceItemTransaction::PROPERTY_KEY);
|
||||
return $object->getNuanceProperty($key);
|
||||
case NuanceItemTransaction::TYPE_COMMAND:
|
||||
return null;
|
||||
}
|
||||
|
||||
return parent::getCustomTransactionOldValue($object, $xaction);
|
||||
}
|
||||
|
||||
protected function getCustomTransactionNewValue(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case NuanceItemTransaction::TYPE_REQUESTOR:
|
||||
case NuanceItemTransaction::TYPE_SOURCE:
|
||||
case NuanceItemTransaction::TYPE_OWNER:
|
||||
case NuanceItemTransaction::TYPE_PROPERTY:
|
||||
case NuanceItemTransaction::TYPE_QUEUE:
|
||||
case NuanceItemTransaction::TYPE_COMMAND:
|
||||
return $xaction->getNewValue();
|
||||
}
|
||||
|
||||
return parent::getCustomTransactionNewValue($object, $xaction);
|
||||
}
|
||||
|
||||
protected function applyCustomInternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case NuanceItemTransaction::TYPE_REQUESTOR:
|
||||
$object->setRequestorPHID($xaction->getNewValue());
|
||||
break;
|
||||
case NuanceItemTransaction::TYPE_SOURCE:
|
||||
$object->setSourcePHID($xaction->getNewValue());
|
||||
break;
|
||||
case NuanceItemTransaction::TYPE_OWNER:
|
||||
$object->setOwnerPHID($xaction->getNewValue());
|
||||
break;
|
||||
case NuanceItemTransaction::TYPE_QUEUE:
|
||||
$object->setQueuePHID($xaction->getNewValue());
|
||||
break;
|
||||
case NuanceItemTransaction::TYPE_PROPERTY:
|
||||
$key = $xaction->getMetadataValue(
|
||||
NuanceItemTransaction::PROPERTY_KEY);
|
||||
$object->setNuanceProperty($key, $xaction->getNewValue());
|
||||
break;
|
||||
case NuanceItemTransaction::TYPE_COMMAND:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function applyCustomExternalTransaction(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case NuanceItemTransaction::TYPE_REQUESTOR:
|
||||
case NuanceItemTransaction::TYPE_SOURCE:
|
||||
case NuanceItemTransaction::TYPE_OWNER:
|
||||
case NuanceItemTransaction::TYPE_PROPERTY:
|
||||
case NuanceItemTransaction::TYPE_QUEUE:
|
||||
case NuanceItemTransaction::TYPE_COMMAND:
|
||||
return;
|
||||
}
|
||||
|
||||
return parent::applyCustomExternalTransaction($object, $xaction);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ abstract class NuanceItemType
|
|||
}
|
||||
|
||||
$xaction = id(new NuanceItemTransaction())
|
||||
->setTransactionType(NuanceItemTransaction::TYPE_COMMAND)
|
||||
->setTransactionType(NuanceItemCommandTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue(
|
||||
array(
|
||||
'command' => $command->getCommand(),
|
||||
|
|
|
@ -162,18 +162,19 @@ abstract class NuanceSourceDefinition extends Phobject {
|
|||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new NuanceItemTransaction())
|
||||
->setTransactionType(NuanceItemTransaction::TYPE_SOURCE)
|
||||
->setTransactionType(NuanceItemSourceTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($source->getPHID());
|
||||
|
||||
// TODO: Eventually, apply real routing rules. For now, just put everything
|
||||
// in the default queue for the source.
|
||||
$xactions[] = id(new NuanceItemTransaction())
|
||||
->setTransactionType(NuanceItemTransaction::TYPE_QUEUE)
|
||||
->setTransactionType(NuanceItemQueueTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue($source->getDefaultQueuePHID());
|
||||
|
||||
// TODO: Maybe this should all be modular transactions now?
|
||||
foreach ($properties as $key => $property) {
|
||||
$xactions[] = id(new NuanceItemTransaction())
|
||||
->setTransactionType(NuanceItemTransaction::TYPE_PROPERTY)
|
||||
->setTransactionType(NuanceItemPropertyTransaction::TRANSACTIONTYPE)
|
||||
->setMetadataValue(NuanceItemTransaction::PROPERTY_KEY, $key)
|
||||
->setNewValue($property);
|
||||
}
|
||||
|
|
|
@ -5,13 +5,6 @@ final class NuanceItemTransaction
|
|||
|
||||
const PROPERTY_KEY = 'property.key';
|
||||
|
||||
const TYPE_OWNER = 'nuance.item.owner';
|
||||
const TYPE_REQUESTOR = 'nuance.item.requestor';
|
||||
const TYPE_SOURCE = 'nuance.item.source';
|
||||
const TYPE_PROPERTY = 'nuance.item.property';
|
||||
const TYPE_QUEUE = 'nuance.item.queue';
|
||||
const TYPE_COMMAND = 'nuance.item.command';
|
||||
|
||||
public function getApplicationTransactionType() {
|
||||
return NuanceItemPHIDType::TYPECONST;
|
||||
}
|
||||
|
@ -20,61 +13,8 @@ final class NuanceItemTransaction
|
|||
return new NuanceItemTransactionComment();
|
||||
}
|
||||
|
||||
public function shouldHide() {
|
||||
$old = $this->getOldValue();
|
||||
$type = $this->getTransactionType();
|
||||
|
||||
switch ($type) {
|
||||
case self::TYPE_REQUESTOR:
|
||||
case self::TYPE_SOURCE:
|
||||
return ($old === null);
|
||||
}
|
||||
|
||||
return parent::shouldHide();
|
||||
}
|
||||
|
||||
public function getRequiredHandlePHIDs() {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
$type = $this->getTransactionType();
|
||||
|
||||
$phids = parent::getRequiredHandlePHIDs();
|
||||
switch ($type) {
|
||||
case self::TYPE_QUEUE:
|
||||
if ($old) {
|
||||
$phids[] = $old;
|
||||
}
|
||||
if ($new) {
|
||||
$phids[] = $new;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $phids;
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
$type = $this->getTransactionType();
|
||||
|
||||
$author_phid = $this->getAuthorPHID();
|
||||
|
||||
switch ($type) {
|
||||
case self::TYPE_QUEUE:
|
||||
return pht(
|
||||
'%s routed this item to the %s queue.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($new));
|
||||
case self::TYPE_COMMAND:
|
||||
// TODO: Give item types a chance to render this properly.
|
||||
return pht(
|
||||
'%s applied command "%s" to this item.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
idx($new, 'command'));
|
||||
}
|
||||
|
||||
return parent::getTitle();
|
||||
public function getBaseTransactionClass() {
|
||||
return 'NuanceItemTransactionType';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,6 +12,10 @@ final class NuanceQueueTransaction extends NuanceTransaction {
|
|||
return new NuanceQueueTransactionComment();
|
||||
}
|
||||
|
||||
public function getBaseTransactionClass() {
|
||||
return 'NuanceSourceTransactionType';
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
|
|
@ -14,6 +14,10 @@ final class NuanceSourceTransaction
|
|||
return new NuanceSourceTransactionComment();
|
||||
}
|
||||
|
||||
public function getBaseTransactionClass() {
|
||||
return 'NuanceSourceTransactionType';
|
||||
}
|
||||
|
||||
public function shouldHide() {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
abstract class NuanceTransaction
|
||||
extends PhabricatorApplicationTransaction {
|
||||
extends PhabricatorModularTransaction {
|
||||
|
||||
public function getApplicationName() {
|
||||
return 'nuance';
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
final class NuanceItemCommandTransaction
|
||||
extends NuanceItemTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'nuance.item.command';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
// TODO: Probably implement this.
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s applied a command to this item.',
|
||||
$this->renderAuthor());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
final class NuanceItemOwnerTransaction
|
||||
extends NuanceItemTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'nuance.item.owner';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getOwnerPHID();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setOwnerPHID($value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
|
||||
// TODO: Assign, unassign strings probably need variants.
|
||||
|
||||
return pht(
|
||||
'%s reassigned this item from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderHandle($this->getOldValue()),
|
||||
$this->renderHandle($this->getNewValue()));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
final class NuanceItemPropertyTransaction
|
||||
extends NuanceItemTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'nuance.item.property';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
$property_key = NuanceItemTransaction::PROPERTY_KEY;
|
||||
$key = $this->getMetadataValue($property_key);
|
||||
return $object->getNuanceProperty($key);
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$property_key = NuanceItemTransaction::PROPERTY_KEY;
|
||||
$key = $this->getMetadataValue($property_key);
|
||||
|
||||
$object->setNuanceProperty($key, $value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s set a property on this item.',
|
||||
$this->renderAuthor());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
final class NuanceItemQueueTransaction
|
||||
extends NuanceItemTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'nuance.item.queue';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getQueuePHID();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setQueuePHID($value);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s rerouted this item from %s to %s.',
|
||||
$this->renderAuthor(),
|
||||
$this->renderHandle($this->getOldValue()),
|
||||
$this->renderHandle($this->getNewValue()));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
final class NuanceItemRequestorTransaction
|
||||
extends NuanceItemTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'nuance.item.requestor';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getRequestorPHID();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setRequestorPHID($value);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
final class NuanceItemSourceTransaction
|
||||
extends NuanceItemTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'nuance.item.source';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
return $object->getSourcePHID();
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$object->setSourcePHID($value);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
abstract class NuanceItemTransactionType
|
||||
extends PhabricatorModularTransactionType {}
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
abstract class NuanceQueueTransactionType
|
||||
extends PhabricatorModularTransactionType {}
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
|
||||
abstract class NuanceSourceTransactionType
|
||||
extends PhabricatorModularTransactionType {}
|
Loading…
Reference in a new issue