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
@@ -1728,6 +1728,7 @@
'PhabricatorMetaMTAMail' => 'applications/metamta/storage/PhabricatorMetaMTAMail.php',
'PhabricatorMetaMTAMailBody' => 'applications/metamta/view/PhabricatorMetaMTAMailBody.php',
'PhabricatorMetaMTAMailBodyTestCase' => 'applications/metamta/view/__tests__/PhabricatorMetaMTAMailBodyTestCase.php',
+ 'PhabricatorMetaMTAMailSection' => 'applications/metamta/view/PhabricatorMetaMTAMailSection.php',
'PhabricatorMetaMTAMailTestCase' => 'applications/metamta/storage/__tests__/PhabricatorMetaMTAMailTestCase.php',
'PhabricatorMetaMTAMailableDatasource' => 'applications/metamta/typeahead/PhabricatorMetaMTAMailableDatasource.php',
'PhabricatorMetaMTAMailgunReceiveController' => 'applications/metamta/controller/PhabricatorMetaMTAMailgunReceiveController.php',
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
@@ -1179,23 +1179,21 @@
$config_attach = PhabricatorEnv::getEnvConfig($config_key_attach);
if ($config_inline || $config_attach) {
- list($patch, $html_patch) = $this->renderPatchForMail($diff);
- $lines = count(phutil_split_lines($patch));
+ $patchSection = $this->renderPatchForMail($diff);
+ $lines = count(phutil_split_lines($patchSection->getPlaintext()));
if ($config_inline && ($lines <= $config_inline)) {
- $body->addPlaintextSection(
+ $body->addTextSection(
pht('CHANGE DETAILS'),
- $patch);
- $body->addHTMLSection(
- pht('CHANGE DETAILS'),
- $html_patch);
+ $patchSection);
}
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));
+ new PhabricatorMetaMTAAttachment(
+ $patchSection->getPlaintext(), $name, $mime_type));
}
}
}
@@ -1333,7 +1331,7 @@
$hunk_parser = new DifferentialHunkParser();
}
- $result = array();
+ $section = new PhabricatorMetaMTAMailSection();
foreach ($inline_groups as $changeset_id => $group) {
$changeset = idx($changesets, $changeset_id);
if (!$changeset) {
@@ -1354,25 +1352,27 @@
$inline_content = $comment->getContent();
if (!$show_context) {
- $result[] = "{$file}:{$range} {$inline_content}";
+ $section->addFragment("{$file}:{$range} {$inline_content}");
} else {
- $result[] = '================';
- $result[] = 'Comment at: '.$file.':'.$range;
- $result[] = $hunk_parser->makeContextDiff(
+ $patch = $hunk_parser->makeContextDiff(
$changeset->getHunks(),
$comment->getIsNewFile(),
$comment->getLineNumber(),
$comment->getLineLength(),
1);
- $result[] = '----------------';
- $result[] = $inline_content;
- $result[] = null;
+ $section->addFragment('================')
+ ->addFragment('Comment at: '.$file.':'.$range)
+ ->addPlaintextFragment($patch)
+ ->addHTMLFragment($this->renderPatchHTMLForMail($patch))
+ ->addFragment('----------------')
+ ->addFragment($inline_content)
+ ->addFragment(null);
}
}
}
- return implode("\n", $result);
+ return $section;
}
private function loadDiff($phid, $need_changesets = false) {
@@ -1765,6 +1765,11 @@
return implode("\n", $filenames);
}
+ private function renderPatchHTMLForMail($patch) {
+ return phutil_tag('pre',
+ array('style' => 'font-family: monospace;'), $patch);
+ }
+
private function renderPatchForMail(DifferentialDiff $diff) {
$format = PhabricatorEnv::getEnvConfig('metamta.differential.patch-format');
@@ -1774,25 +1779,11 @@
->setChangesets($diff->getChangesets())
->buildPatch();
- // some basic formatting (switch to a PhutilSyntaxHighlighterEngine?)
- $patch_html_lines = array();
- foreach (phutil_split_lines($patch) as $line) {
- $len = strlen($line);
- if ($len >= 1 && $line[0] == '+') {
- $patch_html_lines[] = "${line}";
- } else if ($len >= 1 && $line[0] == '-') {
- $patch_html_lines[] = "${line}";
- } else if ($len >= 2 && substr($line, 0, 2) == '@@') {
- $patch_html_lines[] = "${line}";
- } else {
- $patch_html_lines[] = "${line}";
- }
- }
-
- $html_patch = "
".
- implode('
', $patch_html_lines).'
';
+ $section = new PhabricatorMetaMTAMailSection();
+ $section->addHTMLFragment($this->renderPatchHTMLForMail($patch));
+ $section->addPlaintextFragment($patch);
- return array($patch, $html_patch);
+ return $section;
}
}
diff --git a/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php b/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php
--- a/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php
+++ b/src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php
@@ -116,7 +116,6 @@
->addCCs($ccs)
->setSubject($subject)
->setBody($body)
- ->setIsHTML($is_html)
->setIsBulk($is_bulk)
->setMailTags($tags);
diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
--- a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
+++ b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php
@@ -214,6 +214,7 @@
public function setHTMLBody($html) {
$this->setParam('html-body', $html);
+ return $this;
}
public function getBody() {
@@ -376,6 +377,32 @@
$add_cc = array();
$add_to = array();
+ // Only try to use preferences if everything is multiplexed, so we
+ // get consistent behavior.
+ $use_prefs = self::shouldMultiplexAllMail();
+
+ $prefs = null;
+ if ($use_prefs) {
+
+ // If multiplexing is enabled, some recipients will be in "Cc"
+ // rather than "To". We'll move them to "To" later (or supply a
+ // dummy "To") but need to look for the recipient in either the
+ // "To" or "Cc" fields here.
+ $target_phid = head(idx($params, 'to', array()));
+ if (!$target_phid) {
+ $target_phid = head(idx($params, 'cc', array()));
+ }
+
+ if ($target_phid) {
+ $user = id(new PhabricatorUser())->loadOneWhere(
+ 'phid = %s',
+ $target_phid);
+ if ($user) {
+ $prefs = $user->loadPreferences();
+ }
+ }
+ }
+
foreach ($params as $key => $value) {
switch ($key) {
case 'from':
@@ -444,32 +471,6 @@
}
break;
case 'subject':
- // Only try to use preferences if everything is multiplexed, so we
- // get consistent behavior.
- $use_prefs = self::shouldMultiplexAllMail();
-
- $prefs = null;
- if ($use_prefs) {
-
- // If multiplexing is enabled, some recipients will be in "Cc"
- // rather than "To". We'll move them to "To" later (or supply a
- // dummy "To") but need to look for the recipient in either the
- // "To" or "Cc" fields here.
- $target_phid = head(idx($params, 'to', array()));
- if (!$target_phid) {
- $target_phid = head(idx($params, 'cc', array()));
- }
-
- if ($target_phid) {
- $user = id(new PhabricatorUser())->loadOneWhere(
- 'phid = %s',
- $target_phid);
- if ($user) {
- $prefs = $user->loadPreferences();
- }
- }
- }
-
$subject = array();
if ($is_threaded) {
@@ -555,7 +556,7 @@
}
}
- $body = $params['body'];
+ $body = idx($params, 'body', '');
$max = PhabricatorEnv::getEnvConfig('metamta.email-body-limit');
if (strlen($body) > $max) {
$body = phutil_utf8_shorten($body, $max);
@@ -564,8 +565,14 @@
}
$mailer->setBody($body);
- if (PhabricatorEnv::getEnvConfig('metamta.html-emails') &&
- isset($params['html-body'])) {
+ $html_emails = PhabricatorEnv::getEnvConfig('metamta.html-emails');
+ if ($use_prefs && $prefs) {
+ $html_emails = $prefs->getPreference(
+ PhabricatorUserPreferences::PREFERENCE_HTML_EMAILS,
+ $html_emails);
+ }
+
+ if ($html_emails && isset($params['html-body'])) {
$mailer->setHTMLBody($params['html-body']);
}
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
@@ -48,6 +48,7 @@
return $this;
}
+
/**
* Add a block of text with a section header. This is rendered like this:
*
@@ -59,10 +60,17 @@
* @return this
* @task compose
*/
- public function addTextSection($header, $text) {
- $this->addPlaintextSection($header, $text);
- $this->addHTMLSection($header,
- phutil_escape_html_newlines(phutil_tag('div', array(), $text)));
+ public function addTextSection($header, $section) {
+ if ($section instanceof PhabricatorMetaMTAMailSection) {
+ $plaintext = $section->getPlaintext();
+ $html = $section->getHTML();
+ } else {
+ $plaintext = $section;
+ $html = phutil_escape_html_newlines(phutil_tag('div', array(), $section));
+ }
+
+ $this->addPlaintextSection($header, $plaintext);
+ $this->addHTMLSection($header, $html);
return $this;
}
diff --git a/src/applications/metamta/view/PhabricatorMetaMTAMailSection.php b/src/applications/metamta/view/PhabricatorMetaMTAMailSection.php
new file mode 100644
--- /dev/null
+++ b/src/applications/metamta/view/PhabricatorMetaMTAMailSection.php
@@ -0,0 +1,40 @@
+htmlFragments);
+ }
+
+ public function getPlaintext() {
+ return implode('\n', $this->plaintextFragments);
+ }
+
+ public function addHTMLFragment($fragment) {
+ $this->htmlFragments[] = $fragment;
+ return $this;
+
+ }
+
+ public function addPlaintextFragment($fragment) {
+ $this->plaintextFragments[] = $fragment;
+ return $this;
+ }
+
+ public function addFragment($fragment) {
+ $this->plaintextFragments[] = $fragment;
+ $this->htmlFragments[] =
+ phutil_escape_html_newlines(phutil_tag('div', array(), $fragment));
+
+ return $this;
+ }
+}
diff --git a/src/applications/settings/panel/PhabricatorSettingsPanelEmailFormat.php b/src/applications/settings/panel/PhabricatorSettingsPanelEmailFormat.php
--- a/src/applications/settings/panel/PhabricatorSettingsPanelEmailFormat.php
+++ b/src/applications/settings/panel/PhabricatorSettingsPanelEmailFormat.php
@@ -22,6 +22,7 @@
$pref_re_prefix = PhabricatorUserPreferences::PREFERENCE_RE_PREFIX;
$pref_vary = PhabricatorUserPreferences::PREFERENCE_VARY_SUBJECT;
+ $prefs_html_email = PhabricatorUserPreferences::PREFERENCE_HTML_EMAILS;
$errors = array();
if ($request->isFormPost()) {
@@ -42,6 +43,14 @@
$pref_vary,
$request->getBool($pref_vary));
}
+
+ if ($request->getStr($prefs_html_email) == 'default') {
+ $preferences->unsetPreference($prefs_html_email);
+ } else {
+ $preferences->setPreference(
+ $prefs_html_email,
+ $request->getBool($prefs_html_email));
+ }
}
$preferences->save();
@@ -58,6 +67,10 @@
? pht('Vary')
: pht('Do Not Vary');
+ $html_emails_default = PhabricatorEnv::getEnvConfig('metamta.html-emails')
+ ? pht('HTML')
+ : pht('plaintext');
+
$re_prefix_value = $preferences->getPreference($pref_re_prefix);
if ($re_prefix_value === null) {
$re_prefix_value = 'default';
@@ -76,11 +89,30 @@
: 'false';
}
+ $html_emails_value = $preferences->getPreference($prefs_html_email);
+ if ($html_emails_value === null) {
+ $html_emails_value = 'default';
+ } else {
+ $html_emails_value = $html_emails_value
+ ? 'true'
+ : 'false';
+ }
+
$form = new AphrontFormView();
$form
->setUser($user);
if (PhabricatorMetaMTAMail::shouldMultiplexAllMail()) {
+ $html_email_control = id(new AphrontFormSelectControl())
+ ->setName($prefs_html_email)
+ ->setOptions(
+ array(
+ 'default' => pht('Use Server Default (%s)', $html_emails_default),
+ 'true' => pht('HTML emails'),
+ 'false' => pht('Plaintext emails'),
+ ))
+ ->setValue($html_emails_value);
+
$re_control = id(new AphrontFormSelectControl())
->setName($pref_re_prefix)
->setOptions(
@@ -101,6 +133,9 @@
))
->setValue($vary_value);
} else {
+ $html_email_control = id(new AphrontFormStaticControl())
+ ->setValue('Server Default ('.$html_emails_default.')');
+
$re_control = id(new AphrontFormStaticControl())
->setValue('Server Default ('.$re_prefix_default.')');
@@ -124,6 +159,7 @@
}
$form
+ ->appendChild($html_email_control)
->appendRemarkupInstructions('')
->appendRemarkupInstructions(
pht(
diff --git a/src/applications/settings/storage/PhabricatorUserPreferences.php b/src/applications/settings/storage/PhabricatorUserPreferences.php
--- a/src/applications/settings/storage/PhabricatorUserPreferences.php
+++ b/src/applications/settings/storage/PhabricatorUserPreferences.php
@@ -15,6 +15,7 @@
const PREFERENCE_NO_MAIL = 'no-mail';
const PREFERENCE_MAILTAGS = 'mailtags';
const PREFERENCE_VARY_SUBJECT = 'vary-subject';
+ const PREFERENCE_HTML_EMAILS = 'html-emails';
const PREFERENCE_SEARCHBAR_JUMP = 'searchbar-jump';
const PREFERENCE_SEARCH_SHORTCUT = 'search-shortcut';