3 // TODO: Some "final" modifiers have been VERY TEMPORARILY moved aside to
4 // allow DifferentialTransaction to extend this class without converting
5 // fully to ModularTransactions.
7 abstract class PhabricatorModularTransaction
8 extends PhabricatorApplicationTransaction
{
10 private $implementation;
12 abstract public function getBaseTransactionClass();
14 public function getModularType() {
15 return $this->getTransactionImplementation();
18 final protected function getTransactionImplementation() {
19 if (!$this->implementation
) {
20 $this->implementation
= $this->newTransactionImplementation();
23 return $this->implementation
;
26 public function newModularTransactionTypes() {
27 $base_class = $this->getBaseTransactionClass();
29 $types = id(new PhutilClassMapQuery())
30 ->setAncestorClass($base_class)
31 ->setUniqueMethod('getTransactionTypeConstant')
34 // Add core transaction types.
35 $types +
= id(new PhutilClassMapQuery())
36 ->setAncestorClass('PhabricatorCoreTransactionType')
37 ->setUniqueMethod('getTransactionTypeConstant')
43 private function newTransactionImplementation() {
44 $types = $this->newModularTransactionTypes();
46 $key = $this->getTransactionType();
48 if (empty($types[$key])) {
49 $type = $this->newFallbackModularTransactionType();
51 $type = clone $types[$key];
54 $type->setStorage($this);
59 protected function newFallbackModularTransactionType() {
60 return new PhabricatorCoreVoidTransaction();
63 final public function generateOldValue($object) {
64 return $this->getTransactionImplementation()->generateOldValue($object);
67 final public function generateNewValue($object) {
68 return $this->getTransactionImplementation()
69 ->generateNewValue($object, $this->getNewValue());
72 final public function applyInternalEffects($object) {
73 return $this->getTransactionImplementation()
74 ->applyInternalEffects($object);
77 final public function applyExternalEffects($object) {
78 return $this->getTransactionImplementation()
79 ->applyExternalEffects($object);
82 /* final */ public function shouldHide() {
83 if ($this->getTransactionImplementation()->shouldHide()) {
87 return parent
::shouldHide();
90 final public function shouldHideForFeed() {
91 if ($this->getTransactionImplementation()->shouldHideForFeed()) {
95 return parent
::shouldHideForFeed();
98 /* final */ public function shouldHideForMail(array $xactions) {
99 if ($this->getTransactionImplementation()->shouldHideForMail()) {
103 return parent
::shouldHideForMail($xactions);
106 final public function shouldHideForNotifications() {
107 $hide = $this->getTransactionImplementation()->shouldHideForNotifications();
109 // Returning "null" means "use the default behavior".
110 if ($hide === null) {
111 return parent
::shouldHideForNotifications();
117 /* final */ public function getIcon() {
118 $icon = $this->getTransactionImplementation()->getIcon();
119 if ($icon !== null) {
123 return parent
::getIcon();
126 /* final */ public function getTitle() {
127 $title = $this->getTransactionImplementation()->getTitle();
128 if ($title !== null) {
132 return parent
::getTitle();
135 /* final */ public function getActionName() {
136 $action = $this->getTransactionImplementation()->getActionName();
137 if ($action !== null) {
141 return parent
::getActionName();
144 /* final */ public function getActionStrength() {
145 $strength = $this->getTransactionImplementation()->getActionStrength();
146 if ($strength !== null) {
150 return parent
::getActionStrength();
153 /* final */ public function getTitleForFeed() {
154 $title = $this->getTransactionImplementation()->getTitleForFeed();
155 if ($title !== null) {
159 return parent
::getTitleForFeed();
162 /* final */ public function getColor() {
163 $color = $this->getTransactionImplementation()->getColor();
164 if ($color !== null) {
168 return parent
::getColor();
171 public function attachViewer(PhabricatorUser
$viewer) {
172 $this->getTransactionImplementation()->setViewer($viewer);
173 return parent
::attachViewer($viewer);
176 final public function hasChangeDetails() {
177 if ($this->getTransactionImplementation()->hasChangeDetailView()) {
181 return parent
::hasChangeDetails();
184 final public function renderChangeDetails(PhabricatorUser
$viewer) {
185 $impl = $this->getTransactionImplementation();
186 $impl->setViewer($viewer);
187 $view = $impl->newChangeDetailView();
188 if ($view !== null) {
192 return parent
::renderChangeDetails($viewer);
195 final protected function newRemarkupChanges() {
196 return $this->getTransactionImplementation()->newRemarkupChanges();
199 /* final */ public function newWarningForTransactions(
202 throw new PhutilMethodNotImplementedException();