diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php index 2754f53662..fa9abaf77d 100644 --- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php +++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php @@ -220,9 +220,10 @@ abstract class PhabricatorApplicationTransactionEditor $this->validateEditParameters($object, $xactions); - $actor = $this->requireActor(); + $xactions = $this->applyImplicitCC($object, $xactions); + $mention_xaction = $this->buildMentionTransaction($object, $xactions); if ($mention_xaction) { $xactions[] = $mention_xaction; @@ -642,6 +643,73 @@ abstract class PhabricatorApplicationTransactionEditor } +/* -( Implicit CCs )------------------------------------------------------- */ + + + /** + * When a user interacts with an object, we might want to add them to CC. + */ + final public function applyImplicitCC( + PhabricatorLiskDAO $object, + array $xactions) { + + if (!($object instanceof PhabricatorSubscribableInterface)) { + // If the object isn't subscribable, we can't CC them. + return $xactions; + } + + $actor_phid = $this->requireActor()->getPHID(); + if ($object->isAutomaticallySubscribed($actor_phid)) { + // If they're auto-subscribed, don't CC them. + return $xactions; + } + + $should_cc = false; + foreach ($xactions as $xaction) { + if ($this->shouldImplyCC($object, $xaction)) { + $should_cc = true; + break; + } + } + + if (!$should_cc) { + // Only some types of actions imply a CC (like adding a comment). + return $xactions; + } + + if ($object->getPHID()) { + $unsub = PhabricatorEdgeQuery::loadDestinationPHIDs( + $object->getPHID(), + PhabricatorEdgeConfig::TYPE_OBJECT_HAS_UNSUBSCRIBER); + $unsub = array_fuse($unsub); + if (isset($unsub[$actor_phid])) { + // If the user has previously unsubscribed from this object explicitly, + // don't implicitly CC them. + return $xactions; + } + } + + $xaction = newv(get_class(head($xactions)), array()); + $xaction->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS); + $xaction->setNewValue(array('+' => array($actor_phid))); + + array_unshift($xactions, $xaction); + + return $xactions; + } + + protected function shouldImplyCC( + PhabricatorLiskDAO $object, + PhabricatorApplicationTransaction $xaction) { + + switch ($xaction->getTransactionType()) { + case PhabricatorTransactions::TYPE_COMMENT: + return true; + default: + return false; + } + } + /* -( Sending Mail )------------------------------------------------------- */