Differential D20462 Diff 48816 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 971 Lines • ▼ Show 20 Lines | abstract class PhabricatorApplicationTransactionEditor | ||||
| public function getCancelURI() { | public function getCancelURI() { | ||||
| return $this->cancelURI; | return $this->cancelURI; | ||||
| } | } | ||||
| final public function applyTransactions( | final public function applyTransactions( | ||||
| PhabricatorLiskDAO $object, | PhabricatorLiskDAO $object, | ||||
| array $xactions) { | array $xactions) { | ||||
| $is_new = ($object->getPHID() === null); | |||||
| $this->isNewObject = $is_new; | |||||
| $is_preview = $this->getIsPreview(); | |||||
| $read_locking = false; | |||||
| $transaction_open = false; | |||||
| // If we're attempting to apply transactions, lock and reload the object | |||||
| // before we go anywhere. If we don't do this at the very beginning, we | |||||
| // may be looking at an older version of the object when we populate and | |||||
| // filter the transactions. See PHI1165 for an example. | |||||
| if (!$is_preview) { | |||||
| if (!$is_new) { | |||||
| $this->buildOldRecipientLists($object, $xactions); | |||||
| $object->openTransaction(); | |||||
| $transaction_open = true; | |||||
| $object->beginReadLocking(); | |||||
| $read_locking = true; | |||||
| $object->reload(); | |||||
| } | |||||
| } | |||||
| try { | |||||
| $this->object = $object; | $this->object = $object; | ||||
| $this->xactions = $xactions; | $this->xactions = $xactions; | ||||
| $this->isNewObject = ($object->getPHID() === null); | |||||
| $this->validateEditParameters($object, $xactions); | $this->validateEditParameters($object, $xactions); | ||||
| $xactions = $this->newMFATransactions($object, $xactions); | $xactions = $this->newMFATransactions($object, $xactions); | ||||
epriestley: (Maybe the indent code should render an indent change if a line is blank and the adjacent lines… | |||||
jmeadorUnsubmitted Not Done Inline ActionsWould it be too farfetched to consider collapsing indentation changes if the indentation delta is exactly the same throughout the entire section of collapsed code? jmeador: Would it be too farfetched to consider collapsing indentation changes if the indentation delta… | |||||
| $actor = $this->requireActor(); | $actor = $this->requireActor(); | ||||
| // NOTE: Some transaction expansion requires that the edited object be | // NOTE: Some transaction expansion requires that the edited object be | ||||
| // attached. | // attached. | ||||
| foreach ($xactions as $xaction) { | foreach ($xactions as $xaction) { | ||||
| $xaction->attachObject($object); | $xaction->attachObject($object); | ||||
| $xaction->attachViewer($actor); | $xaction->attachViewer($actor); | ||||
| } | } | ||||
| $xactions = $this->expandTransactions($object, $xactions); | $xactions = $this->expandTransactions($object, $xactions); | ||||
| $xactions = $this->expandSupportTransactions($object, $xactions); | $xactions = $this->expandSupportTransactions($object, $xactions); | ||||
| $xactions = $this->combineTransactions($xactions); | $xactions = $this->combineTransactions($xactions); | ||||
| foreach ($xactions as $xaction) { | foreach ($xactions as $xaction) { | ||||
| $xaction = $this->populateTransaction($object, $xaction); | $xaction = $this->populateTransaction($object, $xaction); | ||||
| } | } | ||||
| $is_preview = $this->getIsPreview(); | |||||
| $read_locking = false; | |||||
| $transaction_open = false; | |||||
| if (!$is_preview) { | if (!$is_preview) { | ||||
| $errors = array(); | $errors = array(); | ||||
| $type_map = mgroup($xactions, 'getTransactionType'); | $type_map = mgroup($xactions, 'getTransactionType'); | ||||
| foreach ($this->getTransactionTypes() as $type) { | foreach ($this->getTransactionTypes() as $type) { | ||||
| $type_xactions = idx($type_map, $type, array()); | $type_xactions = idx($type_map, $type, array()); | ||||
| $errors[] = $this->validateTransaction($object, $type, $type_xactions); | $errors[] = $this->validateTransaction( | ||||
| $object, | |||||
| $type, | |||||
| $type_xactions); | |||||
| } | } | ||||
| $errors[] = $this->validateAllTransactions($object, $xactions); | $errors[] = $this->validateAllTransactions($object, $xactions); | ||||
| $errors[] = $this->validateTransactionsWithExtensions($object, $xactions); | $errors[] = $this->validateTransactionsWithExtensions( | ||||
| $object, | |||||
| $xactions); | |||||
| $errors = array_mergev($errors); | $errors = array_mergev($errors); | ||||
| $continue_on_missing = $this->getContinueOnMissingFields(); | $continue_on_missing = $this->getContinueOnMissingFields(); | ||||
| foreach ($errors as $key => $error) { | foreach ($errors as $key => $error) { | ||||
| if ($continue_on_missing && $error->getIsMissingFieldError()) { | if ($continue_on_missing && $error->getIsMissingFieldError()) { | ||||
| unset($errors[$key]); | unset($errors[$key]); | ||||
| } | } | ||||
| } | } | ||||
| if ($errors) { | if ($errors) { | ||||
| throw new PhabricatorApplicationTransactionValidationException($errors); | throw new PhabricatorApplicationTransactionValidationException( | ||||
| $errors); | |||||
| } | } | ||||
| if ($this->raiseWarnings) { | if ($this->raiseWarnings) { | ||||
| $warnings = array(); | $warnings = array(); | ||||
| foreach ($xactions as $xaction) { | foreach ($xactions as $xaction) { | ||||
| if ($this->hasWarnings($object, $xaction)) { | if ($this->hasWarnings($object, $xaction)) { | ||||
| $warnings[] = $xaction; | $warnings[] = $xaction; | ||||
| } | } | ||||
| } | } | ||||
| if ($warnings) { | if ($warnings) { | ||||
| throw new PhabricatorApplicationTransactionWarningException( | throw new PhabricatorApplicationTransactionWarningException( | ||||
| $warnings); | $warnings); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| foreach ($xactions as $xaction) { | foreach ($xactions as $xaction) { | ||||
| $this->adjustTransactionValues($object, $xaction); | $this->adjustTransactionValues($object, $xaction); | ||||
| } | } | ||||
| // Now that we've merged and combined transactions, check for required | // Now that we've merged and combined transactions, check for required | ||||
| // capabilities. Note that we're doing this before filtering | // capabilities. Note that we're doing this before filtering | ||||
| // transactions: if you try to apply an edit which you do not have | // transactions: if you try to apply an edit which you do not have | ||||
| // permission to apply, we want to give you a permissions error even | // permission to apply, we want to give you a permissions error even | ||||
| // if the edit would have no effect. | // if the edit would have no effect. | ||||
| $this->applyCapabilityChecks($object, $xactions); | $this->applyCapabilityChecks($object, $xactions); | ||||
| $xactions = $this->filterTransactions($object, $xactions); | $xactions = $this->filterTransactions($object, $xactions); | ||||
| if (!$is_preview) { | if (!$is_preview) { | ||||
| $this->hasRequiredMFA = true; | $this->hasRequiredMFA = true; | ||||
| if ($this->getShouldRequireMFA()) { | if ($this->getShouldRequireMFA()) { | ||||
| $this->requireMFA($object, $xactions); | $this->requireMFA($object, $xactions); | ||||
| } | } | ||||
| if ($object->getID()) { | |||||
| $this->buildOldRecipientLists($object, $xactions); | |||||
| $object->openTransaction(); | |||||
| $transaction_open = true; | |||||
| $object->beginReadLocking(); | |||||
| $read_locking = true; | |||||
| $object->reload(); | |||||
| } | |||||
| if ($this->shouldApplyInitialEffects($object, $xactions)) { | if ($this->shouldApplyInitialEffects($object, $xactions)) { | ||||
| if (!$transaction_open) { | if (!$transaction_open) { | ||||
| $object->openTransaction(); | $object->openTransaction(); | ||||
| $transaction_open = true; | $transaction_open = true; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| try { | |||||
| if ($this->shouldApplyInitialEffects($object, $xactions)) { | if ($this->shouldApplyInitialEffects($object, $xactions)) { | ||||
| $this->applyInitialEffects($object, $xactions); | $this->applyInitialEffects($object, $xactions); | ||||
| } | } | ||||
| // TODO: Once everything is on EditEngine, just use getIsNewObject() to | // TODO: Once everything is on EditEngine, just use getIsNewObject() to | ||||
| // figure this out instead. | // figure this out instead. | ||||
| $mark_as_create = false; | $mark_as_create = false; | ||||
| $create_type = PhabricatorTransactions::TYPE_CREATE; | $create_type = PhabricatorTransactions::TYPE_CREATE; | ||||
| ▲ Show 20 Lines • Show All 4,156 Lines • Show Last 20 Lines | |||||
(Maybe the indent code should render an indent change if a line is blank and the adjacent lines both have an indentation marker.)