Modularize application transactions in Paste, mostly
Summary:
Ref T9789. `Transaction` and `Editor` classes are the last major pieces of infrastructure that haven't been fully modularized.
Some of the specific issues are:
- `Editor` classes rely on a bunch of `instanceof` stuff in the base class to pick up transaction types like "subscribe", "projects", etc. Instead, applications should be adding these, and third-party applications should be able to add them.
- Code is spread across `Transaction` and `Editor` classes somewhat oddly. For example, generating old/new values would probably make more sense at the `Transaction` level, but it currently exists at the `Editor` level.
- Both types of classes have a lot of functions based on `switch()` statements, which require a ton of boilerplate and are just generally kind of hard to work with.
This creates classes for each type of transaction, and moves almost all of the logic to them. These classes are simpler and more focused than the old stuff was, and can organize related code better.
This starts inching toward defining `CoreTransactions` for features shared across applications. It only defines the "Create" transaction so far, but at some point I plan to move all the other shared transactions to Core and let them control which objects they're available for.
Test Plan:
- Created pastes with web UI and API.
- Edited all paste properites.
- Archived/activated.
- Verified files got reasonable names.
- Reviewed timeline and feed.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9789
Differential Revision: https://secure.phabricator.com/D16111
2016-06-10 01:00:06 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
abstract class PhabricatorModularTransaction
|
|
|
|
extends PhabricatorApplicationTransaction {
|
|
|
|
|
|
|
|
private $implementation;
|
|
|
|
|
|
|
|
abstract public function getBaseTransactionClass();
|
|
|
|
|
Smooth out various transaction/editing behaviors for Calendar
Summary:
Ref T11809.
- Allow users to remove the "Until" date from recurring events.
- When removing "Until", show a sensible string ("...set this event to repeat forever.")
- When users go through the "Make Recurring" workflow, don't require them to explicitly select "Recurring: Recurring" from the dropdown. This intent is clear from clicking "Make Recurring".
- When editing "All Future Events", don't literally apply date changes to them, since that doesn't make sense. We update the template, then reschedule any events which haven't been edited already. I think this is what users probably mean if they make this edit.
- When creating an event with a non-default icon, don't show "alice changed the icon from Default to Party.".
- Hide the "recurring mode" transaction, which had no string ("alice edited this Event.") and was redundant anyway.
- Also, add a little piece of developer text to make hunting these things down easier.
Test Plan: Edited various events, parents, children, made events recur, set until, unset until, viewed transactions, rescheduled parents, rescheduled children.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T11809
Differential Revision: https://secure.phabricator.com/D16796
2016-11-02 23:15:09 +01:00
|
|
|
public function getModularType() {
|
|
|
|
return $this->getTransactionImplementation();
|
|
|
|
}
|
|
|
|
|
Modularize application transactions in Paste, mostly
Summary:
Ref T9789. `Transaction` and `Editor` classes are the last major pieces of infrastructure that haven't been fully modularized.
Some of the specific issues are:
- `Editor` classes rely on a bunch of `instanceof` stuff in the base class to pick up transaction types like "subscribe", "projects", etc. Instead, applications should be adding these, and third-party applications should be able to add them.
- Code is spread across `Transaction` and `Editor` classes somewhat oddly. For example, generating old/new values would probably make more sense at the `Transaction` level, but it currently exists at the `Editor` level.
- Both types of classes have a lot of functions based on `switch()` statements, which require a ton of boilerplate and are just generally kind of hard to work with.
This creates classes for each type of transaction, and moves almost all of the logic to them. These classes are simpler and more focused than the old stuff was, and can organize related code better.
This starts inching toward defining `CoreTransactions` for features shared across applications. It only defines the "Create" transaction so far, but at some point I plan to move all the other shared transactions to Core and let them control which objects they're available for.
Test Plan:
- Created pastes with web UI and API.
- Edited all paste properites.
- Archived/activated.
- Verified files got reasonable names.
- Reviewed timeline and feed.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9789
Differential Revision: https://secure.phabricator.com/D16111
2016-06-10 01:00:06 +02:00
|
|
|
final protected function getTransactionImplementation() {
|
|
|
|
if (!$this->implementation) {
|
|
|
|
$this->implementation = $this->newTransactionImplementation();
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->implementation;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function newModularTransactionTypes() {
|
|
|
|
$base_class = $this->getBaseTransactionClass();
|
|
|
|
|
|
|
|
$types = id(new PhutilClassMapQuery())
|
|
|
|
->setAncestorClass($base_class)
|
|
|
|
->setUniqueMethod('getTransactionTypeConstant')
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
// Add core transaction types.
|
|
|
|
$types += id(new PhutilClassMapQuery())
|
|
|
|
->setAncestorClass('PhabricatorCoreTransactionType')
|
|
|
|
->setUniqueMethod('getTransactionTypeConstant')
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
return $types;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function newTransactionImplementation() {
|
|
|
|
$types = $this->newModularTransactionTypes();
|
|
|
|
|
|
|
|
$key = $this->getTransactionType();
|
|
|
|
|
|
|
|
if (empty($types[$key])) {
|
|
|
|
$type = new PhabricatorCoreVoidTransaction();
|
|
|
|
} else {
|
|
|
|
$type = clone $types[$key];
|
|
|
|
}
|
|
|
|
|
|
|
|
$type->setStorage($this);
|
|
|
|
|
|
|
|
return $type;
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function generateOldValue($object) {
|
|
|
|
return $this->getTransactionImplementation()->generateOldValue($object);
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function generateNewValue($object) {
|
|
|
|
return $this->getTransactionImplementation()
|
|
|
|
->generateNewValue($object, $this->getNewValue());
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function willApplyTransactions($object, array $xactions) {
|
|
|
|
return $this->getTransactionImplementation()
|
|
|
|
->willApplyTransactions($object, $xactions);
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function applyInternalEffects($object) {
|
|
|
|
return $this->getTransactionImplementation()
|
|
|
|
->applyInternalEffects($object);
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function applyExternalEffects($object) {
|
|
|
|
return $this->getTransactionImplementation()
|
|
|
|
->applyExternalEffects($object);
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function shouldHide() {
|
|
|
|
if ($this->getTransactionImplementation()->shouldHide()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::shouldHide();
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function getIcon() {
|
|
|
|
$icon = $this->getTransactionImplementation()->getIcon();
|
|
|
|
if ($icon !== null) {
|
|
|
|
return $icon;
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::getIcon();
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function getTitle() {
|
|
|
|
$title = $this->getTransactionImplementation()->getTitle();
|
|
|
|
if ($title !== null) {
|
|
|
|
return $title;
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::getTitle();
|
|
|
|
}
|
|
|
|
|
2016-07-08 02:17:16 +02:00
|
|
|
public function getTitleForMail() {
|
|
|
|
$old_target = $this->getRenderingTarget();
|
|
|
|
$new_target = self::TARGET_TEXT;
|
|
|
|
$this->setRenderingTarget($new_target);
|
|
|
|
$title = $this->getTitle();
|
|
|
|
$this->setRenderingTarget($old_target);
|
|
|
|
return $title;
|
|
|
|
}
|
|
|
|
|
Modularize application transactions in Paste, mostly
Summary:
Ref T9789. `Transaction` and `Editor` classes are the last major pieces of infrastructure that haven't been fully modularized.
Some of the specific issues are:
- `Editor` classes rely on a bunch of `instanceof` stuff in the base class to pick up transaction types like "subscribe", "projects", etc. Instead, applications should be adding these, and third-party applications should be able to add them.
- Code is spread across `Transaction` and `Editor` classes somewhat oddly. For example, generating old/new values would probably make more sense at the `Transaction` level, but it currently exists at the `Editor` level.
- Both types of classes have a lot of functions based on `switch()` statements, which require a ton of boilerplate and are just generally kind of hard to work with.
This creates classes for each type of transaction, and moves almost all of the logic to them. These classes are simpler and more focused than the old stuff was, and can organize related code better.
This starts inching toward defining `CoreTransactions` for features shared across applications. It only defines the "Create" transaction so far, but at some point I plan to move all the other shared transactions to Core and let them control which objects they're available for.
Test Plan:
- Created pastes with web UI and API.
- Edited all paste properites.
- Archived/activated.
- Verified files got reasonable names.
- Reviewed timeline and feed.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9789
Differential Revision: https://secure.phabricator.com/D16111
2016-06-10 01:00:06 +02:00
|
|
|
final public function getTitleForFeed() {
|
|
|
|
$title = $this->getTransactionImplementation()->getTitleForFeed();
|
|
|
|
if ($title !== null) {
|
|
|
|
return $title;
|
|
|
|
}
|
|
|
|
|
2016-06-14 19:56:53 +02:00
|
|
|
return parent::getTitleForFeed();
|
Modularize application transactions in Paste, mostly
Summary:
Ref T9789. `Transaction` and `Editor` classes are the last major pieces of infrastructure that haven't been fully modularized.
Some of the specific issues are:
- `Editor` classes rely on a bunch of `instanceof` stuff in the base class to pick up transaction types like "subscribe", "projects", etc. Instead, applications should be adding these, and third-party applications should be able to add them.
- Code is spread across `Transaction` and `Editor` classes somewhat oddly. For example, generating old/new values would probably make more sense at the `Transaction` level, but it currently exists at the `Editor` level.
- Both types of classes have a lot of functions based on `switch()` statements, which require a ton of boilerplate and are just generally kind of hard to work with.
This creates classes for each type of transaction, and moves almost all of the logic to them. These classes are simpler and more focused than the old stuff was, and can organize related code better.
This starts inching toward defining `CoreTransactions` for features shared across applications. It only defines the "Create" transaction so far, but at some point I plan to move all the other shared transactions to Core and let them control which objects they're available for.
Test Plan:
- Created pastes with web UI and API.
- Edited all paste properites.
- Archived/activated.
- Verified files got reasonable names.
- Reviewed timeline and feed.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9789
Differential Revision: https://secure.phabricator.com/D16111
2016-06-10 01:00:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
final public function getColor() {
|
|
|
|
$color = $this->getTransactionImplementation()->getColor();
|
|
|
|
if ($color !== null) {
|
|
|
|
return $color;
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::getColor();
|
|
|
|
}
|
|
|
|
|
2016-07-06 03:54:51 +02:00
|
|
|
public function attachViewer(PhabricatorUser $viewer) {
|
|
|
|
$this->getTransactionImplementation()->setViewer($viewer);
|
|
|
|
return parent::attachViewer($viewer);
|
|
|
|
}
|
|
|
|
|
Modularize application transactions in Paste, mostly
Summary:
Ref T9789. `Transaction` and `Editor` classes are the last major pieces of infrastructure that haven't been fully modularized.
Some of the specific issues are:
- `Editor` classes rely on a bunch of `instanceof` stuff in the base class to pick up transaction types like "subscribe", "projects", etc. Instead, applications should be adding these, and third-party applications should be able to add them.
- Code is spread across `Transaction` and `Editor` classes somewhat oddly. For example, generating old/new values would probably make more sense at the `Transaction` level, but it currently exists at the `Editor` level.
- Both types of classes have a lot of functions based on `switch()` statements, which require a ton of boilerplate and are just generally kind of hard to work with.
This creates classes for each type of transaction, and moves almost all of the logic to them. These classes are simpler and more focused than the old stuff was, and can organize related code better.
This starts inching toward defining `CoreTransactions` for features shared across applications. It only defines the "Create" transaction so far, but at some point I plan to move all the other shared transactions to Core and let them control which objects they're available for.
Test Plan:
- Created pastes with web UI and API.
- Edited all paste properites.
- Archived/activated.
- Verified files got reasonable names.
- Reviewed timeline and feed.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9789
Differential Revision: https://secure.phabricator.com/D16111
2016-06-10 01:00:06 +02:00
|
|
|
final public function hasChangeDetails() {
|
|
|
|
if ($this->getTransactionImplementation()->hasChangeDetailView()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::hasChangeDetails();
|
|
|
|
}
|
|
|
|
|
|
|
|
final public function renderChangeDetails(PhabricatorUser $viewer) {
|
|
|
|
$impl = $this->getTransactionImplementation();
|
|
|
|
$impl->setViewer($viewer);
|
|
|
|
$view = $impl->newChangeDetailView();
|
|
|
|
if ($view !== null) {
|
|
|
|
return $view;
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::renderChangeDetails($viewer);
|
|
|
|
}
|
|
|
|
|
2016-08-31 23:59:37 +02:00
|
|
|
final protected function newRemarkupChanges() {
|
|
|
|
return $this->getTransactionImplementation()->newRemarkupChanges();
|
|
|
|
}
|
|
|
|
|
Modularize application transactions in Paste, mostly
Summary:
Ref T9789. `Transaction` and `Editor` classes are the last major pieces of infrastructure that haven't been fully modularized.
Some of the specific issues are:
- `Editor` classes rely on a bunch of `instanceof` stuff in the base class to pick up transaction types like "subscribe", "projects", etc. Instead, applications should be adding these, and third-party applications should be able to add them.
- Code is spread across `Transaction` and `Editor` classes somewhat oddly. For example, generating old/new values would probably make more sense at the `Transaction` level, but it currently exists at the `Editor` level.
- Both types of classes have a lot of functions based on `switch()` statements, which require a ton of boilerplate and are just generally kind of hard to work with.
This creates classes for each type of transaction, and moves almost all of the logic to them. These classes are simpler and more focused than the old stuff was, and can organize related code better.
This starts inching toward defining `CoreTransactions` for features shared across applications. It only defines the "Create" transaction so far, but at some point I plan to move all the other shared transactions to Core and let them control which objects they're available for.
Test Plan:
- Created pastes with web UI and API.
- Edited all paste properites.
- Archived/activated.
- Verified files got reasonable names.
- Reviewed timeline and feed.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9789
Differential Revision: https://secure.phabricator.com/D16111
2016-06-10 01:00:06 +02:00
|
|
|
}
|