mirror of
https://we.phorge.it/source/phorge.git
synced 2024-09-20 09:18:48 +02:00
Ponder - make feed stories and emails a bit better
Summary: Also some random cleanup now and again. Note reply handler stuff is kind of bojangles bad right now. It didn't work before though either so hey. Test Plan: asked questions, answered questions, edited answers... the feed pleased my eye Reviewers: epriestley Reviewed By: epriestley CC: Korvin, aran Maniphest Tasks: T3653 Differential Revision: https://secure.phabricator.com/D7027
This commit is contained in:
parent
77143d5600
commit
b1dfbda741
21 changed files with 326 additions and 109 deletions
|
@ -1938,12 +1938,12 @@ phutil_register_library_map(array(
|
|||
'PonderAnswerTransaction' => 'applications/ponder/storage/PonderAnswerTransaction.php',
|
||||
'PonderAnswerTransactionComment' => 'applications/ponder/storage/PonderAnswerTransactionComment.php',
|
||||
'PonderAnswerTransactionQuery' => 'applications/ponder/query/PonderAnswerTransactionQuery.php',
|
||||
'PonderAnswerViewController' => 'applications/ponder/controller/PonderAnswerViewController.php',
|
||||
'PonderComment' => 'applications/ponder/storage/PonderComment.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',
|
||||
'PonderEditor' => 'applications/ponder/editor/PonderEditor.php',
|
||||
'PonderPHIDTypeAnswer' => 'applications/ponder/phid/PonderPHIDTypeAnswer.php',
|
||||
'PonderPHIDTypeQuestion' => 'applications/ponder/phid/PonderPHIDTypeQuestion.php',
|
||||
'PonderQuestion' => 'applications/ponder/storage/PonderQuestion.php',
|
||||
|
@ -1964,6 +1964,7 @@ phutil_register_library_map(array(
|
|||
'PonderQuestionViewController' => 'applications/ponder/controller/PonderQuestionViewController.php',
|
||||
'PonderRemarkupRule' => 'applications/ponder/remarkup/PonderRemarkupRule.php',
|
||||
'PonderSearchIndexer' => 'applications/ponder/search/PonderSearchIndexer.php',
|
||||
'PonderTransactionFeedStory' => 'applications/ponder/feed/PonderTransactionFeedStory.php',
|
||||
'PonderVotableInterface' => 'applications/ponder/storage/PonderVotableInterface.php',
|
||||
'PonderVotableView' => 'applications/ponder/view/PonderVotableView.php',
|
||||
'PonderVote' => 'applications/ponder/constants/PonderVote.php',
|
||||
|
@ -4149,14 +4150,13 @@ phutil_register_library_map(array(
|
|||
),
|
||||
'PonderAnswerCommentController' => 'PonderController',
|
||||
'PonderAnswerEditController' => 'PonderController',
|
||||
'PonderAnswerEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PonderAnswerEditor' => 'PonderEditor',
|
||||
'PonderAnswerHistoryController' => 'PonderController',
|
||||
'PonderAnswerQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PonderAnswerSaveController' => 'PonderController',
|
||||
'PonderAnswerTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PonderAnswerTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||
'PonderAnswerTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PonderAnswerViewController' => 'PonderController',
|
||||
'PonderComment' =>
|
||||
array(
|
||||
0 => 'PonderDAO',
|
||||
|
@ -4165,6 +4165,7 @@ phutil_register_library_map(array(
|
|||
'PonderCommentQuery' => 'PhabricatorQuery',
|
||||
'PonderController' => 'PhabricatorController',
|
||||
'PonderDAO' => 'PhabricatorLiskDAO',
|
||||
'PonderEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PonderPHIDTypeAnswer' => 'PhabricatorPHIDType',
|
||||
'PonderPHIDTypeQuestion' => 'PhabricatorPHIDType',
|
||||
'PonderQuestion' =>
|
||||
|
@ -4178,7 +4179,7 @@ phutil_register_library_map(array(
|
|||
),
|
||||
'PonderQuestionCommentController' => 'PonderController',
|
||||
'PonderQuestionEditController' => 'PonderController',
|
||||
'PonderQuestionEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PonderQuestionEditor' => 'PonderEditor',
|
||||
'PonderQuestionHistoryController' => 'PonderController',
|
||||
'PonderQuestionListController' =>
|
||||
array(
|
||||
|
@ -4197,6 +4198,7 @@ phutil_register_library_map(array(
|
|||
'PonderQuestionViewController' => 'PonderController',
|
||||
'PonderRemarkupRule' => 'PhabricatorRemarkupRuleObject',
|
||||
'PonderSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
|
||||
'PonderTransactionFeedStory' => 'PhabricatorApplicationTransactionFeedStory',
|
||||
'PonderVotableView' => 'AphrontView',
|
||||
'PonderVote' => 'PonderConstants',
|
||||
'PonderVoteEditor' => 'PhabricatorEditor',
|
||||
|
|
|
@ -92,7 +92,7 @@ final class PhabricatorMacroTransaction
|
|||
return parent::getTitle();
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
public function getTitleForFeed(PhabricatorFeedStory $story) {
|
||||
$author_phid = $this->getAuthorPHID();
|
||||
$object_phid = $this->getObjectPHID();
|
||||
|
||||
|
@ -133,7 +133,7 @@ final class PhabricatorMacroTransaction
|
|||
}
|
||||
}
|
||||
|
||||
return parent::getTitleForFeed();
|
||||
return parent::getTitleForFeed($story);
|
||||
}
|
||||
|
||||
public function getActionName() {
|
||||
|
|
|
@ -88,7 +88,7 @@ final class PhabricatorPasteTransaction
|
|||
return parent::getTitle();
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
public function getTitleForFeed(PhabricatorFeedStory $story) {
|
||||
$author_phid = $this->getAuthorPHID();
|
||||
$object_phid = $this->getObjectPHID();
|
||||
|
||||
|
@ -117,7 +117,7 @@ final class PhabricatorPasteTransaction
|
|||
break;
|
||||
}
|
||||
|
||||
return parent::getTitleForFeed();
|
||||
return parent::getTitleForFeed($story);
|
||||
}
|
||||
|
||||
public function getColor() {
|
||||
|
|
|
@ -180,7 +180,7 @@ final class PholioTransaction extends PhabricatorApplicationTransaction {
|
|||
return parent::getTitle();
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
public function getTitleForFeed(PhabricatorFeedStory $story) {
|
||||
$author_phid = $this->getAuthorPHID();
|
||||
$object_phid = $this->getObjectPHID();
|
||||
|
||||
|
@ -243,7 +243,7 @@ final class PholioTransaction extends PhabricatorApplicationTransaction {
|
|||
break;
|
||||
}
|
||||
|
||||
return parent::getTitleForFeed();
|
||||
return parent::getTitleForFeed($story);
|
||||
}
|
||||
|
||||
public function getBodyForFeed(PhabricatorFeedStory $story) {
|
||||
|
|
|
@ -31,9 +31,8 @@ final class PonderAnswerEditController extends PonderController {
|
|||
|
||||
$question = $answer->getQuestion();
|
||||
$qid = $question->getID();
|
||||
$aid = $answer->getID();
|
||||
|
||||
$question_uri = "/Q{$qid}#A{$aid}";
|
||||
$answer_uri = $answer->getURI();
|
||||
|
||||
$errors = array();
|
||||
if ($request->isFormPost()) {
|
||||
|
@ -58,7 +57,7 @@ final class PonderAnswerEditController extends PonderController {
|
|||
$editor->applyTransactions($answer, $xactions);
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($question_uri);
|
||||
->setURI($answer_uri);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,13 +83,13 @@ final class PonderAnswerEditController extends PonderController {
|
|||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Update Answer'))
|
||||
->addCancelButton($question_uri));
|
||||
->addCancelButton($answer_uri));
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addCrumb(
|
||||
id(new PhabricatorCrumbView())
|
||||
->setName("Q{$qid}")
|
||||
->setHref($question_uri));
|
||||
->setHref($answer_uri));
|
||||
$crumbs->addCrumb(
|
||||
id(new PhabricatorCrumbView())
|
||||
->setName(pht('Edit Answer')));
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PonderAnswerViewController extends PonderController {
|
||||
|
||||
private $answerID;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->answerID = $data['id'];
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$answer = id(new PonderAnswer())->load($this->answerID);
|
||||
|
||||
if (!$answer) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$question_id = $answer->getQuestionID();
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/Q'.$question_id . '#A' . $answer->getID());
|
||||
}
|
||||
|
||||
}
|
|
@ -251,6 +251,8 @@ final class PonderQuestionViewController extends PonderController {
|
|||
|
||||
$out[] = phutil_tag('br');
|
||||
$out[] = phutil_tag('br');
|
||||
$out[] = id(new PhabricatorAnchorView())
|
||||
->setAnchorName("A$id");
|
||||
$out[] = id(new PHUIHeaderView())
|
||||
->setHeader($this->getHandle($author_phid)->getFullName())
|
||||
->setImage($this->getHandle($author_phid)->getImageURI());
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<?php
|
||||
|
||||
final class PonderAnswerEditor
|
||||
extends PhabricatorApplicationTransactionEditor {
|
||||
final class PonderAnswerEditor extends PonderEditor {
|
||||
|
||||
public function getTransactionTypes() {
|
||||
$types = parent::getTransactionTypes();
|
||||
|
@ -62,13 +61,44 @@ final class PonderAnswerEditor
|
|||
return parent::mergeTransactions($u, $v);
|
||||
}
|
||||
|
||||
protected function supportsFeed() {
|
||||
protected function shouldSendMail(
|
||||
PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getMailTo(PhabricatorLiskDAO $object) {
|
||||
return array($object->getAuthorPHID());
|
||||
protected function buildReplyHandler(PhabricatorLiskDAO $object) {
|
||||
$question = $object->getQuestion();
|
||||
return id(new PonderQuestionReplyHandler())
|
||||
->setMailReceiver($question);
|
||||
}
|
||||
|
||||
protected function buildMailTemplate(PhabricatorLiskDAO $object) {
|
||||
$question = $object->getQuestion();
|
||||
return parent::buildMailTemplate($question);
|
||||
}
|
||||
|
||||
|
||||
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->addTextSection(
|
||||
pht('ANSWER DETAIL'),
|
||||
PhabricatorEnv::getProductionURI($object->getURI()));
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
32
src/applications/ponder/editor/PonderEditor.php
Normal file
32
src/applications/ponder/editor/PonderEditor.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
abstract class PonderEditor
|
||||
extends PhabricatorApplicationTransactionEditor {
|
||||
|
||||
protected function supportsFeed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
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 getMailSubjectPrefix() {
|
||||
return '[Ponder]';
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,26 @@
|
|||
<?php
|
||||
|
||||
final class PonderQuestionEditor
|
||||
extends PhabricatorApplicationTransactionEditor {
|
||||
extends PonderEditor {
|
||||
|
||||
private $answer;
|
||||
|
||||
/**
|
||||
* 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,
|
||||
|
@ -32,6 +51,7 @@ final class PonderQuestionEditor
|
|||
continue;
|
||||
}
|
||||
$answer->save();
|
||||
$this->setAnswer($answer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -145,14 +165,27 @@ final class PonderQuestionEditor
|
|||
return parent::mergeTransactions($u, $v);
|
||||
}
|
||||
|
||||
protected function supportsFeed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function supportsSearch() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getFeedStoryType() {
|
||||
return 'PonderTransactionFeedStory';
|
||||
}
|
||||
|
||||
protected function getFeedStoryData(
|
||||
PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
|
||||
$data = parent::getFeedStoryData($object, $xactions);
|
||||
$answer = $this->getAnswer();
|
||||
if ($answer) {
|
||||
$data['answerPHID'] = $answer->getPHID();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function shouldImplyCC(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
@ -176,50 +209,39 @@ final class PonderQuestionEditor
|
|||
->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.
|
||||
$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);
|
||||
}
|
||||
}
|
||||
// If the user gave an answer, add the answer text. Also update
|
||||
// the header and uri to be more answer-specific.
|
||||
if ($type == PonderQuestionTransaction::TYPE_ANSWERS) {
|
||||
$answer = $this->getAnswer();
|
||||
$body->addRawSection($answer->getContent());
|
||||
$header = pht('ANSWER DETAIL');
|
||||
$uri = $answer->getURI();
|
||||
}
|
||||
}
|
||||
|
||||
$body->addTextSection(
|
||||
pht('QUESTION DETAIL'),
|
||||
PhabricatorEnv::getProductionURI('/Q'.$object->getID()));
|
||||
$header,
|
||||
PhabricatorEnv::getProductionURI($uri));
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
protected function getMailSubjectPrefix() {
|
||||
return '[Ponder]';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
14
src/applications/ponder/feed/PonderTransactionFeedStory.php
Normal file
14
src/applications/ponder/feed/PonderTransactionFeedStory.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
final class PonderTransactionFeedStory
|
||||
extends PhabricatorApplicationTransactionFeedStory {
|
||||
|
||||
public function getRequiredObjectPHIDs() {
|
||||
$phids = parent::getRequiredObjectPHIDs();
|
||||
$answer_phid = $this->getValue('answerPHID');
|
||||
if ($answer_phid) {
|
||||
$phids[] = $answer_phid;
|
||||
}
|
||||
return $phids;
|
||||
}
|
||||
}
|
|
@ -17,11 +17,6 @@ final class PonderQuestionReplyHandler extends PhabricatorMailReplyHandler {
|
|||
return $this->getDefaultPublicReplyHandlerEmailAddress('Q');
|
||||
}
|
||||
|
||||
public function getReplyHandlerDomain() {
|
||||
return PhabricatorEnv::getEnvConfig(
|
||||
'metamta.maniphest.reply-handler-domain');
|
||||
}
|
||||
|
||||
public function getReplyHandlerInstructions() {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -36,10 +36,9 @@ final class PonderPHIDTypeAnswer extends PhabricatorPHIDType {
|
|||
$answer = $objects[$phid];
|
||||
|
||||
$id = $answer->getID();
|
||||
$qid = $answer->getQuestionID();
|
||||
|
||||
$handle->setName("Answer {$id}");
|
||||
$handle->setURI("/Q{$qid}#A{$id}");
|
||||
$handle->setURI($answer->getURI());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,11 +36,10 @@ final class PonderPHIDTypeQuestion extends PhabricatorPHIDType {
|
|||
$question = $objects[$phid];
|
||||
|
||||
$id = $question->getID();
|
||||
$title = $question->getTitle();
|
||||
|
||||
$handle->setName("Q{$id}");
|
||||
$handle->setURI("/Q{$id}");
|
||||
$handle->setFullName("Q{$id}: {$title}");
|
||||
$handle->setFullName($question->getFullTitle());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -151,7 +151,8 @@ final class PonderQuestionQuery
|
|||
$answers = mgroup($answers, 'getQuestionID');
|
||||
|
||||
foreach ($questions as $question) {
|
||||
$question->attachAnswers(idx($answers, $question->getID(), array()));
|
||||
$question_answers = idx($answers, $question->getID(), array());
|
||||
$question->attachAnswers(mpull($question_answers, null, 'getPHID'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,11 +23,6 @@ final class PonderAnswer extends PonderDAO
|
|||
|
||||
private $userVotes = array();
|
||||
|
||||
// TODO: Get rid of this method.
|
||||
public function setQuestion($question) {
|
||||
return $this->attachQuestion($question);
|
||||
}
|
||||
|
||||
public function attachQuestion(PonderQuestion $question = null) {
|
||||
$this->question = $question;
|
||||
return $this;
|
||||
|
@ -37,6 +32,10 @@ final class PonderAnswer extends PonderDAO
|
|||
return $this->assertAttached($this->question);
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
return '/Q'.$this->getQuestionID().'#A'.$this->getID();
|
||||
}
|
||||
|
||||
public function setUserVote($vote) {
|
||||
$this->vote = $vote['data'];
|
||||
if (!$this->vote) {
|
||||
|
|
|
@ -21,23 +21,89 @@ final class PonderAnswerTransaction
|
|||
return new PonderAnswerTransactionComment();
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
$author_phid = $this->getAuthorPHID();
|
||||
$object_phid = $this->getObjectPHID();
|
||||
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
public function getRequiredHandlePHIDs() {
|
||||
$phids = parent::getRequiredHandlePHIDs();
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_CONTENT:
|
||||
$phids[] = $this->getObjectPHID();
|
||||
break;
|
||||
}
|
||||
|
||||
return $phids;
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$author_phid = $this->getAuthorPHID();
|
||||
$object_phid = $this->getObjectPHID();
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_CONTENT:
|
||||
// TODO: This is not so good.
|
||||
return pht(
|
||||
'%s edited their answer to %s',
|
||||
'%s edited %s.',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
}
|
||||
|
||||
return $this->getTitle();
|
||||
return parent::getTitle();
|
||||
}
|
||||
|
||||
public function getTitleForFeed(PhabricatorFeedStory $story) {
|
||||
$author_phid = $this->getAuthorPHID();
|
||||
$object_phid = $this->getObjectPHID();
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_CONTENT:
|
||||
$answer = $story->getObject($object_phid);
|
||||
$question = $answer->getQuestion();
|
||||
$answer_handle = $this->getHandle($object_phid);
|
||||
$link = $answer_handle->renderLink(
|
||||
$question->getFullTitle());
|
||||
|
||||
return pht(
|
||||
'%s updated their answer to %s',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$link);
|
||||
}
|
||||
|
||||
return parent::getTitleForFeed($story);
|
||||
}
|
||||
|
||||
public function getBodyForFeed(PhabricatorFeedStory $story) {
|
||||
$new = $this->getNewValue();
|
||||
|
||||
$body = null;
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_CONTENT:
|
||||
return phutil_escape_html_newlines(
|
||||
phutil_utf8_shorten($new, 128));
|
||||
break;
|
||||
}
|
||||
return parent::getBodyForFeed($story);
|
||||
}
|
||||
|
||||
|
||||
public function hasChangeDetails() {
|
||||
$old = $this->getOldValue();
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_CONTENT:
|
||||
return $old !== null;
|
||||
}
|
||||
return parent::hasChangeDetails();
|
||||
}
|
||||
|
||||
public function renderChangeDetails(PhabricatorUser $viewer) {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
$view = id(new PhabricatorApplicationTransactionTextDiffDetailView())
|
||||
->setUser($viewer)
|
||||
->setOldText($old)
|
||||
->setNewText($new);
|
||||
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ final class PonderQuestion extends PonderDAO
|
|||
|
||||
$this->setComments(idx($comments, $this->getPHID(), array()));
|
||||
foreach ($this->answers as $answer) {
|
||||
$answer->setQuestion($this);
|
||||
$answer->attachQuestion($this);
|
||||
$answer->setComments(idx($comments, $answer->getPHID(), array()));
|
||||
}
|
||||
}
|
||||
|
@ -208,6 +208,12 @@ final class PonderQuestion extends PonderDAO
|
|||
return $this->getTitle();
|
||||
}
|
||||
|
||||
public function getFullTitle() {
|
||||
$id = $this->getID();
|
||||
$title = $this->getTitle();
|
||||
return "Q{$id}: {$title}";
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorTokenReceiverInterface )---------------------------------- */
|
||||
|
||||
|
|
|
@ -24,8 +24,22 @@ final class PonderQuestionTransaction
|
|||
return new PonderQuestionTransactionComment();
|
||||
}
|
||||
|
||||
public function getRequiredHandlePHIDs() {
|
||||
$phids = parent::getRequiredHandlePHIDs();
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_ANSWERS:
|
||||
$phids[] = $this->getNewAnswerPHID();
|
||||
$phids[] = $this->getObjectPHID();
|
||||
break;
|
||||
}
|
||||
|
||||
return $phids;
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
$author_phid = $this->getAuthorPHID();
|
||||
$object_phid = $this->getObjectPHID();
|
||||
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNewValue();
|
||||
|
@ -48,10 +62,12 @@ final class PonderQuestionTransaction
|
|||
'%s edited the question description.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
case self::TYPE_ANSWERS:
|
||||
// TODO: This could be richer.
|
||||
$answer_handle = $this->getHandle($this->getNewAnswerPHID());
|
||||
$question_handle = $this->getHandle($object_phid);
|
||||
return pht(
|
||||
'%s added an answer.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
'%s answered %s',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$answer_handle->renderLink($question_handle->getFullName()));
|
||||
case self::TYPE_STATUS:
|
||||
switch ($new) {
|
||||
case PonderQuestionStatus::STATUS_OPEN:
|
||||
|
@ -178,7 +194,7 @@ final class PonderQuestionTransaction
|
|||
return parent::shouldHide();
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
public function getTitleForFeed(PhabricatorFeedStory $story) {
|
||||
$author_phid = $this->getAuthorPHID();
|
||||
$object_phid = $this->getObjectPHID();
|
||||
|
||||
|
@ -205,11 +221,12 @@ final class PonderQuestionTransaction
|
|||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
case self::TYPE_ANSWERS:
|
||||
// TODO: This could be richer, too.
|
||||
$answer_handle = $this->getHandle($this->getNewAnswerPHID());
|
||||
$question_handle = $this->getHandle($object_phid);
|
||||
return pht(
|
||||
'%s answered %s',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($object_phid));
|
||||
$answer_handle->renderLink($question_handle->getFullName()));
|
||||
case self::TYPE_STATUS:
|
||||
switch ($new) {
|
||||
case PonderQuestionStatus::STATUS_OPEN:
|
||||
|
@ -225,8 +242,67 @@ final class PonderQuestionTransaction
|
|||
}
|
||||
}
|
||||
|
||||
return $this->getTitle();
|
||||
return parent::getTitleForFeed($story);
|
||||
}
|
||||
|
||||
public function getBodyForFeed(PhabricatorFeedStory $story) {
|
||||
$new = $this->getNewValue();
|
||||
$old = $this->getOldValue();
|
||||
|
||||
$body = null;
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case self::TYPE_TITLE:
|
||||
if ($old === null) {
|
||||
$question = $story->getObject($this->getObjectPHID());
|
||||
return phutil_escape_html_newlines(
|
||||
phutil_utf8_shorten($question->getContent(), 128));
|
||||
}
|
||||
case self::TYPE_ANSWERS:
|
||||
$answer = $this->getNewAnswerObject($story);
|
||||
if ($answer) {
|
||||
return phutil_escape_html_newlines(
|
||||
phutil_utf8_shorten($answer->getContent(), 128));
|
||||
}
|
||||
}
|
||||
return parent::getBodyForFeed($story);
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently the application only supports adding answers one at a time.
|
||||
* This data is stored as a list of phids. Use this function to get the
|
||||
* new phid.
|
||||
*/
|
||||
private function getNewAnswerPHID() {
|
||||
$new = $this->getNewValue();
|
||||
$old = $this->getOldValue();
|
||||
$add = array_diff($new, $old);
|
||||
|
||||
if (count($add) != 1) {
|
||||
throw new Exception(
|
||||
'There should be only one answer added at a time.');
|
||||
}
|
||||
|
||||
return reset($add);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generally, the answer object is only available if the transaction
|
||||
* type is self::TYPE_ANSWERS.
|
||||
*
|
||||
* Some stories - notably ones made before D7027 - will be of the more
|
||||
* generic @{class:PhabricatorApplicationTransactionFeedStory}. These
|
||||
* poor stories won't have the PonderAnswer loaded, and thus will have
|
||||
* less cool information.
|
||||
*/
|
||||
private function getNewAnswerObject(PhabricatorFeedStory $story) {
|
||||
if ($story instanceof PonderTransactionFeedStory) {
|
||||
$answer_phid = $this->getNewAnswerPHID();
|
||||
if ($answer_phid) {
|
||||
return $story->getObject($answer_phid);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ class PhabricatorApplicationTransactionFeedStory
|
|||
$xaction = $this->getObject(head($xaction_phids));
|
||||
|
||||
$xaction->setHandles($this->getHandles());
|
||||
$view->setTitle($xaction->getTitleForFeed());
|
||||
$view->setTitle($xaction->getTitleForFeed($this));
|
||||
$body = $xaction->getBodyForFeed($this);
|
||||
if (nonempty($body)) {
|
||||
$view->appendChild($body);
|
||||
|
|
|
@ -355,7 +355,7 @@ abstract class PhabricatorApplicationTransaction
|
|||
}
|
||||
}
|
||||
|
||||
public function getTitleForFeed() {
|
||||
public function getTitleForFeed(PhabricatorFeedStory $story) {
|
||||
$author_phid = $this->getAuthorPHID();
|
||||
$object_phid = $this->getObjectPHID();
|
||||
|
||||
|
|
Loading…
Reference in a new issue