diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 1b6264de40..2a5632ff39 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1880,17 +1880,12 @@ phutil_register_library_map(array( 'PonderAnswerTransactionComment' => 'applications/ponder/storage/PonderAnswerTransactionComment.php', 'PonderAnswerTransactionQuery' => 'applications/ponder/query/PonderAnswerTransactionQuery.php', 'PonderAnswerViewController' => 'applications/ponder/controller/PonderAnswerViewController.php', - 'PonderAnsweredMail' => 'applications/ponder/mail/PonderAnsweredMail.php', 'PonderComment' => 'applications/ponder/storage/PonderComment.php', - 'PonderCommentEditor' => 'applications/ponder/editor/PonderCommentEditor.php', - 'PonderCommentMail' => 'applications/ponder/mail/PonderCommentMail.php', 'PonderCommentQuery' => 'applications/ponder/query/PonderCommentQuery.php', 'PonderConstants' => 'applications/ponder/constants/PonderConstants.php', 'PonderController' => 'applications/ponder/controller/PonderController.php', 'PonderDAO' => 'applications/ponder/storage/PonderDAO.php', 'PonderLiterals' => 'applications/ponder/constants/PonderLiterals.php', - 'PonderMail' => 'applications/ponder/mail/PonderMail.php', - 'PonderMentionMail' => 'applications/ponder/mail/PonderMentionMail.php', 'PonderPHIDTypeAnswer' => 'applications/ponder/phid/PonderPHIDTypeAnswer.php', 'PonderPHIDTypeQuestion' => 'applications/ponder/phid/PonderPHIDTypeQuestion.php', 'PonderPostBodyView' => 'applications/ponder/view/PonderPostBodyView.php', @@ -1903,6 +1898,7 @@ phutil_register_library_map(array( 'PonderQuestionMailReceiver' => 'applications/ponder/mail/PonderQuestionMailReceiver.php', 'PonderQuestionPreviewController' => 'applications/ponder/controller/PonderQuestionPreviewController.php', 'PonderQuestionQuery' => 'applications/ponder/query/PonderQuestionQuery.php', + 'PonderQuestionReplyHandler' => 'applications/ponder/mail/PonderQuestionReplyHandler.php', 'PonderQuestionSearchEngine' => 'applications/ponder/query/PonderQuestionSearchEngine.php', 'PonderQuestionStatus' => 'applications/ponder/constants/PonderQuestionStatus.php', 'PonderQuestionStatusController' => 'applications/ponder/controller/PonderQuestionStatusController.php', @@ -1911,7 +1907,6 @@ phutil_register_library_map(array( 'PonderQuestionTransactionQuery' => 'applications/ponder/query/PonderQuestionTransactionQuery.php', 'PonderQuestionViewController' => 'applications/ponder/controller/PonderQuestionViewController.php', 'PonderRemarkupRule' => 'applications/ponder/remarkup/PonderRemarkupRule.php', - 'PonderReplyHandler' => 'applications/ponder/mail/PonderReplyHandler.php', 'PonderSearchIndexer' => 'applications/ponder/search/PonderSearchIndexer.php', 'PonderVotableInterface' => 'applications/ponder/storage/PonderVotableInterface.php', 'PonderVotableView' => 'applications/ponder/view/PonderVotableView.php', @@ -4003,20 +3998,15 @@ phutil_register_library_map(array( 'PonderAnswerTransactionComment' => 'PhabricatorApplicationTransactionComment', 'PonderAnswerTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PonderAnswerViewController' => 'PonderController', - 'PonderAnsweredMail' => 'PonderMail', 'PonderComment' => array( 0 => 'PonderDAO', 1 => 'PhabricatorMarkupInterface', ), - 'PonderCommentEditor' => 'PhabricatorEditor', - 'PonderCommentMail' => 'PonderMail', 'PonderCommentQuery' => 'PhabricatorQuery', 'PonderController' => 'PhabricatorController', 'PonderDAO' => 'PhabricatorLiskDAO', 'PonderLiterals' => 'PonderConstants', - 'PonderMail' => 'PhabricatorMail', - 'PonderMentionMail' => 'PonderMail', 'PonderPHIDTypeAnswer' => 'PhabricatorPHIDType', 'PonderPHIDTypeQuestion' => 'PhabricatorPHIDType', 'PonderPostBodyView' => 'AphrontView', @@ -4041,6 +4031,7 @@ phutil_register_library_map(array( 'PonderQuestionMailReceiver' => 'PhabricatorObjectMailReceiver', 'PonderQuestionPreviewController' => 'PonderController', 'PonderQuestionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PonderQuestionReplyHandler' => 'PhabricatorMailReplyHandler', 'PonderQuestionSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PonderQuestionStatus' => 'PonderConstants', 'PonderQuestionStatusController' => 'PonderController', @@ -4049,7 +4040,6 @@ phutil_register_library_map(array( 'PonderQuestionTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PonderQuestionViewController' => 'PonderController', 'PonderRemarkupRule' => 'PhabricatorRemarkupRuleObject', - 'PonderReplyHandler' => 'PhabricatorMailReplyHandler', 'PonderSearchIndexer' => 'PhabricatorSearchDocumentIndexer', 'PonderVotableView' => 'AphrontView', 'PonderVote' => 'PonderConstants', diff --git a/src/applications/ponder/editor/PonderCommentEditor.php b/src/applications/ponder/editor/PonderCommentEditor.php deleted file mode 100644 index fc4f993629..0000000000 --- a/src/applications/ponder/editor/PonderCommentEditor.php +++ /dev/null @@ -1,104 +0,0 @@ -comment = $comment; - return $this; - } - - public function setQuestion(PonderQuestion $question) { - $this->question = $question; - return $this; - } - - public function setTargetPHID($target) { - $this->targetPHID = $target; - return $this; - } - - public function save() { - $actor = $this->requireActor(); - if (!$this->comment) { - throw new Exception("Must set comment before saving it"); - } - if (!$this->question) { - throw new Exception("Must set question before saving comment"); - } - if (!$this->targetPHID) { - throw new Exception("Must set target before saving comment"); - } - - $comment = $this->comment; - $question = $this->question; - $target = $this->targetPHID; - $comment->save(); - - id(new PhabricatorSearchIndexer()) - ->indexDocumentByPHID($question->getPHID()); - - // subscribe author and @mentions - $subeditor = id(new PhabricatorSubscriptionsEditor()) - ->setObject($question) - ->setActor($actor); - - $subeditor->subscribeExplicit(array($comment->getAuthorPHID())); - - $content = $comment->getContent(); - $at_mention_phids = PhabricatorMarkupEngine::extractPHIDsFromMentions( - array($content)); - $subeditor->subscribeImplicit($at_mention_phids); - $subeditor->save(); - - if ($this->shouldEmail) { - // now load subscribers, including implicitly-added @mention victims - $subscribers = PhabricatorSubscribersQuery - ::loadSubscribersForPHID($question->getPHID()); - - // @mention emails (but not for anyone who has explicitly unsubscribed) - if (array_intersect($at_mention_phids, $subscribers)) { - id(new PonderMentionMail( - $question, - $comment, - $actor)) - ->setToPHIDs($at_mention_phids) - ->send(); - } - - if ($target === $question->getPHID()) { - $target = $question; - } else { - $answers_by_phid = mgroup($question->getAnswers(), 'getPHID'); - $target = head($answers_by_phid[$target]); - } - - // only send emails to others in the same thread - $thread = mpull($target->getComments(), 'getAuthorPHID'); - $thread[] = $target->getAuthorPHID(); - $thread[] = $question->getAuthorPHID(); - - $other_subs = - array_diff( - array_intersect($thread, $subscribers), - $at_mention_phids); - - // 'Comment' emails for subscribers who are in the same comment thread, - // including the author of the parent question and/or answer, excluding - // @mentions (and excluding the author, depending on their MetaMTA - // settings). - if ($other_subs) { - id(new PonderCommentMail( - $question, - $comment, - $actor)) - ->setToPHIDs($other_subs) - ->send(); - } - } - } -} diff --git a/src/applications/ponder/editor/PonderQuestionEditor.php b/src/applications/ponder/editor/PonderQuestionEditor.php index 32caa7da81..7f0c098930 100644 --- a/src/applications/ponder/editor/PonderQuestionEditor.php +++ b/src/applications/ponder/editor/PonderQuestionEditor.php @@ -149,10 +149,6 @@ final class PonderQuestionEditor return true; } - protected function getMailTo(PhabricatorLiskDAO $object) { - return array($object->getAuthorPHID()); - } - protected function supportsSearch() { return true; } @@ -169,6 +165,59 @@ final class PonderQuestionEditor return parent::shouldImplyCC($object, $xaction); } - // TODO: Mail support + protected function supportsMail() { + return true; + } + + protected function buildReplyHandler(PhabricatorLiskDAO $object) { + return id(new PonderQuestionReplyHandler()) + ->setMailReceiver($object); + } + + protected function buildMailTemplate(PhabricatorLiskDAO $object) { + $id = $object->getID(); + $title = $object->getTitle(); + $original_title = $object->getOriginalTitle(); + + return id(new PhabricatorMetaMTAMail()) + ->setSubject("Q{$id}: {$title}") + ->addHeader('Thread-Topic', "Q{$id}: {$original_title}"); + } + + protected function getMailTo(PhabricatorLiskDAO $object) { + return array( + $object->getAuthorPHID(), + $this->requireActor()->getPHID(), + ); + } + + protected function buildMailBody( + PhabricatorLiskDAO $object, + array $xactions) { + + $body = parent::buildMailBody($object, $xactions); + + // If the user just asked the question, add the question text. + foreach ($xactions as $xaction) { + $type = $xaction->getTransactionType(); + $old = $xaction->getOldValue(); + $new = $xaction->getNewValue(); + if ($type == PonderQuestionTransaction::TYPE_CONTENT) { + if ($old === null) { + $body->addRawSection($new); + } + } + } + + $body->addTextSection( + pht('QUESTION DETAIL'), + PhabricatorEnv::getProductionURI('/Q'.$object->getID())); + + return $body; + } + + protected function getMailSubjectPrefix() { + return '[Ponder]'; + } } diff --git a/src/applications/ponder/mail/PonderAnsweredMail.php b/src/applications/ponder/mail/PonderAnsweredMail.php deleted file mode 100644 index 2e1b5adde4..0000000000 --- a/src/applications/ponder/mail/PonderAnsweredMail.php +++ /dev/null @@ -1,38 +0,0 @@ -setQuestion($question); - $this->setTarget($target); - $this->setActorHandle($actor); - $this->setActor($actor); - } - - protected function renderVaryPrefix() { - return "[Answered]"; - } - - protected function renderBody() { - $question = $this->getQuestion(); - $target = $this->getTarget(); - $actor = $this->getActorName(); - $name = $question->getTitle(); - - $body = array(); - $body[] = "{$actor} answered a question that you are subscribed to."; - $body[] = null; - - $content = $target->getContent(); - if (strlen($content)) { - $body[] = $this->formatText($content); - $body[] = null; - } - - return implode("\n", $body); - } -} diff --git a/src/applications/ponder/mail/PonderCommentMail.php b/src/applications/ponder/mail/PonderCommentMail.php deleted file mode 100644 index 3399b1fd1a..0000000000 --- a/src/applications/ponder/mail/PonderCommentMail.php +++ /dev/null @@ -1,38 +0,0 @@ -setQuestion($question); - $this->setTarget($target); - $this->setActorHandle($actor); - $this->setActor($actor); - } - - protected function renderVaryPrefix() { - return "[Commented]"; - } - - protected function renderBody() { - $question = $this->getQuestion(); - $target = $this->getTarget(); - $actor = $this->getActorName(); - $name = $question->getTitle(); - - $body = array(); - $body[] = "{$actor} commented on a question that you are subscribed to."; - $body[] = null; - - $content = $target->getContent(); - if (strlen($content)) { - $body[] = $this->formatText($content); - $body[] = null; - } - - return implode("\n", $body); - } -} diff --git a/src/applications/ponder/mail/PonderMail.php b/src/applications/ponder/mail/PonderMail.php deleted file mode 100644 index e15016e508..0000000000 --- a/src/applications/ponder/mail/PonderMail.php +++ /dev/null @@ -1,127 +0,0 @@ -getQuestion(); - $title = $question->getTitle(); - $id = $question->getID(); - return "Q{$id}: {$title}"; - } - - abstract protected function renderVaryPrefix(); - abstract protected function renderBody(); - - public function setActorHandle($actor_handle) { - $this->actorHandle = $actor_handle; - return $this; - } - - public function getActorHandle() { - return $this->actorHandle; - } - - protected function getActorName() { - return $this->actorHandle->getRealName(); - } - - protected function getSubjectPrefix() { - return "[Ponder]"; - } - - public function setToPHIDs(array $to) { - $this->to = $to; - return $this; - } - - protected function getToPHIDs() { - return $this->to; - } - - public function setQuestion($question) { - $this->question = $question; - return $this; - } - - public function getQuestion() { - return $this->question; - } - - public function setTarget($target) { - $this->target = $target; - return $this; - } - - public function getTarget() { - return $this->target; - } - - protected function getThreadID() { - $phid = $this->getQuestion()->getPHID(); - return "ponder-ques-{$phid}"; - } - - protected function getThreadTopic() { - $id = $this->getQuestion()->getID(); - $title = $this->getQuestion()->getTitle(); - return "Q{$id}: {$title}"; - } - - public function send() { - $email_to = array_filter(array_unique($this->to)); - $question = $this->getQuestion(); - $target = $this->getTarget(); - - $uri = PhabricatorEnv::getURI('/Q'. $question->getID()); - $thread_id = $this->getThreadID(); - - $handles = id(new PhabricatorObjectHandleData($email_to)) - ->setViewer($this->getActor()) - ->loadHandles(); - - $reply_handler = new PonderReplyHandler(); - $reply_handler->setMailReceiver($question); - - $body = new PhabricatorMetaMTAMailBody(); - $body->addRawSection($this->renderBody()); - $body->addTextSection(pht('QUESTION DETAIL'), $uri); - - $template = id(new PhabricatorMetaMTAMail()) - ->setSubject($this->getThreadTopic()) - ->setSubjectPrefix($this->getSubjectPrefix()) - ->setVarySubjectPrefix($this->renderVaryPrefix()) - ->setFrom($target->getAuthorPHID()) - ->setParentMessageID($this->parentMessageID) - ->addHeader('Thread-Topic', $this->getThreadTopic()) - ->setThreadID($this->getThreadID(), false) - ->setRelatedPHID($question->getPHID()) - ->setIsBulk(true) - ->setBody($body->render()); - - $mails = $reply_handler->multiplexMail( - $template, - array_select_keys($handles, $email_to), - array()); - - foreach ($mails as $mail) { - $mail->saveAndSend(); - } - } - - protected function formatText($text) { - $text = explode("\n", rtrim($text)); - foreach ($text as &$line) { - $line = rtrim(' '.$line); - } - unset($line); - return implode("\n", $text); - } -} diff --git a/src/applications/ponder/mail/PonderMentionMail.php b/src/applications/ponder/mail/PonderMentionMail.php deleted file mode 100644 index 3178c9f703..0000000000 --- a/src/applications/ponder/mail/PonderMentionMail.php +++ /dev/null @@ -1,47 +0,0 @@ -setQuestion($question); - $this->setTarget($target); - $this->setActorHandle($actor); - $this->setActor($actor); - } - - protected function renderVaryPrefix() { - return "[Mentioned]"; - } - - protected function renderBody() { - $question = $this->getQuestion(); - $target = $this->getTarget(); - $actor = $this->getActorName(); - $name = $question->getTitle(); - - $targetkind = "somewhere"; - if ($target instanceof PonderQuestion) { - $targetkind = "in a question"; - } else if ($target instanceof PonderAnswer) { - $targetkind = "in an answer"; - } else if ($target instanceof PonderComment) { - $targetkind = "in a comment"; - } - - $body = array(); - $body[] = "{$actor} mentioned you {$targetkind}."; - $body[] = null; - - $content = $target->getContent(); - if (strlen($content)) { - $body[] = $this->formatText($content); - $body[] = null; - } - - return implode("\n", $body); - } -} diff --git a/src/applications/ponder/mail/PonderReplyHandler.php b/src/applications/ponder/mail/PonderQuestionReplyHandler.php similarity index 91% rename from src/applications/ponder/mail/PonderReplyHandler.php rename to src/applications/ponder/mail/PonderQuestionReplyHandler.php index da85ac773b..3892195c07 100644 --- a/src/applications/ponder/mail/PonderReplyHandler.php +++ b/src/applications/ponder/mail/PonderQuestionReplyHandler.php @@ -1,6 +1,6 @@ getPHID() == $this->getAuthorPHID()); } + public function getOriginalTitle() { + // TODO: Make this actually save/return the original title. + return $this->getTitle(); + } + /* -( PhabricatorTokenReceiverInterface )---------------------------------- */ diff --git a/src/applications/ponder/storage/PonderQuestionTransaction.php b/src/applications/ponder/storage/PonderQuestionTransaction.php index 3406c011e8..5bc1c9b16e 100644 --- a/src/applications/ponder/storage/PonderQuestionTransaction.php +++ b/src/applications/ponder/storage/PonderQuestionTransaction.php @@ -38,7 +38,7 @@ final class PonderQuestionTransaction case self::TYPE_TITLE: if ($old === null) { return pht( - '%s created this question.', + '%s asked this question.', $this->renderHandleLink($author_phid)); } else { return pht( @@ -134,6 +134,54 @@ final class PonderQuestionTransaction return $view->render(); } + public function getActionStrength() { + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + switch ($this->getTransactionType()) { + case self::TYPE_TITLE: + if ($old === null) { + return 3; + } + break; + case self::TYPE_ANSWERS: + return 2; + } + + return parent::getActionStrength(); + } + + public function getActionName() { + $old = $this->getOldValue(); + $new = $this->getNewValue(); + + switch ($this->getTransactionType()) { + case self::TYPE_TITLE: + if ($old === null) { + return pht('Asked'); + } + break; + case self::TYPE_ANSWERS: + return pht('Answered'); + } + + return parent::getActionName(); + } + + public function shouldHide() { + switch ($this->getTransactionType()) { + case self::TYPE_CONTENT: + if ($this->getOldValue() === null) { + return true; + } else { + return false; + } + break; + } + + return parent::shouldHide(); + } + public function getTitleForFeed() { $author_phid = $this->getAuthorPHID(); $object_phid = $this->getObjectPHID(); diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php index e96c679c3f..8369e0712b 100644 --- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php +++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php @@ -1188,6 +1188,9 @@ abstract class PhabricatorApplicationTransactionEditor $comments = array(); foreach ($xactions as $xaction) { + if ($xaction->shouldHideForMail()) { + continue; + } $headers[] = id(clone $xaction)->setRenderingTarget('text')->getTitle(); $comment = $xaction->getComment(); if ($comment && strlen($comment->getContent())) { diff --git a/src/applications/transactions/storage/PhabricatorApplicationTransaction.php b/src/applications/transactions/storage/PhabricatorApplicationTransaction.php index b8322e1d09..efb6733f1b 100644 --- a/src/applications/transactions/storage/PhabricatorApplicationTransaction.php +++ b/src/applications/transactions/storage/PhabricatorApplicationTransaction.php @@ -214,6 +214,10 @@ abstract class PhabricatorApplicationTransaction return false; } + public function shouldHideForMail() { + return $this->shouldHide(); + } + public function getNoEffectDescription() { switch ($this->getTransactionType()) {