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

Allow Maniphest to process multiple commands via email

Summary:
Ref T7199. Two notable changes:

- Process multiple commands.
- Process commands when creating //or// updating a task.

And generally clean things up a bit.

Test Plan:
- Used `receive-test` to execute all commands for new tasks.
- Used `receive-test` to execute all commands for existing tasks.
- Used a combination of commands to produce varied effects.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T7199

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

+54 -84
+54 -84
src/applications/maniphest/mail/ManiphestReplyHandler.php
··· 20 20 protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail) { 21 21 // NOTE: We'll drop in here on both the "reply to a task" and "create a 22 22 // new task" workflows! Make sure you test both if you make changes! 23 - 24 23 $task = $this->getMailReceiver(); 24 + $viewer = $this->getActor(); 25 25 26 26 $is_new_task = !$task->getID(); 27 27 28 - $user = $this->getActor(); 29 - 30 28 $body_data = $mail->parseBody(); 31 29 $body = $body_data['body']; 32 30 $body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments()); 33 31 34 - $xactions = array(); 35 32 $content_source = PhabricatorContentSource::newForSource( 36 33 PhabricatorContentSource::SOURCE_EMAIL, 37 34 array( ··· 40 37 41 38 $template = new ManiphestTransaction(); 42 39 43 - $is_unsub = false; 40 + $xactions = array(); 44 41 if ($is_new_task) { 45 - $task = ManiphestTask::initializeNewTask($user); 46 - 47 - $xactions[] = id(new ManiphestTransaction()) 48 - ->setTransactionType(ManiphestTransaction::TYPE_STATUS) 49 - ->setNewValue(ManiphestTaskStatus::getDefaultStatus()); 50 - 51 - $xactions[] = id(new ManiphestTransaction()) 42 + $xactions[] = id(clone $template) 52 43 ->setTransactionType(ManiphestTransaction::TYPE_TITLE) 53 44 ->setNewValue(nonempty($mail->getSubject(), pht('Untitled Task'))); 54 45 55 - $xactions[] = id(new ManiphestTransaction()) 46 + $xactions[] = id(clone $template) 56 47 ->setTransactionType(ManiphestTransaction::TYPE_DESCRIPTION) 57 48 ->setNewValue($body); 58 - 59 49 } else { 50 + $xactions[] = id(clone $template) 51 + ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) 52 + ->attachComment( 53 + id(new ManiphestTransactionComment()) 54 + ->setContent($body)); 55 + } 60 56 61 - $commands = $body_data['commands']; 62 - 63 - // TODO: Support multiple commands. 64 - if ($commands) { 65 - $command_argv = head($commands); 66 - } else { 67 - $command_argv = array(); 68 - } 69 - $command = idx($command_argv, 0); 70 - $command_value = idx($command_argv, 1); 71 - 72 - $ttype = PhabricatorTransactions::TYPE_COMMENT; 73 - $new_value = null; 57 + $commands = $body_data['commands']; 58 + foreach ($commands as $command_argv) { 59 + $command = head($command_argv); 60 + $args = array_slice($command_argv, 1); 74 61 switch ($command) { 75 62 case 'close': 76 - $ttype = ManiphestTransaction::TYPE_STATUS; 77 - $new_value = ManiphestTaskStatus::getDefaultClosedStatus(); 63 + $xactions[] = id(clone $template) 64 + ->setTransactionType(ManiphestTransaction::TYPE_STATUS) 65 + ->setNewValue(ManiphestTaskStatus::getDefaultClosedStatus()); 78 66 break; 79 67 case 'claim': 80 - $ttype = ManiphestTransaction::TYPE_OWNER; 81 - $new_value = $user->getPHID(); 68 + $xactions[] = id(clone $template) 69 + ->setTransactionType(ManiphestTransaction::TYPE_OWNER) 70 + ->setNewValue($viewer->getPHID()); 82 71 break; 83 72 case 'assign': 84 - $ttype = ManiphestTransaction::TYPE_OWNER; 85 - if ($command_value) { 86 - $assign_users = id(new PhabricatorPeopleQuery()) 87 - ->setViewer($user) 88 - ->withUsernames(array($command_value)) 89 - ->execute(); 90 - if ($assign_users) { 91 - $assign_user = head($assign_users); 92 - $new_value = $assign_user->getPHID(); 73 + $assign_to = head($args); 74 + if ($assign_to) { 75 + $assign_user = id(new PhabricatorPeopleQuery()) 76 + ->setViewer($viewer) 77 + ->withUsernames(array($assign_to)) 78 + ->executeOne(); 79 + if ($assign_user) { 80 + $assign_phid = $assign_user->getPHID(); 93 81 } 94 82 } 95 - // assign to the user by default 96 - if (!$new_value) { 97 - $new_value = $user->getPHID(); 83 + 84 + // Treat bad "!assign" like "!claim". 85 + if (!$assign_phid) { 86 + $assign_phid = $viewer->getPHID(); 98 87 } 88 + 89 + $xactions[] = id(clone $template) 90 + ->setTransactionType(ManiphestTransaction::TYPE_OWNER) 91 + ->setNewValue($assign_phid); 99 92 break; 100 93 case 'unsubscribe': 101 - $is_unsub = true; 102 - $ttype = PhabricatorTransactions::TYPE_SUBSCRIBERS; 103 - $ccs = $task->getSubscriberPHIDs(); 104 - foreach ($ccs as $k => $phid) { 105 - if ($phid == $user->getPHID()) { 106 - unset($ccs[$k]); 107 - } 108 - } 109 - $new_value = array('=' => array_values($ccs)); 94 + $xactions[] = id(clone $template) 95 + ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS) 96 + ->setNewValue( 97 + array( 98 + '-' => array($viewer->getPHID()), 99 + )); 110 100 break; 111 101 } 112 - 113 - if ($ttype != PhabricatorTransactions::TYPE_COMMENT) { 114 - $xaction = clone $template; 115 - $xaction->setTransactionType($ttype); 116 - $xaction->setNewValue($new_value); 117 - $xactions[] = $xaction; 118 - } 119 - 120 - if (strlen($body)) { 121 - $xaction = clone $template; 122 - $xaction->setTransactionType(PhabricatorTransactions::TYPE_COMMENT); 123 - $xaction->attachComment( 124 - id(new ManiphestTransactionComment()) 125 - ->setContent($body)); 126 - $xactions[] = $xaction; 127 - } 128 102 } 129 103 130 104 $ccs = $mail->loadCCPHIDs(); 131 - $old_ccs = $task->getSubscriberPHIDs(); 132 - $new_ccs = array_merge($old_ccs, $ccs); 133 - if (!$is_unsub) { 134 - $new_ccs[] = $user->getPHID(); 135 - } 136 - $new_ccs = array_unique($new_ccs); 137 - 138 - if (array_diff($new_ccs, $old_ccs)) { 139 - $cc_xaction = clone $template; 140 - $cc_xaction->setTransactionType( 141 - PhabricatorTransactions::TYPE_SUBSCRIBERS); 142 - $cc_xaction->setNewValue(array('=' => $new_ccs)); 143 - $xactions[] = $cc_xaction; 105 + if ($ccs) { 106 + $xactions[] = id(clone $template) 107 + ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS) 108 + ->setNewValue( 109 + array( 110 + '+' => array($viewer->getPHID()), 111 + )); 144 112 } 145 113 146 114 $event = new PhabricatorEvent( ··· 151 119 'new' => $is_new_task, 152 120 'transactions' => $xactions, 153 121 )); 154 - $event->setUser($user); 122 + $event->setUser($viewer); 155 123 PhutilEventEngine::dispatchEvent($event); 156 124 157 125 $task = $event->getValue('task'); 158 126 $xactions = $event->getValue('transactions'); 159 127 160 128 $editor = id(new ManiphestTransactionEditor()) 161 - ->setActor($user) 129 + ->setActor($viewer) 162 130 ->setParentMessageID($mail->getMessageID()) 163 131 ->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs()) 164 132 ->setContinueOnNoEffect(true) 165 133 ->setContinueOnMissingFields(true) 166 134 ->setContentSource($content_source); 135 + 167 136 if ($this->getApplicationEmail()) { 168 137 $editor->setApplicationEmail($this->getApplicationEmail()); 169 138 } 139 + 170 140 $editor->applyTransactions($task, $xactions); 171 141 172 142 $event = new PhabricatorEvent( ··· 176 146 'new' => $is_new_task, 177 147 'transactions' => $xactions, 178 148 )); 179 - $event->setUser($user); 149 + $event->setUser($viewer); 180 150 PhutilEventEngine::dispatchEvent($event); 181 151 } 182 152