@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.

Lift common code for transaction-based reply handlers into parent class

Summary:
Ref T7199. Essentially all of the reply handlers now apply transactions to something which implements PhabricatorApplicationTransactionInterface.

We can share code between them by lifting this stuff into a superclass.

First, convert paste. Also rename `PasteMockMailReceiver` to `PasteMailReceiver` (this got mis-copied from Pholio at some point, I think).

Test Plan: Used `bin/mail receive-test` to send comments + `!unsubscribe` to pastes.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T7199

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

+105 -43
+5 -3
src/__phutil_library_map__.php
··· 1248 1248 'PasteDefaultViewCapability' => 'applications/paste/capability/PasteDefaultViewCapability.php', 1249 1249 'PasteEmbedView' => 'applications/paste/view/PasteEmbedView.php', 1250 1250 'PasteInfoConduitAPIMethod' => 'applications/paste/conduit/PasteInfoConduitAPIMethod.php', 1251 - 'PasteMockMailReceiver' => 'applications/paste/mail/PasteMockMailReceiver.php', 1251 + 'PasteMailReceiver' => 'applications/paste/mail/PasteMailReceiver.php', 1252 1252 'PasteQueryConduitAPIMethod' => 'applications/paste/conduit/PasteQueryConduitAPIMethod.php', 1253 1253 'PasteReplyHandler' => 'applications/paste/mail/PasteReplyHandler.php', 1254 1254 'PeopleBrowseUserDirectoryCapability' => 'applications/people/capability/PeopleBrowseUserDirectoryCapability.php', ··· 1310 1310 'PhabricatorApplicationTransactionNoEffectException' => 'applications/transactions/exception/PhabricatorApplicationTransactionNoEffectException.php', 1311 1311 'PhabricatorApplicationTransactionNoEffectResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionNoEffectResponse.php', 1312 1312 'PhabricatorApplicationTransactionQuery' => 'applications/transactions/query/PhabricatorApplicationTransactionQuery.php', 1313 + 'PhabricatorApplicationTransactionReplyHandler' => 'applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php', 1313 1314 'PhabricatorApplicationTransactionResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionResponse.php', 1314 1315 'PhabricatorApplicationTransactionShowOlderController' => 'applications/transactions/controller/PhabricatorApplicationTransactionShowOlderController.php', 1315 1316 'PhabricatorApplicationTransactionStructureException' => 'applications/transactions/exception/PhabricatorApplicationTransactionStructureException.php', ··· 4512 4513 'PasteDefaultViewCapability' => 'PhabricatorPolicyCapability', 4513 4514 'PasteEmbedView' => 'AphrontView', 4514 4515 'PasteInfoConduitAPIMethod' => 'PasteConduitAPIMethod', 4515 - 'PasteMockMailReceiver' => 'PhabricatorObjectMailReceiver', 4516 + 'PasteMailReceiver' => 'PhabricatorObjectMailReceiver', 4516 4517 'PasteQueryConduitAPIMethod' => 'PasteConduitAPIMethod', 4517 - 'PasteReplyHandler' => 'PhabricatorMailReplyHandler', 4518 + 'PasteReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler', 4518 4519 'PeopleBrowseUserDirectoryCapability' => 'PhabricatorPolicyCapability', 4519 4520 'PeopleCreateUsersCapability' => 'PhabricatorPolicyCapability', 4520 4521 'PeopleUserLogGarbageCollector' => 'PhabricatorGarbageCollector', ··· 4579 4580 'PhabricatorApplicationTransactionNoEffectException' => 'Exception', 4580 4581 'PhabricatorApplicationTransactionNoEffectResponse' => 'AphrontProxyResponse', 4581 4582 'PhabricatorApplicationTransactionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 4583 + 'PhabricatorApplicationTransactionReplyHandler' => 'PhabricatorMailReplyHandler', 4582 4584 'PhabricatorApplicationTransactionResponse' => 'AphrontProxyResponse', 4583 4585 'PhabricatorApplicationTransactionShowOlderController' => 'PhabricatorApplicationTransactionController', 4584 4586 'PhabricatorApplicationTransactionStructureException' => 'Exception',
+1 -1
src/applications/paste/mail/PasteMockMailReceiver.php src/applications/paste/mail/PasteMailReceiver.php
··· 1 1 <?php 2 2 3 - final class PasteMockMailReceiver extends PhabricatorObjectMailReceiver { 3 + final class PasteMailReceiver extends PhabricatorObjectMailReceiver { 4 4 5 5 public function isEnabled() { 6 6 $app_class = 'PhabricatorPasteApplication';
+7 -39
src/applications/paste/mail/PasteReplyHandler.php
··· 1 1 <?php 2 2 3 - final class PasteReplyHandler extends PhabricatorMailReplyHandler { 3 + final class PasteReplyHandler 4 + extends PhabricatorApplicationTransactionReplyHandler { 4 5 5 6 public function validateMailReceiver($mail_receiver) { 6 7 if (!($mail_receiver instanceof PhabricatorPaste)) { ··· 8 9 } 9 10 } 10 11 11 - public function getPrivateReplyHandlerEmailAddress( 12 - PhabricatorObjectHandle $handle) { 13 - return $this->getDefaultPrivateReplyHandlerEmailAddress($handle, 'P'); 14 - } 15 - 16 - public function getPublicReplyHandlerEmailAddress() { 17 - return $this->getDefaultPublicReplyHandlerEmailAddress('P'); 12 + public function getObjectPrefix() { 13 + return 'P'; 18 14 } 19 15 20 - protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail) { 21 - $actor = $this->getActor(); 22 - $paste = $this->getMailReceiver(); 23 - 24 - $body_data = $mail->parseBody(); 25 - $body = $body_data['body']; 26 - $body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments()); 27 - 28 - $content_source = PhabricatorContentSource::newForSource( 29 - PhabricatorContentSource::SOURCE_EMAIL, 30 - array( 31 - 'id' => $mail->getID(), 32 - )); 33 - 34 - $lines = explode("\n", trim($body)); 35 - $first_line = head($lines); 16 + protected function processMailCommands(array $commands) { 17 + $actor = $this->getActor(); 36 18 37 19 $xactions = array(); 38 - 39 - $commands = $body_data['commands']; 40 20 foreach ($commands as $command) { 41 21 switch (head($command)) { 42 22 case 'unsubscribe': ··· 48 28 } 49 29 } 50 30 51 - $xactions[] = id(new PhabricatorPasteTransaction()) 52 - ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) 53 - ->attachComment( 54 - id(new PhabricatorPasteTransactionComment()) 55 - ->setContent($body)); 56 - 57 - $editor = id(new PhabricatorPasteEditor()) 58 - ->setActor($actor) 59 - ->setContentSource($content_source) 60 - ->setContinueOnNoEffect(true) 61 - ->setIsPreview(false); 62 - 63 - $editor->applyTransactions($paste, $xactions); 31 + return $xactions; 64 32 } 65 33 66 34 }
+92
src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorApplicationTransactionReplyHandler 4 + extends PhabricatorMailReplyHandler { 5 + 6 + abstract public function getObjectPrefix(); 7 + 8 + public function getPrivateReplyHandlerEmailAddress( 9 + PhabricatorObjectHandle $handle) { 10 + return $this->getDefaultPrivateReplyHandlerEmailAddress( 11 + $handle, 12 + $this->getObjectPrefix()); 13 + } 14 + 15 + public function getPublicReplyHandlerEmailAddress() { 16 + return $this->getDefaultPublicReplyHandlerEmailAddress( 17 + $this->getObjectPrefix()); 18 + } 19 + 20 + private function newEditor(PhabricatorMetaMTAReceivedMail $mail) { 21 + $content_source = PhabricatorContentSource::newForSource( 22 + PhabricatorContentSource::SOURCE_EMAIL, 23 + array( 24 + 'id' => $mail->getID(), 25 + )); 26 + 27 + $editor = $this->getMailReceiver() 28 + ->getApplicationTransactionEditor() 29 + ->setActor($this->getActor()) 30 + ->setContentSource($content_source) 31 + ->setContinueOnMissingFields(true) 32 + ->setParentMessageID($mail->getMessageID()) 33 + ->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs()); 34 + 35 + if ($this->getApplicationEmail()) { 36 + $editor->setApplicationEmail($this->getApplicationEmail()); 37 + } 38 + 39 + return $editor; 40 + } 41 + 42 + private function newTransaction() { 43 + return $this->getMailReceiver()->getApplicationTransactionTemplate(); 44 + } 45 + 46 + final protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail) { 47 + $viewer = $this->getActor(); 48 + $object = $this->getMailReceiver(); 49 + 50 + $body_data = $mail->parseBody(); 51 + 52 + $xactions = $this->processMailCommands($body_data['commands']); 53 + 54 + // If this object is subscribable, subscribe all the users who were 55 + // CC'd on the message. 56 + if ($object instanceof PhabricatorSubscribableInterface) { 57 + $subscriber_phids = $mail->loadCCPHIDs(); 58 + if ($subscriber_phids) { 59 + $xactions[] = $this->newTransaction() 60 + ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS) 61 + ->setNewValue( 62 + array( 63 + '+' => array($viewer->getPHID()), 64 + )); 65 + } 66 + } 67 + 68 + $body = $body_data['body']; 69 + $body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments()); 70 + 71 + $comment = $this 72 + ->newTransaction() 73 + ->getApplicationTransactionCommentObject() 74 + ->setContent($body); 75 + 76 + $xactions[] = $this->newTransaction() 77 + ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) 78 + ->attachComment($comment); 79 + 80 + $target = $object->getApplicationTransactionObject(); 81 + 82 + $this->newEditor($mail) 83 + ->setContinueOnNoEffect(true) 84 + ->applyTransactions($target, $xactions); 85 + } 86 + 87 + protected function processMailCommands(array $commands) { 88 + // TODO: Modularize this. 89 + return array(); 90 + } 91 + 92 + }