@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add ability to reply to Ponder Answer emails

Summary: Ref T9068, Ref T3846. Maybe fixes both, but I'm having issues testing email replies in a sandbox. Moves answer feed/mail generation to the AnswerEditor, hides it in QuestionEditor.

Test Plan: Write an answer, see feed story, check /mail/ for mail generation.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T3846, T9068

Differential Revision: https://secure.phabricator.com/D13905

+67 -62
+4 -2
src/__phutil_library_map__.php
··· 3406 3406 'PonderAnswerEditor' => 'applications/ponder/editor/PonderAnswerEditor.php', 3407 3407 'PonderAnswerHasVotingUserEdgeType' => 'applications/ponder/edge/PonderAnswerHasVotingUserEdgeType.php', 3408 3408 'PonderAnswerHistoryController' => 'applications/ponder/controller/PonderAnswerHistoryController.php', 3409 + 'PonderAnswerMailReceiver' => 'applications/ponder/mail/PonderAnswerMailReceiver.php', 3409 3410 'PonderAnswerPHIDType' => 'applications/ponder/phid/PonderAnswerPHIDType.php', 3410 3411 'PonderAnswerQuery' => 'applications/ponder/query/PonderAnswerQuery.php', 3412 + 'PonderAnswerReplyHandler' => 'applications/ponder/mail/PonderAnswerReplyHandler.php', 3411 3413 'PonderAnswerSaveController' => 'applications/ponder/controller/PonderAnswerSaveController.php', 3412 3414 'PonderAnswerStatus' => 'applications/ponder/constants/PonderAnswerStatus.php', 3413 3415 'PonderAnswerTransaction' => 'applications/ponder/storage/PonderAnswerTransaction.php', ··· 3442 3444 'PonderRemarkupRule' => 'applications/ponder/remarkup/PonderRemarkupRule.php', 3443 3445 'PonderSchemaSpec' => 'applications/ponder/storage/PonderSchemaSpec.php', 3444 3446 'PonderSearchIndexer' => 'applications/ponder/search/PonderSearchIndexer.php', 3445 - 'PonderTransactionFeedStory' => 'applications/ponder/feed/PonderTransactionFeedStory.php', 3446 3447 'PonderVotableInterface' => 'applications/ponder/storage/PonderVotableInterface.php', 3447 3448 'PonderVote' => 'applications/ponder/constants/PonderVote.php', 3448 3449 'PonderVoteEditor' => 'applications/ponder/editor/PonderVoteEditor.php', ··· 7607 7608 'PonderAnswerEditor' => 'PonderEditor', 7608 7609 'PonderAnswerHasVotingUserEdgeType' => 'PhabricatorEdgeType', 7609 7610 'PonderAnswerHistoryController' => 'PonderController', 7611 + 'PonderAnswerMailReceiver' => 'PhabricatorObjectMailReceiver', 7610 7612 'PonderAnswerPHIDType' => 'PhabricatorPHIDType', 7611 7613 'PonderAnswerQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 7614 + 'PonderAnswerReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler', 7612 7615 'PonderAnswerSaveController' => 'PonderController', 7613 7616 'PonderAnswerStatus' => 'PonderConstants', 7614 7617 'PonderAnswerTransaction' => 'PhabricatorApplicationTransaction', ··· 7654 7657 'PonderRemarkupRule' => 'PhabricatorObjectRemarkupRule', 7655 7658 'PonderSchemaSpec' => 'PhabricatorConfigSchemaSpec', 7656 7659 'PonderSearchIndexer' => 'PhabricatorSearchDocumentIndexer', 7657 - 'PonderTransactionFeedStory' => 'PhabricatorApplicationTransactionFeedStory', 7658 7660 'PonderVote' => 'PonderConstants', 7659 7661 'PonderVoteEditor' => 'PhabricatorEditor', 7660 7662 'PonderVotingUserHasAnswerEdgeType' => 'PhabricatorEdgeType',
+20 -27
src/applications/ponder/editor/PonderQuestionEditor.php
··· 177 177 return true; 178 178 } 179 179 180 - protected function getFeedStoryType() { 181 - return 'PonderTransactionFeedStory'; 182 - } 183 - 184 - protected function getFeedStoryData( 185 - PhabricatorLiskDAO $object, 186 - array $xactions) { 187 - 188 - $data = parent::getFeedStoryData($object, $xactions); 189 - $answer = $this->getAnswer(); 190 - if ($answer) { 191 - $data['answerPHID'] = $answer->getPHID(); 192 - } 193 - 194 - return $data; 195 - } 196 - 197 180 protected function shouldImplyCC( 198 181 PhabricatorLiskDAO $object, 199 182 PhabricatorApplicationTransaction $xaction) { 200 183 201 184 switch ($xaction->getTransactionType()) { 202 185 case PonderQuestionTransaction::TYPE_ANSWERS: 203 - return true; 186 + return false; 204 187 } 205 188 206 189 return parent::shouldImplyCC($object, $xaction); ··· 209 192 protected function shouldSendMail( 210 193 PhabricatorLiskDAO $object, 211 194 array $xactions) { 212 - return true; 195 + foreach ($xactions as $xaction) { 196 + switch ($xaction->getTransactionType()) { 197 + case PonderQuestionTransaction::TYPE_ANSWERS: 198 + return false; 199 + } 200 + } 201 + return true; 202 + } 203 + 204 + protected function shouldPublishFeedStory( 205 + PhabricatorLiskDAO $object, 206 + array $xactions) { 207 + foreach ($xactions as $xaction) { 208 + switch ($xaction->getTransactionType()) { 209 + case PonderQuestionTransaction::TYPE_ANSWERS: 210 + return false; 211 + } 212 + } 213 + return true; 213 214 } 214 215 215 216 public function getMailTagsMap() { ··· 247 248 if ($old === null) { 248 249 $body->addRawSection($new); 249 250 } 250 - } 251 - // If the user gave an answer, add the answer text. Also update 252 - // the header and uri to be more answer-specific. 253 - if ($type == PonderQuestionTransaction::TYPE_ANSWERS) { 254 - $answer = $this->getAnswer(); 255 - $body->addRawSection($answer->getContent()); 256 - $header = pht('ANSWER DETAIL'); 257 - $uri = $answer->getURI(); 258 251 } 259 252 } 260 253
-14
src/applications/ponder/feed/PonderTransactionFeedStory.php
··· 1 - <?php 2 - 3 - final class PonderTransactionFeedStory 4 - extends PhabricatorApplicationTransactionFeedStory { 5 - 6 - public function getRequiredObjectPHIDs() { 7 - $phids = parent::getRequiredObjectPHIDs(); 8 - $answer_phid = $this->getValue('answerPHID'); 9 - if ($answer_phid) { 10 - $phids[] = $answer_phid; 11 - } 12 - return $phids; 13 - } 14 - }
+27
src/applications/ponder/mail/PonderAnswerMailReceiver.php
··· 1 + <?php 2 + 3 + final class PonderAnswerMailReceiver extends PhabricatorObjectMailReceiver { 4 + 5 + public function isEnabled() { 6 + $app_class = 'PhabricatorPonderApplication'; 7 + return PhabricatorApplication::isClassInstalled($app_class); 8 + } 9 + 10 + protected function getObjectPattern() { 11 + return 'ANSR[1-9]\d*'; 12 + } 13 + 14 + protected function loadObject($pattern, PhabricatorUser $viewer) { 15 + $id = (int)trim($pattern, 'ANSR'); 16 + 17 + return id(new PonderAnswerQuery()) 18 + ->setViewer($viewer) 19 + ->withIDs(array($id)) 20 + ->executeOne(); 21 + } 22 + 23 + protected function getTransactionReplyHandler() { 24 + return new PonderAnswerReplyHandler(); 25 + } 26 + 27 + }
+16
src/applications/ponder/mail/PonderAnswerReplyHandler.php
··· 1 + <?php 2 + 3 + final class PonderAnswerReplyHandler 4 + extends PhabricatorApplicationTransactionReplyHandler { 5 + 6 + public function validateMailReceiver($mail_receiver) { 7 + if (!($mail_receiver instanceof PonderAnswer)) { 8 + throw new Exception(pht('Mail receiver is not a %s!', 'PonderAnswer')); 9 + } 10 + } 11 + 12 + public function getObjectPrefix() { 13 + return 'ANSR'; 14 + } 15 + 16 + }
-19
src/applications/ponder/storage/PonderQuestionTransaction.php
··· 336 336 return reset($add); 337 337 } 338 338 339 - /** 340 - * Generally, the answer object is only available if the transaction 341 - * type is `self::TYPE_ANSWERS`. 342 - * 343 - * Some stories - notably ones made before D7027 - will be of the more 344 - * generic @{class:PhabricatorApplicationTransactionFeedStory}. These 345 - * poor stories won't have the PonderAnswer loaded, and thus will have 346 - * less cool information. 347 - */ 348 - private function getNewAnswerObject(PhabricatorFeedStory $story) { 349 - if ($story instanceof PonderTransactionFeedStory) { 350 - $answer_phid = $this->getNewAnswerPHID(); 351 - if ($answer_phid) { 352 - return $story->getObject($answer_phid); 353 - } 354 - } 355 - return null; 356 - } 357 - 358 339 }