Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/conpherence/controller/ConpherenceUpdateController.php b/src/applications/conpherence/controller/ConpherenceUpdateController.php
index 4fe4ddcb1e..cf193f4419 100644
--- a/src/applications/conpherence/controller/ConpherenceUpdateController.php
+++ b/src/applications/conpherence/controller/ConpherenceUpdateController.php
@@ -1,209 +1,187 @@
<?php
/**
* @group conpherence
*/
final class ConpherenceUpdateController extends
ConpherenceController {
private $conpherenceID;
public function setConpherenceID($conpherence_id) {
$this->conpherenceID = $conpherence_id;
return $this;
}
public function getConpherenceID() {
return $this->conpherenceID;
}
public function willProcessRequest(array $data) {
$this->setConpherenceID(idx($data, 'id'));
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$conpherence_id = $this->getConpherenceID();
if (!$conpherence_id) {
return new Aphront404Response();
}
$conpherence = id(new ConpherenceThreadQuery())
->setViewer($user)
->withIDs(array($conpherence_id))
->executeOne();
$supported_formats = PhabricatorFile::getTransformableImageFormats();
$updated = false;
$error_view = null;
$e_file = array();
$errors = array();
if ($request->isFormPost()) {
$content_source = PhabricatorContentSource::newForSource(
PhabricatorContentSource::SOURCE_WEB,
array(
'ip' => $request->getRemoteAddr()
));
+ $editor = id(new ConpherenceEditor())
+ ->setContentSource($content_source)
+ ->setActor($user);
$action = $request->getStr('action');
switch ($action) {
case 'message':
$message = $request->getStr('text');
- $files = array();
- $file_phids =
- PhabricatorMarkupEngine::extractFilePHIDsFromEmbeddedFiles(
- array($message)
- );
- if ($file_phids) {
- $files = id(new PhabricatorFileQuery())
- ->setViewer($user)
- ->withPHIDs($file_phids)
- ->execute();
- }
- $xactions = array();
- if ($files) {
- $xactions[] = id(new ConpherenceTransaction())
- ->setTransactionType(ConpherenceTransactionType::TYPE_FILES)
- ->setNewValue(array('+' => mpull($files, 'getPHID')));
- }
- $xactions[] = id(new ConpherenceTransaction())
- ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
- ->attachComment(
- id(new ConpherenceTransactionComment())
- ->setContent($message)
- ->setConpherencePHID($conpherence->getPHID())
- );
+ $xactions = $editor->generateTransactionsFromText(
+ $conpherence,
+ $message
+ );
$time = time();
$conpherence->openTransaction();
- $xactions = id(new ConpherenceEditor())
- ->setContentSource($content_source)
- ->setActor($user)
- ->applyTransactions($conpherence, $xactions);
+ $xactions = $editor->applyTransactions($conpherence, $xactions);
$last_xaction = end($xactions);
$xaction_phid = $last_xaction->getPHID();
$behind = ConpherenceParticipationStatus::BEHIND;
$up_to_date = ConpherenceParticipationStatus::UP_TO_DATE;
$participants = $conpherence->getParticipants();
foreach ($participants as $phid => $participant) {
if ($phid != $user->getPHID()) {
if ($participant->getParticipationStatus() != $behind) {
$participant->setBehindTransactionPHID($xaction_phid);
}
$participant->setParticipationStatus($behind);
$participant->setDateTouched($time);
} else {
$participant->setParticipationStatus($up_to_date);
$participant->setDateTouched($time);
}
$participant->save();
}
$updated = $conpherence->saveTransaction();
break;
case 'metadata':
$xactions = array();
$images = $request->getArr('image');
if ($images) {
// just take the first one
$file_phid = reset($images);
$file = id(new PhabricatorFileQuery())
->setViewer($user)
->withPHIDs(array($file_phid))
->executeOne();
$okay = $file->isTransformableImage();
if ($okay) {
$xformer = new PhabricatorImageTransformer();
$xformed = $xformer->executeThumbTransform(
$file,
$x = 50,
$y = 50);
$image_phid = $xformed->getPHID();
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_PICTURE)
->setNewValue($image_phid);
} else {
$e_file[] = $file;
$errors[] =
pht('This server only supports these image formats: %s.',
implode(', ', $supported_formats));
}
}
$title = $request->getStr('title');
if ($title != $conpherence->getTitle()) {
$xactions[] = id(new ConpherenceTransaction())
->setTransactionType(ConpherenceTransactionType::TYPE_TITLE)
->setNewValue($title);
}
if ($xactions) {
$conpherence->openTransaction();
- $xactions = id(new ConpherenceEditor())
- ->setContentSource($content_source)
- ->setActor($user)
+ $xactions = $editor
->setContinueOnNoEffect(true)
->applyTransactions($conpherence, $xactions);
$updated = $conpherence->saveTransaction();
} else if (empty($errors)) {
$errors[] = pht(
'That was a non-update. Try cancel.'
);
}
break;
default:
throw new Exception('Unknown action: '.$action);
break;
}
}
if ($updated) {
return id(new AphrontRedirectResponse())->setURI(
$this->getApplicationURI($conpherence_id.'/')
);
}
if ($errors) {
$error_view = id(new AphrontErrorView())
->setTitle(pht('Errors editing conpherence.'))
->setInsideDialogue(true)
->setErrors($errors);
}
$form = id(new AphrontFormLayoutView())
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Title'))
->setName('title')
->setValue($conpherence->getTitle())
)
->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Image'))
->setValue(phutil_render_tag(
'img',
array(
'src' => $conpherence->loadImageURI(),
))
)
)
->appendChild(
id(new AphrontFormDragAndDropUploadControl())
->setLabel(pht('Change Image'))
->setName('image')
->setValue($e_file)
->setCaption('Supported formats: '.implode(', ', $supported_formats))
);
require_celerity_resource('conpherence-update-css');
return id(new AphrontDialogResponse())
->setDialog(
id(new AphrontDialogView())
->setUser($user)
->setTitle(pht('Update Conpherence'))
->setWidth(AphrontDialogView::WIDTH_FORM)
->setSubmitURI($this->getApplicationURI('update/'.$conpherence_id.'/'))
->addHiddenInput('action', 'metadata')
->appendChild($error_view)
->appendChild($form)
->addSubmitButton()
->addCancelButton($this->getApplicationURI($conpherence->getID().'/'))
);
}
}
diff --git a/src/applications/conpherence/editor/ConpherenceEditor.php b/src/applications/conpherence/editor/ConpherenceEditor.php
index f993696ed0..9304e0f14e 100644
--- a/src/applications/conpherence/editor/ConpherenceEditor.php
+++ b/src/applications/conpherence/editor/ConpherenceEditor.php
@@ -1,181 +1,217 @@
<?php
/**
* @group conpherence
*/
final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
+ public function generateTransactionsFromText(
+ ConpherenceThread $conpherence,
+ $text) {
+
+ $files = array();
+ $file_phids =
+ PhabricatorMarkupEngine::extractFilePHIDsFromEmbeddedFiles(
+ array($text)
+ );
+ // Since these are extracted from text, we might be re-including the
+ // same file -- e.g. a mock under discussion. Filter files we
+ // already have.
+ $existing_file_phids = $conpherence->getFilePHIDs();
+ $file_phids = array_diff($file_phids, $existing_file_phids);
+ if ($file_phids) {
+ $files = id(new PhabricatorFileQuery())
+ ->setViewer($this->getActor())
+ ->withPHIDs($file_phids)
+ ->execute();
+ }
+ $xactions = array();
+ if ($files) {
+ $xactions[] = id(new ConpherenceTransaction())
+ ->setTransactionType(ConpherenceTransactionType::TYPE_FILES)
+ ->setNewValue(array('+' => mpull($files, 'getPHID')));
+ }
+ $xactions[] = id(new ConpherenceTransaction())
+ ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
+ ->attachComment(
+ id(new ConpherenceTransactionComment())
+ ->setContent($text)
+ ->setConpherencePHID($conpherence->getPHID())
+ );
+ return $xactions;
+ }
+
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
$types[] = PhabricatorTransactions::TYPE_COMMENT;
$types[] = ConpherenceTransactionType::TYPE_TITLE;
$types[] = ConpherenceTransactionType::TYPE_PICTURE;
$types[] = ConpherenceTransactionType::TYPE_PARTICIPANTS;
$types[] = ConpherenceTransactionType::TYPE_FILES;
return $types;
}
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_TITLE:
return $object->getTitle();
case ConpherenceTransactionType::TYPE_PICTURE:
return $object->getImagePHID();
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
return $object->getParticipantPHIDs();
case ConpherenceTransactionType::TYPE_FILES:
return $object->getFilePHIDs();
}
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransactionType::TYPE_PICTURE:
return $xaction->getNewValue();
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
case ConpherenceTransactionType::TYPE_FILES:
return $this->getPHIDTransactionNewValue($xaction);
}
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_TITLE:
$object->setTitle($xaction->getNewValue());
break;
case ConpherenceTransactionType::TYPE_PICTURE:
$object->setImagePHID($xaction->getNewValue());
break;
}
}
/**
* For now this only supports adding more files and participants.
*/
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case ConpherenceTransactionType::TYPE_FILES:
$editor = id(new PhabricatorEdgeEditor())
->setActor($this->getActor());
$edge_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_FILE;
foreach ($xaction->getNewValue() as $file_phid) {
$editor->addEdge(
$object->getPHID(),
$edge_type,
$file_phid
);
}
$editor->save();
break;
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
foreach ($xaction->getNewValue() as $participant) {
if ($participant == $this->getActor()->getPHID()) {
$status = ConpherenceParticipationStatus::UP_TO_DATE;
} else {
$status = ConpherenceParticipationStatus::BEHIND;
}
id(new ConpherenceParticipant())
->setConpherencePHID($object->getPHID())
->setParticipantPHID($participant)
->setParticipationStatus($status)
->setDateTouched(time())
->setBehindTransactionPHID($xaction->getPHID())
->save();
}
break;
}
}
protected function mergeTransactions(
PhabricatorApplicationTransaction $u,
PhabricatorApplicationTransaction $v) {
$type = $u->getTransactionType();
switch ($type) {
case ConpherenceTransactionType::TYPE_TITLE:
case ConpherenceTransactionType::TYPE_PICTURE:
return $v;
case ConpherenceTransactionType::TYPE_FILES:
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
return $this->mergePHIDTransactions($u, $v);
}
return parent::mergeTransactions($u, $v);
}
protected function supportsMail() {
return true;
}
protected function buildReplyHandler(PhabricatorLiskDAO $object) {
return id(new ConpherenceReplyHandler())
->setActor($this->getActor())
->setMailReceiver($object);
}
protected function buildMailTemplate(PhabricatorLiskDAO $object) {
$id = $object->getID();
$title = $object->getTitle();
if (!$title) {
$title = pht(
'%s sent you a message.',
$this->getActor()->getUserName()
);
}
$phid = $object->getPHID();
return id(new PhabricatorMetaMTAMail())
->setSubject("E{$id}: {$title}")
->addHeader('Thread-Topic', "E{$id}: {$phid}");
}
protected function getMailTo(PhabricatorLiskDAO $object) {
$participants = $object->getParticipants();
return array_keys($participants);
}
protected function getMailCC(PhabricatorLiskDAO $object) {
return array();
}
protected function buildMailBody(
PhabricatorLiskDAO $object,
array $xactions) {
$body = parent::buildMailBody($object, $xactions);
$body->addTextSection(
pht('CONPHERENCE DETAIL'),
PhabricatorEnv::getProductionURI('/conpherence/'.$object->getID().'/'));
return $body;
}
protected function getMailSubjectPrefix() {
return PhabricatorEnv::getEnvConfig('metamta.conpherence.subject-prefix');
}
protected function supportsFeed() {
return false;
}
protected function supportsSearch() {
return false;
}
}
diff --git a/src/applications/conpherence/mail/ConpherenceReplyHandler.php b/src/applications/conpherence/mail/ConpherenceReplyHandler.php
index 60aa0e152e..f7de36cb25 100644
--- a/src/applications/conpherence/mail/ConpherenceReplyHandler.php
+++ b/src/applications/conpherence/mail/ConpherenceReplyHandler.php
@@ -1,85 +1,80 @@
<?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();
if (!$conpherence->getPHID()) {
$conpherence
->attachParticipants(array())
->attachFilePHIDs(array());
} else {
$edge_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_FILE;
$file_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
$conpherence->getPHID(),
$edge_type
);
$conpherence->attachFilePHIDs($file_phids);
$participants = id(new ConpherenceParticipant())
->loadAllWhere('conpherencePHID = %s', $conpherence->getPHID());
$participants = mpull($participants, null, 'getParticipantPHID');
$conpherence->attachParticipants($participants);
}
- $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);
+ ->setParentMessageID($mail->getMessageID());
+
+ $body = $mail->getCleanTextBody();
+ $body = trim($body);
+ $file_phids = $mail->getAttachments();
+ $body = $this->enhanceBodyWithAttachments(
+ $body,
+ $file_phids,
+ '{F%d}'
+ );
+ $xactions = $editor->generateTransactionsFromText(
+ $conpherence,
+ $body
+ );
+
+ $editor->applyTransactions($conpherence, $xactions);
return null;
}
}
diff --git a/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php b/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php
index d6b862e23d..51784d7b96 100644
--- a/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php
+++ b/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php
@@ -1,320 +1,322 @@
<?php
abstract class PhabricatorMailReplyHandler {
private $mailReceiver;
private $actor;
private $excludePHIDs = array();
final public function setMailReceiver($mail_receiver) {
$this->validateMailReceiver($mail_receiver);
$this->mailReceiver = $mail_receiver;
return $this;
}
final public function getMailReceiver() {
return $this->mailReceiver;
}
final public function setActor(PhabricatorUser $actor) {
$this->actor = $actor;
return $this;
}
final public function getActor() {
return $this->actor;
}
final public function setExcludeMailRecipientPHIDs(array $exclude) {
$this->excludePHIDs = $exclude;
return $this;
}
final public function getExcludeMailRecipientPHIDs() {
return $this->excludePHIDs;
}
abstract public function validateMailReceiver($mail_receiver);
abstract public function getPrivateReplyHandlerEmailAddress(
PhabricatorObjectHandle $handle);
public function getReplyHandlerDomain() {
return PhabricatorEnv::getEnvConfig(
'metamta.reply-handler-domain'
);
}
abstract public function getReplyHandlerInstructions();
abstract protected function receiveEmail(
PhabricatorMetaMTAReceivedMail $mail);
public function processEmail(PhabricatorMetaMTAReceivedMail $mail) {
$error = $this->sanityCheckEmail($mail);
if ($error) {
if ($this->shouldSendErrorEmail($mail)) {
$this->sendErrorEmail($error, $mail);
}
return null;
}
return $this->receiveEmail($mail);
}
private function sanityCheckEmail(PhabricatorMetaMTAReceivedMail $mail) {
$body = $mail->getCleanTextBody();
$attachments = $mail->getAttachments();
if (empty($body) && empty($attachments)) {
return 'Empty email body. Email should begin with an !action and / or '.
'text to comment. Inline replies and signatures are ignored.';
}
return null;
}
/**
* Only send an error email if the user is talking to just Phabricator. We
* can assume if there is only one To address it is a Phabricator address
* since this code is running and everything.
*/
private function shouldSendErrorEmail(PhabricatorMetaMTAReceivedMail $mail) {
return (count($mail->getToAddresses()) == 1) &&
(count($mail->getCCAddresses()) == 0);
}
private function sendErrorEmail($error,
PhabricatorMetaMTAReceivedMail $mail) {
$template = new PhabricatorMetaMTAMail();
$template->setSubject('Exception: unable to process your mail request');
$template->setBody($this->buildErrorMailBody($error, $mail));
$template->setRelatedPHID($mail->getRelatedPHID());
$phid = $this->getActor()->getPHID();
$tos = array(
$phid => PhabricatorObjectHandleData::loadOneHandle($phid)
);
$mails = $this->multiplexMail($template, $tos, array());
foreach ($mails as $email) {
$email->saveAndSend();
}
return true;
}
private function buildErrorMailBody($error,
PhabricatorMetaMTAReceivedMail $mail) {
$original_body = $mail->getRawTextBody();
$main_body = <<<EOBODY
Your request failed because an error was encoutered while processing it:
ERROR: {$error}
-- Original Body -------------------------------------------------------------
{$original_body}
EOBODY;
$body = new PhabricatorMetaMTAMailBody();
$body->addRawSection($main_body);
$body->addReplySection($this->getReplyHandlerInstructions());
return $body->render();
}
public function supportsPrivateReplies() {
return (bool)$this->getReplyHandlerDomain() &&
!$this->supportsPublicReplies();
}
public function supportsPublicReplies() {
if (!PhabricatorEnv::getEnvConfig('metamta.public-replies')) {
return false;
}
if (!$this->getReplyHandlerDomain()) {
return false;
}
return (bool)$this->getPublicReplyHandlerEmailAddress();
}
final public function supportsReplies() {
return $this->supportsPrivateReplies() ||
$this->supportsPublicReplies();
}
public function getPublicReplyHandlerEmailAddress() {
return null;
}
final public function getRecipientsSummary(
array $to_handles,
array $cc_handles) {
assert_instances_of($to_handles, 'PhabricatorObjectHandle');
assert_instances_of($cc_handles, 'PhabricatorObjectHandle');
$body = '';
if (PhabricatorEnv::getEnvConfig('metamta.recipients.show-hints')) {
if ($to_handles) {
$body .= "To: ".implode(', ', mpull($to_handles, 'getName'))."\n";
}
if ($cc_handles) {
$body .= "Cc: ".implode(', ', mpull($cc_handles, 'getName'))."\n";
}
}
return $body;
}
final public function multiplexMail(
PhabricatorMetaMTAMail $mail_template,
array $to_handles,
array $cc_handles) {
assert_instances_of($to_handles, 'PhabricatorObjectHandle');
assert_instances_of($cc_handles, 'PhabricatorObjectHandle');
$result = array();
// If MetaMTA is configured to always multiplex, skip the single-email
// case.
if (!PhabricatorMetaMTAMail::shouldMultiplexAllMail()) {
// If private replies are not supported, simply send one email to all
// recipients and CCs. This covers cases where we have no reply handler,
// or we have a public reply handler.
if (!$this->supportsPrivateReplies()) {
$mail = clone $mail_template;
$mail->addTos(mpull($to_handles, 'getPHID'));
$mail->addCCs(mpull($cc_handles, 'getPHID'));
if ($this->supportsPublicReplies()) {
$reply_to = $this->getPublicReplyHandlerEmailAddress();
$mail->setReplyTo($reply_to);
}
$result[] = $mail;
return $result;
}
}
$tos = mpull($to_handles, null, 'getPHID');
$ccs = mpull($cc_handles, null, 'getPHID');
// Merge all the recipients together. TODO: We could keep the CCs as real
// CCs and send to a "noreply@domain.com" type address, but keep it simple
// for now.
$recipients = $tos + $ccs;
// When multiplexing mail, explicitly include To/Cc information in the
// message body and headers.
$mail_template = clone $mail_template;
$mail_template->addPHIDHeaders('X-Phabricator-To', array_keys($tos));
$mail_template->addPHIDHeaders('X-Phabricator-Cc', array_keys($ccs));
$body = $mail_template->getBody();
$body .= "\n";
$body .= $this->getRecipientsSummary($to_handles, $cc_handles);
foreach ($recipients as $phid => $recipient) {
$mail = clone $mail_template;
if (isset($to_handles[$phid])) {
$mail->addTos(array($phid));
} else if (isset($cc_handles[$phid])) {
$mail->addCCs(array($phid));
} else {
// not good - they should be a to or a cc
continue;
}
$mail->setBody($body);
$reply_to = null;
if (!$reply_to && $this->supportsPrivateReplies()) {
$reply_to = $this->getPrivateReplyHandlerEmailAddress($recipient);
}
if (!$reply_to && $this->supportsPublicReplies()) {
$reply_to = $this->getPublicReplyHandlerEmailAddress();
}
if ($reply_to) {
$mail->setReplyTo($reply_to);
}
$result[] = $mail;
}
return $result;
}
protected function getDefaultPublicReplyHandlerEmailAddress($prefix) {
$receiver = $this->getMailReceiver();
$receiver_id = $receiver->getID();
$domain = $this->getReplyHandlerDomain();
// We compute a hash using the object's own PHID to prevent an attacker
// from blindly interacting with objects that they haven't ever received
// mail about by just sending to D1@, D2@, etc...
$hash = PhabricatorMetaMTAReceivedMail::computeMailHash(
$receiver->getMailKey(),
$receiver->getPHID());
$address = "{$prefix}{$receiver_id}+public+{$hash}@{$domain}";
return $this->getSingleReplyHandlerPrefix($address);
}
protected function getSingleReplyHandlerPrefix($address) {
$single_handle_prefix = PhabricatorEnv::getEnvConfig(
'metamta.single-reply-handler-prefix');
return ($single_handle_prefix)
? $single_handle_prefix . '+' . $address
: $address;
}
protected function getDefaultPrivateReplyHandlerEmailAddress(
PhabricatorObjectHandle $handle,
$prefix) {
if ($handle->getType() != PhabricatorPHIDConstants::PHID_TYPE_USER) {
// You must be a real user to get a private reply handler address.
return null;
}
$receiver = $this->getMailReceiver();
$receiver_id = $receiver->getID();
$user_id = $handle->getAlternateID();
$hash = PhabricatorMetaMTAReceivedMail::computeMailHash(
$receiver->getMailKey(),
$handle->getPHID());
$domain = $this->getReplyHandlerDomain();
$address = "{$prefix}{$receiver_id}+{$user_id}+{$hash}@{$domain}";
return $this->getSingleReplyHandlerPrefix($address);
}
- final protected function enhanceBodyWithAttachments($body,
- array $attachments) {
+ final protected function enhanceBodyWithAttachments(
+ $body,
+ array $attachments,
+ $format = '- {F%d, layout=link}') {
if (!$attachments) {
return $body;
}
$files = id(new PhabricatorFile())
->loadAllWhere('phid in (%Ls)', $attachments);
// if we have some text then double return before adding our file list
if ($body) {
$body .= "\n\n";
}
foreach ($files as $file) {
- $file_str = sprintf('- {F%d, layout=link}', $file->getID());
+ $file_str = sprintf($format, $file->getID());
$body .= $file_str."\n";
}
return rtrim($body);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Jul 28, 2:30 AM (1 w, 21 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
186366
Default Alt Text
(28 KB)

Event Timeline