Differential D21839 Diff 52052 src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
Show First 20 Lines • Show All 392 Lines • ▼ Show 20 Lines | private function adjustTransactionValues( | ||||
// Apply an optional transformation to convert "external" tranaction | // Apply an optional transformation to convert "external" tranaction | ||||
// values (provided by APIs) into "internal" values. | // values (provided by APIs) into "internal" values. | ||||
$old = $xaction->getOldValue(); | $old = $xaction->getOldValue(); | ||||
$new = $xaction->getNewValue(); | $new = $xaction->getNewValue(); | ||||
$type = $xaction->getTransactionType(); | $type = $xaction->getTransactionType(); | ||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if ($xtype) { | if ($xtype) { | ||||
$xtype = clone $xtype; | $xtype = clone $xtype; | ||||
$xtype->setStorage($xaction); | $xtype->setStorage($xaction); | ||||
// TODO: Provide a modular hook for modern transactions to do a | // TODO: Provide a modular hook for modern transactions to do a | ||||
// transformation. | // transformation. | ||||
list($old, $new) = array($old, $new); | list($old, $new) = array($old, $new); | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | abstract class PhabricatorApplicationTransactionEditor | ||||
} | } | ||||
private function getTransactionOldValue( | private function getTransactionOldValue( | ||||
PhabricatorLiskDAO $object, | PhabricatorLiskDAO $object, | ||||
PhabricatorApplicationTransaction $xaction) { | PhabricatorApplicationTransaction $xaction) { | ||||
$type = $xaction->getTransactionType(); | $type = $xaction->getTransactionType(); | ||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if ($xtype) { | if ($xtype) { | ||||
$xtype = clone $xtype; | $xtype = clone $xtype; | ||||
$xtype->setStorage($xaction); | $xtype->setStorage($xaction); | ||||
return $xtype->generateOldValue($object); | return $xtype->generateOldValue($object); | ||||
} | } | ||||
switch ($type) { | switch ($type) { | ||||
case PhabricatorTransactions::TYPE_CREATE: | case PhabricatorTransactions::TYPE_CREATE: | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | abstract class PhabricatorApplicationTransactionEditor | ||||
} | } | ||||
private function getTransactionNewValue( | private function getTransactionNewValue( | ||||
PhabricatorLiskDAO $object, | PhabricatorLiskDAO $object, | ||||
PhabricatorApplicationTransaction $xaction) { | PhabricatorApplicationTransaction $xaction) { | ||||
$type = $xaction->getTransactionType(); | $type = $xaction->getTransactionType(); | ||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if ($xtype) { | if ($xtype) { | ||||
$xtype = clone $xtype; | $xtype = clone $xtype; | ||||
$xtype->setStorage($xaction); | $xtype->setStorage($xaction); | ||||
return $xtype->generateNewValue($object, $xaction->getNewValue()); | return $xtype->generateNewValue($object, $xaction->getNewValue()); | ||||
} | } | ||||
switch ($type) { | switch ($type) { | ||||
case PhabricatorTransactions::TYPE_CREATE: | case PhabricatorTransactions::TYPE_CREATE: | ||||
▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | switch ($xaction->getTransactionType()) { | ||||
return true; | return true; | ||||
} | } | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
$type = $xaction->getTransactionType(); | $type = $xaction->getTransactionType(); | ||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if ($xtype) { | if ($xtype) { | ||||
return $xtype->getTransactionHasEffect( | return $xtype->getTransactionHasEffect( | ||||
$object, | $object, | ||||
$xaction->getOldValue(), | $xaction->getOldValue(), | ||||
$xaction->getNewValue()); | $xaction->getNewValue()); | ||||
} | } | ||||
if ($xaction->hasComment()) { | if ($xaction->hasComment()) { | ||||
Show All 16 Lines | abstract class PhabricatorApplicationTransactionEditor | ||||
} | } | ||||
private function applyInternalEffects( | private function applyInternalEffects( | ||||
PhabricatorLiskDAO $object, | PhabricatorLiskDAO $object, | ||||
PhabricatorApplicationTransaction $xaction) { | PhabricatorApplicationTransaction $xaction) { | ||||
$type = $xaction->getTransactionType(); | $type = $xaction->getTransactionType(); | ||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if ($xtype) { | if ($xtype) { | ||||
$xtype = clone $xtype; | $xtype = clone $xtype; | ||||
$xtype->setStorage($xaction); | $xtype->setStorage($xaction); | ||||
return $xtype->applyInternalEffects($object, $xaction->getNewValue()); | return $xtype->applyInternalEffects($object, $xaction->getNewValue()); | ||||
} | } | ||||
switch ($type) { | switch ($type) { | ||||
case PhabricatorTransactions::TYPE_CUSTOMFIELD: | case PhabricatorTransactions::TYPE_CUSTOMFIELD: | ||||
Show All 21 Lines | abstract class PhabricatorApplicationTransactionEditor | ||||
} | } | ||||
private function applyExternalEffects( | private function applyExternalEffects( | ||||
PhabricatorLiskDAO $object, | PhabricatorLiskDAO $object, | ||||
PhabricatorApplicationTransaction $xaction) { | PhabricatorApplicationTransaction $xaction) { | ||||
$type = $xaction->getTransactionType(); | $type = $xaction->getTransactionType(); | ||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if ($xtype) { | if ($xtype) { | ||||
$xtype = clone $xtype; | $xtype = clone $xtype; | ||||
$xtype->setStorage($xaction); | $xtype->setStorage($xaction); | ||||
return $xtype->applyExternalEffects($object, $xaction->getNewValue()); | return $xtype->applyExternalEffects($object, $xaction->getNewValue()); | ||||
} | } | ||||
switch ($type) { | switch ($type) { | ||||
case PhabricatorTransactions::TYPE_SUBSCRIBERS: | case PhabricatorTransactions::TYPE_SUBSCRIBERS: | ||||
▲ Show 20 Lines • Show All 320 Lines • ▼ Show 20 Lines | foreach ($xactions as $xaction) { | ||||
$this->applyInverseEdgeTransactions( | $this->applyInverseEdgeTransactions( | ||||
$object, | $object, | ||||
$xaction, | $xaction, | ||||
$edge_type->getInverseEdgeConstant()); | $edge_type->getInverseEdgeConstant()); | ||||
} | } | ||||
continue; | continue; | ||||
} | } | ||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if (!$xtype) { | if (!$xtype) { | ||||
continue; | continue; | ||||
} | } | ||||
$xtype = clone $xtype; | $xtype = clone $xtype; | ||||
$xtype->setStorage($xaction); | $xtype->setStorage($xaction); | ||||
$xtype->didCommitTransaction($object, $xaction->getNewValue()); | $xtype->didCommitTransaction($object, $xaction->getNewValue()); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 724 Lines • ▼ Show 20 Lines | if ($this->getIsNewObject()) { | ||||
// If we aren't doing anything, require CAN_EDIT to improve consistency. | // If we aren't doing anything, require CAN_EDIT to improve consistency. | ||||
$required_capabilities = array($can_edit); | $required_capabilities = array($can_edit); | ||||
} else { | } else { | ||||
$required_capabilities = array(); | $required_capabilities = array(); | ||||
foreach ($xactions as $xaction) { | foreach ($xactions as $xaction) { | ||||
$type = $xaction->getTransactionType(); | $type = $xaction->getTransactionType(); | ||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if (!$xtype) { | if (!$xtype) { | ||||
$capabilities = $this->getLegacyRequiredCapabilities($xaction); | $capabilities = $this->getLegacyRequiredCapabilities($xaction); | ||||
} else { | } else { | ||||
$capabilities = $xtype->getRequiredCapabilities($object, $xaction); | $capabilities = $xtype->getRequiredCapabilities($object, $xaction); | ||||
} | } | ||||
// For convenience, we allow flexibility in the return types because | // For convenience, we allow flexibility in the return types because | ||||
// it's very unusual that a transaction actually requires multiple | // it's very unusual that a transaction actually requires multiple | ||||
▲ Show 20 Lines • Show All 258 Lines • ▼ Show 20 Lines | private function buildSubscribeTransaction( | ||||
return $xaction; | return $xaction; | ||||
} | } | ||||
protected function mergeTransactions( | protected function mergeTransactions( | ||||
PhabricatorApplicationTransaction $u, | PhabricatorApplicationTransaction $u, | ||||
PhabricatorApplicationTransaction $v) { | PhabricatorApplicationTransaction $v) { | ||||
$object = $this->object; | |||||
$type = $u->getTransactionType(); | $type = $u->getTransactionType(); | ||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if ($xtype) { | if ($xtype) { | ||||
$object = $this->object; | |||||
return $xtype->mergeTransactions($object, $u, $v); | return $xtype->mergeTransactions($object, $u, $v); | ||||
} | } | ||||
switch ($type) { | switch ($type) { | ||||
case PhabricatorTransactions::TYPE_SUBSCRIBERS: | case PhabricatorTransactions::TYPE_SUBSCRIBERS: | ||||
return $this->mergePHIDOrEdgeTransactions($u, $v); | return $this->mergePHIDOrEdgeTransactions($u, $v); | ||||
case PhabricatorTransactions::TYPE_EDGE: | case PhabricatorTransactions::TYPE_EDGE: | ||||
$u_type = $u->getMetadataValue('edge:type'); | $u_type = $u->getMetadataValue('edge:type'); | ||||
▲ Show 20 Lines • Show All 709 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
protected function validateTransaction( | protected function validateTransaction( | ||||
PhabricatorLiskDAO $object, | PhabricatorLiskDAO $object, | ||||
$type, | $type, | ||||
array $xactions) { | array $xactions) { | ||||
$errors = array(); | $errors = array(); | ||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if ($xtype) { | if ($xtype) { | ||||
$errors[] = $xtype->validateTransactions($object, $xactions); | $errors[] = $xtype->validateTransactions($object, $xactions); | ||||
} | } | ||||
switch ($type) { | switch ($type) { | ||||
case PhabricatorTransactions::TYPE_VIEW_POLICY: | case PhabricatorTransactions::TYPE_VIEW_POLICY: | ||||
$errors[] = $this->validatePolicyTransaction( | $errors[] = $this->validatePolicyTransaction( | ||||
$object, | $object, | ||||
▲ Show 20 Lines • Show All 1,126 Lines • ▼ Show 20 Lines | foreach ($details as $xaction) { | ||||
$body->addHTMLSection($label, $details); | $body->addHTMLSection($label, $details); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
private function getMailDiffSectionHeader($xaction) { | private function getMailDiffSectionHeader($xaction) { | ||||
$type = $xaction->getTransactionType(); | $type = $xaction->getTransactionType(); | ||||
$object = $this->object; | |||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if ($xtype) { | if ($xtype) { | ||||
return $xtype->getMailDiffSectionHeader(); | return $xtype->getMailDiffSectionHeader(); | ||||
} | } | ||||
return pht('EDIT DETAILS'); | return pht('EDIT DETAILS'); | ||||
} | } | ||||
/** | /** | ||||
▲ Show 20 Lines • Show All 381 Lines • ▼ Show 20 Lines | private function extractFilePHIDs( | ||||
PhabricatorLiskDAO $object, | PhabricatorLiskDAO $object, | ||||
array $xactions) { | array $xactions) { | ||||
$phids = array(); | $phids = array(); | ||||
foreach ($xactions as $xaction) { | foreach ($xactions as $xaction) { | ||||
$type = $xaction->getTransactionType(); | $type = $xaction->getTransactionType(); | ||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if ($xtype) { | if ($xtype) { | ||||
$phids[] = $xtype->extractFilePHIDs($object, $xaction->getNewValue()); | $phids[] = $xtype->extractFilePHIDs($object, $xaction->getNewValue()); | ||||
} else { | } else { | ||||
$phids[] = $this->extractFilePHIDsFromCustomTransaction( | $phids[] = $this->extractFilePHIDsFromCustomTransaction( | ||||
$object, | $object, | ||||
$xaction); | $xaction); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 529 Lines • ▼ Show 20 Lines | private function updateWorkboardColumns($object, $const, $old, $new) { | ||||
queryfx( | queryfx( | ||||
$conn_w, | $conn_w, | ||||
'DELETE FROM %T WHERE objectPHID = %s AND columnPHID IN (%Ls)', | 'DELETE FROM %T WHERE objectPHID = %s AND columnPHID IN (%Ls)', | ||||
$position_table->getTableName(), | $position_table->getTableName(), | ||||
$object->getPHID(), | $object->getPHID(), | ||||
$proxy_phids); | $proxy_phids); | ||||
} | } | ||||
private function getModularTransactionTypes() { | private function getModularTransactionTypes( | ||||
PhabricatorLiskDAO $object) { | |||||
if ($this->modularTypes === null) { | if ($this->modularTypes === null) { | ||||
$template = $this->object->getApplicationTransactionTemplate(); | $template = $object->getApplicationTransactionTemplate(); | ||||
if ($template instanceof PhabricatorModularTransaction) { | if ($template instanceof PhabricatorModularTransaction) { | ||||
$xtypes = $template->newModularTransactionTypes(); | $xtypes = $template->newModularTransactionTypes(); | ||||
foreach ($xtypes as $key => $xtype) { | foreach ($xtypes as $key => $xtype) { | ||||
$xtype = clone $xtype; | $xtype = clone $xtype; | ||||
$xtype->setEditor($this); | $xtype->setEditor($this); | ||||
$xtypes[$key] = $xtype; | $xtypes[$key] = $xtype; | ||||
} | } | ||||
} else { | } else { | ||||
$xtypes = array(); | $xtypes = array(); | ||||
} | } | ||||
$this->modularTypes = $xtypes; | $this->modularTypes = $xtypes; | ||||
} | } | ||||
return $this->modularTypes; | return $this->modularTypes; | ||||
} | } | ||||
private function getModularTransactionType($type) { | private function getModularTransactionType($object, $type) { | ||||
$types = $this->getModularTransactionTypes(); | $types = $this->getModularTransactionTypes($object); | ||||
return idx($types, $type); | return idx($types, $type); | ||||
} | } | ||||
public function getCreateObjectTitle($author, $object) { | public function getCreateObjectTitle($author, $object) { | ||||
return pht('%s created this object.', $author); | return pht('%s created this object.', $author); | ||||
} | } | ||||
public function getCreateObjectTitleForFeed($author, $object) { | public function getCreateObjectTitleForFeed($author, $object) { | ||||
▲ Show 20 Lines • Show All 543 Lines • ▼ Show 20 Lines | private function newMFATransactions( | ||||
if (!$require_mfa) { | if (!$require_mfa) { | ||||
// If the object hasn't already opted into MFA, see if any of the | // If the object hasn't already opted into MFA, see if any of the | ||||
// transactions want it. | // transactions want it. | ||||
if (!$try_mfa) { | if (!$try_mfa) { | ||||
foreach ($xactions as $xaction) { | foreach ($xactions as $xaction) { | ||||
$type = $xaction->getTransactionType(); | $type = $xaction->getTransactionType(); | ||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if ($xtype) { | if ($xtype) { | ||||
$xtype = clone $xtype; | $xtype = clone $xtype; | ||||
$xtype->setStorage($xaction); | $xtype->setStorage($xaction); | ||||
if ($xtype->shouldTryMFA($object, $xaction)) { | if ($xtype->shouldTryMFA($object, $xaction)) { | ||||
$try_mfa = true; | $try_mfa = true; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
Show All 30 Lines | private function newMFATransactions( | ||||
array_unshift($xactions, $mfa_xaction); | array_unshift($xactions, $mfa_xaction); | ||||
return $xactions; | return $xactions; | ||||
} | } | ||||
private function getTitleForTextMail( | private function getTitleForTextMail( | ||||
PhabricatorApplicationTransaction $xaction) { | PhabricatorApplicationTransaction $xaction) { | ||||
$type = $xaction->getTransactionType(); | $type = $xaction->getTransactionType(); | ||||
$object = $this->object; | |||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if ($xtype) { | if ($xtype) { | ||||
$xtype = clone $xtype; | $xtype = clone $xtype; | ||||
$xtype->setStorage($xaction); | $xtype->setStorage($xaction); | ||||
$comment = $xtype->getTitleForTextMail(); | $comment = $xtype->getTitleForTextMail(); | ||||
if ($comment !== false) { | if ($comment !== false) { | ||||
return $comment; | return $comment; | ||||
} | } | ||||
} | } | ||||
return $xaction->getTitleForTextMail(); | return $xaction->getTitleForTextMail(); | ||||
} | } | ||||
private function getTitleForHTMLMail( | private function getTitleForHTMLMail( | ||||
PhabricatorApplicationTransaction $xaction) { | PhabricatorApplicationTransaction $xaction) { | ||||
$type = $xaction->getTransactionType(); | $type = $xaction->getTransactionType(); | ||||
$object = $this->object; | |||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if ($xtype) { | if ($xtype) { | ||||
$xtype = clone $xtype; | $xtype = clone $xtype; | ||||
$xtype->setStorage($xaction); | $xtype->setStorage($xaction); | ||||
$comment = $xtype->getTitleForHTMLMail(); | $comment = $xtype->getTitleForHTMLMail(); | ||||
if ($comment !== false) { | if ($comment !== false) { | ||||
return $comment; | return $comment; | ||||
} | } | ||||
} | } | ||||
return $xaction->getTitleForHTMLMail(); | return $xaction->getTitleForHTMLMail(); | ||||
} | } | ||||
private function getBodyForTextMail( | private function getBodyForTextMail( | ||||
PhabricatorApplicationTransaction $xaction) { | PhabricatorApplicationTransaction $xaction) { | ||||
$type = $xaction->getTransactionType(); | $type = $xaction->getTransactionType(); | ||||
$object = $this->object; | |||||
$xtype = $this->getModularTransactionType($type); | $xtype = $this->getModularTransactionType($object, $type); | ||||
if ($xtype) { | if ($xtype) { | ||||
$xtype = clone $xtype; | $xtype = clone $xtype; | ||||
$xtype->setStorage($xaction); | $xtype->setStorage($xaction); | ||||
$comment = $xtype->getBodyForTextMail(); | $comment = $xtype->getBodyForTextMail(); | ||||
if ($comment !== false) { | if ($comment !== false) { | ||||
return $comment; | return $comment; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 110 Lines • Show Last 20 Lines |