diff --git a/src/applications/ponder/editor/PonderAnswerEditor.php b/src/applications/ponder/editor/PonderAnswerEditor.php index fdb5c48437..521c1948ed 100644 --- a/src/applications/ponder/editor/PonderAnswerEditor.php +++ b/src/applications/ponder/editor/PonderAnswerEditor.php @@ -1,123 +1,144 @@ <?php final class PonderAnswerEditor extends PonderEditor { public function getEditorObjectsDescription() { return pht('Ponder Answers'); } public function getTransactionTypes() { $types = parent::getTransactionTypes(); $types[] = PhabricatorTransactions::TYPE_COMMENT; $types[] = PonderAnswerTransaction::TYPE_CONTENT; $types[] = PonderAnswerTransaction::TYPE_STATUS; $types[] = PonderAnswerTransaction::TYPE_QUESTION_ID; return $types; } protected function getCustomTransactionOldValue( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PonderAnswerTransaction::TYPE_CONTENT: case PonderAnswerTransaction::TYPE_STATUS: return $object->getContent(); case PonderAnswerTransaction::TYPE_QUESTION_ID: return $object->getQuestionID(); } } protected function getCustomTransactionNewValue( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PonderAnswerTransaction::TYPE_CONTENT: case PonderAnswerTransaction::TYPE_STATUS: case PonderAnswerTransaction::TYPE_QUESTION_ID: return $xaction->getNewValue(); } } protected function applyCustomInternalTransaction( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PonderAnswerTransaction::TYPE_CONTENT: $object->setContent($xaction->getNewValue()); break; case PonderAnswerTransaction::TYPE_STATUS: $object->setStatus($xaction->getNewValue()); break; case PonderAnswerTransaction::TYPE_QUESTION_ID: $object->setQuestionID($xaction->getNewValue()); break; } } protected function applyCustomExternalTransaction( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { return; } protected function mergeTransactions( PhabricatorApplicationTransaction $u, PhabricatorApplicationTransaction $v) { $type = $u->getTransactionType(); switch ($type) { case PonderAnswerTransaction::TYPE_CONTENT: return $v; } return parent::mergeTransactions($u, $v); } protected function shouldSendMail( PhabricatorLiskDAO $object, array $xactions) { return true; } + protected function getMailTo(PhabricatorLiskDAO $object) { + $phids = array(); + $phids[] = $object->getAuthorPHID(); + $phids[] = $this->requireActor()->getPHID(); + + $question = id(new PonderQuestionQuery()) + ->setViewer($this->requireActor()) + ->withIDs(array($object->getQuestionID())) + ->executeOne(); + + $phids[] = $question->getAuthorPHID(); + + return $phids; + } + + protected function shouldPublishFeedStory( + PhabricatorLiskDAO $object, + array $xactions) { + return true; + } + protected function buildReplyHandler(PhabricatorLiskDAO $object) { return id(new PonderAnswerReplyHandler()) ->setMailReceiver($object); } protected function buildMailTemplate(PhabricatorLiskDAO $object) { $id = $object->getID(); return id(new PhabricatorMetaMTAMail()) ->setSubject("ANSR{$id}") ->addHeader('Thread-Topic', "ANSR{$id}"); } protected function buildMailBody( PhabricatorLiskDAO $object, array $xactions) { $body = parent::buildMailBody($object, $xactions); // If the user just gave the answer, add the answer text. foreach ($xactions as $xaction) { $type = $xaction->getTransactionType(); $new = $xaction->getNewValue(); if ($type == PonderAnswerTransaction::TYPE_CONTENT) { $body->addRawSection($new); } } $body->addLinkSection( pht('ANSWER DETAIL'), PhabricatorEnv::getProductionURI($object->getURI())); return $body; } } diff --git a/src/applications/ponder/editor/PonderEditor.php b/src/applications/ponder/editor/PonderEditor.php index 24c6f2d8d2..fcfa981f16 100644 --- a/src/applications/ponder/editor/PonderEditor.php +++ b/src/applications/ponder/editor/PonderEditor.php @@ -1,21 +1,14 @@ <?php abstract class PonderEditor extends PhabricatorApplicationTransactionEditor { public function getEditorApplicationClass() { return 'PhabricatorPonderApplication'; } - protected function getMailTo(PhabricatorLiskDAO $object) { - return array( - $object->getAuthorPHID(), - $this->requireActor()->getPHID(), - ); - } - protected function getMailSubjectPrefix() { return '[Ponder]'; } } diff --git a/src/applications/ponder/editor/PonderQuestionEditor.php b/src/applications/ponder/editor/PonderQuestionEditor.php index b2f143b176..73d9ed0ce0 100644 --- a/src/applications/ponder/editor/PonderQuestionEditor.php +++ b/src/applications/ponder/editor/PonderQuestionEditor.php @@ -1,293 +1,300 @@ <?php final class PonderQuestionEditor extends PonderEditor { private $answer; public function getEditorObjectsDescription() { return pht('Ponder Questions'); } /** * This is used internally on @{method:applyInitialEffects} if a transaction * of type PonderQuestionTransaction::TYPE_ANSWERS is in the mix. The value * is set to the //last// answer in the transactions. Practically, one * answer is given at a time in the application, though theoretically * this is buggy. * * The answer is used in emails to generate proper links. */ private function setAnswer(PonderAnswer $answer) { $this->answer = $answer; return $this; } private function getAnswer() { return $this->answer; } protected function shouldApplyInitialEffects( PhabricatorLiskDAO $object, array $xactions) { foreach ($xactions as $xaction) { switch ($xaction->getTransactionType()) { case PonderQuestionTransaction::TYPE_ANSWERS: return true; } } return false; } protected function applyInitialEffects( PhabricatorLiskDAO $object, array $xactions) { foreach ($xactions as $xaction) { switch ($xaction->getTransactionType()) { case PonderQuestionTransaction::TYPE_ANSWERS: $new_value = $xaction->getNewValue(); $new = idx($new_value, '+', array()); foreach ($new as $new_answer) { $answer = idx($new_answer, 'answer'); if (!$answer) { continue; } $answer->save(); $this->setAnswer($answer); } break; } } } public function getTransactionTypes() { $types = parent::getTransactionTypes(); $types[] = PhabricatorTransactions::TYPE_COMMENT; $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; $types[] = PhabricatorTransactions::TYPE_SPACE; $types[] = PonderQuestionTransaction::TYPE_TITLE; $types[] = PonderQuestionTransaction::TYPE_CONTENT; $types[] = PonderQuestionTransaction::TYPE_ANSWERS; $types[] = PonderQuestionTransaction::TYPE_STATUS; $types[] = PonderQuestionTransaction::TYPE_ANSWERWIKI; return $types; } protected function getCustomTransactionOldValue( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PonderQuestionTransaction::TYPE_TITLE: return $object->getTitle(); case PonderQuestionTransaction::TYPE_CONTENT: return $object->getContent(); case PonderQuestionTransaction::TYPE_ANSWERS: return mpull($object->getAnswers(), 'getPHID'); case PonderQuestionTransaction::TYPE_STATUS: return $object->getStatus(); case PonderQuestionTransaction::TYPE_ANSWERWIKI: return $object->getAnswerWiki(); } } protected function getCustomTransactionNewValue( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PonderQuestionTransaction::TYPE_TITLE: case PonderQuestionTransaction::TYPE_CONTENT: case PonderQuestionTransaction::TYPE_STATUS: case PonderQuestionTransaction::TYPE_ANSWERWIKI: return $xaction->getNewValue(); case PonderQuestionTransaction::TYPE_ANSWERS: $raw_new_value = $xaction->getNewValue(); $new_value = array(); foreach ($raw_new_value as $key => $answers) { $phids = array(); foreach ($answers as $answer) { $obj = idx($answer, 'answer'); if (!$answer) { continue; } $phids[] = $obj->getPHID(); } $new_value[$key] = $phids; } $xaction->setNewValue($new_value); return $this->getPHIDTransactionNewValue($xaction); } } protected function applyCustomInternalTransaction( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PonderQuestionTransaction::TYPE_TITLE: $object->setTitle($xaction->getNewValue()); break; case PonderQuestionTransaction::TYPE_CONTENT: $object->setContent($xaction->getNewValue()); break; case PonderQuestionTransaction::TYPE_STATUS: $object->setStatus($xaction->getNewValue()); break; case PonderQuestionTransaction::TYPE_ANSWERWIKI: $object->setAnswerWiki($xaction->getNewValue()); break; case PonderQuestionTransaction::TYPE_ANSWERS: $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); $add = array_diff_key($new, $old); $rem = array_diff_key($old, $new); $count = $object->getAnswerCount(); $count += count($add); $count -= count($rem); $object->setAnswerCount($count); break; } } protected function applyCustomExternalTransaction( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { return; } protected function mergeTransactions( PhabricatorApplicationTransaction $u, PhabricatorApplicationTransaction $v) { $type = $u->getTransactionType(); switch ($type) { case PonderQuestionTransaction::TYPE_TITLE: case PonderQuestionTransaction::TYPE_CONTENT: case PonderQuestionTransaction::TYPE_STATUS: case PonderQuestionTransaction::TYPE_ANSWERWIKI: return $v; } return parent::mergeTransactions($u, $v); } protected function supportsSearch() { return true; } protected function shouldImplyCC( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PonderQuestionTransaction::TYPE_ANSWERS: return false; } return parent::shouldImplyCC($object, $xaction); } protected function shouldSendMail( PhabricatorLiskDAO $object, array $xactions) { foreach ($xactions as $xaction) { switch ($xaction->getTransactionType()) { case PonderQuestionTransaction::TYPE_ANSWERS: return false; } } return true; } + protected function getMailTo(PhabricatorLiskDAO $object) { + return array( + $object->getAuthorPHID(), + $this->requireActor()->getPHID(), + ); + } + protected function shouldPublishFeedStory( PhabricatorLiskDAO $object, array $xactions) { foreach ($xactions as $xaction) { switch ($xaction->getTransactionType()) { case PonderQuestionTransaction::TYPE_ANSWERS: return false; } } return true; } public function getMailTagsMap() { return array( PonderQuestionTransaction::MAILTAG_DETAILS => pht('Someone changes the questions details.'), PonderQuestionTransaction::MAILTAG_ANSWERS => pht('Someone adds a new answer.'), PonderQuestionTransaction::MAILTAG_COMMENT => pht('Someone comments on the question.'), PonderQuestionTransaction::MAILTAG_OTHER => pht('Other question activity not listed above occurs.'), ); } 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 buildMailBody( PhabricatorLiskDAO $object, array $xactions) { $body = parent::buildMailBody($object, $xactions); $header = pht('QUESTION DETAIL'); $uri = '/Q'.$object->getID(); foreach ($xactions as $xaction) { $type = $xaction->getTransactionType(); $old = $xaction->getOldValue(); $new = $xaction->getNewValue(); // If the user just asked the question, add the question text. if ($type == PonderQuestionTransaction::TYPE_CONTENT) { if ($old === null) { $body->addRawSection($new); } } } $body->addLinkSection( $header, PhabricatorEnv::getProductionURI($uri)); return $body; } protected function shouldApplyHeraldRules( PhabricatorLiskDAO $object, array $xactions) { return true; } protected function buildHeraldAdapter( PhabricatorLiskDAO $object, array $xactions) { return id(new HeraldPonderQuestionAdapter()) ->setQuestion($object); } }