mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-29 17:00:59 +01:00
Make reply-to fully work in Maniphest and Differential for open source
Phabricator Summary: Hook up the last pieces. This shouldn't impact the Facebook install, EXCEPT that I removed "!accept" and added "!rethink" (plan changes). If you want to continue supporting !accept, you should override the method in your subclass if you don't already. Test Plan: Used the Mail Receiver test console to send mail to tasks and revisions. Reviewed By: aran Reviewers: jungejason, tuomaspelkonen, aran CC: aran Differential Revision: 289
This commit is contained in:
parent
4b92b2cead
commit
a69f217f98
9 changed files with 96 additions and 39 deletions
|
@ -156,7 +156,7 @@ EOTEXT;
|
||||||
return $body;
|
return $body;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getReplyHandler() {
|
public function getReplyHandler() {
|
||||||
if ($this->replyHandler) {
|
if ($this->replyHandler) {
|
||||||
return $this->replyHandler;
|
return $this->replyHandler;
|
||||||
}
|
}
|
||||||
|
@ -164,14 +164,26 @@ EOTEXT;
|
||||||
$handler_class = PhabricatorEnv::getEnvConfig(
|
$handler_class = PhabricatorEnv::getEnvConfig(
|
||||||
'metamta.differential.reply-handler');
|
'metamta.differential.reply-handler');
|
||||||
|
|
||||||
$reply_handler = newv($handler_class, array());
|
$reply_handler = self::newReplyHandlerForRevision($this->getRevision());
|
||||||
$reply_handler->setMailReceiver($this->getRevision());
|
|
||||||
|
|
||||||
$this->replyHandler = $reply_handler;
|
$this->replyHandler = $reply_handler;
|
||||||
|
|
||||||
return $this->replyHandler;
|
return $this->replyHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function newReplyHandlerForRevision(
|
||||||
|
DifferentialRevision $revision) {
|
||||||
|
|
||||||
|
$handler_class = PhabricatorEnv::getEnvConfig(
|
||||||
|
'metamta.differential.reply-handler');
|
||||||
|
|
||||||
|
$reply_handler = newv($handler_class, array());
|
||||||
|
$reply_handler->setMailReceiver($revision);
|
||||||
|
|
||||||
|
return $reply_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected function formatText($text) {
|
protected function formatText($text) {
|
||||||
$text = explode("\n", $text);
|
$text = explode("\n", $text);
|
||||||
foreach ($text as &$line) {
|
foreach ($text as &$line) {
|
||||||
|
|
|
@ -84,14 +84,18 @@ class DifferentialReplyHandler extends PhabricatorMailReplyHandler {
|
||||||
public function getSupportedCommands() {
|
public function getSupportedCommands() {
|
||||||
return array(
|
return array(
|
||||||
DifferentialAction::ACTION_COMMENT,
|
DifferentialAction::ACTION_COMMENT,
|
||||||
DifferentialAction::ACTION_ACCEPT,
|
|
||||||
DifferentialAction::ACTION_REJECT,
|
DifferentialAction::ACTION_REJECT,
|
||||||
DifferentialAction::ACTION_ABANDON,
|
DifferentialAction::ACTION_ABANDON,
|
||||||
DifferentialAction::ACTION_RECLAIM,
|
DifferentialAction::ACTION_RECLAIM,
|
||||||
DifferentialAction::ACTION_RESIGN,
|
DifferentialAction::ACTION_RESIGN,
|
||||||
|
DifferentialAction::ACTION_RETHINK,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function receiveEmail(PhabricatorMetaMTAReceivedMail $mail) {
|
||||||
|
$this->handleAction($mail->getCleanTextBody());
|
||||||
|
}
|
||||||
|
|
||||||
public function handleAction($body) {
|
public function handleAction($body) {
|
||||||
// all commands start with a bang and separated from the body by a newline
|
// all commands start with a bang and separated from the body by a newline
|
||||||
// to make sure that actual feedback text couldn't trigger an action.
|
// to make sure that actual feedback text couldn't trigger an action.
|
||||||
|
|
|
@ -212,7 +212,7 @@ class ManiphestTransactionEditor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildReplyHandler(ManiphestTask $task) {
|
public function buildReplyHandler(ManiphestTask $task) {
|
||||||
$handler_class = PhabricatorEnv::getEnvConfig(
|
$handler_class = PhabricatorEnv::getEnvConfig(
|
||||||
'metamta.maniphest.reply-handler');
|
'metamta.maniphest.reply-handler');
|
||||||
|
|
||||||
|
|
|
@ -36,12 +36,66 @@ class ManiphestReplyHandler extends PhabricatorMailReplyHandler {
|
||||||
|
|
||||||
public function getReplyHandlerInstructions() {
|
public function getReplyHandlerInstructions() {
|
||||||
if ($this->supportsReplies()) {
|
if ($this->supportsReplies()) {
|
||||||
return "Reply to comment or attach files, or !close, !claim, ".
|
return "Reply to comment or attach files, or !close, !claim, or ".
|
||||||
"!unsubscribe, or !assign <user|upforgrabs>. ".
|
"!unsubscribe.";
|
||||||
"TODO: None of this works yet!";
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function receiveEmail(PhabricatorMetaMTAReceivedMail $mail) {
|
||||||
|
|
||||||
|
$task = $this->getMailReceiver();
|
||||||
|
$user = $this->getActor();
|
||||||
|
|
||||||
|
$body = $mail->getCleanTextBody();
|
||||||
|
$body = trim($body);
|
||||||
|
|
||||||
|
$lines = explode("\n", trim($body));
|
||||||
|
$first_line = head($lines);
|
||||||
|
|
||||||
|
$command = null;
|
||||||
|
$matches = null;
|
||||||
|
if (preg_match('/^!(\w+)/', $first_line, $matches)) {
|
||||||
|
$lines = array_slice($lines, 1);
|
||||||
|
$body = implode("\n", $lines);
|
||||||
|
$body = trim($body);
|
||||||
|
|
||||||
|
$command = $matches[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$ttype = ManiphestTransactionType::TYPE_NONE;
|
||||||
|
$new_value = null;
|
||||||
|
switch ($command) {
|
||||||
|
case 'close':
|
||||||
|
$ttype = ManiphestTransactionType::TYPE_STATUS;
|
||||||
|
$new_value = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED;
|
||||||
|
break;
|
||||||
|
case 'claim':
|
||||||
|
$ttype = ManiphestTransactionType::TYPE_OWNER;
|
||||||
|
$new_value = $user->getPHID();
|
||||||
|
break;
|
||||||
|
case 'unsubscribe':
|
||||||
|
$ttype = ManiphestTransactionType::TYPE_CCS;
|
||||||
|
$ccs = $task->getCCPHIDs();
|
||||||
|
foreach ($ccs as $k => $phid) {
|
||||||
|
if ($phid == $user->getPHID()) {
|
||||||
|
unset($ccs[$k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$new_value = array_values($ccs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$xaction = new ManiphestTransaction();
|
||||||
|
$xaction->setAuthorPHID($user->getPHID());
|
||||||
|
$xaction->setTransactionType($ttype);
|
||||||
|
$xaction->setNewValue($new_value);
|
||||||
|
$xaction->setComments($body);
|
||||||
|
|
||||||
|
$editor = new ManiphestTransactionEditor();
|
||||||
|
$editor->applyTransactions($task, array($xaction));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,14 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/maniphest/constants/status');
|
||||||
|
phutil_require_module('phabricator', 'applications/maniphest/constants/transactiontype');
|
||||||
|
phutil_require_module('phabricator', 'applications/maniphest/editor/transaction');
|
||||||
|
phutil_require_module('phabricator', 'applications/maniphest/storage/transaction');
|
||||||
phutil_require_module('phabricator', 'applications/metamta/replyhandler/base');
|
phutil_require_module('phabricator', 'applications/metamta/replyhandler/base');
|
||||||
phutil_require_module('phabricator', 'infrastructure/env');
|
phutil_require_module('phabricator', 'infrastructure/env');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
phutil_require_source('ManiphestReplyHandler.php');
|
phutil_require_source('ManiphestReplyHandler.php');
|
||||||
|
|
|
@ -32,8 +32,8 @@ class PhabricatorMetaMTAReceiveController
|
||||||
}
|
}
|
||||||
|
|
||||||
$hash = PhabricatorMetaMTAReceivedMail::computeMailHash(
|
$hash = PhabricatorMetaMTAReceivedMail::computeMailHash(
|
||||||
$receiver,
|
$receiver->getMailKey(),
|
||||||
$user);
|
$user->getPHID());
|
||||||
|
|
||||||
$received = new PhabricatorMetaMTAReceivedMail();
|
$received = new PhabricatorMetaMTAReceivedMail();
|
||||||
$received->setHeaders(
|
$received->setHeaders(
|
||||||
|
|
|
@ -45,6 +45,7 @@ abstract class PhabricatorMailReplyHandler {
|
||||||
PhabricatorObjectHandle $handle);
|
PhabricatorObjectHandle $handle);
|
||||||
abstract public function getReplyHandlerDomain();
|
abstract public function getReplyHandlerDomain();
|
||||||
abstract public function getReplyHandlerInstructions();
|
abstract public function getReplyHandlerInstructions();
|
||||||
|
abstract public function receiveEmail(PhabricatorMetaMTAReceivedMail $mail);
|
||||||
|
|
||||||
public function supportsPrivateReplies() {
|
public function supportsPrivateReplies() {
|
||||||
return (bool)$this->getReplyHandlerDomain();
|
return (bool)$this->getReplyHandlerDomain();
|
||||||
|
|
|
@ -78,42 +78,22 @@ class PhabricatorMetaMTAReceivedMail extends PhabricatorMetaMTADAO {
|
||||||
return $this->setMessage("Invalid mail hash!")->save();
|
return $this->setMessage("Invalid mail hash!")->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move this into the application logic instead.
|
|
||||||
if ($receiver instanceof ManiphestTask) {
|
if ($receiver instanceof ManiphestTask) {
|
||||||
$this->processManiphestMail($receiver, $user);
|
$editor = new ManiphestTransactionEditor();
|
||||||
|
$handler = $editor->buildReplyHandler($receiver);
|
||||||
} else if ($receiver instanceof DifferentialRevision) {
|
} else if ($receiver instanceof DifferentialRevision) {
|
||||||
$this->processDifferentialMail($receiver, $user);
|
$handler = DifferentialMail::newReplyHandlerForRevision($receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$handler->setActor($user);
|
||||||
|
$handler->receiveEmail($this);
|
||||||
|
|
||||||
$this->setMessage('OK');
|
$this->setMessage('OK');
|
||||||
|
|
||||||
return $this->save();
|
return $this->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processManiphestMail(
|
public function getCleanTextBody() {
|
||||||
ManiphestTask $task,
|
|
||||||
PhabricatorUser $user) {
|
|
||||||
|
|
||||||
// TODO: implement this
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private function processDifferentialMail(
|
|
||||||
DifferentialRevision $revision,
|
|
||||||
PhabricatorUser $user) {
|
|
||||||
|
|
||||||
// TODO: Support actions
|
|
||||||
|
|
||||||
$editor = new DifferentialCommentEditor(
|
|
||||||
$revision,
|
|
||||||
$user->getPHID(),
|
|
||||||
DifferentialAction::ACTION_COMMENT);
|
|
||||||
$editor->setMessage($this->getCleanTextBody());
|
|
||||||
$editor->save();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getCleanTextBody() {
|
|
||||||
$body = idx($this->bodies, 'text');
|
$body = idx($this->bodies, 'text');
|
||||||
|
|
||||||
// TODO: Detect quoted content and exclude it.
|
// TODO: Detect quoted content and exclude it.
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
phutil_require_module('phabricator', 'applications/differential/constants/action');
|
phutil_require_module('phabricator', 'applications/differential/mail/base');
|
||||||
phutil_require_module('phabricator', 'applications/differential/editor/comment');
|
phutil_require_module('phabricator', 'applications/maniphest/editor/transaction');
|
||||||
phutil_require_module('phabricator', 'applications/metamta/storage/base');
|
phutil_require_module('phabricator', 'applications/metamta/storage/base');
|
||||||
phutil_require_module('phabricator', 'applications/people/storage/user');
|
phutil_require_module('phabricator', 'applications/people/storage/user');
|
||||||
phutil_require_module('phabricator', 'infrastructure/env');
|
phutil_require_module('phabricator', 'infrastructure/env');
|
||||||
|
|
Loading…
Reference in a new issue