mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-05 12:21:02 +01:00
Conpherence - reply handler integration
Summary: Added a reply handler. A few problems -- first, I can't seem to get this to actually send me email so I haven't been able to reply (which I would have done by generating a reply, then copying the raw email into scripts/mail_handler.php). Second, the subject is often terrible on these emails -- unless the conpherence is named its something gross like "E4:" Third, on create I am noticing an error on array_combine() which I think is related to the need to write array_combine_not_broken or what have you I saw go by... (PhabricatorTransactionEditor does array_combine(xaction->getOldValue(), xaction->getOldValue()) and complains that the arrays are empty) Test Plan: noted that /mail/ said mails were being sent Reviewers: epriestley Reviewed By: epriestley CC: chad, aran, Korvin Maniphest Tasks: T2399 Differential Revision: https://secure.phabricator.com/D4656
This commit is contained in:
parent
e344f57df1
commit
4d22c9104f
9 changed files with 151 additions and 16 deletions
|
@ -195,6 +195,7 @@ phutil_register_library_map(array(
|
||||||
'ConduitCallTestCase' => 'applications/conduit/call/__tests__/ConduitCallTestCase.php',
|
'ConduitCallTestCase' => 'applications/conduit/call/__tests__/ConduitCallTestCase.php',
|
||||||
'ConduitException' => 'applications/conduit/protocol/ConduitException.php',
|
'ConduitException' => 'applications/conduit/protocol/ConduitException.php',
|
||||||
'ConduitSSHWorkflow' => 'applications/conduit/ssh/ConduitSSHWorkflow.php',
|
'ConduitSSHWorkflow' => 'applications/conduit/ssh/ConduitSSHWorkflow.php',
|
||||||
|
'ConpherenceConfigOptions' => 'applications/conpherence/config/ConpherenceConfigOptions.php',
|
||||||
'ConpherenceConstants' => 'applications/conpherence/constants/ConpherenceConstants.php',
|
'ConpherenceConstants' => 'applications/conpherence/constants/ConpherenceConstants.php',
|
||||||
'ConpherenceController' => 'applications/conpherence/controller/ConpherenceController.php',
|
'ConpherenceController' => 'applications/conpherence/controller/ConpherenceController.php',
|
||||||
'ConpherenceDAO' => 'applications/conpherence/storage/ConpherenceDAO.php',
|
'ConpherenceDAO' => 'applications/conpherence/storage/ConpherenceDAO.php',
|
||||||
|
@ -205,6 +206,7 @@ phutil_register_library_map(array(
|
||||||
'ConpherenceParticipant' => 'applications/conpherence/storage/ConpherenceParticipant.php',
|
'ConpherenceParticipant' => 'applications/conpherence/storage/ConpherenceParticipant.php',
|
||||||
'ConpherenceParticipantQuery' => 'applications/conpherence/query/ConpherenceParticipantQuery.php',
|
'ConpherenceParticipantQuery' => 'applications/conpherence/query/ConpherenceParticipantQuery.php',
|
||||||
'ConpherenceParticipationStatus' => 'applications/conpherence/constants/ConpherenceParticipationStatus.php',
|
'ConpherenceParticipationStatus' => 'applications/conpherence/constants/ConpherenceParticipationStatus.php',
|
||||||
|
'ConpherenceReplyHandler' => 'applications/conpherence/mail/ConpherenceReplyHandler.php',
|
||||||
'ConpherenceThread' => 'applications/conpherence/storage/ConpherenceThread.php',
|
'ConpherenceThread' => 'applications/conpherence/storage/ConpherenceThread.php',
|
||||||
'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php',
|
'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php',
|
||||||
'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php',
|
'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php',
|
||||||
|
@ -1666,6 +1668,7 @@ phutil_register_library_map(array(
|
||||||
'ConduitCallTestCase' => 'PhabricatorTestCase',
|
'ConduitCallTestCase' => 'PhabricatorTestCase',
|
||||||
'ConduitException' => 'Exception',
|
'ConduitException' => 'Exception',
|
||||||
'ConduitSSHWorkflow' => 'PhabricatorSSHWorkflow',
|
'ConduitSSHWorkflow' => 'PhabricatorSSHWorkflow',
|
||||||
|
'ConpherenceConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
'ConpherenceController' => 'PhabricatorController',
|
'ConpherenceController' => 'PhabricatorController',
|
||||||
'ConpherenceDAO' => 'PhabricatorLiskDAO',
|
'ConpherenceDAO' => 'PhabricatorLiskDAO',
|
||||||
'ConpherenceEditor' => 'PhabricatorApplicationTransactionEditor',
|
'ConpherenceEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||||
|
@ -1675,6 +1678,7 @@ phutil_register_library_map(array(
|
||||||
'ConpherenceParticipant' => 'ConpherenceDAO',
|
'ConpherenceParticipant' => 'ConpherenceDAO',
|
||||||
'ConpherenceParticipantQuery' => 'PhabricatorOffsetPagedQuery',
|
'ConpherenceParticipantQuery' => 'PhabricatorOffsetPagedQuery',
|
||||||
'ConpherenceParticipationStatus' => 'ConpherenceConstants',
|
'ConpherenceParticipationStatus' => 'ConpherenceConstants',
|
||||||
|
'ConpherenceReplyHandler' => 'PhabricatorMailReplyHandler',
|
||||||
'ConpherenceThread' =>
|
'ConpherenceThread' =>
|
||||||
array(
|
array(
|
||||||
0 => 'ConpherenceDAO',
|
0 => 'ConpherenceDAO',
|
||||||
|
|
|
@ -235,6 +235,13 @@ EODOC
|
||||||
pht(
|
pht(
|
||||||
'Controls whether Phabricator sends email "From" users.'))
|
'Controls whether Phabricator sends email "From" users.'))
|
||||||
->setDescription($send_as_user_desc),
|
->setDescription($send_as_user_desc),
|
||||||
|
$this->newOption(
|
||||||
|
'metamta.reply-handler-domain',
|
||||||
|
'string',
|
||||||
|
'phabricator.example.com')
|
||||||
|
->setDescription(pht(
|
||||||
|
'Domain used for reply email addresses. Some applications can '.
|
||||||
|
'configure this domain.')),
|
||||||
$this->newOption('metamta.reply.show-hints', 'bool', true)
|
$this->newOption('metamta.reply.show-hints', 'bool', true)
|
||||||
->setBoolOptions(
|
->setBoolOptions(
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ConpherenceConfigOptions
|
||||||
|
extends PhabricatorApplicationConfigOptions {
|
||||||
|
|
||||||
|
public function getName() {
|
||||||
|
return pht('Copherence');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription() {
|
||||||
|
return pht('Configure Conpherence messaging.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOptions() {
|
||||||
|
return array(
|
||||||
|
$this->newOption(
|
||||||
|
'metamta.conpherence.subject-prefix',
|
||||||
|
'string',
|
||||||
|
'[Conpherence]')
|
||||||
|
->setDescription(pht('Subject prefix for Conpherence mail.')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -60,6 +60,11 @@ final class ConpherenceNewController extends ConpherenceController {
|
||||||
$xactions[] = id(new ConpherenceTransaction())
|
$xactions[] = id(new ConpherenceTransaction())
|
||||||
->setTransactionType(ConpherenceTransactionType::TYPE_PARTICIPANTS)
|
->setTransactionType(ConpherenceTransactionType::TYPE_PARTICIPANTS)
|
||||||
->setNewValue(array('+' => $participants));
|
->setNewValue(array('+' => $participants));
|
||||||
|
if ($files) {
|
||||||
|
$xactions[] = id(new ConpherenceTransaction())
|
||||||
|
->setTransactionType(ConpherenceTransactionType::TYPE_FILES)
|
||||||
|
->setNewValue(array('+' => mpull($files, 'getPHID')));
|
||||||
|
}
|
||||||
$xactions[] = id(new ConpherenceTransaction())
|
$xactions[] = id(new ConpherenceTransaction())
|
||||||
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
|
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
|
||||||
->attachComment(
|
->attachComment(
|
||||||
|
@ -67,11 +72,6 @@ final class ConpherenceNewController extends ConpherenceController {
|
||||||
->setContent($message)
|
->setContent($message)
|
||||||
->setConpherencePHID($conpherence->getPHID())
|
->setConpherencePHID($conpherence->getPHID())
|
||||||
);
|
);
|
||||||
if ($files) {
|
|
||||||
$xactions[] = id(new ConpherenceTransaction())
|
|
||||||
->setTransactionType(ConpherenceTransactionType::TYPE_FILES)
|
|
||||||
->setNewValue(array('+' => mpull($files, 'getPHID')));
|
|
||||||
}
|
|
||||||
$content_source = PhabricatorContentSource::newForSource(
|
$content_source = PhabricatorContentSource::newForSource(
|
||||||
PhabricatorContentSource::SOURCE_WEB,
|
PhabricatorContentSource::SOURCE_WEB,
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -120,33 +120,40 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function supportsMail() {
|
protected function supportsMail() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO
|
|
||||||
|
|
||||||
protected function buildReplyHandler(PhabricatorLiskDAO $object) {
|
protected function buildReplyHandler(PhabricatorLiskDAO $object) {
|
||||||
return id(new ConpherenceReplyHandler())
|
return id(new ConpherenceReplyHandler())
|
||||||
|
->setActor($this->getActor())
|
||||||
->setMailReceiver($object);
|
->setMailReceiver($object);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildMailTemplate(PhabricatorLiskDAO $object) {
|
protected function buildMailTemplate(PhabricatorLiskDAO $object) {
|
||||||
$id = $object->getID();
|
$id = $object->getID();
|
||||||
$title = $object->getTitle();
|
$title = $object->getTitle();
|
||||||
|
if (!$title) {
|
||||||
|
$title = pht(
|
||||||
|
'%s sent you a message.',
|
||||||
|
$this->getActor()->getUserName()
|
||||||
|
);
|
||||||
|
}
|
||||||
$phid = $object->getPHID();
|
$phid = $object->getPHID();
|
||||||
$original_name = $object->getOriginalName();
|
|
||||||
|
|
||||||
return id(new PhabricatorMetaMTAMail())
|
return id(new PhabricatorMetaMTAMail())
|
||||||
->setSubject("C{$id}: {$title}")
|
->setSubject("E{$id}: {$title}")
|
||||||
->addHeader('Thread-Topic', "C{$id}: {$phid}");
|
->addHeader('Thread-Topic', "E{$id}: {$phid}");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getMailTo(PhabricatorLiskDAO $object) {
|
protected function getMailTo(PhabricatorLiskDAO $object) {
|
||||||
$participants = $object->getParticipants();
|
$participants = $object->getParticipants();
|
||||||
$participants[$this->requireActor()->getPHID()] = true;
|
|
||||||
return array_keys($participants);
|
return array_keys($participants);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getMailCC(PhabricatorLiskDAO $object) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
protected function buildMailBody(
|
protected function buildMailBody(
|
||||||
PhabricatorLiskDAO $object,
|
PhabricatorLiskDAO $object,
|
||||||
array $xactions) {
|
array $xactions) {
|
||||||
|
@ -162,7 +169,6 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
||||||
protected function getMailSubjectPrefix() {
|
protected function getMailSubjectPrefix() {
|
||||||
return PhabricatorEnv::getEnvConfig('metamta.conpherence.subject-prefix');
|
return PhabricatorEnv::getEnvConfig('metamta.conpherence.subject-prefix');
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
protected function supportsFeed() {
|
protected function supportsFeed() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group conpherence
|
||||||
|
*/
|
||||||
|
final class ConpherenceReplyHandler extends PhabricatorMailReplyHandler {
|
||||||
|
|
||||||
|
public function validateMailReceiver($mail_receiver) {
|
||||||
|
if (!($mail_receiver instanceof ConpherenceThread)) {
|
||||||
|
throw new Exception("Mail receiver is not a ConpherenceThread!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPrivateReplyHandlerEmailAddress(
|
||||||
|
PhabricatorObjectHandle $handle) {
|
||||||
|
return $this->getDefaultPrivateReplyHandlerEmailAddress($handle, 'E');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPublicReplyHandlerEmailAddress() {
|
||||||
|
return $this->getDefaultPublicReplyHandlerEmailAddress('E');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getReplyHandlerInstructions() {
|
||||||
|
if ($this->supportsReplies()) {
|
||||||
|
return pht('Reply to comment and attach files.');
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail) {
|
||||||
|
$conpherence = $this->getMailReceiver();
|
||||||
|
$user = $this->getActor();
|
||||||
|
|
||||||
|
$body = $mail->getCleanTextBody();
|
||||||
|
$body = trim($body);
|
||||||
|
$file_phids = $mail->getAttachments();
|
||||||
|
$body = $this->enhanceBodyWithAttachments($body, $file_phids);
|
||||||
|
|
||||||
|
$xactions = array();
|
||||||
|
if ($file_phids) {
|
||||||
|
$xactions[] = id(new ConpherenceTransaction())
|
||||||
|
->setTransactionType(ConpherenceTransactionType::TYPE_FILES)
|
||||||
|
->setNewValue(array('+' => $file_phids));
|
||||||
|
}
|
||||||
|
$xactions[] = id(new ConpherenceTransaction())
|
||||||
|
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
|
||||||
|
->attachComment(
|
||||||
|
id(new ConpherenceTransactionComment())
|
||||||
|
->setContent($body)
|
||||||
|
->setConpherencePHID($conpherence->getPHID())
|
||||||
|
);
|
||||||
|
|
||||||
|
$content_source = PhabricatorContentSource::newForSource(
|
||||||
|
PhabricatorContentSource::SOURCE_EMAIL,
|
||||||
|
array(
|
||||||
|
'id' => $mail->getID(),
|
||||||
|
));
|
||||||
|
|
||||||
|
$editor = id(new ConpherenceEditor())
|
||||||
|
->setActor($user)
|
||||||
|
->setContentSource($content_source)
|
||||||
|
->setParentMessageID($mail->getMessageID())
|
||||||
|
->applyTransactions($conpherence, $xactions);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -37,7 +37,11 @@ abstract class PhabricatorMailReplyHandler {
|
||||||
abstract public function validateMailReceiver($mail_receiver);
|
abstract public function validateMailReceiver($mail_receiver);
|
||||||
abstract public function getPrivateReplyHandlerEmailAddress(
|
abstract public function getPrivateReplyHandlerEmailAddress(
|
||||||
PhabricatorObjectHandle $handle);
|
PhabricatorObjectHandle $handle);
|
||||||
abstract public function getReplyHandlerDomain();
|
public function getReplyHandlerDomain() {
|
||||||
|
return PhabricatorEnv::getEnvConfig(
|
||||||
|
'metamta.reply-handler-domain'
|
||||||
|
);
|
||||||
|
}
|
||||||
abstract public function getReplyHandlerInstructions();
|
abstract public function getReplyHandlerInstructions();
|
||||||
abstract protected function receiveEmail(
|
abstract protected function receiveEmail(
|
||||||
PhabricatorMetaMTAReceivedMail $mail);
|
PhabricatorMetaMTAReceivedMail $mail);
|
||||||
|
|
|
@ -289,6 +289,10 @@ final class PhabricatorMetaMTAReceivedMail extends PhabricatorMetaMTADAO {
|
||||||
} else if ($receiver instanceof PhabricatorRepositoryCommit) {
|
} else if ($receiver instanceof PhabricatorRepositoryCommit) {
|
||||||
$handler = PhabricatorAuditCommentEditor::newReplyHandlerForCommit(
|
$handler = PhabricatorAuditCommentEditor::newReplyHandlerForCommit(
|
||||||
$receiver);
|
$receiver);
|
||||||
|
} else if ($receiver instanceof ConpherenceThread) {
|
||||||
|
$handler = id(new ConpherenceEditor())
|
||||||
|
->setActor($user)
|
||||||
|
->buildReplyHandler($receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
$handler->setActor($user);
|
$handler->setActor($user);
|
||||||
|
@ -331,6 +335,9 @@ final class PhabricatorMetaMTAReceivedMail extends PhabricatorMetaMTADAO {
|
||||||
case 'C':
|
case 'C':
|
||||||
$class_obj = new PhabricatorRepositoryCommit();
|
$class_obj = new PhabricatorRepositoryCommit();
|
||||||
break;
|
break;
|
||||||
|
case 'E':
|
||||||
|
$class_obj = new ConpherenceThread();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
private $isNewObject;
|
private $isNewObject;
|
||||||
private $mentionedPHIDs;
|
private $mentionedPHIDs;
|
||||||
private $continueOnNoEffect;
|
private $continueOnNoEffect;
|
||||||
|
private $parentMessageID;
|
||||||
|
|
||||||
private $isPreview;
|
private $isPreview;
|
||||||
|
|
||||||
|
@ -40,6 +41,18 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
return $this->continueOnNoEffect;
|
return $this->continueOnNoEffect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not strictly necessary, but reply handlers ideally set this value to
|
||||||
|
* make email threading work better.
|
||||||
|
*/
|
||||||
|
public function setParentMessageID($parent_message_id) {
|
||||||
|
$this->parentMessageID = $parent_message_id;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
public function getParentMessageID() {
|
||||||
|
return $this->parentMessageID;
|
||||||
|
}
|
||||||
|
|
||||||
protected function getIsNewObject() {
|
protected function getIsNewObject() {
|
||||||
return $this->isNewObject;
|
return $this->isNewObject;
|
||||||
}
|
}
|
||||||
|
@ -669,8 +682,9 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
->setIsBulk(true)
|
->setIsBulk(true)
|
||||||
->setBody($body->render());
|
->setBody($body->render());
|
||||||
|
|
||||||
// TODO
|
if ($this->getParentMessageID()) {
|
||||||
// ->setParentMessageID(...)
|
$template->setParentMessageID($this->getParentMessageID());
|
||||||
|
}
|
||||||
|
|
||||||
$mails = $this
|
$mails = $this
|
||||||
->buildReplyHandler($object)
|
->buildReplyHandler($object)
|
||||||
|
|
Loading…
Reference in a new issue