Page MenuHomePhabricator

D12238.diff
No OneTemporary

D12238.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1069,6 +1069,7 @@
'ManiphestUpdateConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestUpdateConduitAPIMethod.php',
'ManiphestView' => 'applications/maniphest/view/ManiphestView.php',
'MetaMTAConstants' => 'applications/metamta/constants/MetaMTAConstants.php',
+ 'MetaMTAEmailTransactionCommand' => 'applications/metamta/command/MetaMTAEmailTransactionCommand.php',
'MetaMTAMailReceivedGarbageCollector' => 'applications/metamta/garbagecollector/MetaMTAMailReceivedGarbageCollector.php',
'MetaMTAMailSentGarbageCollector' => 'applications/metamta/garbagecollector/MetaMTAMailSentGarbageCollector.php',
'MetaMTANotificationType' => 'applications/metamta/constants/MetaMTANotificationType.php',
@@ -2544,6 +2545,7 @@
'PhabricatorSubscriptionsListController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsListController.php',
'PhabricatorSubscriptionsTransactionController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsTransactionController.php',
'PhabricatorSubscriptionsUIEventListener' => 'applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php',
+ 'PhabricatorSubscriptionsUnsubscribeEmailCommand' => 'applications/subscriptions/command/PhabricatorSubscriptionsUnsubscribeEmailCommand.php',
'PhabricatorSupportApplication' => 'applications/support/application/PhabricatorSupportApplication.php',
'PhabricatorSyntaxHighlighter' => 'infrastructure/markup/PhabricatorSyntaxHighlighter.php',
'PhabricatorSyntaxHighlightingConfigOptions' => 'applications/config/option/PhabricatorSyntaxHighlightingConfigOptions.php',
@@ -4320,6 +4322,7 @@
'ManiphestTransactionSaveController' => 'ManiphestController',
'ManiphestUpdateConduitAPIMethod' => 'ManiphestConduitAPIMethod',
'ManiphestView' => 'AphrontView',
+ 'MetaMTAEmailTransactionCommand' => 'Phobject',
'MetaMTAMailReceivedGarbageCollector' => 'PhabricatorGarbageCollector',
'MetaMTAMailSentGarbageCollector' => 'PhabricatorGarbageCollector',
'MetaMTANotificationType' => 'MetaMTAConstants',
@@ -5921,6 +5924,7 @@
'PhabricatorSubscriptionsListController' => 'PhabricatorController',
'PhabricatorSubscriptionsTransactionController' => 'PhabricatorController',
'PhabricatorSubscriptionsUIEventListener' => 'PhabricatorEventListener',
+ 'PhabricatorSubscriptionsUnsubscribeEmailCommand' => 'MetaMTAEmailTransactionCommand',
'PhabricatorSupportApplication' => 'PhabricatorApplication',
'PhabricatorSyntaxHighlightingConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorSystemActionEngine' => 'Phobject',
diff --git a/src/applications/files/mail/FileReplyHandler.php b/src/applications/files/mail/FileReplyHandler.php
--- a/src/applications/files/mail/FileReplyHandler.php
+++ b/src/applications/files/mail/FileReplyHandler.php
@@ -13,22 +13,4 @@
return 'F';
}
- protected function processMailCommands(array $commands) {
- $actor = $this->getActor();
-
- $xactions = array();
- foreach ($commands as $command) {
- switch (head($command)) {
- case 'unsubscribe':
- $xaction = id(new PhabricatorFileTransaction())
- ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)
- ->setNewValue(array('-' => array($actor->getPHID())));
- $xactions[] = $xaction;
- break;
- }
- }
-
- return $xactions;
- }
-
}
diff --git a/src/applications/metamta/command/MetaMTAEmailTransactionCommand.php b/src/applications/metamta/command/MetaMTAEmailTransactionCommand.php
new file mode 100644
--- /dev/null
+++ b/src/applications/metamta/command/MetaMTAEmailTransactionCommand.php
@@ -0,0 +1,81 @@
+<?php
+
+abstract class MetaMTAEmailTransactionCommand extends Phobject {
+
+ abstract public function getCommand();
+ abstract public function isCommandSupportedForObject(
+ PhabricatorApplicationTransactionInterface $object);
+ abstract public function buildTransactions(
+ PhabricatorUser $viewer,
+ PhabricatorApplicationTransactionInterface $object,
+ PhabricatorMetaMTAReceivedMail $mail,
+ $command,
+ array $argv);
+
+ public function getCommandAliases() {
+ return array();
+ }
+
+ public function getCommandObjects() {
+ return array($this);
+ }
+
+ public static function getAllCommands() {
+ static $commands;
+
+ if ($commands === null) {
+ $kinds = id(new PhutilSymbolLoader())
+ ->setAncestorClass(__CLASS__)
+ ->loadObjects();
+ $commands = array();
+ foreach ($kinds as $kind) {
+ foreach ($kind->getCommandObjects() as $command) {
+ $commands[] = $command;
+ }
+ }
+ }
+
+ return $commands;
+ }
+
+ public static function getAllCommandsForObject(
+ PhabricatorApplicationTransactionInterface $object) {
+
+ $commands = self::getAllCommands();
+ foreach ($commands as $key => $command) {
+ if (!$command->isCommandSupportedForObject($object)) {
+ unset($commands[$key]);
+ }
+ }
+
+ return $commands;
+ }
+
+ public static function getCommandMap(array $commands) {
+ assert_instances_of($commands, 'MetaMTAEmailTransactionCommand');
+
+ $map = array();
+ foreach ($commands as $command) {
+ $keywords = $command->getCommandAliases();
+ $keywords[] = $command->getCommand();
+
+ foreach ($keywords as $keyword) {
+ $keyword = phutil_utf8_strtolower($keyword);
+ if (empty($map[$keyword])) {
+ $map[$keyword] = $command;
+ } else {
+ throw new Exception(
+ pht(
+ 'Mail commands "%s" and "%s" both respond to keyword "%s". '.
+ 'Keywords must be uniquely associated with commands.',
+ get_class($command),
+ get_class($map[$keyword]),
+ $keyword));
+ }
+ }
+ }
+
+ return $map;
+ }
+
+}
diff --git a/src/applications/paste/mail/PasteReplyHandler.php b/src/applications/paste/mail/PasteReplyHandler.php
--- a/src/applications/paste/mail/PasteReplyHandler.php
+++ b/src/applications/paste/mail/PasteReplyHandler.php
@@ -13,22 +13,4 @@
return 'P';
}
- protected function processMailCommands(array $commands) {
- $actor = $this->getActor();
-
- $xactions = array();
- foreach ($commands as $command) {
- switch (head($command)) {
- case 'unsubscribe':
- $xaction = id(new PhabricatorPasteTransaction())
- ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)
- ->setNewValue(array('-' => array($actor->getPHID())));
- $xactions[] = $xaction;
- break;
- }
- }
-
- return $xactions;
- }
-
}
diff --git a/src/applications/subscriptions/command/PhabricatorSubscriptionsUnsubscribeEmailCommand.php b/src/applications/subscriptions/command/PhabricatorSubscriptionsUnsubscribeEmailCommand.php
new file mode 100644
--- /dev/null
+++ b/src/applications/subscriptions/command/PhabricatorSubscriptionsUnsubscribeEmailCommand.php
@@ -0,0 +1,33 @@
+<?php
+
+final class PhabricatorSubscriptionsUnsubscribeEmailCommand
+ extends MetaMTAEmailTransactionCommand {
+
+ public function getCommand() {
+ return 'unsubscribe';
+ }
+
+ public function isCommandSupportedForObject(
+ PhabricatorApplicationTransactionInterface $object) {
+ return ($object instanceof PhabricatorSubscribableInterface);
+ }
+
+ public function buildTransactions(
+ PhabricatorUser $viewer,
+ PhabricatorApplicationTransactionInterface $object,
+ PhabricatorMetaMTAReceivedMail $mail,
+ $command,
+ array $argv) {
+ $xactions = array();
+
+ $xactions[] = $object->getApplicationTransactionTemplate()
+ ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)
+ ->setNewValue(
+ array(
+ '-' => array($viewer->getPHID()),
+ ));
+
+ return $xactions;
+ }
+
+}
diff --git a/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php b/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php
--- a/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php
+++ b/src/applications/transactions/replyhandler/PhabricatorApplicationTransactionReplyHandler.php
@@ -49,7 +49,9 @@
$body_data = $mail->parseBody();
- $xactions = $this->processMailCommands($body_data['commands']);
+ $xactions = $this->processMailCommands(
+ $mail,
+ $body_data['commands']);
// If this object is subscribable, subscribe all the users who were
// CC'd on the message.
@@ -84,9 +86,60 @@
->applyTransactions($target, $xactions);
}
- protected function processMailCommands(array $commands) {
- // TODO: Modularize this.
- return array();
+ private function processMailCommands(
+ PhabricatorMetaMTAReceivedMail $mail,
+ array $command_list) {
+
+ $viewer = $this->getActor();
+ $object = $this->getMailReceiver();
+
+ $list = MetaMTAEmailTransactionCommand::getAllCommandsForObject($object);
+ $map = MetaMTAEmailTransactionCommand::getCommandMap($list);
+
+ $xactions = array();
+ foreach ($command_list as $command_argv) {
+ $command = head($command_argv);
+ $argv = array_slice($command_argv, 1);
+
+ $handler = idx($map, phutil_utf8_strtolower($command));
+ if ($handler) {
+ $results = $handler->buildTransactions(
+ $viewer,
+ $object,
+ $mail,
+ $command,
+ $argv);
+ foreach ($results as $result) {
+ $xactions[] = $result;
+ }
+ } else {
+ $valid_commands = array();
+ foreach ($list as $valid_command) {
+ $aliases = $valid_command->getCommandAliases();
+ if ($aliases) {
+ foreach ($aliases as $key => $alias) {
+ $aliases[$key] = '!'.$alias;
+ }
+ $aliases = implode(', ', $aliases);
+ $valid_commands[] = pht(
+ '!%s (or %s)',
+ $valid_command->getCommand(),
+ $aliases);
+ } else {
+ $valid_commands[] = '!'.$valid_command->getCommand();
+ }
+ }
+
+ throw new Exception(
+ pht(
+ 'The command "!%s" is not a supported mail command. Valid '.
+ 'commands for this object are: %s.',
+ $command,
+ implode(', ', $valid_commands)));
+ }
+ }
+
+ return $xactions;
}
}

File Metadata

Mime Type
text/plain
Expires
Wed, May 15, 11:39 PM (2 w, 2 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6287679
Default Alt Text
D12238.diff (10 KB)

Event Timeline