@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
at upstream/main 171 lines 5.1 kB view raw
1<?php 2 3abstract class PhabricatorApplicationTransactionReplyHandler 4 extends PhabricatorMailReplyHandler { 5 6 abstract public function getObjectPrefix(); 7 8 public function getPrivateReplyHandlerEmailAddress( 9 PhabricatorUser $user) { 10 return $this->getDefaultPrivateReplyHandlerEmailAddress( 11 $user, 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 = $mail->newContentSource(); 22 23 $editor = $this->getMailReceiver() 24 ->getApplicationTransactionEditor() 25 ->setActor($this->getActor()) 26 ->setContentSource($content_source) 27 ->setContinueOnMissingFields(true) 28 ->setParentMessageID($mail->getMessageID()) 29 ->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs()); 30 31 if ($this->getApplicationEmail()) { 32 $editor->setApplicationEmail($this->getApplicationEmail()); 33 } 34 35 return $editor; 36 } 37 38 protected function newTransaction() { 39 return $this->getMailReceiver()->getApplicationTransactionTemplate(); 40 } 41 42 protected function didReceiveMail( 43 PhabricatorMetaMTAReceivedMail $mail, 44 $body) { 45 return array(); 46 } 47 48 protected function shouldCreateCommentFromMailBody() { 49 return (bool)$this->getMailReceiver()->getID(); 50 } 51 52 final protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail) { 53 $viewer = $this->getActor(); 54 $object = $this->getMailReceiver(); 55 $app_email = $this->getApplicationEmail(); 56 57 $is_new = !$object->getID(); 58 59 // If this is a new object which implements the Spaces interface and was 60 // created by sending mail to an ApplicationEmail address, put the object 61 // in the same Space the address is in. 62 if ($is_new) { 63 if ($object instanceof PhabricatorSpacesInterface) { 64 if ($app_email) { 65 $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID( 66 $app_email); 67 $object->setSpacePHID($space_phid); 68 } 69 } 70 } 71 72 $body_data = $mail->parseBody(); 73 $body = $body_data['body']; 74 $body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments()); 75 76 $xactions = $this->didReceiveMail($mail, $body); 77 78 // If this object is subscribable, subscribe all the users who were 79 // recipients on the message. 80 if ($object instanceof PhabricatorSubscribableInterface) { 81 $subscriber_phids = $mail->loadAllRecipientPHIDs(); 82 if ($subscriber_phids) { 83 $xactions[] = $this->newTransaction() 84 ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS) 85 ->setNewValue( 86 array( 87 '+' => $subscriber_phids, 88 )); 89 } 90 } 91 92 $command_xactions = $this->processMailCommands( 93 $mail, 94 $body_data['commands']); 95 foreach ($command_xactions as $xaction) { 96 $xactions[] = $xaction; 97 } 98 99 if ($this->shouldCreateCommentFromMailBody()) { 100 $comment = $this 101 ->newTransaction() 102 ->getApplicationTransactionCommentObject() 103 ->setContent($body); 104 105 $xactions[] = $this->newTransaction() 106 ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) 107 ->attachComment($comment); 108 } 109 110 $this->newEditor($mail) 111 ->setContinueOnNoEffect(true) 112 ->applyTransactions($object, $xactions); 113 } 114 115 private function processMailCommands( 116 PhabricatorMetaMTAReceivedMail $mail, 117 array $command_list) { 118 119 $viewer = $this->getActor(); 120 $object = $this->getMailReceiver(); 121 122 $list = MetaMTAEmailTransactionCommand::getAllCommandsForObject($object); 123 $map = MetaMTAEmailTransactionCommand::getCommandMap($list); 124 125 $xactions = array(); 126 foreach ($command_list as $command_argv) { 127 $command = head($command_argv); 128 $argv = array_slice($command_argv, 1); 129 130 $handler = idx($map, phutil_utf8_strtolower($command)); 131 if ($handler) { 132 $results = $handler->buildTransactions( 133 $viewer, 134 $object, 135 $mail, 136 $command, 137 $argv); 138 foreach ($results as $result) { 139 $xactions[] = $result; 140 } 141 } else { 142 $valid_commands = array(); 143 foreach ($list as $valid_command) { 144 $aliases = $valid_command->getCommandAliases(); 145 if ($aliases) { 146 foreach ($aliases as $key => $alias) { 147 $aliases[$key] = '!'.$alias; 148 } 149 $aliases = implode(', ', $aliases); 150 $valid_commands[] = pht( 151 '!%s (or %s)', 152 $valid_command->getCommand(), 153 $aliases); 154 } else { 155 $valid_commands[] = '!'.$valid_command->getCommand(); 156 } 157 } 158 159 throw new Exception( 160 pht( 161 'The command "!%s" is not a supported mail command. Valid '. 162 'commands for this object are: %s.', 163 $command, 164 implode(', ', $valid_commands))); 165 } 166 } 167 168 return $xactions; 169 } 170 171}