mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Centralize rendering of application mail bodies
Summary: This is a minor quality-of-life improvement to prevent D2968 from being as nasty as it is. Test Plan: Ran unit tests; generated Differential, Maniphest and Diffusion emails and verified the bodies looked sensible. Reviewers: btrahan, vrana Reviewed By: vrana CC: aran Maniphest Tasks: T931 Differential Revision: https://secure.phabricator.com/D2986
This commit is contained in:
parent
f3dec13431
commit
378feb3ffb
8 changed files with 215 additions and 75 deletions
|
@ -23,7 +23,8 @@
|
||||||
"search" : "Search",
|
"search" : "Search",
|
||||||
"daemon" : "Daemons, Tasks and Workers",
|
"daemon" : "Daemons, Tasks and Workers",
|
||||||
"irc" : "IRC",
|
"irc" : "IRC",
|
||||||
"markup" : "Remarkup Extensions"
|
"markup" : "Remarkup Extensions",
|
||||||
|
"metamta" : "MetaMTA (Mail)"
|
||||||
},
|
},
|
||||||
"engines" : [
|
"engines" : [
|
||||||
["DivinerArticleEngine", {}],
|
["DivinerArticleEngine", {}],
|
||||||
|
|
|
@ -751,6 +751,8 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorMetaMTAEmailBodyParserTestCase' => 'applications/metamta/__tests__/PhabricatorMetaMTAEmailBodyParserTestCase.php',
|
'PhabricatorMetaMTAEmailBodyParserTestCase' => 'applications/metamta/__tests__/PhabricatorMetaMTAEmailBodyParserTestCase.php',
|
||||||
'PhabricatorMetaMTAListController' => 'applications/metamta/controller/PhabricatorMetaMTAListController.php',
|
'PhabricatorMetaMTAListController' => 'applications/metamta/controller/PhabricatorMetaMTAListController.php',
|
||||||
'PhabricatorMetaMTAMail' => 'applications/metamta/storage/PhabricatorMetaMTAMail.php',
|
'PhabricatorMetaMTAMail' => 'applications/metamta/storage/PhabricatorMetaMTAMail.php',
|
||||||
|
'PhabricatorMetaMTAMailBody' => 'applications/metamta/view/PhabricatorMetaMTAMailBody.php',
|
||||||
|
'PhabricatorMetaMTAMailBodyTestCase' => 'applications/metamta/view/__tests__/PhabricatorMetaMTAMailBodyTestCase.php',
|
||||||
'PhabricatorMetaMTAMailTestCase' => 'applications/metamta/storage/__tests__/PhabricatorMetaMTAMailTestCase.php',
|
'PhabricatorMetaMTAMailTestCase' => 'applications/metamta/storage/__tests__/PhabricatorMetaMTAMailTestCase.php',
|
||||||
'PhabricatorMetaMTAMailingList' => 'applications/metamta/storage/PhabricatorMetaMTAMailingList.php',
|
'PhabricatorMetaMTAMailingList' => 'applications/metamta/storage/PhabricatorMetaMTAMailingList.php',
|
||||||
'PhabricatorMetaMTAMailingListEditController' => 'applications/metamta/controller/PhabricatorMetaMTAMailingListEditController.php',
|
'PhabricatorMetaMTAMailingListEditController' => 'applications/metamta/controller/PhabricatorMetaMTAMailingListEditController.php',
|
||||||
|
@ -1763,6 +1765,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorMetaMTAEmailBodyParserTestCase' => 'PhabricatorTestCase',
|
'PhabricatorMetaMTAEmailBodyParserTestCase' => 'PhabricatorTestCase',
|
||||||
'PhabricatorMetaMTAListController' => 'PhabricatorMetaMTAController',
|
'PhabricatorMetaMTAListController' => 'PhabricatorMetaMTAController',
|
||||||
'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO',
|
'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO',
|
||||||
|
'PhabricatorMetaMTAMailBodyTestCase' => 'PhabricatorTestCase',
|
||||||
'PhabricatorMetaMTAMailTestCase' => 'PhabricatorTestCase',
|
'PhabricatorMetaMTAMailTestCase' => 'PhabricatorTestCase',
|
||||||
'PhabricatorMetaMTAMailingList' => 'PhabricatorMetaMTADAO',
|
'PhabricatorMetaMTAMailingList' => 'PhabricatorMetaMTADAO',
|
||||||
'PhabricatorMetaMTAMailingListEditController' => 'PhabricatorMetaMTAController',
|
'PhabricatorMetaMTAMailingListEditController' => 'PhabricatorMetaMTAController',
|
||||||
|
|
|
@ -251,8 +251,7 @@ final class DifferentialRevisionEditor {
|
||||||
$adapter->setForbiddenCCs($revision->getUnsubscribedPHIDs());
|
$adapter->setForbiddenCCs($revision->getUnsubscribedPHIDs());
|
||||||
|
|
||||||
$xscript = HeraldEngine::loadAndApplyRules($adapter);
|
$xscript = HeraldEngine::loadAndApplyRules($adapter);
|
||||||
$xscript_uri = PhabricatorEnv::getProductionURI(
|
$xscript_uri = '/herald/transcript/'.$xscript->getID().'/';
|
||||||
'/herald/transcript/'.$xscript->getID().'/');
|
|
||||||
$xscript_phid = $xscript->getPHID();
|
$xscript_phid = $xscript->getPHID();
|
||||||
$xscript_header = $xscript->getXHeraldRulesHeader();
|
$xscript_header = $xscript->getXHeraldRulesHeader();
|
||||||
|
|
||||||
|
|
|
@ -260,34 +260,21 @@ abstract class DifferentialMail {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildBody() {
|
protected function buildBody() {
|
||||||
|
$main_body = $this->renderBody();
|
||||||
|
|
||||||
$body = $this->renderBody();
|
$body = new PhabricatorMetaMTAMailBody();
|
||||||
|
$body->addRawSection($main_body);
|
||||||
|
|
||||||
$reply_handler = $this->getReplyHandler();
|
$reply_handler = $this->getReplyHandler();
|
||||||
$reply_instructions = $reply_handler->getReplyHandlerInstructions();
|
$body->addReplySection($reply_handler->getReplyHandlerInstructions());
|
||||||
if ($reply_instructions) {
|
|
||||||
$body .=
|
|
||||||
"\nREPLY HANDLER ACTIONS\n".
|
|
||||||
" {$reply_instructions}\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->getHeraldTranscriptURI() && $this->isFirstMailToRecipients()) {
|
if ($this->getHeraldTranscriptURI() && $this->isFirstMailToRecipients()) {
|
||||||
$manage_uri = PhabricatorEnv::getProductionURI(
|
$manage_uri = '/herald/view/differential/';
|
||||||
'/herald/view/differential/');
|
|
||||||
|
|
||||||
$xscript_uri = $this->getHeraldTranscriptURI();
|
$xscript_uri = $this->getHeraldTranscriptURI();
|
||||||
$body .= <<<EOTEXT
|
$body->addHeraldSection($manage_uri, $xscript_uri);
|
||||||
|
|
||||||
MANAGE HERALD DIFFERENTIAL RULES
|
|
||||||
{$manage_uri}
|
|
||||||
|
|
||||||
WHY DID I GET THIS EMAIL?
|
|
||||||
{$xscript_uri}
|
|
||||||
|
|
||||||
EOTEXT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $body;
|
return $body->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -245,7 +245,7 @@ final class ManiphestTransactionEditor {
|
||||||
$view->setTransactionGroup($transactions);
|
$view->setTransactionGroup($transactions);
|
||||||
$view->setHandles($handles);
|
$view->setHandles($handles);
|
||||||
$view->setAuxiliaryFields($this->auxiliaryFields);
|
$view->setAuxiliaryFields($this->auxiliaryFields);
|
||||||
list($action, $body) = $view->renderForEmail($with_date = false);
|
list($action, $main_body) = $view->renderForEmail($with_date = false);
|
||||||
|
|
||||||
$is_create = $this->isCreate($transactions);
|
$is_create = $this->isCreate($transactions);
|
||||||
|
|
||||||
|
@ -253,25 +253,13 @@ final class ManiphestTransactionEditor {
|
||||||
|
|
||||||
$reply_handler = $this->buildReplyHandler($task);
|
$reply_handler = $this->buildReplyHandler($task);
|
||||||
|
|
||||||
|
$body = new PhabricatorMetaMTAMailBody();
|
||||||
|
$body->addRawSection($main_body);
|
||||||
if ($is_create) {
|
if ($is_create) {
|
||||||
$body .=
|
$body->addTextSection(pht('TASK DESCRIPTION'), $task->getDescription());
|
||||||
"\n\n".
|
|
||||||
"TASK DESCRIPTION\n".
|
|
||||||
" ".$task->getDescription();
|
|
||||||
}
|
|
||||||
|
|
||||||
$body .=
|
|
||||||
"\n\n".
|
|
||||||
"TASK DETAIL\n".
|
|
||||||
" ".$task_uri."\n";
|
|
||||||
|
|
||||||
$reply_instructions = $reply_handler->getReplyHandlerInstructions();
|
|
||||||
if ($reply_instructions) {
|
|
||||||
$body .=
|
|
||||||
"\n".
|
|
||||||
"REPLY HANDLER ACTIONS\n".
|
|
||||||
" ".$reply_instructions."\n";
|
|
||||||
}
|
}
|
||||||
|
$body->addTextSection(pht('TASK DETAIL'), $task_uri);
|
||||||
|
$body->addReplySection($reply_handler->getReplyHandlerInstructions());
|
||||||
|
|
||||||
$thread_id = 'maniphest-task-'.$task->getPHID();
|
$thread_id = 'maniphest-task-'.$task->getPHID();
|
||||||
$task_id = $task->getID();
|
$task_id = $task->getID();
|
||||||
|
@ -290,7 +278,7 @@ final class ManiphestTransactionEditor {
|
||||||
->setRelatedPHID($task->getPHID())
|
->setRelatedPHID($task->getPHID())
|
||||||
->setIsBulk(true)
|
->setIsBulk(true)
|
||||||
->setMailTags($mailtags)
|
->setMailTags($mailtags)
|
||||||
->setBody($body);
|
->setBody($body->render());
|
||||||
|
|
||||||
$mails = $reply_handler->multiplexMail(
|
$mails = $reply_handler->multiplexMail(
|
||||||
$template,
|
$template,
|
||||||
|
|
125
src/applications/metamta/view/PhabricatorMetaMTAMailBody.php
Normal file
125
src/applications/metamta/view/PhabricatorMetaMTAMailBody.php
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the body of an application email by building it up section-by-section.
|
||||||
|
*
|
||||||
|
* @task compose Composition
|
||||||
|
* @task render Rendering
|
||||||
|
* @group metamta
|
||||||
|
*/
|
||||||
|
final class PhabricatorMetaMTAMailBody {
|
||||||
|
|
||||||
|
private $sections = array();
|
||||||
|
|
||||||
|
|
||||||
|
/* -( Composition )-------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a raw block of text to the email. This will be rendered as-is.
|
||||||
|
*
|
||||||
|
* @param string Block of text.
|
||||||
|
* @return this
|
||||||
|
* @task compose
|
||||||
|
*/
|
||||||
|
public function addRawSection($text) {
|
||||||
|
if (strlen($text)) {
|
||||||
|
$this->sections[] = rtrim($text);
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a block of text with a section header. This is rendered like this:
|
||||||
|
*
|
||||||
|
* HEADER
|
||||||
|
* Text is indented.
|
||||||
|
*
|
||||||
|
* @param string Header text.
|
||||||
|
* @param string Section text.
|
||||||
|
* @return this
|
||||||
|
* @task compose
|
||||||
|
*/
|
||||||
|
public function addTextSection($header, $text) {
|
||||||
|
$this->sections[] = $header."\n".$this->indent($text);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a Herald section with a rule management URI and a transcript URI.
|
||||||
|
*
|
||||||
|
* @param string URI to rule management.
|
||||||
|
* @param string URI to rule transcripts.
|
||||||
|
* @return this
|
||||||
|
* @task compose
|
||||||
|
*/
|
||||||
|
public function addHeraldSection($rules_uri, $xscript_uri) {
|
||||||
|
$this->addTextSection(
|
||||||
|
pht('MANAGE HERALD RULES'),
|
||||||
|
PhabricatorEnv::getProductionURI($rules_uri));
|
||||||
|
$this->addTextSection(
|
||||||
|
pht('WHY DID I GET THIS EMAIL?'),
|
||||||
|
PhabricatorEnv::getProductionURI($xscript_uri));
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a section with reply handler instructions.
|
||||||
|
*
|
||||||
|
* @param string Reply handler instructions.
|
||||||
|
* @return this
|
||||||
|
* @task compose
|
||||||
|
*/
|
||||||
|
public function addReplySection($instructions) {
|
||||||
|
if (strlen($instructions)) {
|
||||||
|
$this->addTextSection(pht('REPLY HANDLER ACTIONS'), $instructions);
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( Rendering )---------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the email body.
|
||||||
|
*
|
||||||
|
* @return string Rendered body.
|
||||||
|
* @task render
|
||||||
|
*/
|
||||||
|
public function render() {
|
||||||
|
return implode("\n\n", $this->sections)."\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indent a block of text for rendering under a section heading.
|
||||||
|
*
|
||||||
|
* @param string Text to indent.
|
||||||
|
* @return string Indented text.
|
||||||
|
* @task render
|
||||||
|
*/
|
||||||
|
private function indent($text) {
|
||||||
|
return rtrim(" ".str_replace("\n", "\n ", $text));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group metamta
|
||||||
|
*/
|
||||||
|
final class PhabricatorMetaMTAMailBodyTestCase extends PhabricatorTestCase {
|
||||||
|
|
||||||
|
public function testBodyRender() {
|
||||||
|
|
||||||
|
$env = PhabricatorEnv::beginScopedEnv();
|
||||||
|
$env->overrideEnvConfig('phabricator.base-uri', 'http://test.com/');
|
||||||
|
|
||||||
|
$body = new PhabricatorMetaMTAMailBody();
|
||||||
|
$body->addRawSection("salmon");
|
||||||
|
$body->addTextSection("HEADER", "bass\ntrout\n");
|
||||||
|
$body->addHeraldSection("/rules/", "/xscript/");
|
||||||
|
$body->addReplySection("pike");
|
||||||
|
|
||||||
|
$expect = <<<EOTEXT
|
||||||
|
salmon
|
||||||
|
|
||||||
|
HEADER
|
||||||
|
bass
|
||||||
|
trout
|
||||||
|
|
||||||
|
MANAGE HERALD RULES
|
||||||
|
http://test.com/rules/
|
||||||
|
|
||||||
|
WHY DID I GET THIS EMAIL?
|
||||||
|
http://test.com/xscript/
|
||||||
|
|
||||||
|
REPLY HANDLER ACTIONS
|
||||||
|
pike
|
||||||
|
|
||||||
|
EOTEXT;
|
||||||
|
|
||||||
|
$this->assertEqual($expect, $body->render());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -111,49 +111,29 @@ final class PhabricatorRepositoryCommitHeraldWorker
|
||||||
|
|
||||||
$files = $adapter->loadAffectedPaths();
|
$files = $adapter->loadAffectedPaths();
|
||||||
sort($files);
|
sort($files);
|
||||||
$files = implode("\n ", $files);
|
$files = implode("\n", $files);
|
||||||
|
|
||||||
$xscript_id = $xscript->getID();
|
$xscript_id = $xscript->getID();
|
||||||
|
|
||||||
$manage_uri = PhabricatorEnv::getProductionURI('/herald/view/commits/');
|
$manage_uri = '/herald/view/commits/';
|
||||||
$why_uri = PhabricatorEnv::getProductionURI(
|
$why_uri = '/herald/transcript/'.$xscript_id.'/';
|
||||||
'/herald/transcript/'.$xscript_id.'/');
|
|
||||||
|
|
||||||
$reply_handler = PhabricatorAuditCommentEditor::newReplyHandlerForCommit(
|
$reply_handler = PhabricatorAuditCommentEditor::newReplyHandlerForCommit(
|
||||||
$commit);
|
$commit);
|
||||||
|
|
||||||
$reply_instructions = $reply_handler->getReplyHandlerInstructions();
|
|
||||||
if ($reply_instructions) {
|
|
||||||
$reply_instructions =
|
|
||||||
"\n".
|
|
||||||
"REPLY HANDLER ACTIONS\n".
|
|
||||||
" ".$reply_instructions."\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$template = new PhabricatorMetaMTAMail();
|
$template = new PhabricatorMetaMTAMail();
|
||||||
|
|
||||||
$inline_patch_text = $this->buildPatch($template, $repository, $commit);
|
$inline_patch_text = $this->buildPatch($template, $repository, $commit);
|
||||||
|
|
||||||
$body = <<<EOBODY
|
$body = new PhabricatorMetaMTAMailBody();
|
||||||
DESCRIPTION
|
$body->addRawSection($description);
|
||||||
{$description}
|
$body->addTextSection(pht('DETAILS'), $commit_uri);
|
||||||
|
$body->addTextSection(pht('DIFFERENTIAL REVISION'), $differential);
|
||||||
DETAILS
|
$body->addTextSection(pht('AFFECTED FILES'), $files);
|
||||||
{$commit_uri}
|
$body->addReplySection($reply_handler->getReplyHandlerInstructions());
|
||||||
|
$body->addHeraldSection($manage_uri, $why_uri);
|
||||||
DIFFERENTIAL REVISION
|
$body->addRawSection($inline_patch_text);
|
||||||
{$differential}
|
$body = $body->render();
|
||||||
|
|
||||||
AFFECTED FILES
|
|
||||||
{$files}
|
|
||||||
{$reply_instructions}
|
|
||||||
MANAGE HERALD COMMIT RULES
|
|
||||||
{$manage_uri}
|
|
||||||
|
|
||||||
WHY DID I GET THIS EMAIL?
|
|
||||||
{$why_uri}
|
|
||||||
{$inline_patch_text}
|
|
||||||
EOBODY;
|
|
||||||
|
|
||||||
$prefix = PhabricatorEnv::getEnvConfig('metamta.diffusion.subject-prefix');
|
$prefix = PhabricatorEnv::getEnvConfig('metamta.diffusion.subject-prefix');
|
||||||
|
|
||||||
|
@ -369,7 +349,7 @@ EOBODY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$result = "\nPATCH\n\n{$result}\n";
|
$result = "PATCH\n\n{$result}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
|
|
Loading…
Reference in a new issue