protected function processReceivedMail(PhabricatorMetaMTAReceivedMail $mail, PhabricatorUser $sender)
 {
     $title = $mail->getSubject();
     if (!$title) {
         $title = pht('Email Paste');
     }
     $file = PhabricatorPasteEditor::initializeFileForPaste($sender, $title, $mail->getCleanTextBody());
     $xactions = array();
     $xactions[] = id(new PhabricatorPasteTransaction())->setTransactionType(PhabricatorPasteTransaction::TYPE_CONTENT)->setNewValue($file->getPHID());
     $xactions[] = id(new PhabricatorPasteTransaction())->setTransactionType(PhabricatorPasteTransaction::TYPE_TITLE)->setNewValue($title);
     $xactions[] = id(new PhabricatorPasteTransaction())->setTransactionType(PhabricatorPasteTransaction::TYPE_LANGUAGE)->setNewValue('');
     // auto-detect
     $paste = PhabricatorPaste::initializeNewPaste($sender);
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_EMAIL, array('id' => $mail->getID()));
     $editor = id(new PhabricatorPasteEditor())->setActor($sender)->setContentSource($content_source)->setContinueOnNoEffect(true);
     $xactions = $editor->applyTransactions($paste, $xactions);
     $mail->setRelatedPHID($paste->getPHID());
     $subject_prefix = PhabricatorEnv::getEnvConfig('metamta.paste.subject-prefix');
     $subject = pht('You successfully created a paste.');
     $paste_uri = PhabricatorEnv::getProductionURI($paste->getURI());
     $body = new PhabricatorMetaMTAMailBody();
     $body->addRawSection($subject);
     $body->addTextSection(pht('PASTE LINK'), $paste_uri);
     id(new PhabricatorMetaMTAMail())->addTos(array($sender->getPHID()))->setSubject($subject)->setSubjectPrefix($subject_prefix)->setFrom($sender->getPHID())->setRelatedPHID($paste->getPHID())->setBody($body->render())->saveAndSend();
 }
 protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail)
 {
     $conpherence = $this->getMailReceiver();
     $user = $this->getActor();
     if (!$conpherence->getPHID()) {
         $conpherence->attachParticipants(array())->attachFilePHIDs(array());
     } else {
         $edge_type = PhabricatorObjectHasFileEdgeType::EDGECONST;
         $file_phids = PhabricatorEdgeQuery::loadDestinationPHIDs($conpherence->getPHID(), $edge_type);
         $conpherence->attachFilePHIDs($file_phids);
         $participants = id(new ConpherenceParticipant())->loadAllWhere('conpherencePHID = %s', $conpherence->getPHID());
         $participants = mpull($participants, null, 'getParticipantPHID');
         $conpherence->attachParticipants($participants);
     }
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_EMAIL, array('id' => $mail->getID()));
     $editor = id(new ConpherenceEditor())->setActor($user)->setContentSource($content_source)->setParentMessageID($mail->getMessageID());
     $body = $mail->getCleanTextBody();
     $body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments());
     $xactions = array();
     if ($this->getMailAddedParticipantPHIDs()) {
         $xactions[] = id(new ConpherenceTransaction())->setTransactionType(ConpherenceTransaction::TYPE_PARTICIPANTS)->setNewValue(array('+' => $this->getMailAddedParticipantPHIDs()));
     }
     $xactions = array_merge($xactions, $editor->generateTransactionsFromText($user, $conpherence, $body));
     $editor->applyTransactions($conpherence, $xactions);
     return $conpherence;
 }
 protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail)
 {
     $actor = $this->getActor();
     $document = $this->getMailReceiver();
     $body_data = $mail->parseBody();
     $body = $body_data['body'];
     $body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments());
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_EMAIL, array('id' => $mail->getID()));
     $xactions = array();
     $command = $body_data['command'];
     switch ($command) {
         case 'unsubscribe':
             $xaction = id(new LegalpadTransaction())->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)->setNewValue(array('-' => array($actor->getPHID())));
             $xactions[] = $xaction;
             break;
     }
     $xactions[] = id(new LegalpadTransaction())->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)->attachComment(id(new LegalpadTransactionComment())->setDocumentID($document->getID())->setLineNumber(0)->setLineLength(0)->setContent($body));
     $editor = id(new LegalpadDocumentEditor())->setActor($actor)->setContentSource($content_source)->setContinueOnNoEffect(true)->setIsPreview(false);
     try {
         $xactions = $editor->applyTransactions($document, $xactions);
     } catch (PhabricatorApplicationTransactionNoEffectException $ex) {
         // just do nothing, though unclear why you're sending a blank email
         return true;
     }
     $head_xaction = head($xactions);
     return $head_xaction->getID();
 }
 private function newEditor(PhabricatorMetaMTAReceivedMail $mail)
 {
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_EMAIL, array('id' => $mail->getID()));
     $editor = $this->getMailReceiver()->getApplicationTransactionEditor()->setActor($this->getActor())->setContentSource($content_source)->setContinueOnMissingFields(true)->setParentMessageID($mail->getMessageID())->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs());
     if ($this->getApplicationEmail()) {
         $editor->setApplicationEmail($this->getApplicationEmail());
     }
     return $editor;
 }
 protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail)
 {
     $commit = $this->getMailReceiver();
     $actor = $this->getActor();
     $message = $mail->getCleanTextBody();
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_EMAIL, array('id' => $mail->getID()));
     // TODO: Support !raise, !accept, etc.
     $xactions = array();
     $xactions[] = id(new PhabricatorAuditTransaction())->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)->attachComment(id(new PhabricatorAuditTransactionComment())->setCommitPHID($commit->getPHID())->setContent($message));
     $editor = id(new PhabricatorAuditEditor())->setActor($actor)->setContentSource($content_source)->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs())->setContinueOnMissingFields(true)->applyTransactions($commit, $xactions);
 }
 protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail)
 {
     $rq = $this->getMailReceiver();
     $user = $this->getActor();
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_EMAIL, array('id' => $mail->getID()));
     $editor = id(new ReleephRequestTransactionalEditor())->setActor($user)->setContentSource($content_source)->setParentMessageID($mail->getMessageID());
     $body = $mail->getCleanTextBody();
     $xactions = array();
     $xactions[] = id(new ReleephRequestTransaction())->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)->attachComment($body);
     $editor->applyTransactions($rq, $xactions);
     return $rq;
 }
 public function receiveEmail(PhabricatorMetaMTAReceivedMail $mail)
 {
     // NOTE: We'll drop in here on both the "reply to a task" and "create a
     // new task" workflows! Make sure you test both if you make changes!
     $task = $this->getMailReceiver();
     $is_new_task = !$task->getID();
     $user = $this->getActor();
     $body = $mail->getCleanTextBody();
     $body = trim($body);
     $xactions = array();
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_EMAIL, array('id' => $mail->getID()));
     $template = new ManiphestTransaction();
     $template->setContentSource($content_source);
     $template->setAuthorPHID($user->getPHID());
     if ($is_new_task) {
         // If this is a new task, create a "User created this task." transaction
         // and then set the title and description.
         $xaction = clone $template;
         $xaction->setTransactionType(ManiphestTransactionType::TYPE_STATUS);
         $xaction->setNewValue(ManiphestTaskStatus::STATUS_OPEN);
         $xactions[] = $xaction;
         $task->setAuthorPHID($user->getPHID());
         $task->setTitle(nonempty($mail->getSubject(), 'Untitled Task'));
         $task->setDescription($body);
     } else {
         $lines = explode("\n", trim($body));
         $first_line = head($lines);
         $command = null;
         $matches = null;
         if (preg_match('/^!(\\w+)/', $first_line, $matches)) {
             $lines = array_slice($lines, 1);
             $body = implode("\n", $lines);
             $body = trim($body);
             $command = $matches[1];
         }
         $ttype = ManiphestTransactionType::TYPE_NONE;
         $new_value = null;
         switch ($command) {
             case 'close':
                 $ttype = ManiphestTransactionType::TYPE_STATUS;
                 $new_value = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED;
                 break;
             case 'claim':
                 $ttype = ManiphestTransactionType::TYPE_OWNER;
                 $new_value = $user->getPHID();
                 break;
             case 'unsubscribe':
                 $ttype = ManiphestTransactionType::TYPE_CCS;
                 $ccs = $task->getCCPHIDs();
                 foreach ($ccs as $k => $phid) {
                     if ($phid == $user->getPHID()) {
                         unset($ccs[$k]);
                     }
                 }
                 $new_value = array_values($ccs);
                 break;
         }
         $xaction = clone $template;
         $xaction->setTransactionType($ttype);
         $xaction->setNewValue($new_value);
         $xaction->setComments($body);
         $xactions[] = $xaction;
     }
     // TODO: We should look at CCs on the mail and add them as CCs.
     $files = $mail->getAttachments();
     if ($files) {
         $file_xaction = clone $template;
         $file_xaction->setTransactionType(ManiphestTransactionType::TYPE_ATTACH);
         $phid_type = PhabricatorPHIDConstants::PHID_TYPE_FILE;
         $new = $task->getAttached();
         foreach ($files as $file_phid) {
             $new[$phid_type][$file_phid] = array();
         }
         $file_xaction->setNewValue($new);
         $xactions[] = $file_xaction;
     }
     $event = new PhabricatorEvent(PhabricatorEventType::TYPE_MANIPHEST_WILLEDITTASK, array('task' => $task, 'mail' => $mail, 'new' => $is_new_task, 'transactions' => $xactions));
     $event->setUser($user);
     PhutilEventEngine::dispatchEvent($event);
     $task = $event->getValue('task');
     $xactions = $event->getValue('transactions');
     $editor = new ManiphestTransactionEditor();
     $editor->setParentMessageID($mail->getMessageID());
     $editor->applyTransactions($task, $xactions);
 }
 public function execute(PhutilArgumentParser $args)
 {
     $console = PhutilConsole::getConsole();
     $to = $args->getArg('to');
     if (!$to) {
         throw new PhutilArgumentUsageException(pht("Use '%s' to specify the receiving object or email address.", '--to'));
     }
     $to_application_email = id(new PhabricatorMetaMTAApplicationEmailQuery())->setViewer($this->getViewer())->withAddresses(array($to))->executeOne();
     $as = $args->getArg('as');
     if (!$as && $to_application_email) {
         $default_phid = $to_application_email->getConfigValue(PhabricatorMetaMTAApplicationEmail::CONFIG_DEFAULT_AUTHOR);
         if ($default_phid) {
             $default_user = id(new PhabricatorPeopleQuery())->setViewer($this->getViewer())->withPHIDs(array($default_phid))->executeOne();
             if ($default_user) {
                 $as = $default_user->getUsername();
             }
         }
     }
     if (!$as) {
         throw new PhutilArgumentUsageException(pht("Use '--as' to specify the acting user."));
     }
     $user = id(new PhabricatorPeopleQuery())->setViewer($this->getViewer())->withUsernames(array($as))->executeOne();
     if (!$user) {
         throw new PhutilArgumentUsageException(pht("No such user '%s' exists.", $as));
     }
     $from = $args->getArg('from');
     if (!$from) {
         $from = $user->loadPrimaryEmail()->getAddress();
     }
     $console->writeErr("%s\n", pht('Reading message body from stdin...'));
     $body = file_get_contents('php://stdin');
     $received = new PhabricatorMetaMTAReceivedMail();
     $header_content = array('Message-ID' => Filesystem::readRandomCharacters(12), 'From' => $from);
     if (preg_match('/.+@.+/', $to)) {
         $header_content['to'] = $to;
     } else {
         // We allow the user to use an object name instead of a real address
         // as a convenience. To build the mail, we build a similar message and
         // look for a receiver which will accept it.
         $pseudohash = PhabricatorObjectMailReceiver::computeMailHash('x', 'y');
         $pseudomail = id(new PhabricatorMetaMTAReceivedMail())->setHeaders(array('to' => $to . '+1+' . $pseudohash));
         $receivers = id(new PhutilClassMapQuery())->setAncestorClass('PhabricatorMailReceiver')->setFilterMethod('isEnabled')->execute();
         $receiver = null;
         foreach ($receivers as $possible_receiver) {
             if (!$possible_receiver->canAcceptMail($pseudomail)) {
                 continue;
             }
             $receiver = $possible_receiver;
             break;
         }
         if (!$receiver) {
             throw new Exception(pht("No configured mail receiver can accept mail to '%s'.", $to));
         }
         if (!$receiver instanceof PhabricatorObjectMailReceiver) {
             $class = get_class($receiver);
             throw new Exception(pht("Receiver '%s' accepts mail to '%s', but is not a " . "subclass of PhabricatorObjectMailReceiver.", $class, $to));
         }
         $object = $receiver->loadMailReceiverObject($to, $user);
         if (!$object) {
             throw new Exception(pht("No such object '%s'!", $to));
         }
         $hash = PhabricatorObjectMailReceiver::computeMailHash($object->getMailKey(), $user->getPHID());
         $header_content['to'] = $to . '+' . $user->getID() . '+' . $hash . '@test.com';
     }
     $received->setHeaders($header_content);
     $received->setBodies(array('text' => $body));
     $received->save();
     $received->processReceivedMail();
     $console->writeErr("%s\n\n    phabricator/ \$ ./bin/mail show-inbound --id %d\n\n", pht('Mail received! You can view details by running this command:'), $received->getID());
 }
 protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail)
 {
     // NOTE: We'll drop in here on both the "reply to a task" and "create a
     // new task" workflows! Make sure you test both if you make changes!
     $task = $this->getMailReceiver();
     $is_new_task = !$task->getID();
     $user = $this->getActor();
     $body_data = $mail->parseBody();
     $body = $body_data['body'];
     $body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments());
     $xactions = array();
     $content_source = PhabricatorContentSource::newForSource(PhabricatorContentSource::SOURCE_EMAIL, array('id' => $mail->getID()));
     $template = new ManiphestTransaction();
     $is_unsub = false;
     if ($is_new_task) {
         $task = ManiphestTask::initializeNewTask($user);
         $xactions[] = id(new ManiphestTransaction())->setTransactionType(ManiphestTransaction::TYPE_STATUS)->setNewValue(ManiphestTaskStatus::getDefaultStatus());
         $xactions[] = id(new ManiphestTransaction())->setTransactionType(ManiphestTransaction::TYPE_TITLE)->setNewValue(nonempty($mail->getSubject(), pht('Untitled Task')));
         $xactions[] = id(new ManiphestTransaction())->setTransactionType(ManiphestTransaction::TYPE_DESCRIPTION)->setNewValue($body);
     } else {
         $command = $body_data['command'];
         $command_value = $body_data['command_value'];
         $ttype = PhabricatorTransactions::TYPE_COMMENT;
         $new_value = null;
         switch ($command) {
             case 'close':
                 $ttype = ManiphestTransaction::TYPE_STATUS;
                 $new_value = ManiphestTaskStatus::getDefaultClosedStatus();
                 break;
             case 'claim':
                 $ttype = ManiphestTransaction::TYPE_OWNER;
                 $new_value = $user->getPHID();
                 break;
             case 'assign':
                 $ttype = ManiphestTransaction::TYPE_OWNER;
                 if ($command_value) {
                     $assign_users = id(new PhabricatorPeopleQuery())->setViewer($user)->withUsernames(array($command_value))->execute();
                     if ($assign_users) {
                         $assign_user = head($assign_users);
                         $new_value = $assign_user->getPHID();
                     }
                 }
                 // assign to the user by default
                 if (!$new_value) {
                     $new_value = $user->getPHID();
                 }
                 break;
             case 'unsubscribe':
                 $is_unsub = true;
                 $ttype = ManiphestTransaction::TYPE_CCS;
                 $ccs = $task->getCCPHIDs();
                 foreach ($ccs as $k => $phid) {
                     if ($phid == $user->getPHID()) {
                         unset($ccs[$k]);
                     }
                 }
                 $new_value = array_values($ccs);
                 break;
         }
         if ($ttype != PhabricatorTransactions::TYPE_COMMENT) {
             $xaction = clone $template;
             $xaction->setTransactionType($ttype);
             $xaction->setNewValue($new_value);
             $xactions[] = $xaction;
         }
         if (strlen($body)) {
             $xaction = clone $template;
             $xaction->setTransactionType(PhabricatorTransactions::TYPE_COMMENT);
             $xaction->attachComment(id(new ManiphestTransactionComment())->setContent($body));
             $xactions[] = $xaction;
         }
     }
     $ccs = $mail->loadCCPHIDs();
     $old_ccs = $task->getCCPHIDs();
     $new_ccs = array_merge($old_ccs, $ccs);
     if (!$is_unsub) {
         $new_ccs[] = $user->getPHID();
     }
     $new_ccs = array_unique($new_ccs);
     if (array_diff($new_ccs, $old_ccs)) {
         $cc_xaction = clone $template;
         $cc_xaction->setTransactionType(ManiphestTransaction::TYPE_CCS);
         $cc_xaction->setNewValue($new_ccs);
         $xactions[] = $cc_xaction;
     }
     $event = new PhabricatorEvent(PhabricatorEventType::TYPE_MANIPHEST_WILLEDITTASK, array('task' => $task, 'mail' => $mail, 'new' => $is_new_task, 'transactions' => $xactions));
     $event->setUser($user);
     PhutilEventEngine::dispatchEvent($event);
     $task = $event->getValue('task');
     $xactions = $event->getValue('transactions');
     $editor = id(new ManiphestTransactionEditor())->setActor($user)->setParentMessageID($mail->getMessageID())->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs())->setContinueOnNoEffect(true)->setContinueOnMissingFields(true)->setContentSource($content_source)->applyTransactions($task, $xactions);
     $event = new PhabricatorEvent(PhabricatorEventType::TYPE_MANIPHEST_DIDEDITTASK, array('task' => $task, 'new' => $is_new_task, 'transactions' => $xactions));
     $event->setUser($user);
     PhutilEventEngine::dispatchEvent($event);
 }