public function buildMailSection()
 {
     $inlines = $this->getInlines();
     $comments = mpull($inlines, 'getComment');
     $comments = mpull($comments, null, 'getPHID');
     $parents = $this->loadParents($comments);
     $all_comments = $comments + $parents;
     $this->changesets = $this->loadChangesets($all_comments);
     $this->authors = $this->loadAuthors($all_comments);
     $groups = $this->groupInlines($inlines);
     $hunk_parser = new DifferentialHunkParser();
     $spacer_text = null;
     $spacer_html = phutil_tag('br');
     $section = new PhabricatorMetaMTAMailSection();
     $last_group_key = last_key($groups);
     foreach ($groups as $changeset_id => $group) {
         $changeset = $this->getChangeset($changeset_id);
         if (!$changeset) {
             continue;
         }
         $is_last_group = $changeset_id == $last_group_key;
         $last_inline_key = last_key($group);
         foreach ($group as $inline_key => $inline) {
             $comment = $inline->getComment();
             $parent_phid = $comment->getReplyToCommentPHID();
             $is_last_inline = $inline_key == $last_inline_key;
             $context_text = null;
             $context_html = null;
             if ($parent_phid) {
                 $parent = idx($parents, $parent_phid);
                 if ($parent) {
                     $context_text = $this->renderInline($parent, false, true);
                     $context_html = $this->renderInline($parent, true, true);
                 }
             } else {
                 $patch_text = $this->getPatch($hunk_parser, $comment, false);
                 $context_text = $this->renderPatch($comment, $patch_text, false);
                 $patch_html = $this->getPatch($hunk_parser, $comment, true);
                 $context_html = $this->renderPatch($comment, $patch_html, true);
             }
             $render_text = $this->renderInline($comment, false, false);
             $render_html = $this->renderInline($comment, true, false);
             $section->addPlaintextFragment($context_text);
             $section->addPlaintextFragment($spacer_text);
             $section->addPlaintextFragment($render_text);
             $html_fragment = $this->renderContentBox(array($context_html, $render_html));
             $section->addHTMLFragment($html_fragment);
             if (!$is_last_group || !$is_last_inline) {
                 $section->addPlaintextFragment($spacer_text);
                 $section->addHTMLFragment($spacer_html);
             }
         }
     }
     return $section;
 }
 private function renderPatchForMail(DifferentialDiff $diff)
 {
     $format = PhabricatorEnv::getEnvConfig('metamta.differential.patch-format');
     $patch = id(new DifferentialRawDiffRenderer())->setViewer($this->getActor())->setFormat($format)->setChangesets($diff->getChangesets())->buildPatch();
     $section = new PhabricatorMetaMTAMailSection();
     $section->addHTMLFragment($this->renderPatchHTMLForMail($patch));
     $section->addPlaintextFragment($patch);
     return $section;
 }
 protected function processReceivedMail(PhabricatorMetaMTAReceivedMail $mail, PhabricatorUser $sender)
 {
     $attachments = $mail->getAttachments();
     $files = array();
     $errors = array();
     if ($attachments) {
         $files = id(new PhabricatorFileQuery())->setViewer($sender)->withPHIDs($attachments)->execute();
         foreach ($files as $index => $file) {
             if ($file->getMimeType() != 'text/plain') {
                 $errors[] = pht('Could not parse file %s; only files with mimetype text/plain ' . 'can be parsed via email.', $file->getName());
                 unset($files[$index]);
             }
         }
     }
     $diffs = array();
     foreach ($files as $file) {
         $call = new ConduitCall('differential.createrawdiff', array('diff' => $file->loadFileData()));
         $call->setUser($sender);
         try {
             $result = $call->execute();
             $diffs[$file->getName()] = $result['uri'];
         } catch (Exception $e) {
             $errors[] = pht('Could not parse attachment %s; only attachments (and mail bodies) ' . 'generated via "diff" commands can be parsed.', $file->getName());
         }
     }
     $body = $mail->getCleanTextBody();
     if ($body) {
         $call = new ConduitCall('differential.createrawdiff', array('diff' => $body));
         $call->setUser($sender);
         try {
             $result = $call->execute();
             $diffs[pht('Mail Body')] = $result['uri'];
         } catch (Exception $e) {
             $errors[] = pht('Could not parse mail body; only mail bodies (and attachments) ' . 'generated via "diff" commands can be parsed.');
         }
     }
     $subject_prefix = PhabricatorEnv::getEnvConfig('metamta.differential.subject-prefix');
     if (count($diffs)) {
         $subject = pht('You successfully created %d diff(s).', count($diffs));
     } else {
         $subject = pht('Diff creation failed; see body for %s error(s).', new PhutilNumber(count($errors)));
     }
     $body = new PhabricatorMetaMTAMailBody();
     $body->addRawSection($subject);
     if (count($diffs)) {
         $text_body = '';
         $html_body = array();
         $body_label = pht('%s DIFF LINK(S)', new PhutilNumber(count($diffs)));
         foreach ($diffs as $filename => $diff_uri) {
             $text_body .= $filename . ': ' . $diff_uri . "\n";
             $html_body[] = phutil_tag('a', array('href' => $diff_uri), $filename);
             $html_body[] = phutil_tag('br');
         }
         $body->addTextSection($body_label, $text_body);
         $body->addHTMLSection($body_label, $html_body);
     }
     if (count($errors)) {
         $body_section = new PhabricatorMetaMTAMailSection();
         $body_label = pht('%s ERROR(S)', new PhutilNumber(count($errors)));
         foreach ($errors as $error) {
             $body_section->addFragment($error);
         }
         $body->addTextSection($body_label, $body_section);
     }
     id(new PhabricatorMetaMTAMail())->addTos(array($sender->getPHID()))->setSubject($subject)->setSubjectPrefix($subject_prefix)->setFrom($sender->getPHID())->setBody($body->render())->saveAndSend();
 }