mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 05:50:55 +01:00
Hook Ponder to Subscriptions
Summary: Adding email aggro email aggro Test Plan: Added some content; annoyed some coworkers. Reviewers: epriestley, nh, vrana Reviewed By: epriestley CC: aran, Korvin Maniphest Tasks: T1808 Differential Revision: https://secure.phabricator.com/D3643
This commit is contained in:
parent
cd9d78c107
commit
3440839c99
14 changed files with 587 additions and 6 deletions
|
@ -1200,15 +1200,19 @@ phutil_register_library_map(array(
|
|||
'PonderAnswerQuery' => 'applications/ponder/query/PonderAnswerQuery.php',
|
||||
'PonderAnswerSaveController' => 'applications/ponder/controller/PonderAnswerSaveController.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',
|
||||
'PonderCommentListView' => 'applications/ponder/view/PonderCommentListView.php',
|
||||
'PonderCommentMail' => 'applications/ponder/mail/PonderCommentMail.php',
|
||||
'PonderCommentQuery' => 'applications/ponder/query/PonderCommentQuery.php',
|
||||
'PonderCommentSaveController' => 'applications/ponder/controller/PonderCommentSaveController.php',
|
||||
'PonderConstants' => 'applications/ponder/PonderConstants.php',
|
||||
'PonderController' => 'applications/ponder/controller/PonderController.php',
|
||||
'PonderDAO' => 'applications/ponder/storage/PonderDAO.php',
|
||||
'PonderFeedController' => 'applications/ponder/controller/PonderFeedController.php',
|
||||
'PonderMail' => 'applications/ponder/mail/PonderMail.php',
|
||||
'PonderMentionMail' => 'applications/ponder/mail/PonderMentionMail.php',
|
||||
'PonderPostBodyView' => 'applications/ponder/view/PonderPostBodyView.php',
|
||||
'PonderQuestion' => 'applications/ponder/storage/PonderQuestion.php',
|
||||
'PonderQuestionAskController' => 'applications/ponder/controller/PonderQuestionAskController.php',
|
||||
|
@ -1218,6 +1222,7 @@ phutil_register_library_map(array(
|
|||
'PonderQuestionQuery' => 'applications/ponder/query/PonderQuestionQuery.php',
|
||||
'PonderQuestionSummaryView' => 'applications/ponder/view/PonderQuestionSummaryView.php',
|
||||
'PonderQuestionViewController' => 'applications/ponder/controller/PonderQuestionViewController.php',
|
||||
'PonderReplyHandler' => 'applications/ponder/PonderReplyHandler.php',
|
||||
'PonderRuleQuestion' => 'infrastructure/markup/rule/PonderRuleQuestion.php',
|
||||
'PonderUserProfileView' => 'applications/ponder/view/PonderUserProfileView.php',
|
||||
'PonderVotableInterface' => 'applications/ponder/storage/PonderVotableInterface.php',
|
||||
|
@ -2318,23 +2323,27 @@ phutil_register_library_map(array(
|
|||
'PonderAnswerQuery' => 'PhabricatorOffsetPagedQuery',
|
||||
'PonderAnswerSaveController' => 'PonderController',
|
||||
'PonderAnswerViewController' => 'PonderController',
|
||||
'PonderAnsweredMail' => 'PonderMail',
|
||||
'PonderComment' =>
|
||||
array(
|
||||
0 => 'PonderDAO',
|
||||
1 => 'PhabricatorMarkupInterface',
|
||||
),
|
||||
'PonderCommentListView' => 'AphrontView',
|
||||
'PonderCommentMail' => 'PonderMail',
|
||||
'PonderCommentQuery' => 'PhabricatorQuery',
|
||||
'PonderCommentSaveController' => 'PonderController',
|
||||
'PonderController' => 'PhabricatorController',
|
||||
'PonderDAO' => 'PhabricatorLiskDAO',
|
||||
'PonderFeedController' => 'PonderController',
|
||||
'PonderMentionMail' => 'PonderMail',
|
||||
'PonderPostBodyView' => 'AphrontView',
|
||||
'PonderQuestion' =>
|
||||
array(
|
||||
0 => 'PonderDAO',
|
||||
1 => 'PhabricatorMarkupInterface',
|
||||
2 => 'PonderVotableInterface',
|
||||
3 => 'PhabricatorSubscribableInterface',
|
||||
),
|
||||
'PonderQuestionAskController' => 'PonderController',
|
||||
'PonderQuestionDetailView' => 'AphrontView',
|
||||
|
@ -2342,6 +2351,7 @@ phutil_register_library_map(array(
|
|||
'PonderQuestionQuery' => 'PhabricatorOffsetPagedQuery',
|
||||
'PonderQuestionSummaryView' => 'AphrontView',
|
||||
'PonderQuestionViewController' => 'PonderController',
|
||||
'PonderReplyHandler' => 'PhabricatorMailReplyHandler',
|
||||
'PonderRuleQuestion' => 'PhabricatorRemarkupRuleObjectName',
|
||||
'PonderUserProfileView' => 'AphrontView',
|
||||
'PonderVotableView' => 'AphrontView',
|
||||
|
|
48
src/applications/ponder/PonderReplyHandler.php
Normal file
48
src/applications/ponder/PonderReplyHandler.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
final class PonderReplyHandler extends PhabricatorMailReplyHandler {
|
||||
|
||||
public function validateMailReceiver($mail_receiver) {
|
||||
if (!($mail_receiver instanceof PonderQuestion)) {
|
||||
throw new Exception("Mail receiver is not a PonderQuestion!");
|
||||
}
|
||||
}
|
||||
|
||||
public function getPrivateReplyHandlerEmailAddress(
|
||||
PhabricatorObjectHandle $handle) {
|
||||
return $this->getDefaultPrivateReplyHandlerEmailAddress($handle, 'Q');
|
||||
}
|
||||
|
||||
public function getPublicReplyHandlerEmailAddress() {
|
||||
return $this->getDefaultPublicReplyHandlerEmailAddress('Q');
|
||||
}
|
||||
|
||||
public function getReplyHandlerDomain() {
|
||||
return PhabricatorEnv::getEnvConfig(
|
||||
'metamta.maniphest.reply-handler-domain');
|
||||
}
|
||||
|
||||
public function getReplyHandlerInstructions() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail) {
|
||||
// ignore this entirely for now
|
||||
}
|
||||
}
|
|
@ -60,6 +60,7 @@ final class PonderAnswerSaveController extends PonderController {
|
|||
->setContentSource($content_source);
|
||||
|
||||
id(new PonderAnswerEditor())
|
||||
->setUser($user)
|
||||
->setQuestion($question)
|
||||
->setAnswer($res)
|
||||
->saveAnswer();
|
||||
|
|
|
@ -38,6 +38,7 @@ final class PonderCommentSaveController extends PonderController {
|
|||
if (!$objects) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$content = $request->getStr('content');
|
||||
|
||||
if (!strlen(trim($content))) {
|
||||
|
@ -59,6 +60,8 @@ final class PonderCommentSaveController extends PonderController {
|
|||
id(new PonderCommentEditor())
|
||||
->setQuestion($question)
|
||||
->setComment($res)
|
||||
->setTargetPHID($target)
|
||||
->setUser($user)
|
||||
->save();
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
|
|
|
@ -53,6 +53,7 @@ final class PonderQuestionAskController extends PonderController {
|
|||
|
||||
id(new PonderQuestionEditor())
|
||||
->setQuestion($question)
|
||||
->setUser($user)
|
||||
->save();
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
|
|
|
@ -52,6 +52,11 @@ final class PonderQuestionViewController extends PonderController {
|
|||
}
|
||||
}
|
||||
|
||||
$subscribers = PhabricatorSubscribersQuery::loadSubscribersForPHID(
|
||||
$question->getPHID());
|
||||
|
||||
$object_phids = array_merge($object_phids, $subscribers);
|
||||
|
||||
$handles = $this->loadViewerHandles($object_phids);
|
||||
$this->loadHandles($object_phids);
|
||||
|
||||
|
@ -79,7 +84,7 @@ final class PonderQuestionViewController extends PonderController {
|
|||
->setHeader($question->getTitle());
|
||||
|
||||
$actions = $this->buildActionListView($question);
|
||||
$properties = $this->buildPropertyListView($question);
|
||||
$properties = $this->buildPropertyListView($question, $subscribers);
|
||||
|
||||
$nav = $this->buildSideNavView($question);
|
||||
$nav->appendChild(
|
||||
|
@ -112,7 +117,10 @@ final class PonderQuestionViewController extends PonderController {
|
|||
return $view;
|
||||
}
|
||||
|
||||
private function buildPropertyListView(PonderQuestion $question) {
|
||||
private function buildPropertyListView(
|
||||
PonderQuestion $question,
|
||||
array $subscribers) {
|
||||
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
$view = new PhabricatorPropertyListView();
|
||||
|
||||
|
@ -124,6 +132,17 @@ final class PonderQuestionViewController extends PonderController {
|
|||
pht('Created'),
|
||||
phabricator_datetime($question->getDateCreated(), $viewer));
|
||||
|
||||
if ($subscribers) {
|
||||
foreach ($subscribers as $key => $subscriber) {
|
||||
$subscribers[$key] = $this->getHandle($subscriber)->renderLink();
|
||||
}
|
||||
$subscribers = implode(', ', $subscribers);
|
||||
}
|
||||
|
||||
$view->addProperty(
|
||||
pht('Subscribers'),
|
||||
nonempty($subscribers, '<em>'.pht('None').'</em>'));
|
||||
|
||||
return $view;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
final class PonderAnswerEditor {
|
||||
|
||||
private $question;
|
||||
private $answer;
|
||||
private $viewer;
|
||||
private $shouldEmail = true;
|
||||
|
||||
public function setQuestion($question) {
|
||||
$this->question = $question;
|
||||
|
@ -32,7 +32,15 @@ final class PonderAnswerEditor {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setUser(PhabricatorUser $user) {
|
||||
$this->viewer = $user;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function saveAnswer() {
|
||||
if (!$this->viewer) {
|
||||
throw new Exception("Must set user before saving question");
|
||||
}
|
||||
if (!$this->question) {
|
||||
throw new Exception("Must set question before saving answer");
|
||||
}
|
||||
|
@ -42,6 +50,7 @@ final class PonderAnswerEditor {
|
|||
|
||||
$question = $this->question;
|
||||
$answer = $this->answer;
|
||||
$viewer = $this->viewer;
|
||||
$conn = $answer->establishConnection('w');
|
||||
$trans = $conn->openTransaction();
|
||||
$trans->beginReadLocking();
|
||||
|
@ -63,5 +72,53 @@ final class PonderAnswerEditor {
|
|||
|
||||
$question->attachRelated();
|
||||
PhabricatorSearchPonderIndexer::indexQuestion($question);
|
||||
|
||||
// subscribe author and @mentions
|
||||
$subeditor = id(new PhabricatorSubscriptionsEditor())
|
||||
->setObject($question)
|
||||
->setUser($viewer);
|
||||
|
||||
$subeditor->subscribeExplicit(array($answer->getAuthorPHID()));
|
||||
|
||||
$content = $answer->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,
|
||||
$answer,
|
||||
$viewer))
|
||||
->setToPHIDs($at_mention_phids)
|
||||
->send();
|
||||
}
|
||||
|
||||
$other_subs =
|
||||
array_diff(
|
||||
$subscribers,
|
||||
$at_mention_phids
|
||||
);
|
||||
|
||||
// 'Answered' emails for subscribers who are not @mentiond (and excluding
|
||||
// author depending on their MetaMTA settings).
|
||||
if ($other_subs) {
|
||||
id(new PonderAnsweredMail(
|
||||
$question,
|
||||
$answer,
|
||||
$viewer))
|
||||
->setToPHIDs($other_subs)
|
||||
->send();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ final class PonderCommentEditor {
|
|||
|
||||
private $question;
|
||||
private $comment;
|
||||
private $targetPHID;
|
||||
private $viewer;
|
||||
private $shouldEmail = true;
|
||||
|
||||
public function setComment(PonderComment $comment) {
|
||||
$this->comment = $comment;
|
||||
|
@ -32,6 +35,16 @@ final class PonderCommentEditor {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setTargetPHID($target) {
|
||||
$this->targetPHID = $target;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setUser(PhabricatorUser $user) {
|
||||
$this->viewer = $user;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function save() {
|
||||
if (!$this->comment) {
|
||||
throw new Exception("Must set comment before saving it");
|
||||
|
@ -39,13 +52,82 @@ final class PonderCommentEditor {
|
|||
if (!$this->question) {
|
||||
throw new Exception("Must set question before saving comment");
|
||||
}
|
||||
if (!$this->targetPHID) {
|
||||
throw new Exception("Must set target before saving comment");
|
||||
}
|
||||
if (!$this->viewer) {
|
||||
throw new Exception("Must set viewer before saving comment");
|
||||
}
|
||||
|
||||
$comment = $this->comment;
|
||||
$question = $this->question;
|
||||
|
||||
$target = $this->targetPHID;
|
||||
$viewer = $this->viewer;
|
||||
$comment->save();
|
||||
|
||||
$question->attachRelated();
|
||||
PhabricatorSearchPonderIndexer::indexQuestion($question);
|
||||
|
||||
// subscribe author and @mentions
|
||||
$subeditor = id(new PhabricatorSubscriptionsEditor())
|
||||
->setObject($question)
|
||||
->setUser($viewer);
|
||||
|
||||
$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,
|
||||
$viewer))
|
||||
->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,
|
||||
$viewer))
|
||||
->setToPHIDs($other_subs)
|
||||
->send();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,21 +21,60 @@ final class PonderQuestionEditor {
|
|||
|
||||
private $question;
|
||||
private $viewer;
|
||||
private $shouldEmail = true;
|
||||
|
||||
public function setQuestion(PonderQuestion $question) {
|
||||
$this->question = $question;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setUser(PhabricatorUser $user) {
|
||||
$this->viewer = $user;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setShouldEmail($se) {
|
||||
$this->shouldEmail = $se;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function save() {
|
||||
if (!$this->viewer) {
|
||||
throw new Exception("Must set user before saving question");
|
||||
}
|
||||
if (!$this->question) {
|
||||
throw new Exception("Must set question before saving it");
|
||||
}
|
||||
|
||||
$viewer = $this->viewer;
|
||||
$question = $this->question;
|
||||
$question->save();
|
||||
|
||||
// search index
|
||||
$question->attachRelated();
|
||||
PhabricatorSearchPonderIndexer::indexQuestion($question);
|
||||
|
||||
// subscribe author and @mentions
|
||||
$subeditor = id(new PhabricatorSubscriptionsEditor())
|
||||
->setObject($question)
|
||||
->setUser($viewer);
|
||||
|
||||
$subeditor->subscribeExplicit(array($question->getAuthorPHID()));
|
||||
|
||||
$content = $question->getContent();
|
||||
$at_mention_phids = PhabricatorMarkupEngine::extractPHIDsFromMentions(
|
||||
array($content)
|
||||
);
|
||||
$subeditor->subscribeImplicit($at_mention_phids);
|
||||
$subeditor->save();
|
||||
|
||||
if ($this->shouldEmail && $at_mention_phids) {
|
||||
id(new PonderMentionMail(
|
||||
$question,
|
||||
$question,
|
||||
$viewer))
|
||||
->setToPHIDs($at_mention_phids)
|
||||
->send();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
53
src/applications/ponder/mail/PonderAnsweredMail.php
Normal file
53
src/applications/ponder/mail/PonderAnsweredMail.php
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
final class PonderAnsweredMail extends PonderMail {
|
||||
|
||||
public function __construct(
|
||||
PonderQuestion $question,
|
||||
PonderAnswer $target,
|
||||
PhabricatorUser $actor) {
|
||||
|
||||
$this->setQuestion($question);
|
||||
$this->setTarget($target);
|
||||
$this->setActorHandle($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);
|
||||
}
|
||||
}
|
53
src/applications/ponder/mail/PonderCommentMail.php
Normal file
53
src/applications/ponder/mail/PonderCommentMail.php
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
final class PonderCommentMail extends PonderMail {
|
||||
|
||||
public function __construct(
|
||||
PonderQuestion $question,
|
||||
PonderComment $target,
|
||||
PhabricatorUser $actor) {
|
||||
|
||||
$this->setQuestion($question);
|
||||
$this->setTarget($target);
|
||||
$this->setActorHandle($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);
|
||||
}
|
||||
}
|
144
src/applications/ponder/mail/PonderMail.php
Normal file
144
src/applications/ponder/mail/PonderMail.php
Normal file
|
@ -0,0 +1,144 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
abstract class PonderMail {
|
||||
|
||||
protected $to = array();
|
||||
protected $actorHandle;
|
||||
protected $question;
|
||||
protected $target;
|
||||
|
||||
protected $isFirstMailAboutQuestion;
|
||||
|
||||
// protected $replyHandler;
|
||||
|
||||
protected $parentMessageID;
|
||||
|
||||
protected function renderSubject() {
|
||||
$question = $this->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))
|
||||
->loadHandles();
|
||||
|
||||
$reply_handler = new PonderReplyHandler();
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
64
src/applications/ponder/mail/PonderMentionMail.php
Normal file
64
src/applications/ponder/mail/PonderMentionMail.php
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
final class PonderMentionMail extends PonderMail {
|
||||
|
||||
public function __construct(
|
||||
PonderQuestion $question,
|
||||
$target,
|
||||
PhabricatorUser $actor) {
|
||||
|
||||
$this->setQuestion($question);
|
||||
$this->setTarget($target);
|
||||
$this->setActorHandle($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);
|
||||
}
|
||||
}
|
|
@ -17,7 +17,10 @@
|
|||
*/
|
||||
|
||||
final class PonderQuestion extends PonderDAO
|
||||
implements PhabricatorMarkupInterface, PonderVotableInterface {
|
||||
implements
|
||||
PhabricatorMarkupInterface,
|
||||
PonderVotableInterface,
|
||||
PhabricatorSubscribableInterface {
|
||||
|
||||
const MARKUP_FIELD_CONTENT = 'markup:content';
|
||||
|
||||
|
@ -168,4 +171,8 @@ final class PonderQuestion extends PonderDAO
|
|||
public function getVotablePHID() {
|
||||
return $this->getPHID();
|
||||
}
|
||||
|
||||
public function isAutomaticallySubscribed($phid) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue