mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Prepare TransactionEditor for silent transactions via bulk edit
Summary: Ref T13042. This adds a "silent" edit mechanism which suppresses feed stories, email, and notifications. The other behaviors here are: - The transactions are marked as "silent" so we can render a hint in the UI in the future to make it clear to users that they aren't missing email. - If the editor uses Herald, mail rules are suppressed so they don't fire incorrectly (this mostly affects "the first time this rule matches, send me an email" rules: without this, they'd match "the first time" on the bulk edit, not send email, then never match again since they already matched). - If the edit queues additional edits, those are applied silently too. This doesn't (or, at least, shouldn't) actually change any behavior since you can't apply silent edits yet. Test Plan: Somewhat theoretical, since this isn't reachable yet. Should get meaningful testing in an upcoming change. Did a bit of var_dump() / debug poking to attempt to verify that nothing too crazy is happening. Viewed and edited objects, no changes in behavior. Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T13042 Differential Revision: https://secure.phabricator.com/D18882
This commit is contained in:
parent
8a5def8e0a
commit
8b12fa6d6e
6 changed files with 90 additions and 11 deletions
|
@ -1356,6 +1356,7 @@ phutil_register_library_map(array(
|
||||||
'HeraldConditionTranscript' => 'applications/herald/storage/transcript/HeraldConditionTranscript.php',
|
'HeraldConditionTranscript' => 'applications/herald/storage/transcript/HeraldConditionTranscript.php',
|
||||||
'HeraldContentSourceField' => 'applications/herald/field/HeraldContentSourceField.php',
|
'HeraldContentSourceField' => 'applications/herald/field/HeraldContentSourceField.php',
|
||||||
'HeraldController' => 'applications/herald/controller/HeraldController.php',
|
'HeraldController' => 'applications/herald/controller/HeraldController.php',
|
||||||
|
'HeraldCoreStateReasons' => 'applications/herald/state/HeraldCoreStateReasons.php',
|
||||||
'HeraldDAO' => 'applications/herald/storage/HeraldDAO.php',
|
'HeraldDAO' => 'applications/herald/storage/HeraldDAO.php',
|
||||||
'HeraldDifferentialAdapter' => 'applications/differential/herald/HeraldDifferentialAdapter.php',
|
'HeraldDifferentialAdapter' => 'applications/differential/herald/HeraldDifferentialAdapter.php',
|
||||||
'HeraldDifferentialDiffAdapter' => 'applications/differential/herald/HeraldDifferentialDiffAdapter.php',
|
'HeraldDifferentialDiffAdapter' => 'applications/differential/herald/HeraldDifferentialDiffAdapter.php',
|
||||||
|
@ -6529,6 +6530,7 @@ phutil_register_library_map(array(
|
||||||
'HeraldConditionTranscript' => 'Phobject',
|
'HeraldConditionTranscript' => 'Phobject',
|
||||||
'HeraldContentSourceField' => 'HeraldField',
|
'HeraldContentSourceField' => 'HeraldField',
|
||||||
'HeraldController' => 'PhabricatorController',
|
'HeraldController' => 'PhabricatorController',
|
||||||
|
'HeraldCoreStateReasons' => 'HeraldStateReasons',
|
||||||
'HeraldDAO' => 'PhabricatorLiskDAO',
|
'HeraldDAO' => 'PhabricatorLiskDAO',
|
||||||
'HeraldDifferentialAdapter' => 'HeraldAdapter',
|
'HeraldDifferentialAdapter' => 'HeraldAdapter',
|
||||||
'HeraldDifferentialDiffAdapter' => 'HeraldDifferentialAdapter',
|
'HeraldDifferentialDiffAdapter' => 'HeraldDifferentialAdapter',
|
||||||
|
|
18
src/applications/herald/state/HeraldCoreStateReasons.php
Normal file
18
src/applications/herald/state/HeraldCoreStateReasons.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class HeraldCoreStateReasons
|
||||||
|
extends HeraldStateReasons {
|
||||||
|
|
||||||
|
const REASON_SILENT = 'core.silent';
|
||||||
|
|
||||||
|
public function explainReason($reason) {
|
||||||
|
$reasons = array(
|
||||||
|
self::REASON_SILENT => pht(
|
||||||
|
'This change applied silently, so mail and other notifications '.
|
||||||
|
'will not be sent.'),
|
||||||
|
);
|
||||||
|
|
||||||
|
return idx($reasons, $reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -68,7 +68,9 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
private $feedNotifyPHIDs = array();
|
private $feedNotifyPHIDs = array();
|
||||||
private $feedRelatedPHIDs = array();
|
private $feedRelatedPHIDs = array();
|
||||||
private $feedShouldPublish = false;
|
private $feedShouldPublish = false;
|
||||||
|
private $mailShouldSend = false;
|
||||||
private $modularTypes;
|
private $modularTypes;
|
||||||
|
private $silent;
|
||||||
|
|
||||||
private $transactionQueue = array();
|
private $transactionQueue = array();
|
||||||
|
|
||||||
|
@ -187,6 +189,15 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
return $this->isPreview;
|
return $this->isPreview;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setIsSilent($silent) {
|
||||||
|
$this->silent = $silent;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsSilent() {
|
||||||
|
return $this->silent;
|
||||||
|
}
|
||||||
|
|
||||||
public function setIsInverseEdgeEditor($is_inverse_edge_editor) {
|
public function setIsInverseEdgeEditor($is_inverse_edge_editor) {
|
||||||
$this->isInverseEdgeEditor = $is_inverse_edge_editor;
|
$this->isInverseEdgeEditor = $is_inverse_edge_editor;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -790,6 +801,10 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
$xaction->setObjectPHID($object->getPHID());
|
$xaction->setObjectPHID($object->getPHID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->getIsSilent()) {
|
||||||
|
$xaction->setIsSilentTransaction(true);
|
||||||
|
}
|
||||||
|
|
||||||
return $xaction;
|
return $xaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1136,15 +1151,22 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
// Editors need to pass into workers.
|
// Editors need to pass into workers.
|
||||||
$object = $this->willPublish($object, $xactions);
|
$object = $this->willPublish($object, $xactions);
|
||||||
|
|
||||||
|
if (!$this->getIsSilent()) {
|
||||||
if ($this->shouldSendMail($object, $xactions)) {
|
if ($this->shouldSendMail($object, $xactions)) {
|
||||||
|
$this->mailShouldSend = true;
|
||||||
$this->mailToPHIDs = $this->getMailTo($object);
|
$this->mailToPHIDs = $this->getMailTo($object);
|
||||||
$this->mailCCPHIDs = $this->getMailCC($object);
|
$this->mailCCPHIDs = $this->getMailCC($object);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->shouldPublishFeedStory($object, $xactions)) {
|
if ($this->shouldPublishFeedStory($object, $xactions)) {
|
||||||
$this->feedShouldPublish = true;
|
$this->feedShouldPublish = true;
|
||||||
$this->feedRelatedPHIDs = $this->getFeedRelatedPHIDs($object, $xactions);
|
$this->feedRelatedPHIDs = $this->getFeedRelatedPHIDs(
|
||||||
$this->feedNotifyPHIDs = $this->getFeedNotifyPHIDs($object, $xactions);
|
$object,
|
||||||
|
$xactions);
|
||||||
|
$this->feedNotifyPHIDs = $this->getFeedNotifyPHIDs(
|
||||||
|
$object,
|
||||||
|
$xactions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PhabricatorWorker::scheduleTask(
|
PhabricatorWorker::scheduleTask(
|
||||||
|
@ -1186,7 +1208,7 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
$this->object = $object;
|
$this->object = $object;
|
||||||
|
|
||||||
$messages = array();
|
$messages = array();
|
||||||
if ($this->shouldSendMail($object, $xactions)) {
|
if ($this->mailShouldSend) {
|
||||||
$messages = $this->buildMail($object, $xactions);
|
$messages = $this->buildMail($object, $xactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3138,6 +3160,16 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
$adapter->setApplicationEmail($this->getApplicationEmail());
|
$adapter->setApplicationEmail($this->getApplicationEmail());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this editor is operating in silent mode, tell Herald that we aren't
|
||||||
|
// going to send any mail. This allows it to skip "the first time this
|
||||||
|
// rule matches, send me an email" rules which would otherwise match even
|
||||||
|
// though we aren't going to send any mail.
|
||||||
|
if ($this->getIsSilent()) {
|
||||||
|
$adapter->setForbiddenAction(
|
||||||
|
HeraldMailableState::STATECONST,
|
||||||
|
HeraldCoreStateReasons::REASON_SILENT);
|
||||||
|
}
|
||||||
|
|
||||||
$xscript = HeraldEngine::loadAndApplyRules($adapter);
|
$xscript = HeraldEngine::loadAndApplyRules($adapter);
|
||||||
|
|
||||||
$this->setHeraldAdapter($adapter);
|
$this->setHeraldAdapter($adapter);
|
||||||
|
@ -3493,6 +3525,7 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
'feedNotifyPHIDs',
|
'feedNotifyPHIDs',
|
||||||
'feedRelatedPHIDs',
|
'feedRelatedPHIDs',
|
||||||
'feedShouldPublish',
|
'feedShouldPublish',
|
||||||
|
'mailShouldSend',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3875,7 +3908,8 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
->setActor($this->getActor())
|
->setActor($this->getActor())
|
||||||
->setContentSource($this->getContentSource())
|
->setContentSource($this->getContentSource())
|
||||||
->setContinueOnNoEffect($this->getContinueOnNoEffect())
|
->setContinueOnNoEffect($this->getContinueOnNoEffect())
|
||||||
->setContinueOnMissingFields($this->getContinueOnMissingFields());
|
->setContinueOnMissingFields($this->getContinueOnMissingFields())
|
||||||
|
->setIsSilent($this->getIsSilent());
|
||||||
|
|
||||||
if ($this->actingAsPHID !== null) {
|
if ($this->actingAsPHID !== null) {
|
||||||
$editor->setActingAsPHID($this->actingAsPHID);
|
$editor->setActingAsPHID($this->actingAsPHID);
|
||||||
|
|
|
@ -158,6 +158,14 @@ abstract class PhabricatorApplicationTransaction
|
||||||
return (bool)$this->getMetadataValue('core.default', false);
|
return (bool)$this->getMetadataValue('core.default', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setIsSilentTransaction($silent) {
|
||||||
|
return $this->setMetadataValue('core.silent', $silent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsSilentTransaction() {
|
||||||
|
return (bool)$this->getMetadataValue('core.silent', false);
|
||||||
|
}
|
||||||
|
|
||||||
public function attachComment(
|
public function attachComment(
|
||||||
PhabricatorApplicationTransactionComment $comment) {
|
PhabricatorApplicationTransactionComment $comment) {
|
||||||
$this->comment = $comment;
|
$this->comment = $comment;
|
||||||
|
@ -1515,6 +1523,12 @@ abstract class PhabricatorApplicationTransaction
|
||||||
if ($apart > (60 * 2)) {
|
if ($apart > (60 * 2)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't group silent and nonsilent transactions together.
|
||||||
|
$is_silent = $this->getIsSilentTransaction();
|
||||||
|
if ($is_silent != $xaction->getIsSilentTransaction()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -423,7 +423,8 @@ class PhabricatorApplicationTransactionView extends AphrontView {
|
||||||
->setUserHandle($xaction->getHandle($xaction->getAuthorPHID()))
|
->setUserHandle($xaction->getHandle($xaction->getAuthorPHID()))
|
||||||
->setIcon($xaction->getIcon())
|
->setIcon($xaction->getIcon())
|
||||||
->setColor($xaction->getColor())
|
->setColor($xaction->getColor())
|
||||||
->setHideCommentOptions($this->getHideCommentOptions());
|
->setHideCommentOptions($this->getHideCommentOptions())
|
||||||
|
->setIsSilent($xaction->getIsSilentTransaction());
|
||||||
|
|
||||||
list($token, $token_removed) = $xaction->getToken();
|
list($token, $token_removed) = $xaction->getToken();
|
||||||
if ($token) {
|
if ($token) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ final class PHUITimelineEventView extends AphrontView {
|
||||||
private $authorPHID;
|
private $authorPHID;
|
||||||
private $badges = array();
|
private $badges = array();
|
||||||
private $pinboardItems = array();
|
private $pinboardItems = array();
|
||||||
|
private $isSilent;
|
||||||
|
|
||||||
public function setAuthorPHID($author_phid) {
|
public function setAuthorPHID($author_phid) {
|
||||||
$this->authorPHID = $author_phid;
|
$this->authorPHID = $author_phid;
|
||||||
|
@ -177,6 +178,15 @@ final class PHUITimelineEventView extends AphrontView {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setIsSilent($is_silent) {
|
||||||
|
$this->isSilent = $is_silent;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIsSilent() {
|
||||||
|
return $this->isSilent;
|
||||||
|
}
|
||||||
|
|
||||||
public function setReallyMajorEvent($me) {
|
public function setReallyMajorEvent($me) {
|
||||||
$this->reallyMajorEvent = $me;
|
$this->reallyMajorEvent = $me;
|
||||||
return $this;
|
return $this;
|
||||||
|
|
Loading…
Reference in a new issue