mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-01 19:22:42 +01:00
Port Differential mail features forward to transactions
Summary: Ref T2222. Brings the major mail features (affected files, patches) forward. This drops some of the minor integrations which just show object state (like "Maniphest Tasks") since I think they're not very important. I'll put them back if users miss them. Test Plan: Sent mail with inline/attached patches. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T2222 Differential Revision: https://secure.phabricator.com/D8459
This commit is contained in:
parent
50331016f7
commit
9e8bbdb3a2
19 changed files with 104 additions and 823 deletions
|
@ -335,7 +335,6 @@ phutil_register_library_map(array(
|
||||||
'DifferentialBlameRevisionFieldSpecification' => 'applications/differential/field/specification/DifferentialBlameRevisionFieldSpecification.php',
|
'DifferentialBlameRevisionFieldSpecification' => 'applications/differential/field/specification/DifferentialBlameRevisionFieldSpecification.php',
|
||||||
'DifferentialBranchField' => 'applications/differential/customfield/DifferentialBranchField.php',
|
'DifferentialBranchField' => 'applications/differential/customfield/DifferentialBranchField.php',
|
||||||
'DifferentialBranchFieldSpecification' => 'applications/differential/field/specification/DifferentialBranchFieldSpecification.php',
|
'DifferentialBranchFieldSpecification' => 'applications/differential/field/specification/DifferentialBranchFieldSpecification.php',
|
||||||
'DifferentialCCWelcomeMail' => 'applications/differential/mail/DifferentialCCWelcomeMail.php',
|
|
||||||
'DifferentialCCsFieldSpecification' => 'applications/differential/field/specification/DifferentialCCsFieldSpecification.php',
|
'DifferentialCCsFieldSpecification' => 'applications/differential/field/specification/DifferentialCCsFieldSpecification.php',
|
||||||
'DifferentialCapabilityDefaultView' => 'applications/differential/capability/DifferentialCapabilityDefaultView.php',
|
'DifferentialCapabilityDefaultView' => 'applications/differential/capability/DifferentialCapabilityDefaultView.php',
|
||||||
'DifferentialChangeType' => 'applications/differential/constants/DifferentialChangeType.php',
|
'DifferentialChangeType' => 'applications/differential/constants/DifferentialChangeType.php',
|
||||||
|
@ -382,7 +381,6 @@ phutil_register_library_map(array(
|
||||||
'DifferentialDependsOnField' => 'applications/differential/customfield/DifferentialDependsOnField.php',
|
'DifferentialDependsOnField' => 'applications/differential/customfield/DifferentialDependsOnField.php',
|
||||||
'DifferentialDependsOnFieldSpecification' => 'applications/differential/field/specification/DifferentialDependsOnFieldSpecification.php',
|
'DifferentialDependsOnFieldSpecification' => 'applications/differential/field/specification/DifferentialDependsOnFieldSpecification.php',
|
||||||
'DifferentialDiff' => 'applications/differential/storage/DifferentialDiff.php',
|
'DifferentialDiff' => 'applications/differential/storage/DifferentialDiff.php',
|
||||||
'DifferentialDiffContentMail' => 'applications/differential/mail/DifferentialDiffContentMail.php',
|
|
||||||
'DifferentialDiffCreateController' => 'applications/differential/controller/DifferentialDiffCreateController.php',
|
'DifferentialDiffCreateController' => 'applications/differential/controller/DifferentialDiffCreateController.php',
|
||||||
'DifferentialDiffProperty' => 'applications/differential/storage/DifferentialDiffProperty.php',
|
'DifferentialDiffProperty' => 'applications/differential/storage/DifferentialDiffProperty.php',
|
||||||
'DifferentialDiffQuery' => 'applications/differential/query/DifferentialDiffQuery.php',
|
'DifferentialDiffQuery' => 'applications/differential/query/DifferentialDiffQuery.php',
|
||||||
|
@ -436,7 +434,6 @@ phutil_register_library_map(array(
|
||||||
'DifferentialMailPhase' => 'applications/differential/constants/DifferentialMailPhase.php',
|
'DifferentialMailPhase' => 'applications/differential/constants/DifferentialMailPhase.php',
|
||||||
'DifferentialManiphestTasksField' => 'applications/differential/customfield/DifferentialManiphestTasksField.php',
|
'DifferentialManiphestTasksField' => 'applications/differential/customfield/DifferentialManiphestTasksField.php',
|
||||||
'DifferentialManiphestTasksFieldSpecification' => 'applications/differential/field/specification/DifferentialManiphestTasksFieldSpecification.php',
|
'DifferentialManiphestTasksFieldSpecification' => 'applications/differential/field/specification/DifferentialManiphestTasksFieldSpecification.php',
|
||||||
'DifferentialNewDiffMail' => 'applications/differential/mail/DifferentialNewDiffMail.php',
|
|
||||||
'DifferentialPHIDTypeDiff' => 'applications/differential/phid/DifferentialPHIDTypeDiff.php',
|
'DifferentialPHIDTypeDiff' => 'applications/differential/phid/DifferentialPHIDTypeDiff.php',
|
||||||
'DifferentialPHIDTypeRevision' => 'applications/differential/phid/DifferentialPHIDTypeRevision.php',
|
'DifferentialPHIDTypeRevision' => 'applications/differential/phid/DifferentialPHIDTypeRevision.php',
|
||||||
'DifferentialParseCacheGarbageCollector' => 'applications/differential/garbagecollector/DifferentialParseCacheGarbageCollector.php',
|
'DifferentialParseCacheGarbageCollector' => 'applications/differential/garbagecollector/DifferentialParseCacheGarbageCollector.php',
|
||||||
|
@ -456,7 +453,6 @@ phutil_register_library_map(array(
|
||||||
'DifferentialResultsTableView' => 'applications/differential/view/DifferentialResultsTableView.php',
|
'DifferentialResultsTableView' => 'applications/differential/view/DifferentialResultsTableView.php',
|
||||||
'DifferentialRevertPlanField' => 'applications/differential/customfield/DifferentialRevertPlanField.php',
|
'DifferentialRevertPlanField' => 'applications/differential/customfield/DifferentialRevertPlanField.php',
|
||||||
'DifferentialRevertPlanFieldSpecification' => 'applications/differential/field/specification/DifferentialRevertPlanFieldSpecification.php',
|
'DifferentialRevertPlanFieldSpecification' => 'applications/differential/field/specification/DifferentialRevertPlanFieldSpecification.php',
|
||||||
'DifferentialReviewRequestMail' => 'applications/differential/mail/DifferentialReviewRequestMail.php',
|
|
||||||
'DifferentialReviewedByField' => 'applications/differential/customfield/DifferentialReviewedByField.php',
|
'DifferentialReviewedByField' => 'applications/differential/customfield/DifferentialReviewedByField.php',
|
||||||
'DifferentialReviewedByFieldSpecification' => 'applications/differential/field/specification/DifferentialReviewedByFieldSpecification.php',
|
'DifferentialReviewedByFieldSpecification' => 'applications/differential/field/specification/DifferentialReviewedByFieldSpecification.php',
|
||||||
'DifferentialReviewer' => 'applications/differential/storage/DifferentialReviewer.php',
|
'DifferentialReviewer' => 'applications/differential/storage/DifferentialReviewer.php',
|
||||||
|
@ -2910,7 +2906,6 @@ phutil_register_library_map(array(
|
||||||
'DifferentialBlameRevisionFieldSpecification' => 'DifferentialFieldSpecification',
|
'DifferentialBlameRevisionFieldSpecification' => 'DifferentialFieldSpecification',
|
||||||
'DifferentialBranchField' => 'DifferentialCustomField',
|
'DifferentialBranchField' => 'DifferentialCustomField',
|
||||||
'DifferentialBranchFieldSpecification' => 'DifferentialFieldSpecification',
|
'DifferentialBranchFieldSpecification' => 'DifferentialFieldSpecification',
|
||||||
'DifferentialCCWelcomeMail' => 'DifferentialReviewRequestMail',
|
|
||||||
'DifferentialCCsFieldSpecification' => 'DifferentialFieldSpecification',
|
'DifferentialCCsFieldSpecification' => 'DifferentialFieldSpecification',
|
||||||
'DifferentialCapabilityDefaultView' => 'PhabricatorPolicyCapability',
|
'DifferentialCapabilityDefaultView' => 'PhabricatorPolicyCapability',
|
||||||
'DifferentialChangeset' => 'DifferentialDAO',
|
'DifferentialChangeset' => 'DifferentialDAO',
|
||||||
|
@ -2957,7 +2952,6 @@ phutil_register_library_map(array(
|
||||||
1 => 'PhabricatorPolicyInterface',
|
1 => 'PhabricatorPolicyInterface',
|
||||||
2 => 'HarbormasterBuildableInterface',
|
2 => 'HarbormasterBuildableInterface',
|
||||||
),
|
),
|
||||||
'DifferentialDiffContentMail' => 'DifferentialMail',
|
|
||||||
'DifferentialDiffCreateController' => 'DifferentialController',
|
'DifferentialDiffCreateController' => 'DifferentialController',
|
||||||
'DifferentialDiffProperty' => 'DifferentialDAO',
|
'DifferentialDiffProperty' => 'DifferentialDAO',
|
||||||
'DifferentialDiffQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'DifferentialDiffQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
@ -3004,7 +2998,6 @@ phutil_register_library_map(array(
|
||||||
'DifferentialMail' => 'PhabricatorMail',
|
'DifferentialMail' => 'PhabricatorMail',
|
||||||
'DifferentialManiphestTasksField' => 'DifferentialCoreCustomField',
|
'DifferentialManiphestTasksField' => 'DifferentialCoreCustomField',
|
||||||
'DifferentialManiphestTasksFieldSpecification' => 'DifferentialFieldSpecification',
|
'DifferentialManiphestTasksFieldSpecification' => 'DifferentialFieldSpecification',
|
||||||
'DifferentialNewDiffMail' => 'DifferentialReviewRequestMail',
|
|
||||||
'DifferentialPHIDTypeDiff' => 'PhabricatorPHIDType',
|
'DifferentialPHIDTypeDiff' => 'PhabricatorPHIDType',
|
||||||
'DifferentialPHIDTypeRevision' => 'PhabricatorPHIDType',
|
'DifferentialPHIDTypeRevision' => 'PhabricatorPHIDType',
|
||||||
'DifferentialParseCacheGarbageCollector' => 'PhabricatorGarbageCollector',
|
'DifferentialParseCacheGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||||
|
@ -3023,7 +3016,6 @@ phutil_register_library_map(array(
|
||||||
'DifferentialResultsTableView' => 'AphrontView',
|
'DifferentialResultsTableView' => 'AphrontView',
|
||||||
'DifferentialRevertPlanField' => 'DifferentialStoredCustomField',
|
'DifferentialRevertPlanField' => 'DifferentialStoredCustomField',
|
||||||
'DifferentialRevertPlanFieldSpecification' => 'DifferentialFieldSpecification',
|
'DifferentialRevertPlanFieldSpecification' => 'DifferentialFieldSpecification',
|
||||||
'DifferentialReviewRequestMail' => 'DifferentialMail',
|
|
||||||
'DifferentialReviewedByField' => 'DifferentialCoreCustomField',
|
'DifferentialReviewedByField' => 'DifferentialCoreCustomField',
|
||||||
'DifferentialReviewedByFieldSpecification' => 'DifferentialFieldSpecification',
|
'DifferentialReviewedByFieldSpecification' => 'DifferentialFieldSpecification',
|
||||||
'DifferentialReviewersField' => 'DifferentialCoreCustomField',
|
'DifferentialReviewersField' => 'DifferentialCoreCustomField',
|
||||||
|
|
|
@ -1019,6 +1019,46 @@ final class DifferentialTransactionEditor
|
||||||
pht('REVISION DETAIL'),
|
pht('REVISION DETAIL'),
|
||||||
PhabricatorEnv::getProductionURI('/D'.$object->getID()));
|
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;
|
return $body;
|
||||||
}
|
}
|
||||||
|
@ -1491,4 +1531,30 @@ final class DifferentialTransactionEditor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,18 +35,4 @@ final class DifferentialArcanistProjectFieldSpecification
|
||||||
return $diff->getArcanistProjectPHID();
|
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,16 +31,4 @@ final class DifferentialBranchFieldSpecification
|
||||||
return $this->getBranchOrBookmarkDescription($diff);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,30 +34,4 @@ final class DifferentialCommitsFieldSpecification
|
||||||
return $revision->getCommitPHIDs();
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,23 +385,6 @@ abstract class DifferentialFieldSpecification {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( 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 )------------------------------------ */
|
/* -( Extending the Conduit Interface )------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -127,32 +127,4 @@ final class DifferentialManiphestTasksFieldSpecification
|
||||||
return $task_phids;
|
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.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,25 +173,4 @@ final class DifferentialReviewersFieldSpecification
|
||||||
return $revision->getReviewers();
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,25 +96,4 @@ final class DifferentialRevisionIDFieldSpecification
|
||||||
return 'D'.$revision->getID();
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,18 +67,6 @@ final class DifferentialSummaryFieldSpecification
|
||||||
return (string)$value;
|
return (string)$value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderValueForMail($phase) {
|
|
||||||
if ($phase != DifferentialMailPhase::WELCOME) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->summary == '') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->summary;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function shouldAddToSearchIndex() {
|
public function shouldAddToSearchIndex() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,18 +91,6 @@ final class DifferentialTestPlanFieldSpecification
|
||||||
return $value;
|
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() {
|
public function shouldAddToSearchIndex() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class DifferentialCCWelcomeMail extends DifferentialReviewRequestMail {
|
|
||||||
|
|
||||||
protected function renderVaryPrefix() {
|
|
||||||
return '[Added to CC]';
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function renderBody() {
|
|
||||||
|
|
||||||
$actor = $this->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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class DifferentialDiffContentMail extends DifferentialMail {
|
|
||||||
|
|
||||||
protected $content;
|
|
||||||
|
|
||||||
public function __construct(DifferentialRevision $revision, $content) {
|
|
||||||
$this->setRevision($revision);
|
|
||||||
$this->content = $content;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function renderVaryPrefix() {
|
|
||||||
return '[Content]';
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function renderBody() {
|
|
||||||
return $this->content;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,307 +2,6 @@
|
||||||
|
|
||||||
abstract class DifferentialMail extends PhabricatorMail {
|
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(
|
public static function newReplyHandlerForRevision(
|
||||||
DifferentialRevision $revision) {
|
DifferentialRevision $revision) {
|
||||||
|
|
||||||
|
@ -313,146 +12,4 @@ abstract class DifferentialMail extends PhabricatorMail {
|
||||||
return $reply_handler;
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class DifferentialNewDiffMail extends DifferentialReviewRequestMail {
|
|
||||||
|
|
||||||
protected function renderVaryPrefix() {
|
|
||||||
$revision = $this->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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,129 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
abstract class DifferentialReviewRequestMail extends DifferentialMail {
|
|
||||||
|
|
||||||
const MAX_AFFECTED_FILES = 1000;
|
|
||||||
|
|
||||||
protected $commentText;
|
|
||||||
|
|
||||||
private $patch;
|
|
||||||
|
|
||||||
public function setCommentText($comment_text) {
|
|
||||||
$this->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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -148,6 +148,14 @@ final class DifferentialTransaction extends PhabricatorApplicationTransaction {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
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:
|
case PhabricatorTransactions::TYPE_EDGE:
|
||||||
switch ($this->getMetadataValue('edge:type')) {
|
switch ($this->getMetadataValue('edge:type')) {
|
||||||
case PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER:
|
case PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER:
|
||||||
|
@ -183,8 +191,7 @@ final class DifferentialTransaction extends PhabricatorApplicationTransaction {
|
||||||
case self::TYPE_UPDATE:
|
case self::TYPE_UPDATE:
|
||||||
if ($new) {
|
if ($new) {
|
||||||
// TODO: Migrate to PHIDs and use handles here?
|
// TODO: Migrate to PHIDs and use handles here?
|
||||||
// TODO: Link this?
|
if (phid_get_type($new) == DifferentialPHIDTypeDiff::TYPECONST) {
|
||||||
if (phid_get_type($new) == 'DIFF') {
|
|
||||||
return pht(
|
return pht(
|
||||||
'%s updated this revision to %s.',
|
'%s updated this revision to %s.',
|
||||||
$author_handle,
|
$author_handle,
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
final class PhabricatorMetaMTAMailBody {
|
final class PhabricatorMetaMTAMailBody {
|
||||||
|
|
||||||
private $sections = array();
|
private $sections = array();
|
||||||
|
private $attachments = array();
|
||||||
|
|
||||||
|
|
||||||
/* -( Composition )-------------------------------------------------------- */
|
/* -( Composition )-------------------------------------------------------- */
|
||||||
|
@ -88,6 +89,19 @@ final class PhabricatorMetaMTAMailBody {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an attachment.
|
||||||
|
*
|
||||||
|
* @param PhabricatorMetaMTAAttachment Attachment.
|
||||||
|
* @return this
|
||||||
|
* @task compose
|
||||||
|
*/
|
||||||
|
public function addAttachment(PhabricatorMetaMTAAttachment $attachment) {
|
||||||
|
$this->attachments[] = $attachment;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( Rendering )---------------------------------------------------------- */
|
/* -( Rendering )---------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,6 +116,17 @@ final class PhabricatorMetaMTAMailBody {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve attachments.
|
||||||
|
*
|
||||||
|
* @return list<PhabricatorMetaMTAAttachment> Attachments.
|
||||||
|
* @task render
|
||||||
|
*/
|
||||||
|
public function getAttachments() {
|
||||||
|
return $this->attachments;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indent a block of text for rendering under a section heading.
|
* Indent a block of text for rendering under a section heading.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1662,6 +1662,10 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
->setIsBulk(true)
|
->setIsBulk(true)
|
||||||
->setBody($body->render());
|
->setBody($body->render());
|
||||||
|
|
||||||
|
foreach ($body->getAttachments() as $attachment) {
|
||||||
|
$template->addAttachment($attachment);
|
||||||
|
}
|
||||||
|
|
||||||
$herald_xscript = $this->getHeraldTranscript();
|
$herald_xscript = $this->getHeraldTranscript();
|
||||||
if ($herald_xscript) {
|
if ($herald_xscript) {
|
||||||
$herald_header = $herald_xscript->getXHeraldRulesHeader();
|
$herald_header = $herald_xscript->getXHeraldRulesHeader();
|
||||||
|
|
Loading…
Reference in a new issue