diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -335,7 +335,6 @@ 'DifferentialBlameRevisionFieldSpecification' => 'applications/differential/field/specification/DifferentialBlameRevisionFieldSpecification.php', 'DifferentialBranchField' => 'applications/differential/customfield/DifferentialBranchField.php', 'DifferentialBranchFieldSpecification' => 'applications/differential/field/specification/DifferentialBranchFieldSpecification.php', - 'DifferentialCCWelcomeMail' => 'applications/differential/mail/DifferentialCCWelcomeMail.php', 'DifferentialCCsFieldSpecification' => 'applications/differential/field/specification/DifferentialCCsFieldSpecification.php', 'DifferentialCapabilityDefaultView' => 'applications/differential/capability/DifferentialCapabilityDefaultView.php', 'DifferentialChangeType' => 'applications/differential/constants/DifferentialChangeType.php', @@ -382,7 +381,6 @@ 'DifferentialDependsOnField' => 'applications/differential/customfield/DifferentialDependsOnField.php', 'DifferentialDependsOnFieldSpecification' => 'applications/differential/field/specification/DifferentialDependsOnFieldSpecification.php', 'DifferentialDiff' => 'applications/differential/storage/DifferentialDiff.php', - 'DifferentialDiffContentMail' => 'applications/differential/mail/DifferentialDiffContentMail.php', 'DifferentialDiffCreateController' => 'applications/differential/controller/DifferentialDiffCreateController.php', 'DifferentialDiffProperty' => 'applications/differential/storage/DifferentialDiffProperty.php', 'DifferentialDiffQuery' => 'applications/differential/query/DifferentialDiffQuery.php', @@ -436,7 +434,6 @@ 'DifferentialMailPhase' => 'applications/differential/constants/DifferentialMailPhase.php', 'DifferentialManiphestTasksField' => 'applications/differential/customfield/DifferentialManiphestTasksField.php', 'DifferentialManiphestTasksFieldSpecification' => 'applications/differential/field/specification/DifferentialManiphestTasksFieldSpecification.php', - 'DifferentialNewDiffMail' => 'applications/differential/mail/DifferentialNewDiffMail.php', 'DifferentialPHIDTypeDiff' => 'applications/differential/phid/DifferentialPHIDTypeDiff.php', 'DifferentialPHIDTypeRevision' => 'applications/differential/phid/DifferentialPHIDTypeRevision.php', 'DifferentialParseCacheGarbageCollector' => 'applications/differential/garbagecollector/DifferentialParseCacheGarbageCollector.php', @@ -456,7 +453,6 @@ 'DifferentialResultsTableView' => 'applications/differential/view/DifferentialResultsTableView.php', 'DifferentialRevertPlanField' => 'applications/differential/customfield/DifferentialRevertPlanField.php', 'DifferentialRevertPlanFieldSpecification' => 'applications/differential/field/specification/DifferentialRevertPlanFieldSpecification.php', - 'DifferentialReviewRequestMail' => 'applications/differential/mail/DifferentialReviewRequestMail.php', 'DifferentialReviewedByField' => 'applications/differential/customfield/DifferentialReviewedByField.php', 'DifferentialReviewedByFieldSpecification' => 'applications/differential/field/specification/DifferentialReviewedByFieldSpecification.php', 'DifferentialReviewer' => 'applications/differential/storage/DifferentialReviewer.php', @@ -2910,7 +2906,6 @@ 'DifferentialBlameRevisionFieldSpecification' => 'DifferentialFieldSpecification', 'DifferentialBranchField' => 'DifferentialCustomField', 'DifferentialBranchFieldSpecification' => 'DifferentialFieldSpecification', - 'DifferentialCCWelcomeMail' => 'DifferentialReviewRequestMail', 'DifferentialCCsFieldSpecification' => 'DifferentialFieldSpecification', 'DifferentialCapabilityDefaultView' => 'PhabricatorPolicyCapability', 'DifferentialChangeset' => 'DifferentialDAO', @@ -2957,7 +2952,6 @@ 1 => 'PhabricatorPolicyInterface', 2 => 'HarbormasterBuildableInterface', ), - 'DifferentialDiffContentMail' => 'DifferentialMail', 'DifferentialDiffCreateController' => 'DifferentialController', 'DifferentialDiffProperty' => 'DifferentialDAO', 'DifferentialDiffQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', @@ -3004,7 +2998,6 @@ 'DifferentialMail' => 'PhabricatorMail', 'DifferentialManiphestTasksField' => 'DifferentialCoreCustomField', 'DifferentialManiphestTasksFieldSpecification' => 'DifferentialFieldSpecification', - 'DifferentialNewDiffMail' => 'DifferentialReviewRequestMail', 'DifferentialPHIDTypeDiff' => 'PhabricatorPHIDType', 'DifferentialPHIDTypeRevision' => 'PhabricatorPHIDType', 'DifferentialParseCacheGarbageCollector' => 'PhabricatorGarbageCollector', @@ -3023,7 +3016,6 @@ 'DifferentialResultsTableView' => 'AphrontView', 'DifferentialRevertPlanField' => 'DifferentialStoredCustomField', 'DifferentialRevertPlanFieldSpecification' => 'DifferentialFieldSpecification', - 'DifferentialReviewRequestMail' => 'DifferentialMail', 'DifferentialReviewedByField' => 'DifferentialCoreCustomField', 'DifferentialReviewedByFieldSpecification' => 'DifferentialFieldSpecification', 'DifferentialReviewersField' => 'DifferentialCoreCustomField', diff --git a/src/applications/differential/editor/DifferentialTransactionEditor.php b/src/applications/differential/editor/DifferentialTransactionEditor.php --- a/src/applications/differential/editor/DifferentialTransactionEditor.php +++ b/src/applications/differential/editor/DifferentialTransactionEditor.php @@ -1019,6 +1019,46 @@ pht('REVISION DETAIL'), PhabricatorEnv::getProductionURI('/D'.$object->getID())); + $update_xaction = null; + foreach ($xactions as $xaction) { + switch ($xaction->getTransactionType()) { + case DifferentialTransaction::TYPE_UPDATE: + $update_xaction = $xaction; + break; + } + } + + if ($update_xaction) { + $diff = $this->loadDiff($update_xaction->getNewValue(), true); + + $body->addTextSection( + pht('AFFECTED FILES'), + $this->renderAffectedFilesForMail($diff)); + + $config_key_inline = 'metamta.differential.inline-patches'; + $config_inline = PhabricatorEnv::getEnvConfig($config_key_inline); + + $config_key_attach = 'metamta.differential.attach-patches'; + $config_attach = PhabricatorEnv::getEnvConfig($config_key_attach); + + if ($config_inline || $config_attach) { + $patch = $this->renderPatchForMail($diff); + $lines = count(phutil_split_lines($patch)); + + if ($config_inline && ($lines <= $config_inline)) { + $body->addTextSection( + pht('CHANGE DETAILS'), + $patch); + } + + if ($config_attach) { + $name = pht('D%s.%s.patch', $object->getID(), $diff->getID()); + $mime_type = 'text/x-patch; charset=utf-8'; + $body->addAttachment( + new PhabricatorMetaMTAAttachment($patch, $name, $mime_type)); + } + } + } return $body; } @@ -1491,4 +1531,30 @@ } } + private function renderAffectedFilesForMail(DifferentialDiff $diff) { + $changesets = $diff->getChangesets(); + + $filenames = mpull($changesets, 'getDisplayFilename'); + sort($filenames); + + $count = count($filenames); + $max = 250; + if ($count > $max) { + $filenames = array_slice($filenames, 0, $max); + $filenames[] = pht('(%d more files...)', ($count - $max)); + } + + return implode("\n", $filenames); + } + + private function renderPatchForMail(DifferentialDiff $diff) { + $format = PhabricatorEnv::getEnvConfig('metamta.differential.patch-format'); + + return id(new DifferentialRawDiffRenderer()) + ->setViewer($this->getActor()) + ->setFormat($format) + ->setChangesets($diff->getChangesets()) + ->buildPatch(); + } + } diff --git a/src/applications/differential/field/specification/DifferentialArcanistProjectFieldSpecification.php b/src/applications/differential/field/specification/DifferentialArcanistProjectFieldSpecification.php --- a/src/applications/differential/field/specification/DifferentialArcanistProjectFieldSpecification.php +++ b/src/applications/differential/field/specification/DifferentialArcanistProjectFieldSpecification.php @@ -35,18 +35,4 @@ return $diff->getArcanistProjectPHID(); } - public function renderValueForMail($phase) { - $diff = $this->getRevision()->loadActiveDiff(); - if ($diff) { - $phid = $diff->getArcanistProjectPHID(); - if ($phid) { - $handle = id(new PhabricatorHandleQuery()) - ->setViewer($this->getUser()) - ->withPHIDs(array($phid)) - ->executeOne(); - return "ARCANIST PROJECT\n ".$handle->getName(); - } - } - } - } diff --git a/src/applications/differential/field/specification/DifferentialBranchFieldSpecification.php b/src/applications/differential/field/specification/DifferentialBranchFieldSpecification.php --- a/src/applications/differential/field/specification/DifferentialBranchFieldSpecification.php +++ b/src/applications/differential/field/specification/DifferentialBranchFieldSpecification.php @@ -31,16 +31,4 @@ return $this->getBranchOrBookmarkDescription($diff); } - public function renderValueForMail($phase) { - $diff = $this->getRevision()->loadActiveDiff(); - if ($diff) { - $description = $this->getBranchOrBookmarkDescription($diff); - if ($description) { - return "BRANCH\n {$description}"; - } - } - - return null; - } - } diff --git a/src/applications/differential/field/specification/DifferentialCommitsFieldSpecification.php b/src/applications/differential/field/specification/DifferentialCommitsFieldSpecification.php --- a/src/applications/differential/field/specification/DifferentialCommitsFieldSpecification.php +++ b/src/applications/differential/field/specification/DifferentialCommitsFieldSpecification.php @@ -34,30 +34,4 @@ return $revision->getCommitPHIDs(); } - public function renderValueForMail($phase) { - $revision = $this->getRevision(); - - if ($revision->getStatus() != ArcanistDifferentialRevisionStatus::CLOSED) { - return null; - } - - $phids = $revision->loadCommitPHIDs(); - if (!$phids) { - return null; - } - - $body = array(); - $handles = id(new PhabricatorHandleQuery()) - ->setViewer($this->getUser()) - ->withPHIDs($phids) - ->execute(); - $body[] = pht('COMMIT(S)', count($handles)); - - foreach ($handles as $handle) { - $body[] = ' '.PhabricatorEnv::getProductionURI($handle->getURI()); - } - - return implode("\n", $body); - } - } diff --git a/src/applications/differential/field/specification/DifferentialFieldSpecification.php b/src/applications/differential/field/specification/DifferentialFieldSpecification.php --- a/src/applications/differential/field/specification/DifferentialFieldSpecification.php +++ b/src/applications/differential/field/specification/DifferentialFieldSpecification.php @@ -385,23 +385,6 @@ } -/* -( Extending the E-mail Interface )------------------------------------- */ - - - /** - * Return plain text to render in e-mail messages. The text may span - * multiple lines. - * - * @return int One of DifferentialMailPhase constants. - * @return string|null Plain text, or null for no message. - * - * @task mail - */ - public function renderValueForMail($phase) { - return null; - } - - /* -( Extending the Conduit Interface )------------------------------------ */ diff --git a/src/applications/differential/field/specification/DifferentialManiphestTasksFieldSpecification.php b/src/applications/differential/field/specification/DifferentialManiphestTasksFieldSpecification.php --- a/src/applications/differential/field/specification/DifferentialManiphestTasksFieldSpecification.php +++ b/src/applications/differential/field/specification/DifferentialManiphestTasksFieldSpecification.php @@ -127,32 +127,4 @@ return $task_phids; } - public function renderValueForMail($phase) { - if ($phase == DifferentialMailPhase::COMMENT) { - return null; - } - - if (!$this->maniphestTasks) { - return null; - } - - $handles = id(new PhabricatorHandleQuery()) - ->setViewer($this->getUser()) - ->withPHIDs($this->maniphestTasks) - ->execute(); - $body = array(); - $body[] = 'MANIPHEST TASKS'; - foreach ($handles as $handle) { - $body[] = ' '.PhabricatorEnv::getProductionURI($handle->getURI()); - } - return implode("\n", $body); - } - - public function getCommitMessageTips() { - return array( - 'Use "Fixes T123" in your summary to mark that the current '. - 'revision completes a given task.' - ); - } - } diff --git a/src/applications/differential/field/specification/DifferentialReviewersFieldSpecification.php b/src/applications/differential/field/specification/DifferentialReviewersFieldSpecification.php --- a/src/applications/differential/field/specification/DifferentialReviewersFieldSpecification.php +++ b/src/applications/differential/field/specification/DifferentialReviewersFieldSpecification.php @@ -173,25 +173,4 @@ return $revision->getReviewers(); } - public function renderValueForMail($phase) { - if ($phase == DifferentialMailPhase::COMMENT) { - return null; - } - - if (!$this->reviewers) { - return null; - } - - $handles = id(new PhabricatorHandleQuery()) - ->setViewer($this->getUser()) - ->withPHIDs($this->reviewers) - ->execute(); - $handles = array_select_keys( - $handles, - array($this->getRevision()->getPrimaryReviewer())) + $handles; - - $names = mpull($handles, 'getObjectName'); - return 'Reviewers: '.implode(', ', $names); - } - } diff --git a/src/applications/differential/field/specification/DifferentialRevisionIDFieldSpecification.php b/src/applications/differential/field/specification/DifferentialRevisionIDFieldSpecification.php --- a/src/applications/differential/field/specification/DifferentialRevisionIDFieldSpecification.php +++ b/src/applications/differential/field/specification/DifferentialRevisionIDFieldSpecification.php @@ -96,25 +96,4 @@ return 'D'.$revision->getID(); } - public function renderValueForMail($phase) { - $body = array(); - $body[] = 'REVISION DETAIL'; - $body[] = ' '.PhabricatorEnv::getProductionURI('/D'.$this->id); - - if ($phase == DifferentialMailPhase::UPDATE) { - $diffs = id(new DifferentialDiff())->loadAllWhere( - 'revisionID = %d ORDER BY id DESC LIMIT 2', - $this->id); - if (count($diffs) == 2) { - list($new, $old) = array_values(mpull($diffs, 'getID')); - $body[] = null; - $body[] = 'CHANGE SINCE LAST DIFF'; - $body[] = ' '.PhabricatorEnv::getProductionURI( - "/D{$this->id}?vs={$old}&id={$new}#toc"); - } - } - - return implode("\n", $body); - } - } diff --git a/src/applications/differential/field/specification/DifferentialSummaryFieldSpecification.php b/src/applications/differential/field/specification/DifferentialSummaryFieldSpecification.php --- a/src/applications/differential/field/specification/DifferentialSummaryFieldSpecification.php +++ b/src/applications/differential/field/specification/DifferentialSummaryFieldSpecification.php @@ -67,18 +67,6 @@ return (string)$value; } - public function renderValueForMail($phase) { - if ($phase != DifferentialMailPhase::WELCOME) { - return null; - } - - if ($this->summary == '') { - return null; - } - - return $this->summary; - } - public function shouldAddToSearchIndex() { return true; } diff --git a/src/applications/differential/field/specification/DifferentialTestPlanFieldSpecification.php b/src/applications/differential/field/specification/DifferentialTestPlanFieldSpecification.php --- a/src/applications/differential/field/specification/DifferentialTestPlanFieldSpecification.php +++ b/src/applications/differential/field/specification/DifferentialTestPlanFieldSpecification.php @@ -91,18 +91,6 @@ return $value; } - public function renderValueForMail($phase) { - if ($phase != DifferentialMailPhase::WELCOME) { - return null; - } - - if ($this->plan == '') { - return null; - } - - return "TEST PLAN\n".preg_replace('/^/m', ' ', $this->plan); - } - public function shouldAddToSearchIndex() { return true; } diff --git a/src/applications/differential/mail/DifferentialCCWelcomeMail.php b/src/applications/differential/mail/DifferentialCCWelcomeMail.php deleted file mode 100644 --- a/src/applications/differential/mail/DifferentialCCWelcomeMail.php +++ /dev/null @@ -1,22 +0,0 @@ -getActorName(); - $name = $this->getRevision()->getTitle(); - $body = array(); - - $body[] = "{$actor} added you to the CC list for the revision \"{$name}\"."; - $body[] = null; - - $body[] = $this->renderReviewRequestBody(); - - return implode("\n", $body); - } -} diff --git a/src/applications/differential/mail/DifferentialDiffContentMail.php b/src/applications/differential/mail/DifferentialDiffContentMail.php deleted file mode 100644 --- a/src/applications/differential/mail/DifferentialDiffContentMail.php +++ /dev/null @@ -1,19 +0,0 @@ -setRevision($revision); - $this->content = $content; - } - - protected function renderVaryPrefix() { - return '[Content]'; - } - - protected function renderBody() { - return $this->content; - } -} diff --git a/src/applications/differential/mail/DifferentialMail.php b/src/applications/differential/mail/DifferentialMail.php --- a/src/applications/differential/mail/DifferentialMail.php +++ b/src/applications/differential/mail/DifferentialMail.php @@ -2,307 +2,6 @@ abstract class DifferentialMail extends PhabricatorMail { - protected $to = array(); - protected $cc = array(); - protected $excludePHIDs = array(); - - protected $actorHandle; - - protected $revision; - protected $comments; - protected $changesets; - protected $inlineComments; - protected $isFirstMailAboutRevision; - protected $isFirstMailToRecipients; - protected $heraldTranscriptURI; - protected $heraldRulesHeader; - protected $replyHandler; - protected $parentMessageID; - - private $rawMail; - - public function getRawMail() { - if (!$this->rawMail) { - throw new Exception("Call send() before getRawMail()!"); - } - return $this->rawMail; - } - - protected function renderSubject() { - $revision = $this->getRevision(); - $title = $revision->getTitle(); - $id = $revision->getID(); - return "D{$id}: {$title}"; - } - - abstract protected function renderVaryPrefix(); - abstract protected function renderBody(); - - public function setActorHandle($actor_handle) { - $this->actorHandle = $actor_handle; - return $this; - } - - public function getActorHandle() { - return $this->actorHandle; - } - - protected function getActorName() { - $handle = $this->getActorHandle(); - if ($handle) { - return $handle->getName(); - } - return '???'; - } - - public function setParentMessageID($parent_message_id) { - $this->parentMessageID = $parent_message_id; - return $this; - } - - public function setXHeraldRulesHeader($header) { - $this->heraldRulesHeader = $header; - return $this; - } - - public function send() { - $to_phids = $this->getToPHIDs(); - if (!$to_phids) { - throw new Exception('No "To:" users provided!'); - } - - $cc_phids = $this->getCCPHIDs(); - $attachments = $this->buildAttachments(); - - $template = new PhabricatorMetaMTAMail(); - $actor_handle = $this->getActorHandle(); - $reply_handler = $this->getReplyHandler(); - - if ($actor_handle) { - $template->setFrom($actor_handle->getPHID()); - } - - $template - ->setIsHTML($this->shouldMarkMailAsHTML()) - ->setParentMessageID($this->parentMessageID) - ->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs()) - ->addHeader('Thread-Topic', $this->getThreadTopic()); - - $template->setAttachments($attachments); - - $template->setThreadID( - $this->getThreadID(), - $this->isFirstMailAboutRevision()); - - if ($this->heraldRulesHeader) { - $template->addHeader('X-Herald-Rules', $this->heraldRulesHeader); - } - - $revision = $this->revision; - if ($revision) { - if ($revision->getAuthorPHID()) { - $template->addHeader( - 'X-Differential-Author', - '<'.$revision->getAuthorPHID().'>'); - } - - $reviewer_phids = $revision->getReviewers(); - if ($reviewer_phids) { - // Add several headers to support e-mail clients which are not able to - // create rules using regular expressions or wildcards (namely Outlook). - $template->addPHIDHeaders('X-Differential-Reviewer', $reviewer_phids); - - // Add it also as a list to allow matching of the first reviewer and - // also for backwards compatibility. - $template->addHeader( - 'X-Differential-Reviewers', - '<'.implode('>, <', $reviewer_phids).'>'); - } - - if ($cc_phids) { - $template->addPHIDHeaders('X-Differential-CC', $cc_phids); - $template->addHeader( - 'X-Differential-CCs', - '<'.implode('>, <', $cc_phids).'>'); - - // Determine explicit CCs (those added by humans) and put them in a - // header so users can differentiate between Herald CCs and human CCs. - - $relation_subscribed = DifferentialRevision::RELATION_SUBSCRIBED; - $raw = $revision->getRawRelations($relation_subscribed); - - $reason_phids = ipull($raw, 'reasonPHID'); - $reason_handles = id(new PhabricatorHandleQuery()) - ->setViewer($this->getActor()) - ->withPHIDs($reason_phids) - ->execute(); - - $explicit_cc = array(); - foreach ($raw as $relation) { - if (!$relation['reasonPHID']) { - continue; - } - $type = $reason_handles[$relation['reasonPHID']]->getType(); - if ($type == PhabricatorPeoplePHIDTypeUser::TYPECONST) { - $explicit_cc[] = $relation['objectPHID']; - } - } - - if ($explicit_cc) { - $template->addPHIDHeaders('X-Differential-Explicit-CC', $explicit_cc); - $template->addHeader( - 'X-Differential-Explicit-CCs', - '<'.implode('>, <', $explicit_cc).'>'); - } - } - } - - $template->setIsBulk(true); - $template->setRelatedPHID($this->getRevision()->getPHID()); - - $mailtags = $this->getMailTags(); - if ($mailtags) { - $template->setMailTags($mailtags); - } - - $phids = array(); - foreach ($to_phids as $phid) { - $phids[$phid] = true; - } - foreach ($cc_phids as $phid) { - $phids[$phid] = true; - } - $phids = array_keys($phids); - - $handles = id(new PhabricatorHandleQuery()) - ->setViewer($this->getActor()) - ->withPHIDs($phids) - ->execute(); - $objects = id(new PhabricatorObjectQuery()) - ->setViewer($this->getActor()) - ->withPHIDs($phids) - ->execute(); - - $to_handles = array_select_keys($handles, $to_phids); - $cc_handles = array_select_keys($handles, $cc_phids); - - $this->prepareBody(); - - $this->rawMail = clone $template; - $this->rawMail->addTos($to_phids); - $this->rawMail->addCCs($cc_phids); - - $mails = $reply_handler->multiplexMail($template, $to_handles, $cc_handles); - - $original_translator = PhutilTranslator::getInstance(); - if (!PhabricatorMetaMTAMail::shouldMultiplexAllMail()) { - $translation = PhabricatorEnv::newObjectFromConfig( - 'translation.provider'); - $translator = id(new PhutilTranslator()) - ->setLanguage($translation->getLanguage()) - ->addTranslations($translation->getTranslations()); - } - - try { - foreach ($mails as $mail) { - if (PhabricatorMetaMTAMail::shouldMultiplexAllMail()) { - $translation = newv($mail->getTranslation($objects), array()); - $translator = id(new PhutilTranslator()) - ->setLanguage($translation->getLanguage()) - ->addTranslations($translation->getTranslations()); - PhutilTranslator::setInstance($translator); - } - - $body = - $this->buildBody()."\n". - $reply_handler->getRecipientsSummary($to_handles, $cc_handles); - - $mail - ->setSubject($this->renderSubject()) - ->setSubjectPrefix($this->getSubjectPrefix()) - ->setVarySubjectPrefix($this->renderVaryPrefix()) - ->setBody($body); - - $event = new PhabricatorEvent( - PhabricatorEventType::TYPE_DIFFERENTIAL_WILLSENDMAIL, - array( - 'mail' => $mail, - ) - ); - PhutilEventEngine::dispatchEvent($event); - $mail = $event->getValue('mail'); - - $mail->saveAndSend(); - } - - } catch (Exception $ex) { - PhutilTranslator::setInstance($original_translator); - throw $ex; - } - - PhutilTranslator::setInstance($original_translator); - - return $this; - } - - protected function getMailTags() { - return array(); - } - - protected function getSubjectPrefix() { - return PhabricatorEnv::getEnvConfig('metamta.differential.subject-prefix'); - } - - protected function shouldMarkMailAsHTML() { - return false; - } - - /** - * @{method:buildBody} is called once for each e-mail recipient to allow - * translating text to his language. This method can be used to load data that - * don't need translation and use them later in @{method:buildBody}. - * - * @param - * @return - */ - protected function prepareBody() { - } - - protected function buildBody() { - $main_body = $this->renderBody(); - - $body = new PhabricatorMetaMTAMailBody(); - $body->addRawSection($main_body); - - $reply_handler = $this->getReplyHandler(); - $body->addReplySection($reply_handler->getReplyHandlerInstructions()); - - if ($this->getHeraldTranscriptURI() && $this->isFirstMailToRecipients()) { - $xscript_uri = $this->getHeraldTranscriptURI(); - $body->addHeraldSection($xscript_uri); - } - - return $body->render(); - } - - /** - * You can override this method in a subclass and return array of attachments - * to be sent with the email. Each attachment is an instance of - * PhabricatorMetaMTAAttachment. - */ - protected function buildAttachments() { - return array(); - } - - public function getReplyHandler() { - if (!$this->replyHandler) { - $this->replyHandler = - self::newReplyHandlerForRevision($this->getRevision()); - } - - return $this->replyHandler; - } - public static function newReplyHandlerForRevision( DifferentialRevision $revision) { @@ -313,146 +12,4 @@ return $reply_handler; } - - protected function formatText($text) { - $text = explode("\n", rtrim($text)); - foreach ($text as &$line) { - $line = rtrim(' '.$line); - } - unset($line); - return implode("\n", $text); - } - - public function setExcludeMailRecipientPHIDs(array $exclude) { - $this->excludePHIDs = $exclude; - return $this; - } - - public function getExcludeMailRecipientPHIDs() { - return $this->excludePHIDs; - } - - public function setToPHIDs(array $to) { - $this->to = $to; - return $this; - } - - public function setCCPHIDs(array $cc) { - $this->cc = $cc; - return $this; - } - - protected function getToPHIDs() { - return $this->to; - } - - protected function getCCPHIDs() { - return $this->cc; - } - - public function setRevision($revision) { - $this->revision = $revision; - return $this; - } - - public function getRevision() { - return $this->revision; - } - - protected function getThreadID() { - $phid = $this->getRevision()->getPHID(); - return "differential-rev-{$phid}-req"; - } - - protected function getThreadTopic() { - $id = $this->getRevision()->getID(); - $title = $this->getRevision()->getOriginalTitle(); - return "D{$id}: {$title}"; - } - - public function setComments(array $comments) { - $this->comments = $comments; - return $this; - } - - public function getComments() { - return $this->comments; - } - - public function setChangesets($changesets) { - $this->changesets = $changesets; - return $this; - } - - public function getChangesets() { - return $this->changesets; - } - - public function setInlineComments(array $inline_comments) { - assert_instances_of($inline_comments, 'DifferentialTransaction'); - $this->inlineComments = $inline_comments; - return $this; - } - - public function getInlineComments() { - return $this->inlineComments; - } - - protected function renderAuxFields($phase) { - $selector = DifferentialFieldSelector::newSelector(); - $aux_fields = $selector->sortFieldsForMail( - $selector->getFieldSpecifications()); - - $body = array(); - foreach ($aux_fields as $field) { - $field->setUser($this->getActor()); - $field->setRevision($this->getRevision()); - // TODO: Introduce and use getRequiredHandlePHIDsForMail() and load all - // handles in prepareBody(). - $text = $field->renderValueForMail($phase); - if ($text !== null) { - $body[] = $text; - $body[] = null; - } - } - - return implode("\n", $body); - } - - public function setIsFirstMailToRecipients($first) { - $this->isFirstMailToRecipients = $first; - return $this; - } - - public function isFirstMailToRecipients() { - return $this->isFirstMailToRecipients; - } - - public function setIsFirstMailAboutRevision($first) { - $this->isFirstMailAboutRevision = $first; - return $this; - } - - public function isFirstMailAboutRevision() { - return $this->isFirstMailAboutRevision; - } - - public function setHeraldTranscriptURI($herald_transcript_uri) { - $this->heraldTranscriptURI = $herald_transcript_uri; - return $this; - } - - public function getHeraldTranscriptURI() { - return $this->heraldTranscriptURI; - } - - protected function renderHandleList(array $handles, array $phids) { - assert_instances_of($handles, 'PhabricatorObjectHandle'); - $names = array(); - foreach ($phids as $phid) { - $names[] = $handles[$phid]->getName(); - } - return implode(', ', $names); - } - } diff --git a/src/applications/differential/mail/DifferentialNewDiffMail.php b/src/applications/differential/mail/DifferentialNewDiffMail.php deleted file mode 100644 --- a/src/applications/differential/mail/DifferentialNewDiffMail.php +++ /dev/null @@ -1,37 +0,0 @@ -getRevision(); - $line_count = $revision->getLineCount(); - $lines = pht('%d line(s)', $line_count); - - if ($this->isFirstMailToRecipients()) { - $verb = 'Request'; - } else { - $verb = 'Updated'; - } - - return "[{$verb}, {$lines}]"; - } - - protected function renderBody() { - $actor = $this->getActorName(); - - $name = $this->getRevision()->getTitle(); - - $body = array(); - - if ($this->isFirstMailToRecipients()) { - $body[] = "{$actor} requested code review of \"{$name}\"."; - } else { - $body[] = "{$actor} updated the revision \"{$name}\"."; - } - $body[] = null; - - $body[] = $this->renderReviewRequestBody(); - - return implode("\n", $body); - } -} diff --git a/src/applications/differential/mail/DifferentialReviewRequestMail.php b/src/applications/differential/mail/DifferentialReviewRequestMail.php deleted file mode 100644 --- a/src/applications/differential/mail/DifferentialReviewRequestMail.php +++ /dev/null @@ -1,129 +0,0 @@ -commentText = $comment_text; - return $this; - } - - public function getCommentText() { - return $this->commentText; - } - - public function __construct( - DifferentialRevision $revision, - PhabricatorObjectHandle $actor, - array $changesets) { - assert_instances_of($changesets, 'DifferentialChangeset'); - - $this->setRevision($revision); - $this->setActorHandle($actor); - $this->setChangesets($changesets); - } - - protected function prepareBody() { - parent::prepareBody(); - - $inline_max_length = PhabricatorEnv::getEnvConfig( - 'metamta.differential.inline-patches'); - if ($inline_max_length) { - $patch = $this->buildPatch(); - if (count(explode("\n", $patch)) <= $inline_max_length) { - $this->patch = $patch; - } - } - } - - protected function renderReviewRequestBody() { - $revision = $this->getRevision(); - - $body = array(); - if (!$this->isFirstMailToRecipients()) { - if (strlen($this->getCommentText())) { - $body[] = $this->formatText($this->getCommentText()); - $body[] = null; - } - } - - $phase = ($this->isFirstMailToRecipients() ? - DifferentialMailPhase::WELCOME : - DifferentialMailPhase::UPDATE); - $body[] = $this->renderAuxFields($phase); - - $changesets = $this->getChangesets(); - if ($changesets) { - $body[] = 'AFFECTED FILES'; - $max = self::MAX_AFFECTED_FILES; - foreach (array_values($changesets) as $i => $changeset) { - if ($i == $max) { - $body[] = ' ('.(count($changesets) - $max).' more files)'; - break; - } - $body[] = ' '.$changeset->getFilename(); - } - $body[] = null; - } - - if ($this->patch) { - $body[] = 'CHANGE DETAILS'; - $body[] = $this->patch; - } - - return implode("\n", $body); - } - - protected function buildAttachments() { - $attachments = array(); - - if (PhabricatorEnv::getEnvConfig('metamta.differential.attach-patches')) { - - $revision = $this->getRevision(); - $revision_id = $revision->getID(); - - $diffs = id(new DifferentialDiffQuery()) - ->setViewer($this->getActor()) - ->withRevisionIDs(array($revision_id)) - ->execute(); - $diff_number = count($diffs); - - $attachments[] = new PhabricatorMetaMTAAttachment( - $this->buildPatch(), - "D{$revision_id}.{$diff_number}.patch", - 'text/x-patch; charset=utf-8' - ); - } - - return $attachments; - } - - private function buildPatch() { - $renderer = new DifferentialRawDiffRenderer(); - $renderer->setChangesets($this->getChangesets()); - $renderer->setFormat( - PhabricatorEnv::getEnvConfig('metamta.differential.patch-format')); - - // TODO: It would be nice to have a real viewer here eventually, but - // in the meantime anyone we're sending mail to can certainly see the - // patch. - $renderer->setViewer(PhabricatorUser::getOmnipotentUser()); - return $renderer->buildPatch(); - } - - protected function getMailTags() { - $tags = array(); - if ($this->isFirstMailToRecipients()) { - $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEW_REQUEST; - } else { - $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_UPDATED; - } - return $tags; - } - -} diff --git a/src/applications/differential/storage/DifferentialTransaction.php b/src/applications/differential/storage/DifferentialTransaction.php --- a/src/applications/differential/storage/DifferentialTransaction.php +++ b/src/applications/differential/storage/DifferentialTransaction.php @@ -148,6 +148,14 @@ break; } break; + case self::TYPE_UPDATE: + $old = $this->getOldValue(); + if ($old === null) { + $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEW_REQUEST; + } else { + $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_UPDATED; + } + break; case PhabricatorTransactions::TYPE_EDGE: switch ($this->getMetadataValue('edge:type')) { case PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER: @@ -183,8 +191,7 @@ case self::TYPE_UPDATE: if ($new) { // TODO: Migrate to PHIDs and use handles here? - // TODO: Link this? - if (phid_get_type($new) == 'DIFF') { + if (phid_get_type($new) == DifferentialPHIDTypeDiff::TYPECONST) { return pht( '%s updated this revision to %s.', $author_handle, diff --git a/src/applications/metamta/view/PhabricatorMetaMTAMailBody.php b/src/applications/metamta/view/PhabricatorMetaMTAMailBody.php --- a/src/applications/metamta/view/PhabricatorMetaMTAMailBody.php +++ b/src/applications/metamta/view/PhabricatorMetaMTAMailBody.php @@ -10,6 +10,7 @@ final class PhabricatorMetaMTAMailBody { private $sections = array(); + private $attachments = array(); /* -( Composition )-------------------------------------------------------- */ @@ -88,6 +89,19 @@ } + /** + * Add an attachment. + * + * @param PhabricatorMetaMTAAttachment Attachment. + * @return this + * @task compose + */ + public function addAttachment(PhabricatorMetaMTAAttachment $attachment) { + $this->attachments[] = $attachment; + return $this; + } + + /* -( Rendering )---------------------------------------------------------- */ @@ -103,6 +117,17 @@ /** + * Retrieve attachments. + * + * @return list Attachments. + * @task render + */ + public function getAttachments() { + return $this->attachments; + } + + + /** * Indent a block of text for rendering under a section heading. * * @param string Text to indent. diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php --- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php +++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php @@ -1662,6 +1662,10 @@ ->setIsBulk(true) ->setBody($body->render()); + foreach ($body->getAttachments() as $attachment) { + $template->addAttachment($attachment); + } + $herald_xscript = $this->getHeraldTranscript(); if ($herald_xscript) { $herald_header = $herald_xscript->getXHeraldRulesHeader();